Skip to content

Commit

Permalink
Fix COMMAND response in resp3 (redis 7+) (#2740)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvora-h committed May 4, 2023
1 parent f5abfe0 commit f1aa582
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
21 changes: 21 additions & 0 deletions redis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]))

Expand Down Expand Up @@ -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()
}
Expand Down
20 changes: 16 additions & 4 deletions redis/parsers/resp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down

0 comments on commit f1aa582

Please sign in to comment.