Skip to content

Commit aada66d

Browse files
committed
LPOS: add new command
fix #1353 Signed-off-by: Paul Spooren <[email protected]>
1 parent a50b157 commit aada66d

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

redis/client.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,39 @@ 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, first=None, count=None, maxlen=None):
2034+
"""
2035+
Get position of ``value`` withn the list ``name``
2036+
2037+
``first`` "rank" is the position of the match, so if it is 1, the
2038+
first match is returned, if it is 2 the second match is returned and
2039+
so forth. It is 1 by default. If negative has the same meaning but
2040+
the search is performed starting from the end of the list.
2041+
2042+
If ``count`` is given, instead of returning the single element, a list
2043+
of all the matching elements up to "num-matches" are returned.
2044+
``count`` can be combiled with ``count`` in order to returning only
2045+
the element starting from the Nth. If ``count`` is zero, all the
2046+
matching elements are returned.
2047+
2048+
``maxlen`` tells the command to scan a max of len elements. If zero
2049+
(the default), all the elements in the list are scanned if needed.
2050+
2051+
The returned elements indexes are always referring to what ``lindex``
2052+
would return. So first element from head is 0, and so forth.
2053+
"""
2054+
pieces = [name, value]
2055+
if first is not None:
2056+
pieces.extend(['FIRST', first])
2057+
2058+
if count is not None:
2059+
pieces.extend(['COUNT', count])
2060+
2061+
if maxlen is not None:
2062+
pieces.extend(['MAXLEN', maxlen])
2063+
2064+
return self.execute_command('LPOS', *pieces)
2065+
20332066
def sort(self, name, start=None, num=None, by=None, get=None,
20342067
desc=False, alpha=False, store=None, groups=False):
20352068
"""

tests/test_commands.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,36 @@ 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+
def test_lpos(self, r):
1056+
assert r.rpush('a', 'a', 'b', 'c', '1', '2', '3', 'c', 'c') == 8
1057+
assert r.lpos('a', 'a') == 0
1058+
assert r.lpos('a', 'c') == 2
1059+
1060+
assert r.lpos('a', 'c', first=1) == 2
1061+
assert r.lpos('a', 'c', first=2) == 6
1062+
assert r.lpos('a', 'c', first=4) is None
1063+
assert r.lpos('a', 'c', first=-1) == 7
1064+
assert r.lpos('a', 'c', first=-2) == 6
1065+
1066+
assert r.lpos('a', 'c', count=0) == [2, 6, 7]
1067+
assert r.lpos('a', 'c', count=1) == [2]
1068+
assert r.lpos('a', 'c', count=2) == [2, 6]
1069+
assert r.lpos('a', 'c', count=100) == [2, 6, 7]
1070+
1071+
assert r.lpos('a', 'c', count=0, first=2) == [6, 7]
1072+
assert r.lpos('a', 'c', count=2, first=-1) == [7, 6]
1073+
1074+
assert r.lpos('axxx', 'c', count=0, first=2) == []
1075+
1076+
assert r.lpos('a', 'x', count=2, first=-1) == []
1077+
assert r.lpos('a', 'x', first=-1) is None
1078+
1079+
assert r.lpos('a', 'a', count=0, maxlen=1) == [0]
1080+
assert r.lpos('a', 'c', count=0, maxlen=1) == []
1081+
assert r.lpos('a', 'c', count=0, maxlen=3) == [2]
1082+
assert r.lpos('a', 'c', count=0, maxlen=3, first=-1) == [7, 6]
1083+
assert r.lpos('a', 'c', count=0, maxlen=7, first=2) == [6]
1084+
10551085
def test_rpushx(self, r):
10561086
assert r.rpushx('a', 'b') == 0
10571087
assert r.lrange('a', 0, -1) == []

0 commit comments

Comments
 (0)