Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get command keys for subcommands #2170

Merged
merged 3 commits into from
May 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions redis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,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

Expand Down
1 change: 1 addition & 0 deletions redis/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ class RedisCluster(RedisClusterCommands):
[
"ACL CAT",
"ACL DELUSER",
"ACL DRYRUN",
"ACL GENPASS",
"ACL GETUSER",
"ACL HELP",
Expand Down
26 changes: 25 additions & 1 deletion redis/commands/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ def initialize(self, r):
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
Expand Down Expand Up @@ -73,8 +88,17 @@ def get_keys(self, redis_conn, *args):
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)
Expand Down
1 change: 0 additions & 1 deletion tests/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,6 @@ def test_cluster_links(self, r):
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]

Expand Down
3 changes: 2 additions & 1 deletion tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ def test_expire_option_xx(self, r):
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):
Expand Down Expand Up @@ -3012,6 +3012,7 @@ def test_sort_all_options(self, r):
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
Expand Down