From e9adcb3aadd05131b2931e47ff1e7dc4cf6be207 Mon Sep 17 00:00:00 2001 From: dvora-h Date: Wed, 3 May 2023 19:49:07 +0300 Subject: [PATCH 1/2] fix command response in resp3 --- redis/client.py | 21 +++++++++++++++++++++ redis/parsers/resp3.py | 20 ++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/redis/client.py b/redis/client.py index 71048f548f..565f133d6f 100755 --- a/redis/client.py +++ b/redis/client.py @@ -574,6 +574,26 @@ def parse_command(response, **options): return commands +def parse_command_resp3(response, **options): + commands = {} + for command in response: + cmd_dict = {} + cmd_name = str_if_bytes(command[0]) + cmd_dict["name"] = cmd_name + cmd_dict["arity"] = command[1] + cmd_dict["flags"] = command[2] + cmd_dict["first_key_pos"] = command[3] + cmd_dict["last_key_pos"] = command[4] + cmd_dict["step_count"] = command[5] + cmd_dict["acl_categories"] = command[6] + cmd_dict["tips"] = command[7] + cmd_dict["key_specifications"] = command[8] + cmd_dict["subcommands"] = command[9] + + commands[cmd_name] = cmd_dict + return commands + + def parse_pubsub_numsub(response, **options): return list(zip(response[0::2], response[1::2])) @@ -874,6 +894,7 @@ class AbstractRedis: if isinstance(r, list) else bool_ok(r), **string_keys_to_dict("XREAD XREADGROUP", parse_xread_resp3), + "COMMAND": parse_command_resp3, "STRALGO": lambda r, **options: { str_if_bytes(key): str_if_bytes(value) for key, value in r.items() } diff --git a/redis/parsers/resp3.py b/redis/parsers/resp3.py index 93fb6ff554..f9ef732840 100644 --- a/redis/parsers/resp3.py +++ b/redis/parsers/resp3.py @@ -80,10 +80,16 @@ def _read_response(self, disable_decoding=False, push_request=False): ] # set response elif byte == b"~": - response = { + # redis can return unhashable types (like dict) in a set, + # so we need to first convert to a list, and then try to convert it to a set + response = [ self._read_response(disable_decoding=disable_decoding) for _ in range(int(response)) - } + ] + try: + response = set(response) + except TypeError as e: + pass # map response elif byte == b"%": response = { @@ -199,10 +205,16 @@ async def _read_response( ] # set response elif byte == b"~": - response = { + # redis can return unhashable types (like dict) in a set, + # so we need to first convert to a list, and then try to convert it to a set + response = [ (await self._read_response(disable_decoding=disable_decoding)) for _ in range(int(response)) - } + ] + try: + response = set(response) + except TypeError: + pass # map response elif byte == b"%": response = { From 32e46a73a786aba8b57b8051aba7e4638af8663b Mon Sep 17 00:00:00 2001 From: dvora-h Date: Wed, 3 May 2023 19:50:21 +0300 Subject: [PATCH 2/2] linters --- redis/parsers/resp3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis/parsers/resp3.py b/redis/parsers/resp3.py index f9ef732840..5cd7f388dd 100644 --- a/redis/parsers/resp3.py +++ b/redis/parsers/resp3.py @@ -88,7 +88,7 @@ def _read_response(self, disable_decoding=False, push_request=False): ] try: response = set(response) - except TypeError as e: + except TypeError: pass # map response elif byte == b"%":