Skip to content

Commit ff32a17

Browse files
committed
move key/value related methods to a function
this was done so people can use them with a raw client (cherry picked from commit d39a5ab)
1 parent 1675272 commit ff32a17

File tree

2 files changed

+82
-41
lines changed

2 files changed

+82
-41
lines changed

django_valkey/base_client.py

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import socket
55
import time
66
from collections.abc import AsyncGenerator, Iterable, Iterator
7-
from contextlib import suppress
87
from typing import (
98
Any,
109
Dict,
@@ -28,9 +27,9 @@
2827
from django_valkey import pool
2928
from django_valkey.base import ATTR_DOES_NOT_EXIST
3029
from django_valkey.compressors.identity import IdentityCompressor
31-
from django_valkey.exceptions import CompressorError, ConnectionInterrupted
30+
from django_valkey.exceptions import ConnectionInterrupted
3231
from django_valkey.serializers.pickle import PickleSerializer
33-
from django_valkey.util import CacheKey
32+
from django_valkey.util import CacheKey, decode, encode, make_key, make_pattern
3433

3534
if TYPE_CHECKING:
3635
from valkey.lock import Lock
@@ -132,28 +131,16 @@ def decode(self, value: bytes) -> Any:
132131
"""
133132
Decode the given value.
134133
"""
135-
try:
136-
if value.isdigit():
137-
value = int(value)
138-
else:
139-
value = float(value)
140-
except (ValueError, TypeError):
141-
# Handle little values, chosen to be not compressed
142-
with suppress(CompressorError):
143-
value = self._compressor.decompress(value)
144-
value = self._serializer.loads(value)
145-
return value
134+
return decode(value, serializer=self._serializer, compressor=self._compressor)
146135

147136
def encode(self, value: EncodableT) -> bytes | int | float:
148137
"""
149138
Encode the given value.
150139
"""
151140

152-
if type(value) is not int and type(value) is not float:
153-
value = self._serializer.dumps(value)
154-
return self._compressor.compress(value)
155-
156-
return value
141+
return encode(
142+
value=value, serializer=self._serializer, compressor=self._compressor
143+
)
157144

158145
def _decode_iterable_result(
159146
self, result: Any, convert_to_set: bool = True
@@ -170,32 +157,22 @@ def make_key(
170157
self, key: KeyT, version: int | None = None, prefix: str | None = None
171158
) -> KeyT:
172159
"""Return key as a CacheKey instance so it has additional methods"""
173-
if isinstance(key, CacheKey):
174-
return key
175-
176-
if prefix is None:
177-
prefix = self._backend.key_prefix
178-
179-
if version is None:
180-
version = self._backend.version
181-
182-
return CacheKey(self._backend.key_func(key, prefix, version))
160+
return make_key(
161+
key,
162+
key_func=self._backend.key_func,
163+
version=version or self._backend.version,
164+
prefix=prefix or self._backend.key_prefix,
165+
)
183166

184167
def make_pattern(
185168
self, pattern: str, version: int | None = None, prefix: str | None = None
186169
) -> KeyT:
187-
if isinstance(pattern, CacheKey):
188-
return pattern
189-
190-
if prefix is None:
191-
prefix = self._backend.key_prefix
192-
prefix = glob_escape(prefix)
193-
194-
if version is None:
195-
version = self._backend.version
196-
version_str = glob_escape(str(version))
197-
198-
return CacheKey(self._backend.key_func(pattern, prefix, version_str))
170+
return make_pattern(
171+
pattern=pattern,
172+
key_func=self._backend.key_func,
173+
version=version or self._backend.version,
174+
prefix=prefix or self._backend.key_prefix,
175+
)
199176

200177

201178
class ClientCommands(Generic[Backend]):

django_valkey/util.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
import re
2+
from contextlib import suppress
3+
from typing import Any
4+
5+
from valkey.typing import KeyT, EncodableT
6+
7+
from django_valkey.compressors.base import BaseCompressor
8+
from django_valkey.exceptions import CompressorError
9+
from django_valkey.serializers.base import BaseSerializer
10+
11+
112
class CacheKey(str):
213
"""
314
A stub string class that we can use to check if a key was created already.
@@ -9,3 +20,56 @@ def original_key(self) -> str:
920

1021
def default_reverse_key(key: str) -> str:
1122
return key.split(":", 2)[2]
23+
24+
25+
special_re = re.compile("([*?[])")
26+
27+
28+
def glob_escape(s: str) -> str:
29+
return special_re.sub(r"[\1]", s)
30+
31+
32+
def make_key(
33+
key: KeyT, key_func, version: int | None = None, prefix: str | None = None
34+
) -> KeyT:
35+
if isinstance(key, CacheKey):
36+
return key
37+
38+
return CacheKey(key_func(key, prefix, version))
39+
40+
41+
def make_pattern(
42+
pattern: str, key_func, version: int | None = None, prefix: str | None = None
43+
) -> KeyT:
44+
if isinstance(pattern, CacheKey):
45+
return pattern
46+
47+
prefix = glob_escape(prefix)
48+
version_str = glob_escape(str(version))
49+
50+
return CacheKey(key_func(pattern, prefix, version_str))
51+
52+
53+
def encode(
54+
value: EncodableT, serializer: BaseSerializer, compressor: BaseCompressor
55+
) -> bytes | int | float:
56+
if type(value) not in {int, float}:
57+
value = serializer.dumps(value)
58+
return compressor.compress(value)
59+
60+
return value
61+
62+
63+
def decode(value: bytes, serializer: BaseSerializer, compressor: BaseCompressor) -> Any:
64+
try:
65+
if value.isdigit():
66+
value = int(value)
67+
else:
68+
value = float(value)
69+
70+
except (ValueError, TypeError):
71+
with suppress(CompressorError):
72+
value = compressor.decompress(value)
73+
value = serializer.loads(value)
74+
75+
return value

0 commit comments

Comments
 (0)