summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordvora-h <67596500+dvora-h@users.noreply.github.com>2022-05-08 15:23:09 +0300
committerGitHub <noreply@github.com>2022-05-08 15:23:09 +0300
commit883fca7199a7ab7adc583b9ee324a9e44d0909eb (patch)
tree4a0fd3d4edd9373829502b6de22cb542f7462478
parentfaf55b65ffb7294b1a639cc9adb0231b987b0e32 (diff)
downloadredis-py-883fca7199a7ab7adc583b9ee324a9e44d0909eb.tar.gz
Get command keys for subcommands (#2170)
* parse subcommands * fix tests
-rwxr-xr-xredis/client.py4
-rw-r--r--redis/cluster.py1
-rw-r--r--redis/commands/parser.py26
-rw-r--r--tests/test_cluster.py1
-rw-r--r--tests/test_commands.py3
5 files changed, 32 insertions, 3 deletions
diff --git a/redis/client.py b/redis/client.py
index 7c83b61..58668ee 100755
--- a/redis/client.py
+++ b/redis/client.py
@@ -553,6 +553,10 @@ def parse_command(response, **options):
cmd_dict["first_key_pos"] = command[3]
cmd_dict["last_key_pos"] = command[4]
cmd_dict["step_count"] = command[5]
+ if len(command) > 7:
+ cmd_dict["tips"] = command[7]
+ cmd_dict["key_specifications"] = command[8]
+ cmd_dict["subcommands"] = command[9]
commands[cmd_name] = cmd_dict
return commands
diff --git a/redis/cluster.py b/redis/cluster.py
index e5baee2..fa1322f 100644
--- a/redis/cluster.py
+++ b/redis/cluster.py
@@ -240,6 +240,7 @@ class AbstractRedisCluster:
[
"ACL CAT",
"ACL DELUSER",
+ "ACL DRYRUN",
"ACL GENPASS",
"ACL GETUSER",
"ACL HELP",
diff --git a/redis/commands/parser.py b/redis/commands/parser.py
index 936f2ec..7560603 100644
--- a/redis/commands/parser.py
+++ b/redis/commands/parser.py
@@ -25,6 +25,21 @@ class CommandsParser:
commands[cmd.lower()] = commands.pop(cmd)
self.commands = commands
+ def parse_subcommand(self, command, **options):
+ cmd_dict = {}
+ cmd_name = str_if_bytes(command[0])
+ cmd_dict["name"] = cmd_name
+ cmd_dict["arity"] = int(command[1])
+ cmd_dict["flags"] = [str_if_bytes(flag) for flag in command[2]]
+ cmd_dict["first_key_pos"] = command[3]
+ cmd_dict["last_key_pos"] = command[4]
+ cmd_dict["step_count"] = command[5]
+ if len(command) > 7:
+ cmd_dict["tips"] = command[7]
+ cmd_dict["key_specifications"] = command[8]
+ cmd_dict["subcommands"] = command[9]
+ return cmd_dict
+
# As soon as this PR is merged into Redis, we should reimplement
# our logic to use COMMAND INFO changes to determine the key positions
# https://github.com/redis/redis/pull/8324
@@ -72,8 +87,17 @@ class CommandsParser:
and command["first_key_pos"] == 0
and command["last_key_pos"] == 0
):
+ is_subcmd = False
+ if "subcommands" in command:
+ subcmd_name = f"{cmd_name}|{args[1].lower()}"
+ for subcmd in command["subcommands"]:
+ if str_if_bytes(subcmd[0]) == subcmd_name:
+ command = self.parse_subcommand(subcmd)
+ is_subcmd = True
+
# The command doesn't have keys in it
- return None
+ if not is_subcmd:
+ return None
last_key_pos = command["last_key_pos"]
if last_key_pos < 0:
last_key_pos = len(args) - abs(last_key_pos)
diff --git a/tests/test_cluster.py b/tests/test_cluster.py
index 7e64345..de41a10 100644
--- a/tests/test_cluster.py
+++ b/tests/test_cluster.py
@@ -1121,7 +1121,6 @@ class TestClusterRedisCommands:
links_to = sum(x.count("to") for x in res)
links_for = sum(x.count("from") for x in res)
assert links_to == links_for
- print(res)
for i in range(0, len(res) - 1, 2):
assert res[i][3] == res[i + 1][3]
diff --git a/tests/test_commands.py b/tests/test_commands.py
index 00eac17..d5ab4e3 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -1164,7 +1164,7 @@ class TestRedisCommands:
r.set("key", "val")
assert r.expire("key", 100, xx=True) == 0
assert r.expire("key", 100)
- assert r.expire("key", 500, nx=True) == 1
+ assert r.expire("key", 500, xx=True) == 1
@skip_if_server_version_lt("7.0.0")
def test_expire_option_gt(self, r):
@@ -3012,6 +3012,7 @@ class TestRedisCommands:
assert r.lrange("sorted", 0, 10) == [b"vodka", b"milk", b"gin", b"apple juice"]
@skip_if_server_version_lt("7.0.0")
+ @pytest.mark.onlynoncluster
def test_sort_ro(self, r):
r["score:1"] = 8
r["score:2"] = 3