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..5cd7f388dd 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: + 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 = {