diff options
author | Shay Fadida <shayfadida@gmail.com> | 2022-11-09 14:22:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-09 14:22:27 +0200 |
commit | fb647430f00cc7bb67c978e75f2dabc661567779 (patch) | |
tree | 009cd0ab1bde4d4bcbaab5711079c04aab0eda74 | |
parent | 772079fabd7453edf3788d0c31b9caf21ff5deca (diff) | |
download | redis-py-fb647430f00cc7bb67c978e75f2dabc661567779.tar.gz |
Fix special response parsing options handling (#2302)
* Fix special response parsing options handling
When using special response parsing options like `NEVER_DECODE` and
`EMPTY_RESPONSE`, don't pass them to the response callbacks because some
of them are not prepared for receiving named arguments.
Instead, redis-py should use them before calling the callbacks and
then discard them.
* Use kwargs instead of options
* change options to kwargs in asyncio/cluster.py/L878
Co-authored-by: Chayim <chayim@users.noreply.github.com>
Co-authored-by: dvora-h <67596500+dvora-h@users.noreply.github.com>
-rw-r--r-- | redis/asyncio/client.py | 5 | ||||
-rw-r--r-- | redis/asyncio/cluster.py | 4 | ||||
-rwxr-xr-x | redis/client.py | 5 | ||||
-rw-r--r-- | tests/test_asyncio/test_commands.py | 12 | ||||
-rw-r--r-- | tests/test_commands.py | 12 |
5 files changed, 36 insertions, 2 deletions
diff --git a/redis/asyncio/client.py b/redis/asyncio/client.py index 6e66faa..619ee11 100644 --- a/redis/asyncio/client.py +++ b/redis/asyncio/client.py @@ -501,12 +501,17 @@ class Redis( try: if NEVER_DECODE in options: response = await connection.read_response(disable_decoding=True) + options.pop(NEVER_DECODE) else: response = await connection.read_response() except ResponseError: if EMPTY_RESPONSE in options: return options[EMPTY_RESPONSE] raise + + if EMPTY_RESPONSE in options: + options.pop(EMPTY_RESPONSE) + if command_name in self.response_callbacks: # Mypy bug: https://github.com/python/mypy/issues/10977 command_name = cast(str, command_name) diff --git a/redis/asyncio/cluster.py b/redis/asyncio/cluster.py index 8abb072..97f4151 100644 --- a/redis/asyncio/cluster.py +++ b/redis/asyncio/cluster.py @@ -934,6 +934,7 @@ class ClusterNode: try: if NEVER_DECODE in kwargs: response = await connection.read_response(disable_decoding=True) + kwargs.pop(NEVER_DECODE) else: response = await connection.read_response() except ResponseError: @@ -941,6 +942,9 @@ class ClusterNode: return kwargs[EMPTY_RESPONSE] raise + if EMPTY_RESPONSE in kwargs: + kwargs.pop(EMPTY_RESPONSE) + # Return response if command in self.response_callbacks: return self.response_callbacks[command](response, **kwargs) diff --git a/redis/client.py b/redis/client.py index c1fe9cb..6a26d28 100755 --- a/redis/client.py +++ b/redis/client.py @@ -1258,12 +1258,17 @@ class Redis(AbstractRedis, RedisModuleCommands, CoreCommands, SentinelCommands): try: if NEVER_DECODE in options: response = connection.read_response(disable_decoding=True) + options.pop(NEVER_DECODE) else: response = connection.read_response() except ResponseError: if EMPTY_RESPONSE in options: return options[EMPTY_RESPONSE] raise + + if EMPTY_RESPONSE in options: + options.pop(EMPTY_RESPONSE) + if command_name in self.response_callbacks: return self.response_callbacks[command_name](response, **options) return response diff --git a/tests/test_asyncio/test_commands.py b/tests/test_asyncio/test_commands.py index 1242e04..67471bb 100644 --- a/tests/test_asyncio/test_commands.py +++ b/tests/test_asyncio/test_commands.py @@ -11,7 +11,7 @@ import pytest_asyncio import redis from redis import exceptions -from redis.client import parse_info +from redis.client import EMPTY_RESPONSE, NEVER_DECODE, parse_info from tests.conftest import ( skip_if_server_version_gte, skip_if_server_version_lt, @@ -542,6 +542,16 @@ class TestRedisCommands: assert isinstance(t[0], int) assert isinstance(t[1], int) + async def test_never_decode_option(self, r: redis.Redis): + opts = {NEVER_DECODE: []} + await r.delete("a") + assert await r.execute_command("EXISTS", "a", **opts) == 0 + + async def test_empty_response_option(self, r: redis.Redis): + opts = {EMPTY_RESPONSE: []} + await r.delete("a") + assert await r.execute_command("EXISTS", "a", **opts) == 0 + # BASIC KEY COMMANDS async def test_append(self, r: redis.Redis): assert await r.append("a", "a1") == 2 diff --git a/tests/test_commands.py b/tests/test_commands.py index 1c9a5c2..aa6745b 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -9,7 +9,7 @@ import pytest import redis from redis import exceptions -from redis.client import parse_info +from redis.client import EMPTY_RESPONSE, NEVER_DECODE, parse_info from .conftest import ( _get_client, @@ -917,6 +917,16 @@ class TestRedisCommands: time.sleep(0.3) assert r.bgsave(True) + def test_never_decode_option(self, r: redis.Redis): + opts = {NEVER_DECODE: []} + r.delete("a") + assert r.execute_command("EXISTS", "a", **opts) == 0 + + def test_empty_response_option(self, r: redis.Redis): + opts = {EMPTY_RESPONSE: []} + r.delete("a") + assert r.execute_command("EXISTS", "a", **opts) == 0 + # BASIC KEY COMMANDS def test_append(self, r): assert r.append("a", "a1") == 2 |