Skip to content

Commit

Permalink
Implement ZRANDMEMBER
Browse files Browse the repository at this point in the history
Fix #192
  • Loading branch information
cunla committed Jun 16, 2023
1 parent 72722ea commit dd8a1eb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
26 changes: 26 additions & 0 deletions fakeredis/commands_mixins/sortedset_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import functools
import itertools
import math
import random
from typing import Union, Optional

from fakeredis import _msgs as msgs
Expand Down Expand Up @@ -414,5 +415,30 @@ def zmscore(self, key: CommandItem, *members: Union[str, bytes]) -> list[Optiona
)
return list(scores)

@command(name="ZRANDMEMBER", fixed=(Key(ZSet),), repeat=(bytes,))
def zrandmember(self, key: CommandItem, *args) -> list[Optional[float]]:
count, withscores = 1, None
if len(args) > 0:
count = Int.decode(args[0])
if len(args) > 1:
if casematch(b'withscores', args[1]):
withscores = True
else:
raise SimpleError(msgs.SYNTAX_ERROR_MSG)
zset = key.value
if zset is None:
return None if len(args) == 0 is None else []
if count < 0: # Allow repetitions
res = random.choices(sorted(key.value.items()), k=-count)
else: # Unique values from hash
count = min(count, len(key.value))
res = random.sample(sorted(key.value.items()), count)

if withscores:
res = [item for t in res for item in t]
else:
res = [t[0] for t in res]
return res

def _encodefloat(self, value, humanfriendly):
raise NotImplementedError # Implemented in BaseFakeSocket
12 changes: 12 additions & 0 deletions test/test_mixins/test_sortedset_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1079,3 +1079,15 @@ def test_zscan(r: redis.Redis):
cursor, data = r.zscan(name, cursor, match='*7', count=6)
results.update(data)
assert results == {b'key:7': 7.0, b'key:17': 17.0}


def test_zrandemember(r: redis.Redis):
r.zadd("a", {"a1": 1, "a2": 2, "a3": 3, "a4": 4, "a5": 5})
assert r.zrandmember("a") is not None
assert len(r.zrandmember("a", 2)) == 2
# with scores
assert len(r.zrandmember("a", 2, True)) == 4
# without duplications
assert len(r.zrandmember("a", 10)) == 5
# with duplications
assert len(r.zrandmember("a", -10)) == 10

0 comments on commit dd8a1eb

Please sign in to comment.