From def589d362cfd42992841fa0cfe0a1aa8fc38794 Mon Sep 17 00:00:00 2001 From: Petya Slavova Date: Tue, 13 May 2025 12:32:22 +0300 Subject: [PATCH 1/5] Fix Readme formatting for Installation section --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 177f78feeb..1c5e5774a1 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,14 @@ The Python interface to the Redis key-value store. Start a redis via docker (for Redis versions >= 8.0): ``` bash -docker run -p 6379:6379 -it redis:latest +$ docker run -p 6379:6379 -it redis:latest ``` Start a redis via docker (for Redis versions < 8.0): ``` bash -docker run -p 6379:6379 -it redis/redis-stack:latest +$ docker run -p 6379:6379 -it redis/redis-stack:latest +``` To install redis-py, simply: From 3331a424c1e65e1e8b6f025bd6a2a90a672e4a63 Mon Sep 17 00:00:00 2001 From: Petya Slavova Date: Tue, 13 May 2025 13:21:33 +0300 Subject: [PATCH 2/5] Adding comment for the lib version in __init__.py (to force ci pipeline execution) --- redis/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redis/__init__.py b/redis/__init__.py index cd3ee12adb..d4000c6701 100644 --- a/redis/__init__.py +++ b/redis/__init__.py @@ -45,6 +45,8 @@ def int_or_str(value): return value +# This is the version of redis-py that is being used +# for building and installing the lib. __version__ = "6.1.0" VERSION = tuple(map(int_or_str, __version__.split("."))) From 10b90af3b5914cd4ca746b50e12419f745c60fbe Mon Sep 17 00:00:00 2001 From: petyaslavova Date: Fri, 23 May 2025 19:19:04 +0300 Subject: [PATCH 3/5] fix: Revert wrongly changed default value for check_hostname when instantiating RedisSSLContext (#3655) --- redis/asyncio/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis/asyncio/connection.py b/redis/asyncio/connection.py index d1ae81d269..583a871224 100644 --- a/redis/asyncio/connection.py +++ b/redis/asyncio/connection.py @@ -868,7 +868,7 @@ def __init__( cert_reqs: Optional[Union[str, ssl.VerifyMode]] = None, ca_certs: Optional[str] = None, ca_data: Optional[str] = None, - check_hostname: bool = True, + check_hostname: bool = False, min_version: Optional[TLSVersion] = None, ciphers: Optional[str] = None, ): From ee6f962b2158de51e5ff03b2af7e8b0a0dadd113 Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Mon, 26 May 2025 14:45:34 +0300 Subject: [PATCH 4/5] fix: Fixed potential deadlock from unexpected __del__ call (#3654) --- redis/client.py | 5 +++++ redis/cluster.py | 6 +++--- redis/connection.py | 14 +++++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/redis/client.py b/redis/client.py index dc4f0f9d0c..1f33bd4adf 100755 --- a/redis/client.py +++ b/redis/client.py @@ -369,6 +369,8 @@ def __init__( ]: raise RedisError("Client caching is only supported with RESP version 3") + # TODO: To avoid breaking changes during the bug fix, we have to keep non-reentrant lock. + # TODO: Remove this before next major version (7.0.0) self.single_connection_lock = threading.Lock() self.connection = None self._single_connection_client = single_connection_client @@ -774,6 +776,9 @@ def __init__( self._event_dispatcher = EventDispatcher() else: self._event_dispatcher = event_dispatcher + + # TODO: To avoid breaking changes during the bug fix, we have to keep non-reentrant lock. + # TODO: Remove this before next major version (7.0.0) self._lock = threading.Lock() if self.encoder is None: self.encoder = self.connection_pool.get_encoder() diff --git a/redis/cluster.py b/redis/cluster.py index af60e1c76c..17b93c3d4d 100644 --- a/redis/cluster.py +++ b/redis/cluster.py @@ -710,7 +710,7 @@ def __init__( self.result_callbacks = CaseInsensitiveDict(self.__class__.RESULT_CALLBACKS) self.commands_parser = CommandsParser(self) - self._lock = threading.Lock() + self._lock = threading.RLock() def __enter__(self): return self @@ -1474,7 +1474,7 @@ def __init__( self.connection_kwargs = kwargs self.read_load_balancer = LoadBalancer() if lock is None: - lock = threading.Lock() + lock = threading.RLock() self._lock = lock if event_dispatcher is None: self._event_dispatcher = EventDispatcher() @@ -2178,7 +2178,7 @@ def __init__( kwargs.get("decode_responses", False), ) if lock is None: - lock = threading.Lock() + lock = threading.RLock() self._lock = lock self.parent_execute_command = super().execute_command self._execution_strategy: ExecutionStrategy = ( diff --git a/redis/connection.py b/redis/connection.py index cc805e442f..daf1d8de9b 100644 --- a/redis/connection.py +++ b/redis/connection.py @@ -820,7 +820,7 @@ def __init__( self.credential_provider = conn.credential_provider self._pool_lock = pool_lock self._cache = cache - self._cache_lock = threading.Lock() + self._cache_lock = threading.RLock() self._current_command_cache_key = None self._current_options = None self.register_connect_callback(self._enable_tracking_callback) @@ -1420,8 +1420,16 @@ def __init__( # object of this pool. subsequent threads acquiring this lock # will notice the first thread already did the work and simply # release the lock. - self._fork_lock = threading.Lock() - self._lock = threading.Lock() + + self._fork_lock = threading.RLock() + + if self.cache is None: + self._lock = threading.RLock() + else: + # TODO: To avoid breaking changes during the bug fix, we have to keep non-reentrant lock. + # TODO: Remove this before next major version (7.0.0) + self._lock = threading.Lock() + self.reset() def __repr__(self) -> (str, str): From bd5e4eccf942c37aacb8e0bf09a661d83402f6e4 Mon Sep 17 00:00:00 2001 From: Petya Slavova Date: Mon, 2 Jun 2025 13:46:32 +0300 Subject: [PATCH 5/5] Updating lib version to 6.1.1 --- redis/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis/__init__.py b/redis/__init__.py index d4000c6701..cfddd25e5b 100644 --- a/redis/__init__.py +++ b/redis/__init__.py @@ -47,7 +47,7 @@ def int_or_str(value): # This is the version of redis-py that is being used # for building and installing the lib. -__version__ = "6.1.0" +__version__ = "6.1.1" VERSION = tuple(map(int_or_str, __version__.split(".")))