coredis 4.23.1__tar.gz → 5.0.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of coredis might be problematic. Click here for more details.
- {coredis-4.23.1 → coredis-5.0.0rc1}/HISTORY.rst +33 -0
- {coredis-4.23.1/coredis.egg-info → coredis-5.0.0rc1}/PKG-INFO +4 -5
- {coredis-4.23.1 → coredis-5.0.0rc1}/README.md +1 -2
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/__init__.py +1 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/_packer.py +10 -10
- coredis-5.0.0rc1/coredis/_protocols.py +73 -0
- coredis-5.0.0rc1/coredis/_py_311_typing.py +20 -0
- coredis-5.0.0rc1/coredis/_py_312_typing.py +17 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/_utils.py +49 -51
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/_version.py +3 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/cache.py +57 -82
- coredis-5.0.0rc1/coredis/client/__init__.py +6 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/client/basic.py +129 -56
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/client/cluster.py +147 -70
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/__init__.py +27 -7
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/_key_spec.py +11 -10
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/_utils.py +1 -1
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/_validators.py +30 -20
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/_wrappers.py +19 -99
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/bitfield.py +10 -2
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/constants.py +20 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/core.py +1627 -1246
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/function.py +29 -22
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/monitor.py +0 -71
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/pubsub.py +7 -142
- coredis-5.0.0rc1/coredis/commands/request.py +108 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/script.py +9 -9
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/commands/sentinel.py +60 -49
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/connection.py +14 -15
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/exceptions.py +2 -2
- coredis-5.0.0rc1/coredis/experimental/__init__.py +1 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/globals.py +3 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/autocomplete.py +28 -30
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/base.py +15 -31
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/filters.py +269 -245
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/graph.py +61 -62
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/json.py +172 -140
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/autocomplete.py +5 -4
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/graph.py +34 -29
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/json.py +5 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/search.py +49 -53
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/timeseries.py +18 -30
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/types.py +1 -5
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/search.py +186 -169
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/timeseries.py +184 -164
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/parser.py +6 -19
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/pipeline.py +391 -422
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/pool/basic.py +7 -7
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/pool/cluster.py +3 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/pool/nodemanager.py +10 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/__init__.py +76 -57
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/acl.py +0 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/cluster.py +25 -16
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/command.py +8 -6
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/connection.py +4 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/geo.py +17 -13
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/hash.py +13 -11
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/keys.py +9 -5
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/module.py +2 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/script.py +6 -8
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/sentinel.py +21 -17
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/server.py +36 -14
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/sets.py +3 -4
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/sorted_set.py +27 -24
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/streams.py +22 -13
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_callbacks/strings.py +7 -6
- coredis-5.0.0rc1/coredis/response/_callbacks/vector_sets.py +126 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/types.py +13 -4
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/sentinel.py +1 -1
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/stream.py +4 -3
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/tokens.py +343 -16
- coredis-5.0.0rc1/coredis/typing.py +582 -0
- {coredis-4.23.1 → coredis-5.0.0rc1/coredis.egg-info}/PKG-INFO +4 -5
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis.egg-info/SOURCES.txt +4 -2
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis.egg-info/requires.txt +2 -2
- {coredis-4.23.1 → coredis-5.0.0rc1}/pyproject.toml +3 -2
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/dev.txt +1 -1
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/docs.txt +1 -1
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/main.txt +2 -2
- coredis-4.23.1/coredis/_protocols.py +0 -82
- coredis-4.23.1/coredis/client/__init__.py +0 -7
- coredis-4.23.1/coredis/client/keydb.py +0 -336
- coredis-4.23.1/coredis/experimental/__init__.py +0 -5
- coredis-4.23.1/coredis/pipeline.pyi +0 -2103
- coredis-4.23.1/coredis/typing.py +0 -229
- {coredis-4.23.1 → coredis-5.0.0rc1}/LICENSE +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/MANIFEST.in +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/_json.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/_sidecar.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/config.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/constants.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/credentials.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/modules/response/_callbacks/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/pool/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/py.typed +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/credentials/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/credentials/iam_provider.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/locks/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/locks/extend.lua +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/locks/lua_lock.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/recipes/locks/release.lua +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/__init__.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/response/_utils.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/retry.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/speedups.c +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis/speedups.pyi +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis.egg-info/dependency_links.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/coredis.egg-info/top_level.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/ci.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/dev_extra.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/publishing.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/recipes.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/requirements/test.txt +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/setup.cfg +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/setup.py +0 -0
- {coredis-4.23.1 → coredis-5.0.0rc1}/versioneer.py +0 -0
|
@@ -3,6 +3,37 @@
|
|
|
3
3
|
Changelog
|
|
4
4
|
=========
|
|
5
5
|
|
|
6
|
+
v5.0.0rc1
|
|
7
|
+
---------
|
|
8
|
+
Release Date: 2025-07-07
|
|
9
|
+
|
|
10
|
+
* Features
|
|
11
|
+
|
|
12
|
+
* Add support for using custom types with redis commands
|
|
13
|
+
by registering serializers and deserializers
|
|
14
|
+
* Allow stacking pipeline commands syncronously
|
|
15
|
+
* Expose statically types responses for pipeline commands
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
* Compatibility
|
|
19
|
+
|
|
20
|
+
* Add support for redis 8.0 vector set commands
|
|
21
|
+
* Add support for redis 8.0 hash expiry commands
|
|
22
|
+
* Remove deprecated pubsub ``listen`` and threaded worker APIs
|
|
23
|
+
* Remove support for KeyDB
|
|
24
|
+
|
|
25
|
+
* Performance
|
|
26
|
+
|
|
27
|
+
* Streamline client side cache shrinking
|
|
28
|
+
|
|
29
|
+
v4.24.0
|
|
30
|
+
-------
|
|
31
|
+
Release Date: 2025-07-05
|
|
32
|
+
|
|
33
|
+
* Bug Fix
|
|
34
|
+
|
|
35
|
+
* Add support for using library functions with pipelines
|
|
36
|
+
|
|
6
37
|
v4.23.1
|
|
7
38
|
-------
|
|
8
39
|
Release Date: 2025-06-20
|
|
@@ -1930,3 +1961,5 @@ v1.0.1
|
|
|
1930
1961
|
|
|
1931
1962
|
|
|
1932
1963
|
|
|
1964
|
+
|
|
1965
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coredis
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0rc1
|
|
4
4
|
Summary: Python async client for Redis key-value store
|
|
5
5
|
Home-page: https://github.com/alisaifee/coredis
|
|
6
6
|
Author: Ali-Akber Saifee
|
|
@@ -26,11 +26,11 @@ Requires-Python: >=3.10
|
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: async_timeout<6,>4
|
|
29
|
+
Requires-Dist: beartype>=0.20
|
|
29
30
|
Requires-Dist: deprecated>=1.2
|
|
30
|
-
Requires-Dist: typing_extensions>=4.
|
|
31
|
+
Requires-Dist: typing_extensions>=4.13
|
|
31
32
|
Requires-Dist: packaging<26,>=21
|
|
32
33
|
Requires-Dist: pympler<2,>1
|
|
33
|
-
Requires-Dist: wrapt<2,>=1.1.0
|
|
34
34
|
Provides-Extra: recipes
|
|
35
35
|
Requires-Dist: aiobotocore>=2.15.2; extra == "recipes"
|
|
36
36
|
Requires-Dist: asyncache>=0.3.1; extra == "recipes"
|
|
@@ -201,7 +201,7 @@ Details about supported Redis modules and their commands can be found
|
|
|
201
201
|
|
|
202
202
|
## Compatibility
|
|
203
203
|
|
|
204
|
-
coredis is tested against redis versions >= `
|
|
204
|
+
coredis is tested against redis versions >= `7.0`
|
|
205
205
|
The test matrix status can be reviewed
|
|
206
206
|
[here](https://github.com/alisaifee/coredis/actions/workflows/main.yml)
|
|
207
207
|
|
|
@@ -221,7 +221,6 @@ coredis is additionally tested against:
|
|
|
221
221
|
|
|
222
222
|
**coredis** is known to work with the following databases that have redis protocol compatibility:
|
|
223
223
|
|
|
224
|
-
- [KeyDB](https://docs.keydb.dev/)
|
|
225
224
|
- [Dragonfly](https://dragonflydb.io/)
|
|
226
225
|
- [Redict](https://redict.io/)
|
|
227
226
|
- [Valkey](https://github.com/valkey-io/valkey)
|
|
@@ -148,7 +148,7 @@ Details about supported Redis modules and their commands can be found
|
|
|
148
148
|
|
|
149
149
|
## Compatibility
|
|
150
150
|
|
|
151
|
-
coredis is tested against redis versions >= `
|
|
151
|
+
coredis is tested against redis versions >= `7.0`
|
|
152
152
|
The test matrix status can be reviewed
|
|
153
153
|
[here](https://github.com/alisaifee/coredis/actions/workflows/main.yml)
|
|
154
154
|
|
|
@@ -168,7 +168,6 @@ coredis is additionally tested against:
|
|
|
168
168
|
|
|
169
169
|
**coredis** is known to work with the following databases that have redis protocol compatibility:
|
|
170
170
|
|
|
171
|
-
- [KeyDB](https://docs.keydb.dev/)
|
|
172
171
|
- [Dragonfly](https://dragonflydb.io/)
|
|
173
172
|
- [Redict](https://redict.io/)
|
|
174
173
|
- [Valkey](https://github.com/valkey-io/valkey)
|
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
from typing import cast
|
|
12
12
|
|
|
13
|
-
from coredis.client import
|
|
13
|
+
from coredis.client import Redis, RedisCluster
|
|
14
14
|
from coredis.config import Config
|
|
15
15
|
from coredis.connection import (
|
|
16
16
|
BaseConnection,
|
|
@@ -30,8 +30,6 @@ from . import _version
|
|
|
30
30
|
|
|
31
31
|
__all__ = [
|
|
32
32
|
"Config",
|
|
33
|
-
"KeyDB",
|
|
34
|
-
"KeyDBCluster",
|
|
35
33
|
"Redis",
|
|
36
34
|
"RedisCluster",
|
|
37
35
|
"BaseConnection",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from coredis.constants import SYM_CRLF, SYM_DOLLAR, SYM_EMPTY, SYM_STAR
|
|
4
|
-
from coredis.typing import
|
|
4
|
+
from coredis.typing import RedisValueT
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Packer:
|
|
8
8
|
def __init__(self, encoding: str):
|
|
9
9
|
self.encoding = encoding
|
|
10
10
|
|
|
11
|
-
def encode(self, value:
|
|
11
|
+
def encode(self, value: RedisValueT) -> bytes:
|
|
12
12
|
"""Returns a bytestring representation of the value"""
|
|
13
13
|
if isinstance(value, str):
|
|
14
14
|
return value.encode(self.encoding)
|
|
@@ -18,7 +18,7 @@ class Packer:
|
|
|
18
18
|
return b"%.15g" % value
|
|
19
19
|
return value
|
|
20
20
|
|
|
21
|
-
def pack_command(self, command: bytes, *args:
|
|
21
|
+
def pack_command(self, command: bytes, *args: RedisValueT) -> list[bytes]:
|
|
22
22
|
"Pack a series of arguments into the Redis protocol"
|
|
23
23
|
output: list[bytes] = []
|
|
24
24
|
# the client might have included 1 or more literal arguments in
|
|
@@ -50,22 +50,22 @@ class Packer:
|
|
|
50
50
|
output.append(buff)
|
|
51
51
|
return output
|
|
52
52
|
|
|
53
|
-
def pack_commands(self, commands: list[tuple[
|
|
53
|
+
def pack_commands(self, commands: list[tuple[RedisValueT, ...]]) -> list[bytes]:
|
|
54
54
|
output: list[bytes] = []
|
|
55
|
-
|
|
55
|
+
command_arguments: list[bytes] = []
|
|
56
56
|
buffer_length = 0
|
|
57
57
|
|
|
58
58
|
for cmd in commands:
|
|
59
59
|
for chunk in self.pack_command(self.encode(cmd[0]), *cmd[1:]):
|
|
60
|
-
|
|
60
|
+
command_arguments.append(chunk)
|
|
61
61
|
buffer_length += len(chunk)
|
|
62
62
|
|
|
63
63
|
if buffer_length > 6000:
|
|
64
|
-
output.append(SYM_EMPTY.join(
|
|
64
|
+
output.append(SYM_EMPTY.join(command_arguments))
|
|
65
65
|
buffer_length = 0
|
|
66
|
-
|
|
66
|
+
command_arguments = []
|
|
67
67
|
|
|
68
|
-
if
|
|
69
|
-
output.append(SYM_EMPTY.join(
|
|
68
|
+
if command_arguments:
|
|
69
|
+
output.append(SYM_EMPTY.join(command_arguments))
|
|
70
70
|
|
|
71
71
|
return output
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from typing_extensions import runtime_checkable
|
|
6
|
+
|
|
7
|
+
from coredis.response._callbacks import NoopCallback
|
|
8
|
+
from coredis.typing import (
|
|
9
|
+
TYPE_CHECKING,
|
|
10
|
+
Awaitable,
|
|
11
|
+
Callable,
|
|
12
|
+
ExecutionParameters,
|
|
13
|
+
KeyT,
|
|
14
|
+
Parameters,
|
|
15
|
+
Protocol,
|
|
16
|
+
R,
|
|
17
|
+
RedisCommandP,
|
|
18
|
+
RedisValueT,
|
|
19
|
+
ResponseType,
|
|
20
|
+
StringT,
|
|
21
|
+
TypeVar,
|
|
22
|
+
Unpack,
|
|
23
|
+
ValueT,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
T_co = TypeVar("T_co", covariant=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from coredis.commands import CommandRequest
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AbstractExecutor(Protocol):
|
|
34
|
+
def execute_command(
|
|
35
|
+
self,
|
|
36
|
+
command: RedisCommandP,
|
|
37
|
+
callback: Callable[..., R] = NoopCallback(),
|
|
38
|
+
**options: Unpack[ExecutionParameters],
|
|
39
|
+
) -> Awaitable[R]: ...
|
|
40
|
+
|
|
41
|
+
def create_request(
|
|
42
|
+
self,
|
|
43
|
+
name: bytes,
|
|
44
|
+
*arguments: ValueT,
|
|
45
|
+
callback: Callable[..., R],
|
|
46
|
+
execution_parameters: ExecutionParameters | None = None,
|
|
47
|
+
) -> CommandRequest[R]: ...
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@runtime_checkable
|
|
51
|
+
class SupportsScript(Protocol[T_co]): # noqa
|
|
52
|
+
async def evalsha(
|
|
53
|
+
self,
|
|
54
|
+
sha1: StringT,
|
|
55
|
+
keys: Parameters[KeyT] | None = ...,
|
|
56
|
+
args: Parameters[RedisValueT] | None = ...,
|
|
57
|
+
) -> ResponseType: ...
|
|
58
|
+
|
|
59
|
+
async def evalsha_ro(
|
|
60
|
+
self,
|
|
61
|
+
sha1: StringT,
|
|
62
|
+
keys: Parameters[KeyT] | None = ...,
|
|
63
|
+
args: Parameters[RedisValueT] | None = ...,
|
|
64
|
+
) -> ResponseType: ...
|
|
65
|
+
|
|
66
|
+
async def script_load(self, script: StringT) -> T_co: ...
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@runtime_checkable
|
|
70
|
+
class ConnectionP(Protocol):
|
|
71
|
+
decode_responses: bool
|
|
72
|
+
encoding: str
|
|
73
|
+
push_messages: asyncio.Queue[ResponseType]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Hashable
|
|
4
|
+
from typing import Any, TypeAlias
|
|
5
|
+
|
|
6
|
+
from .typing import MutableSet, RedisError, ResponsePrimitive
|
|
7
|
+
|
|
8
|
+
#: Represents the total structure of any response for any redis command.
|
|
9
|
+
ResponseType: TypeAlias = (
|
|
10
|
+
ResponsePrimitive
|
|
11
|
+
| list[Any]
|
|
12
|
+
| MutableSet[Hashable]
|
|
13
|
+
| dict[
|
|
14
|
+
Hashable,
|
|
15
|
+
Any,
|
|
16
|
+
]
|
|
17
|
+
| RedisError
|
|
18
|
+
)
|
|
19
|
+
#: Type alias for valid python types that can be represented as json
|
|
20
|
+
JsonType: TypeAlias = str | int | float | bool | dict[str, Any] | list[Any] | None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Hashable
|
|
4
|
+
|
|
5
|
+
from .typing import MutableSet, RedisError, ResponsePrimitive
|
|
6
|
+
|
|
7
|
+
#: Type alias for valid python types that can be represented as json
|
|
8
|
+
type JsonType = str | int | float | bool | dict[str, JsonType] | list[JsonType] | None
|
|
9
|
+
|
|
10
|
+
#: Represents the total structure of any response for any redis command.
|
|
11
|
+
type ResponseType = (
|
|
12
|
+
ResponsePrimitive
|
|
13
|
+
| RedisError
|
|
14
|
+
| list[ResponseType]
|
|
15
|
+
| MutableSet[Hashable]
|
|
16
|
+
| dict[Hashable, ResponseType]
|
|
17
|
+
)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import enum
|
|
4
|
+
from collections import UserDict
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
6
|
-
from wrapt import ObjectProxy
|
|
7
|
-
|
|
8
7
|
from coredis.typing import (
|
|
9
8
|
Hashable,
|
|
10
9
|
Iterable,
|
|
11
10
|
Mapping,
|
|
11
|
+
MutableMapping,
|
|
12
12
|
ResponseType,
|
|
13
13
|
StringT,
|
|
14
14
|
TypeVar,
|
|
@@ -18,61 +18,59 @@ T = TypeVar("T")
|
|
|
18
18
|
U = TypeVar("U")
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class EncodingInsensitiveDict(
|
|
21
|
+
class EncodingInsensitiveDict(UserDict[Any, Any]):
|
|
22
22
|
def __init__(
|
|
23
23
|
self,
|
|
24
|
-
|
|
24
|
+
initial: MutableMapping[Any, Any] | None = None,
|
|
25
25
|
encoding: str = "utf-8",
|
|
26
26
|
):
|
|
27
|
-
|
|
28
|
-
super().__init__(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def __getitem__(self, item: StringT) -> Any:
|
|
32
|
-
if isinstance(item, str) and item not in self.__wrapped__:
|
|
33
|
-
return self.__wrapped__.get(
|
|
34
|
-
item, self.__wrapped__.get(item.encode(self._self_encoding))
|
|
35
|
-
)
|
|
36
|
-
elif isinstance(item, bytes) and item not in self.__wrapped__:
|
|
37
|
-
return self.__wrapped__.get(
|
|
38
|
-
item, self.__wrapped__.get(item.decode(self._self_encoding))
|
|
39
|
-
)
|
|
40
|
-
return self.__wrapped__[item]
|
|
41
|
-
|
|
42
|
-
def get(self, item: StringT, default: object | None = None) -> Any:
|
|
43
|
-
return self.__getitem__(item) or default
|
|
44
|
-
|
|
45
|
-
def pop(self, item: StringT, default: object | None = None) -> Any:
|
|
46
|
-
if item in self.__wrapped__:
|
|
47
|
-
return self.__wrapped__.pop(item)
|
|
48
|
-
if isinstance(item, str):
|
|
49
|
-
return self.__wrapped__.pop(item.encode(self._self_encoding), default)
|
|
50
|
-
|
|
51
|
-
def clear(self) -> None:
|
|
52
|
-
self.__wrapped__.clear()
|
|
53
|
-
|
|
54
|
-
def update(self, updates: Mapping[Any, Any]) -> None:
|
|
55
|
-
self.__wrapped__.update(updates)
|
|
56
|
-
|
|
57
|
-
def __setitem__(self, item: StringT, value: object) -> None:
|
|
58
|
-
if item in self.__wrapped__:
|
|
59
|
-
self.__wrapped__[item] = value
|
|
60
|
-
elif isinstance(item, str) and item.encode(self._self_encoding) in self.__wrapped__:
|
|
61
|
-
self.__wrapped__[item.encode(self._self_encoding)] = value
|
|
62
|
-
elif isinstance(item, bytes) and item.decode(self._self_encoding) in self.__wrapped__:
|
|
63
|
-
self.__wrapped__[item.decode(self._self_encoding)] = value
|
|
64
|
-
else:
|
|
65
|
-
self.__wrapped__[item] = value
|
|
66
|
-
|
|
67
|
-
def __contains__(self, key: StringT) -> bool:
|
|
27
|
+
self._encoding = encoding
|
|
28
|
+
super().__init__(initial or {})
|
|
29
|
+
|
|
30
|
+
def _alt_key(self, key: StringT) -> StringT:
|
|
68
31
|
if isinstance(key, str):
|
|
69
|
-
|
|
32
|
+
try:
|
|
33
|
+
byte_alt = key.encode(self._encoding)
|
|
34
|
+
if byte_alt in self.data:
|
|
35
|
+
return byte_alt
|
|
36
|
+
except UnicodeEncodeError:
|
|
37
|
+
pass
|
|
70
38
|
elif isinstance(key, bytes):
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
39
|
+
try:
|
|
40
|
+
str_alt = key.decode(self._encoding)
|
|
41
|
+
if str_alt in self.data:
|
|
42
|
+
return str_alt
|
|
43
|
+
except UnicodeDecodeError:
|
|
44
|
+
pass
|
|
45
|
+
return key
|
|
46
|
+
|
|
47
|
+
def __getitem__(self, key: StringT) -> Any:
|
|
48
|
+
if key in self.data:
|
|
49
|
+
return self.data[key]
|
|
50
|
+
alt = self._alt_key(key)
|
|
51
|
+
if alt in self.data:
|
|
52
|
+
return self.data[alt]
|
|
53
|
+
raise KeyError(key)
|
|
54
|
+
|
|
55
|
+
def __setitem__(self, key: StringT, value: Any) -> None:
|
|
56
|
+
alt = self._alt_key(key)
|
|
57
|
+
self.data[alt] = value
|
|
58
|
+
|
|
59
|
+
def __delitem__(self, key: StringT) -> None:
|
|
60
|
+
alt = self._alt_key(key)
|
|
61
|
+
del self.data[alt]
|
|
62
|
+
|
|
63
|
+
def __contains__(self, key: Any) -> bool:
|
|
64
|
+
return key in self.data or self._alt_key(key) in self.data
|
|
65
|
+
|
|
66
|
+
def get(self, key: StringT, default: Any = None) -> Any:
|
|
67
|
+
return self.data.get(key, self.data.get(self._alt_key(key), default))
|
|
68
|
+
|
|
69
|
+
def pop(self, key: StringT, default: Any = None) -> Any:
|
|
70
|
+
if key in self.data:
|
|
71
|
+
return self.data.pop(key)
|
|
72
|
+
alt = self._alt_key(key)
|
|
73
|
+
return self.data.pop(alt, default)
|
|
76
74
|
|
|
77
75
|
|
|
78
76
|
@enum.unique
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-07-07T11:41:52-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "
|
|
14
|
+
"full-revisionid": "e2034feabddbed8c1a549ccc53976ca41d724a00",
|
|
15
|
+
"version": "5.0.0rc1"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|