diff options
author | dvora-h <67596500+dvora-h@users.noreply.github.com> | 2023-05-04 10:27:31 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-04 10:27:31 +0300 |
commit | f1aa582026de6eaa09c30824ca4274c2efd09b7c (patch) | |
tree | a776162c33da6a48e7e74763fee291f2e51f57c4 | |
parent | f5abfe0a6632c13e6e4e8b739748acf26ace0965 (diff) | |
download | redis-py-f1aa582026de6eaa09c30824ca4274c2efd09b7c.tar.gz |
Fix `COMMAND` response in resp3 (redis 7+) (#2740)
-rwxr-xr-x | redis/client.py | 21 | ||||
-rw-r--r-- | redis/parsers/resp3.py | 20 |
2 files changed, 37 insertions, 4 deletions
diff --git a/redis/client.py b/redis/client.py index 71048f5..565f133 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 93fb6ff..5cd7f38 100644 --- a/redis/parsers/resp3.py +++ b/redis/parsers/resp3.py @@ -80,10 +80,16 @@ class _RESP3Parser(_RESPBase): ] # 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: + pass # map response elif byte == b"%": response = { @@ -199,10 +205,16 @@ class _AsyncRESP3Parser(_AsyncRESPBase): ] # 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 = { |