From 599fba7730a51c864f997033e26fa185ea6d4367 Mon Sep 17 00:00:00 2001 From: dvora-h Date: Mon, 3 Jan 2022 19:44:50 +0200 Subject: [PATCH 1/5] add bzmpop --- redis/commands/core.py | 15 +++++++++++++++ tests/test_commands.py | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/redis/commands/core.py b/redis/commands/core.py index 4f0accd957..56d87c68ed 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -2,6 +2,7 @@ import hashlib import time import warnings +from typing import List, Optional from redis.exceptions import ConnectionError, DataError, NoScriptError, RedisError @@ -3255,6 +3256,20 @@ def bzpopmin(self, keys, timeout=0): keys.append(timeout) return self.execute_command("BZPOPMIN", *keys) + def bzmpop( + self, + timeout: float, + num_keys: int, + keys: List[str], + min_max: str, + count: Optional[int] = 1, + ) -> Optional[list]: + args = [timeout, num_keys] + keys + [min_max] + if count != 1: + args.extend(["COUNT", count]) + + return self.execute_command("BZMPOP", *args) + def _zrange( self, command, diff --git a/tests/test_commands.py b/tests/test_commands.py index b28b63ea6e..af7f8728c8 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2058,6 +2058,18 @@ def test_bzpopmin(self, r): r.zadd("c", {"c1": 100}) assert r.bzpopmin("c", timeout=1) == (b"c", b"c1", 100) + @pytest.mark.onlynoncluster + # @skip_if_server_version_lt("7.0.0") turn on after redis 7 release + def test_bzmpop(self, unstable_r): + unstable_r.zadd("a", {"a1": 1, "a2": 2, "a3": 3}) + res = [b"a", [[b"a1", b"1"], [b"a2", b"2"]]] + assert unstable_r.bzmpop(1, "2", ["b", "a"], "MIN", count=2) == res + with pytest.raises(TypeError): + unstable_r.bzmpop(1, "2", ["b", "a"], count=2) + unstable_r.zadd("b", {"b1": 10, "ab": 9, "b3": 8}) + assert unstable_r.bzmpop(0, "2", ["b", "a"], "MAX") == [b"b", [[b"b1", b"10"]]] + assert unstable_r.bzmpop(1, "2", ["foo", "bar"], "MAX") is None + def test_zrange(self, r): r.zadd("a", {"a1": 1, "a2": 2, "a3": 3}) assert r.zrange("a", 0, 1) == [b"a1", b"a2"] From 3374ed2f26eaeb8077846dfe48286e3fb7865cf0 Mon Sep 17 00:00:00 2001 From: dvora-h Date: Tue, 4 Jan 2022 09:32:37 +0200 Subject: [PATCH 2/5] add comment --- redis/commands/core.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/redis/commands/core.py b/redis/commands/core.py index 56d87c68ed..73ba4f939f 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -3264,6 +3264,18 @@ def bzmpop( min_max: str, count: Optional[int] = 1, ) -> Optional[list]: + """ + Pop ``count`` values (default 1) off of the first non-empty sorted set + named in the ``keys`` list. + + If none of the sorted sets in ``keys`` has a value to pop, + then block for ``timeout`` seconds, or until a member gets added + to one of the sorted sets. + + If timeout is 0, then block indefinitely. + + For more information check https://redis.io/commands/bzmpop + """ args = [timeout, num_keys] + keys + [min_max] if count != 1: args.extend(["COUNT", count]) From 97f86f932cdadb15a8c485d49027cf73fabf69aa Mon Sep 17 00:00:00 2001 From: dvora-h Date: Wed, 12 Jan 2022 16:15:03 +0200 Subject: [PATCH 3/5] fix pr comment --- redis/commands/core.py | 11 +++++++++-- tests/test_commands.py | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/redis/commands/core.py b/redis/commands/core.py index 73ba4f939f..97c88eec14 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -3261,7 +3261,8 @@ def bzmpop( timeout: float, num_keys: int, keys: List[str], - min_max: str, + min: Optional[bool] = False, + max: Optional[bool] = False, count: Optional[int] = 1, ) -> Optional[list]: """ @@ -3276,7 +3277,13 @@ def bzmpop( For more information check https://redis.io/commands/bzmpop """ - args = [timeout, num_keys] + keys + [min_max] + args = [timeout, num_keys, *keys] + if (min and max) or (not min and not max): + raise DataError + elif min: + args.append("MIN") + else: + args.append("MAX") if count != 1: args.extend(["COUNT", count]) diff --git a/tests/test_commands.py b/tests/test_commands.py index af7f8728c8..560399fa62 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2063,12 +2063,12 @@ def test_bzpopmin(self, r): def test_bzmpop(self, unstable_r): unstable_r.zadd("a", {"a1": 1, "a2": 2, "a3": 3}) res = [b"a", [[b"a1", b"1"], [b"a2", b"2"]]] - assert unstable_r.bzmpop(1, "2", ["b", "a"], "MIN", count=2) == res - with pytest.raises(TypeError): + assert unstable_r.bzmpop(1, "2", ["b", "a"], min=True, count=2) == res + with pytest.raises(redis.DataError): unstable_r.bzmpop(1, "2", ["b", "a"], count=2) unstable_r.zadd("b", {"b1": 10, "ab": 9, "b3": 8}) - assert unstable_r.bzmpop(0, "2", ["b", "a"], "MAX") == [b"b", [[b"b1", b"10"]]] - assert unstable_r.bzmpop(1, "2", ["foo", "bar"], "MAX") is None + assert unstable_r.bzmpop(0, "2", ["b", "a"], max=True) == [b"b", [[b"b1", b"10"]]] + assert unstable_r.bzmpop(1, "2", ["foo", "bar"], max=True) is None def test_zrange(self, r): r.zadd("a", {"a1": 1, "a2": 2, "a3": 3}) From 0783f052a363282270b75f55f0512f25f94bdd10 Mon Sep 17 00:00:00 2001 From: dvora-h Date: Wed, 12 Jan 2022 16:22:43 +0200 Subject: [PATCH 4/5] fix linters --- tests/test_commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_commands.py b/tests/test_commands.py index 560399fa62..937172a195 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2067,7 +2067,8 @@ def test_bzmpop(self, unstable_r): with pytest.raises(redis.DataError): unstable_r.bzmpop(1, "2", ["b", "a"], count=2) unstable_r.zadd("b", {"b1": 10, "ab": 9, "b3": 8}) - assert unstable_r.bzmpop(0, "2", ["b", "a"], max=True) == [b"b", [[b"b1", b"10"]]] + res = [b"b", [[b"b1", b"10"]]] + assert unstable_r.bzmpop(0, "2", ["b", "a"], max=True) == res assert unstable_r.bzmpop(1, "2", ["foo", "bar"], max=True) is None def test_zrange(self, r): From dbc342cdd532aa7af800d3ea433a7f6df0bca0d1 Mon Sep 17 00:00:00 2001 From: dvora-h Date: Tue, 25 Jan 2022 15:45:15 +0200 Subject: [PATCH 5/5] fix pr comments --- redis/commands/core.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/redis/commands/core.py b/redis/commands/core.py index 97c88eec14..6b3bc4e76b 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -3259,7 +3259,7 @@ def bzpopmin(self, keys, timeout=0): def bzmpop( self, timeout: float, - num_keys: int, + numkeys: int, keys: List[str], min: Optional[bool] = False, max: Optional[bool] = False, @@ -3277,15 +3277,14 @@ def bzmpop( For more information check https://redis.io/commands/bzmpop """ - args = [timeout, num_keys, *keys] + args = [timeout, numkeys, *keys] if (min and max) or (not min and not max): - raise DataError + raise DataError("Either min or max, but not both must be set") elif min: args.append("MIN") else: args.append("MAX") - if count != 1: - args.extend(["COUNT", count]) + args.extend(["COUNT", count]) return self.execute_command("BZMPOP", *args)