Skip to content

Commit 027abe5

Browse files
authored
Support Hiredis >= 1.x only (remove packaging dependency) (#2385)
* Only set HIREDIS_AVAILABLE if Hiredis is not 0.x * Remove compatibility code for old Hiredis versions * Move packaging dependency to dev only
1 parent 947b8e8 commit 027abe5

File tree

7 files changed

+16
-48
lines changed

7 files changed

+16
-48
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* Fix reusing the old nodes' connections when cluster topology refresh is being done
2020
* Fix RedisCluster to immediately raise AuthenticationError without a retry
2121
* ClusterPipeline Doesn't Handle ConnectionError for Dead Hosts (#2225)
22+
* Remove compatibility code for old versions of Hiredis, drop Packaging dependency
2223

2324
* 4.1.3 (Feb 8, 2022)
2425
* Fix flushdb and flushall (#1926)

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ To install redis-py, simply:
2727
$ pip install redis
2828
```
2929

30-
For faster performance, install redis with hiredis support, this provides a compiled response parser, and *for most cases* requires zero code changes. By default, if hiredis is available, redis-py will attempt to use it for response parsing.
30+
For faster performance, install redis with hiredis support, this provides a compiled response parser, and *for most cases* requires zero code changes.
31+
By default, if hiredis >= 1.0 is available, redis-py will attempt to use it for response parsing.
3132

3233
``` bash
3334
$ pip install redis[hiredis]

dev_requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ flake8==4.0.1
44
flynt~=0.69.0
55
isort==5.10.1
66
mock==4.0.3
7+
packaging>=20.4
78
pytest==6.2.5
89
pytest-timeout==2.0.1
910
pytest-asyncio>=0.16.0

redis/connection.py

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from time import time
1111
from urllib.parse import parse_qs, unquote, urlparse
1212

13-
from packaging.version import Version
14-
1513
from redis.backoff import NoBackoff
1614
from redis.exceptions import (
1715
AuthenticationError,
@@ -54,16 +52,6 @@
5452
if HIREDIS_AVAILABLE:
5553
import hiredis
5654

57-
hiredis_version = Version(hiredis.__version__)
58-
HIREDIS_SUPPORTS_CALLABLE_ERRORS = hiredis_version >= Version("0.1.3")
59-
HIREDIS_SUPPORTS_BYTE_BUFFER = hiredis_version >= Version("0.1.4")
60-
HIREDIS_SUPPORTS_ENCODING_ERRORS = hiredis_version >= Version("1.0.0")
61-
62-
HIREDIS_USE_BYTE_BUFFER = True
63-
# only use byte buffer if hiredis supports it
64-
if not HIREDIS_SUPPORTS_BYTE_BUFFER:
65-
HIREDIS_USE_BYTE_BUFFER = False
66-
6755
SYM_STAR = b"*"
6856
SYM_DOLLAR = b"$"
6957
SYM_CRLF = b"\r\n"
@@ -380,9 +368,7 @@ def __init__(self, socket_read_size):
380368
if not HIREDIS_AVAILABLE:
381369
raise RedisError("Hiredis is not installed")
382370
self.socket_read_size = socket_read_size
383-
384-
if HIREDIS_USE_BYTE_BUFFER:
385-
self._buffer = bytearray(socket_read_size)
371+
self._buffer = bytearray(socket_read_size)
386372

387373
def __del__(self):
388374
try:
@@ -393,16 +379,14 @@ def __del__(self):
393379
def on_connect(self, connection, **kwargs):
394380
self._sock = connection._sock
395381
self._socket_timeout = connection.socket_timeout
396-
kwargs = {"protocolError": InvalidResponse, "replyError": self.parse_error}
397-
398-
# hiredis < 0.1.3 doesn't support functions that create exceptions
399-
if not HIREDIS_SUPPORTS_CALLABLE_ERRORS:
400-
kwargs["replyError"] = ResponseError
382+
kwargs = {
383+
"protocolError": InvalidResponse,
384+
"replyError": self.parse_error,
385+
"errors": connection.encoder.encoding_errors,
386+
}
401387

402388
if connection.encoder.decode_responses:
403389
kwargs["encoding"] = connection.encoder.encoding
404-
if HIREDIS_SUPPORTS_ENCODING_ERRORS:
405-
kwargs["errors"] = connection.encoder.encoding_errors
406390
self._reader = hiredis.Reader(**kwargs)
407391
self._next_response = False
408392

@@ -427,17 +411,10 @@ def read_from_socket(self, timeout=SENTINEL, raise_on_timeout=True):
427411
try:
428412
if custom_timeout:
429413
sock.settimeout(timeout)
430-
if HIREDIS_USE_BYTE_BUFFER:
431-
bufflen = self._sock.recv_into(self._buffer)
432-
if bufflen == 0:
433-
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
434-
self._reader.feed(self._buffer, 0, bufflen)
435-
else:
436-
buffer = self._sock.recv(self.socket_read_size)
437-
# an empty string indicates the server shutdown the socket
438-
if not isinstance(buffer, bytes) or len(buffer) == 0:
439-
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
440-
self._reader.feed(buffer)
414+
bufflen = self._sock.recv_into(self._buffer)
415+
if bufflen == 0:
416+
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
417+
self._reader.feed(self._buffer, 0, bufflen)
441418
# data was read from the socket and added to the buffer.
442419
# return True to indicate that data was read.
443420
return True
@@ -479,17 +456,6 @@ def read_response(self, disable_decoding=False):
479456
response = self._reader.gets(False)
480457
else:
481458
response = self._reader.gets()
482-
# if an older version of hiredis is installed, we need to attempt
483-
# to convert ResponseErrors to their appropriate types.
484-
if not HIREDIS_SUPPORTS_CALLABLE_ERRORS:
485-
if isinstance(response, ResponseError):
486-
response = self.parse_error(response.args[0])
487-
elif (
488-
isinstance(response, list)
489-
and response
490-
and isinstance(response[0], ResponseError)
491-
):
492-
response[0] = self.parse_error(response[0].args[0])
493459
# if the response is a ConnectionError or the response is a list and
494460
# the first item is a ConnectionError, raise it as something bad
495461
# happened

redis/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
try:
55
import hiredis # noqa
66

7-
HIREDIS_AVAILABLE = True
7+
# Only support Hiredis >= 1.0:
8+
HIREDIS_AVAILABLE = not hiredis.__version__.startswith("0.")
89
except ImportError:
910
HIREDIS_AVAILABLE = False
1011

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
async-timeout>=4.0.2
22
deprecated>=1.2.3
3-
packaging>=20.4
43
typing-extensions; python_version<"3.8"

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
python_requires=">=3.7",
3434
install_requires=[
3535
"deprecated>=1.2.3",
36-
"packaging>=20.4",
3736
'importlib-metadata >= 1.0; python_version < "3.8"',
3837
'typing-extensions; python_version<"3.8"',
3938
"async-timeout>=4.0.2",

0 commit comments

Comments
 (0)