Skip to content

Commit 5ba8d91

Browse files
authored
Merge branch 'master' into json-t-h
2 parents 38085df + 4d7de6d commit 5ba8d91

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

redis/commands/core.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,46 @@ def brpoplpush(self, src, dst, timeout=0):
19171917
timeout = 0
19181918
return self.execute_command("BRPOPLPUSH", src, dst, timeout)
19191919

1920+
def blmpop(
1921+
self,
1922+
timeout: float,
1923+
numkeys: int,
1924+
*args: List[str],
1925+
direction: str,
1926+
count: Optional[int] = 1,
1927+
) -> Optional[list]:
1928+
"""
1929+
Pop ``count`` values (default 1) from first non-empty in the list
1930+
of provided key names.
1931+
1932+
When all lists are empty this command blocks the connection until another
1933+
client pushes to it or until the timeout, timeout of 0 blocks indefinitely
1934+
1935+
For more information check https://redis.io/commands/blmpop
1936+
"""
1937+
args = [timeout, numkeys, *args, direction, "COUNT", count]
1938+
1939+
return self.execute_command("BLMPOP", *args)
1940+
1941+
def lmpop(
1942+
self,
1943+
num_keys: int,
1944+
*args: List[str],
1945+
direction: str = None,
1946+
count: Optional[int] = 1,
1947+
) -> List:
1948+
"""
1949+
Pop ``count`` values (default 1) first non-empty list key from the list
1950+
of args provided key names.
1951+
1952+
For more information check https://redis.io/commands/lmpop
1953+
"""
1954+
args = [num_keys] + list(args) + [direction]
1955+
if count != 1:
1956+
args.extend(["COUNT", count])
1957+
1958+
return self.execute_command("LMPOP", *args)
1959+
19201960
def lindex(self, name, index):
19211961
"""
19221962
Return the item from list ``name`` at position ``index``
@@ -2388,6 +2428,19 @@ def sinter(self, keys, *args):
23882428
args = list_or_args(keys, args)
23892429
return self.execute_command("SINTER", *args)
23902430

2431+
def sintercard(self, numkeys: int, keys: List[str], limit: int = 0) -> int:
2432+
"""
2433+
Return the cardinality of the intersect of multiple sets specified by ``keys`.
2434+
2435+
When LIMIT provided (defaults to 0 and means unlimited), if the intersection
2436+
cardinality reaches limit partway through the computation, the algorithm will
2437+
exit and yield limit as the cardinality
2438+
2439+
For more information check https://redis.io/commands/sintercard
2440+
"""
2441+
args = [numkeys, *keys, "LIMIT", limit]
2442+
return self.execute_command("SINTERCARD", *args)
2443+
23912444
def sinterstore(self, dest, keys, *args):
23922445
"""
23932446
Store the intersection of sets specified by ``keys`` into a new

redis/commands/json/commands.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def arrpop(
7777
path: Optional[str] = Path.rootPath(),
7878
index: Optional[int] = -1,
7979
) -> List[Union[str, None]]:
80+
8081
"""Pop the element at ``index`` in the array JSON value under
8182
``path`` at key ``name``.
8283
@@ -95,6 +96,7 @@ def arrtrim(
9596
return self.execute_command("JSON.ARRTRIM", name, str(path), start, stop)
9697

9798
def type(self, name: str, path: Optional[str] = Path.rootPath()) -> List[str]:
99+
98100
"""Get the type of the JSON value under ``path`` from key ``name``.
99101
100102
For more information: https://oss.redis.com/redisjson/commands/#jsontype

tests/test_commands.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,29 @@ def test_brpoplpush_empty_string(self, r):
14801480
r.rpush("a", "")
14811481
assert r.brpoplpush("a", "b") == b""
14821482

1483+
@pytest.mark.onlynoncluster
1484+
# @skip_if_server_version_lt("7.0.0") turn on after redis 7 release
1485+
def test_blmpop(self, unstable_r):
1486+
unstable_r.rpush("a", "1", "2", "3", "4", "5")
1487+
res = [b"a", [b"1", b"2"]]
1488+
assert unstable_r.blmpop(1, "2", "b", "a", direction="LEFT", count=2) == res
1489+
with pytest.raises(TypeError):
1490+
unstable_r.blmpop(1, "2", "b", "a", count=2)
1491+
unstable_r.rpush("b", "6", "7", "8", "9")
1492+
assert unstable_r.blmpop(0, "2", "b", "a", direction="LEFT") == [b"b", [b"6"]]
1493+
assert unstable_r.blmpop(1, "2", "foo", "bar", direction="RIGHT") is None
1494+
1495+
@pytest.mark.onlynoncluster
1496+
# @skip_if_server_version_lt("7.0.0") turn on after redis 7 release
1497+
def test_lmpop(self, unstable_r):
1498+
unstable_r.rpush("foo", "1", "2", "3", "4", "5")
1499+
result = [b"foo", [b"1", b"2"]]
1500+
assert unstable_r.lmpop("2", "bar", "foo", direction="LEFT", count=2) == result
1501+
with pytest.raises(redis.ResponseError):
1502+
unstable_r.lmpop("2", "bar", "foo", direction="up", count=2)
1503+
unstable_r.rpush("bar", "a", "b", "c", "d")
1504+
assert unstable_r.lmpop("2", "bar", "foo", direction="LEFT") == [b"bar", [b"a"]]
1505+
14831506
def test_lindex(self, r):
14841507
r.rpush("a", "1", "2", "3")
14851508
assert r.lindex("a", "0") == b"1"
@@ -1748,6 +1771,15 @@ def test_sinter(self, r):
17481771
r.sadd("b", "2", "3")
17491772
assert r.sinter("a", "b") == {b"2", b"3"}
17501773

1774+
@pytest.mark.onlynoncluster
1775+
# @skip_if_server_version_lt("7.0.0") turn on after redis 7 release
1776+
def test_sintercard(self, unstable_r):
1777+
unstable_r.sadd("a", 1, 2, 3)
1778+
unstable_r.sadd("b", 1, 2, 3)
1779+
unstable_r.sadd("c", 1, 3, 4)
1780+
assert unstable_r.sintercard(3, ["a", "b", "c"]) == 2
1781+
assert unstable_r.sintercard(3, ["a", "b", "c"], limit=1) == 1
1782+
17511783
@pytest.mark.onlynoncluster
17521784
def test_sinterstore(self, r):
17531785
r.sadd("a", "1", "2", "3")

0 commit comments

Comments
 (0)