Skip to content

Commit f1aa582

Browse files
authored
Fix COMMAND response in resp3 (redis 7+) (#2740)
1 parent f5abfe0 commit f1aa582

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

redis/client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,26 @@ def parse_command(response, **options):
574574
return commands
575575

576576

577+
def parse_command_resp3(response, **options):
578+
commands = {}
579+
for command in response:
580+
cmd_dict = {}
581+
cmd_name = str_if_bytes(command[0])
582+
cmd_dict["name"] = cmd_name
583+
cmd_dict["arity"] = command[1]
584+
cmd_dict["flags"] = command[2]
585+
cmd_dict["first_key_pos"] = command[3]
586+
cmd_dict["last_key_pos"] = command[4]
587+
cmd_dict["step_count"] = command[5]
588+
cmd_dict["acl_categories"] = command[6]
589+
cmd_dict["tips"] = command[7]
590+
cmd_dict["key_specifications"] = command[8]
591+
cmd_dict["subcommands"] = command[9]
592+
593+
commands[cmd_name] = cmd_dict
594+
return commands
595+
596+
577597
def parse_pubsub_numsub(response, **options):
578598
return list(zip(response[0::2], response[1::2]))
579599

@@ -874,6 +894,7 @@ class AbstractRedis:
874894
if isinstance(r, list)
875895
else bool_ok(r),
876896
**string_keys_to_dict("XREAD XREADGROUP", parse_xread_resp3),
897+
"COMMAND": parse_command_resp3,
877898
"STRALGO": lambda r, **options: {
878899
str_if_bytes(key): str_if_bytes(value) for key, value in r.items()
879900
}

redis/parsers/resp3.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,16 @@ def _read_response(self, disable_decoding=False, push_request=False):
8080
]
8181
# set response
8282
elif byte == b"~":
83-
response = {
83+
# redis can return unhashable types (like dict) in a set,
84+
# so we need to first convert to a list, and then try to convert it to a set
85+
response = [
8486
self._read_response(disable_decoding=disable_decoding)
8587
for _ in range(int(response))
86-
}
88+
]
89+
try:
90+
response = set(response)
91+
except TypeError:
92+
pass
8793
# map response
8894
elif byte == b"%":
8995
response = {
@@ -199,10 +205,16 @@ async def _read_response(
199205
]
200206
# set response
201207
elif byte == b"~":
202-
response = {
208+
# redis can return unhashable types (like dict) in a set,
209+
# so we need to first convert to a list, and then try to convert it to a set
210+
response = [
203211
(await self._read_response(disable_decoding=disable_decoding))
204212
for _ in range(int(response))
205-
}
213+
]
214+
try:
215+
response = set(response)
216+
except TypeError:
217+
pass
206218
# map response
207219
elif byte == b"%":
208220
response = {

0 commit comments

Comments
 (0)