diff options
author | Aarni Koskela <akx@iki.fi> | 2022-09-28 14:09:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-28 14:09:32 +0300 |
commit | 027abe524acd0aec24e92ea7eef328f983d5278c (patch) | |
tree | 7a8c6191b51b74ea829e6ca99c5c170cae5a2982 | |
parent | 947b8e8595e3aff4aeb3eb3ebbe56b86fb5e76fb (diff) | |
download | redis-py-027abe524acd0aec24e92ea7eef328f983d5278c.tar.gz |
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
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | dev_requirements.txt | 1 | ||||
-rwxr-xr-x | redis/connection.py | 54 | ||||
-rw-r--r-- | redis/utils.py | 3 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | setup.py | 1 |
7 files changed, 16 insertions, 48 deletions
@@ -19,6 +19,7 @@ * Fix reusing the old nodes' connections when cluster topology refresh is being done * Fix RedisCluster to immediately raise AuthenticationError without a retry * ClusterPipeline Doesn't Handle ConnectionError for Dead Hosts (#2225) + * Remove compatibility code for old versions of Hiredis, drop Packaging dependency * 4.1.3 (Feb 8, 2022) * Fix flushdb and flushall (#1926) @@ -27,7 +27,8 @@ To install redis-py, simply: $ pip install redis ``` -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. +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 >= 1.0 is available, redis-py will attempt to use it for response parsing. ``` bash $ pip install redis[hiredis] diff --git a/dev_requirements.txt b/dev_requirements.txt index 31ae26e..66be6d1 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -4,6 +4,7 @@ flake8==4.0.1 flynt~=0.69.0 isort==5.10.1 mock==4.0.3 +packaging>=20.4 pytest==6.2.5 pytest-timeout==2.0.1 pytest-asyncio>=0.16.0 diff --git a/redis/connection.py b/redis/connection.py index 3281b14..491df8e 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -10,8 +10,6 @@ from queue import Empty, Full, LifoQueue from time import time from urllib.parse import parse_qs, unquote, urlparse -from packaging.version import Version - from redis.backoff import NoBackoff from redis.exceptions import ( AuthenticationError, @@ -54,16 +52,6 @@ NONBLOCKING_EXCEPTIONS = tuple(NONBLOCKING_EXCEPTION_ERROR_NUMBERS.keys()) if HIREDIS_AVAILABLE: import hiredis - hiredis_version = Version(hiredis.__version__) - HIREDIS_SUPPORTS_CALLABLE_ERRORS = hiredis_version >= Version("0.1.3") - HIREDIS_SUPPORTS_BYTE_BUFFER = hiredis_version >= Version("0.1.4") - HIREDIS_SUPPORTS_ENCODING_ERRORS = hiredis_version >= Version("1.0.0") - - HIREDIS_USE_BYTE_BUFFER = True - # only use byte buffer if hiredis supports it - if not HIREDIS_SUPPORTS_BYTE_BUFFER: - HIREDIS_USE_BYTE_BUFFER = False - SYM_STAR = b"*" SYM_DOLLAR = b"$" SYM_CRLF = b"\r\n" @@ -380,9 +368,7 @@ class HiredisParser(BaseParser): if not HIREDIS_AVAILABLE: raise RedisError("Hiredis is not installed") self.socket_read_size = socket_read_size - - if HIREDIS_USE_BYTE_BUFFER: - self._buffer = bytearray(socket_read_size) + self._buffer = bytearray(socket_read_size) def __del__(self): try: @@ -393,16 +379,14 @@ class HiredisParser(BaseParser): def on_connect(self, connection, **kwargs): self._sock = connection._sock self._socket_timeout = connection.socket_timeout - kwargs = {"protocolError": InvalidResponse, "replyError": self.parse_error} - - # hiredis < 0.1.3 doesn't support functions that create exceptions - if not HIREDIS_SUPPORTS_CALLABLE_ERRORS: - kwargs["replyError"] = ResponseError + kwargs = { + "protocolError": InvalidResponse, + "replyError": self.parse_error, + "errors": connection.encoder.encoding_errors, + } if connection.encoder.decode_responses: kwargs["encoding"] = connection.encoder.encoding - if HIREDIS_SUPPORTS_ENCODING_ERRORS: - kwargs["errors"] = connection.encoder.encoding_errors self._reader = hiredis.Reader(**kwargs) self._next_response = False @@ -427,17 +411,10 @@ class HiredisParser(BaseParser): try: if custom_timeout: sock.settimeout(timeout) - if HIREDIS_USE_BYTE_BUFFER: - bufflen = self._sock.recv_into(self._buffer) - if bufflen == 0: - raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) - self._reader.feed(self._buffer, 0, bufflen) - else: - buffer = self._sock.recv(self.socket_read_size) - # an empty string indicates the server shutdown the socket - if not isinstance(buffer, bytes) or len(buffer) == 0: - raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) - self._reader.feed(buffer) + bufflen = self._sock.recv_into(self._buffer) + if bufflen == 0: + raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) + self._reader.feed(self._buffer, 0, bufflen) # data was read from the socket and added to the buffer. # return True to indicate that data was read. return True @@ -479,17 +456,6 @@ class HiredisParser(BaseParser): response = self._reader.gets(False) else: response = self._reader.gets() - # if an older version of hiredis is installed, we need to attempt - # to convert ResponseErrors to their appropriate types. - if not HIREDIS_SUPPORTS_CALLABLE_ERRORS: - if isinstance(response, ResponseError): - response = self.parse_error(response.args[0]) - elif ( - isinstance(response, list) - and response - and isinstance(response[0], ResponseError) - ): - response[0] = self.parse_error(response[0].args[0]) # if the response is a ConnectionError or the response is a list and # the first item is a ConnectionError, raise it as something bad # happened diff --git a/redis/utils.py b/redis/utils.py index 0c34e1e..25d2491 100644 --- a/redis/utils.py +++ b/redis/utils.py @@ -4,7 +4,8 @@ from typing import Any, Dict, Mapping, Union try: import hiredis # noqa - HIREDIS_AVAILABLE = True + # Only support Hiredis >= 1.0: + HIREDIS_AVAILABLE = not hiredis.__version__.startswith("0.") except ImportError: HIREDIS_AVAILABLE = False diff --git a/requirements.txt b/requirements.txt index c40eca7..b764668 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ async-timeout>=4.0.2 deprecated>=1.2.3 -packaging>=20.4 typing-extensions; python_version<"3.8" @@ -33,7 +33,6 @@ setup( python_requires=">=3.7", install_requires=[ "deprecated>=1.2.3", - "packaging>=20.4", 'importlib-metadata >= 1.0; python_version < "3.8"', 'typing-extensions; python_version<"3.8"', "async-timeout>=4.0.2", |