summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordvora-h <67596500+dvora-h@users.noreply.github.com>2023-05-04 10:27:31 +0300
committerGitHub <noreply@github.com>2023-05-04 10:27:31 +0300
commitf1aa582026de6eaa09c30824ca4274c2efd09b7c (patch)
treea776162c33da6a48e7e74763fee291f2e51f57c4
parentf5abfe0a6632c13e6e4e8b739748acf26ace0965 (diff)
downloadredis-py-f1aa582026de6eaa09c30824ca4274c2efd09b7c.tar.gz
Fix `COMMAND` response in resp3 (redis 7+) (#2740)
-rwxr-xr-xredis/client.py21
-rw-r--r--redis/parsers/resp3.py20
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 = {