Skip to content

Commit

Permalink
Fix stream key type (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
cunla authored Sep 8, 2023
1 parent d065cc6 commit d54b5ed
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 33 deletions.
22 changes: 13 additions & 9 deletions docs/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ description: Change log of all fakeredis releases

## v2.18.1

### 🐛 Bug Fixes

- Fix stream type issue #233

### 🧰 Maintenance

- Add mypy hints to everything
Expand All @@ -19,7 +23,7 @@ description: Change log of all fakeredis releases
- Implement `PUBSUB NUMPAT` #195, `SSUBSCRIBE` #199, `SPUBLISH` #198,
`SUNSUBSCRIBE` #200, `PUBSUB SHARDCHANNELS` #196, `PUBSUB SHARDNUMSUB` #197

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fix All aio.FakeRedis instances share the same server #218

Expand All @@ -30,7 +34,7 @@ description: Change log of all fakeredis releases
- Implement `LPOS` #207, `LMPOP` #184, and `BLMPOP` #183
- Implement `ZMPOP` #191, `BZMPOP` #186

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fix incorrect error msg for the group not found #210
- fix: use the same server_key within the pipeline when issued watch #213
Expand All @@ -48,7 +52,7 @@ We'd like to thank all the contributors who worked on this release!

- Implemented support for `JSON.MSET` #174, `JSON.MERGE` #181

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Add support for `version` for async FakeRedis #205

Expand Down Expand Up @@ -76,13 +80,13 @@ We'd like to thank all the contributors who worked on this release!

## v2.14.2

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fix documentation link

## v2.14.1

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fix requirement for packaging.Version #177

Expand All @@ -99,7 +103,7 @@ We'd like to thank all the contributors who worked on this release!

## v2.13.0

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fixed xadd timestamp (fixes #151) (#152)
- Implement XDEL #153
Expand All @@ -111,7 +115,7 @@ We'd like to thank all the contributors who worked on this release!

## v2.12.1

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Add support for `Connection.read_response` arguments used in redis-py 4.5.5 and 5.0.0
- Adding state for scan commands (#99)
Expand All @@ -129,7 +133,7 @@ We'd like to thank all the contributors who worked on this release!

## v2.11.2

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Unique FakeServer when no connection params are provided (#142)

Expand All @@ -148,7 +152,7 @@ We'd like to thank all the contributors who worked on this release!
Creating multiple clients with the same connection parameters will result in
the same server data structure.

### 🧰 Bug Fixes
### 🐛 Bug Fixes

- Fix creating fakeredis.aioredis using url with user/password (#139)

Expand Down
25 changes: 23 additions & 2 deletions fakeredis/_basefakesocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from . import _msgs as msgs
from ._command_args_parsing import extract_args
from ._commands import Int, Float, SUPPORTED_COMMANDS, COMMANDS_WITH_SUB, key_value_type
from ._commands import Int, Float, SUPPORTED_COMMANDS, COMMANDS_WITH_SUB, Item
from ._helpers import (
SimpleError,
valid_response_type,
Expand All @@ -20,6 +20,8 @@
QUEUED,
encode_command,
)
from ._stream import XStream
from ._zset import ZSet


def _extract_command(fields: List[bytes]) -> Tuple[Any, List[Any]]:
Expand Down Expand Up @@ -346,7 +348,7 @@ def match_key(key: bytes) -> Union[bool, Match[bytes], None]:
return regex.match(key) if regex is not None else True

def match_type(key) -> bool:
return _type is None or casematch(key_value_type(self._db[key]).value, _type)
return _type is None or casematch(BaseFakeSocket._key_value_type(self._db[key]).value, _type)

if pattern is not None or _type is not None:
for val in itertools.islice(data, cursor, cursor + count):
Expand Down Expand Up @@ -377,3 +379,22 @@ def _encodeint(self, value: int) -> bytes:
if self.version >= (7,):
value = 0 + value
return Int.encode(value)

@staticmethod
def _key_value_type(key: Item) -> SimpleString:
if key.value is None:
return SimpleString(b"none")
elif isinstance(key.value, bytes):
return SimpleString(b"string")
elif isinstance(key.value, list):
return SimpleString(b"list")
elif isinstance(key.value, set):
return SimpleString(b"set")
elif isinstance(key.value, ZSet):
return SimpleString(b"zset")
elif isinstance(key.value, dict):
return SimpleString(b"hash")
elif isinstance(key.value, XStream):
return SimpleString(b"stream")
else:
assert False # pragma: nocover
20 changes: 1 addition & 19 deletions fakeredis/_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
from typing import Tuple, Union, Optional, Any, Type

from . import _msgs as msgs
from ._helpers import null_terminate, SimpleError, SimpleString, Database
from ._zset import ZSet
from ._helpers import null_terminate, SimpleError, Database

MAX_STRING_SIZE = 512 * 1024 * 1024
SUPPORTED_COMMANDS = dict() # Dictionary of supported commands name => Signature
Expand Down Expand Up @@ -463,20 +462,3 @@ def fix_range_string(start: int, end: int, length: int) -> Tuple[int, int]:
end = max(0, end + length)
end = min(end, length - 1)
return start, end + 1


def key_value_type(key: Item) -> SimpleString:
if key.value is None:
return SimpleString(b"none")
elif isinstance(key.value, bytes):
return SimpleString(b"string")
elif isinstance(key.value, list):
return SimpleString(b"list")
elif isinstance(key.value, set):
return SimpleString(b"set")
elif isinstance(key.value, ZSet):
return SimpleString(b"zset")
elif isinstance(key.value, dict):
return SimpleString(b"hash")
else:
assert False # pragma: nocover
4 changes: 2 additions & 2 deletions fakeredis/commands_mixins/generic_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
CommandItem,
SortFloat,
delete_keys,
key_value_type,
)
from fakeredis._helpers import compile_pattern, SimpleError, OK, casematch, Database
from fakeredis._zset import ZSet
Expand All @@ -27,6 +26,7 @@ class GenericCommandsMixin:
_db_num: int
_ttl: Callable
_scan: Callable
_key_value_type: Callable

def _lookup_key(self, key, pattern):
"""Python implementation of lookupKeyByPattern from redis"""
Expand Down Expand Up @@ -297,7 +297,7 @@ def ttl(self, key):

@command((Key(),))
def type(self, key):
return key_value_type(key)
return self._key_value_type(key)

@command((Key(),), (Key(),), name="unlink")
def unlink(self, *keys):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ name = "fakeredis"
packages = [
{ include = "fakeredis" },
]
version = "2.18.0"
version = "2.18.1"
description = "Python implementation of redis API, can be used for testing purposes."
readme = "README.md"
keywords = ["redis", "RedisJson", "tests", "redis-stack"]
Expand Down
7 changes: 7 additions & 0 deletions test/test_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,10 @@ def test_scan_expired_key(r: redis.Redis):
r.pexpire('expiringkey', 1)
sleep(1)
assert r.scan()[1] == []


def test_scan_stream(r: redis.Redis):
r.xadd("mystream", {"test": "value"})
assert r.type("mystream") == b"stream"
for s in r.scan_iter(_type="STRING"):
print(s)

0 comments on commit d54b5ed

Please sign in to comment.