Skip to content

Commit f001927

Browse files
authored
LPOS: add new command (#1354)
Added the LPOS command from Redis 6.0.6 Fixes #1353
1 parent 75a2cfe commit f001927

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

docker/base/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
FROM redis:6.0.5-buster
1+
FROM redis:6.0.6-buster

redis/client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,42 @@ def rpushx(self, name, value):
20302030
"Push ``value`` onto the tail of the list ``name`` if ``name`` exists"
20312031
return self.execute_command('RPUSHX', name, value)
20322032

2033+
def lpos(self, name, value, rank=None, count=None, maxlen=None):
2034+
"""
2035+
Get position of ``value`` within the list ``name``
2036+
2037+
If specified, ``rank`` indicates the "rank" of the first element to
2038+
return in case there are multiple copies of ``value`` in the list.
2039+
By default, LPOS returns the position of the first occurrence of
2040+
``value`` in the list. When ``rank`` 2, LPOS returns the position of
2041+
the second ``value`` in the list. If ``rank`` is negative, LPOS
2042+
searches the list in reverse. For example, -1 would return the
2043+
position of the last occurrence of ``value`` and -2 would return the
2044+
position of the next to last occurrence of ``value``.
2045+
2046+
If specified, ``count`` indicates that LPOS should return a list of
2047+
up to ``count`` positions. A ``count`` of 2 would return a list of
2048+
up to 2 positions. A ``count`` of 0 returns a list of all positions
2049+
matching ``value``. When ``count`` is specified and but ``value``
2050+
does not exist in the list, an empty list is returned.
2051+
2052+
If specified, ``maxlen`` indicates the maximum number of list
2053+
elements to scan. A ``maxlen`` of 1000 will only return the
2054+
position(s) of items within the first 1000 entries in the list.
2055+
A ``maxlen`` of 0 (the default) will scan the entire list.
2056+
"""
2057+
pieces = [name, value]
2058+
if rank is not None:
2059+
pieces.extend(['RANK', rank])
2060+
2061+
if count is not None:
2062+
pieces.extend(['COUNT', count])
2063+
2064+
if maxlen is not None:
2065+
pieces.extend(['MAXLEN', maxlen])
2066+
2067+
return self.execute_command('LPOS', *pieces)
2068+
20332069
def sort(self, name, start=None, num=None, by=None, get=None,
20342070
desc=False, alpha=False, store=None, groups=False):
20352071
"""

tests/test_commands.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,38 @@ def test_rpush(self, r):
10521052
assert r.rpush('a', '3', '4') == 4
10531053
assert r.lrange('a', 0, -1) == [b'1', b'2', b'3', b'4']
10541054

1055+
@skip_if_server_version_lt('6.0.6')
1056+
def test_lpos(self, r):
1057+
assert r.rpush('a', 'a', 'b', 'c', '1', '2', '3', 'c', 'c') == 8
1058+
assert r.lpos('a', 'a') == 0
1059+
assert r.lpos('a', 'c') == 2
1060+
1061+
assert r.lpos('a', 'c', rank=1) == 2
1062+
assert r.lpos('a', 'c', rank=2) == 6
1063+
assert r.lpos('a', 'c', rank=4) is None
1064+
assert r.lpos('a', 'c', rank=-1) == 7
1065+
assert r.lpos('a', 'c', rank=-2) == 6
1066+
1067+
assert r.lpos('a', 'c', count=0) == [2, 6, 7]
1068+
assert r.lpos('a', 'c', count=1) == [2]
1069+
assert r.lpos('a', 'c', count=2) == [2, 6]
1070+
assert r.lpos('a', 'c', count=100) == [2, 6, 7]
1071+
1072+
assert r.lpos('a', 'c', count=0, rank=2) == [6, 7]
1073+
assert r.lpos('a', 'c', count=2, rank=-1) == [7, 6]
1074+
1075+
assert r.lpos('axxx', 'c', count=0, rank=2) == []
1076+
assert r.lpos('axxx', 'c') is None
1077+
1078+
assert r.lpos('a', 'x', count=2) == []
1079+
assert r.lpos('a', 'x') is None
1080+
1081+
assert r.lpos('a', 'a', count=0, maxlen=1) == [0]
1082+
assert r.lpos('a', 'c', count=0, maxlen=1) == []
1083+
assert r.lpos('a', 'c', count=0, maxlen=3) == [2]
1084+
assert r.lpos('a', 'c', count=0, maxlen=3, rank=-1) == [7, 6]
1085+
assert r.lpos('a', 'c', count=0, maxlen=7, rank=2) == [6]
1086+
10551087
def test_rpushx(self, r):
10561088
assert r.rpushx('a', 'b') == 0
10571089
assert r.lrange('a', 0, -1) == []

0 commit comments

Comments
 (0)