coredis 5.5.0__cp313-cp313-macosx_11_0_arm64.whl
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.
- 22fe76227e35f92ab5c3__mypyc.cpython-313-darwin.so +0 -0
- coredis/__init__.py +42 -0
- coredis/_enum.py +42 -0
- coredis/_json.py +11 -0
- coredis/_packer.cpython-313-darwin.so +0 -0
- coredis/_packer.py +71 -0
- coredis/_protocols.py +50 -0
- coredis/_py_311_typing.py +20 -0
- coredis/_py_312_typing.py +17 -0
- coredis/_sidecar.py +114 -0
- coredis/_utils.cpython-313-darwin.so +0 -0
- coredis/_utils.py +440 -0
- coredis/_version.py +34 -0
- coredis/_version.pyi +1 -0
- coredis/cache.py +801 -0
- coredis/client/__init__.py +6 -0
- coredis/client/basic.py +1240 -0
- coredis/client/cluster.py +1265 -0
- coredis/commands/__init__.py +64 -0
- coredis/commands/_key_spec.py +517 -0
- coredis/commands/_utils.py +108 -0
- coredis/commands/_validators.py +159 -0
- coredis/commands/_wrappers.py +175 -0
- coredis/commands/bitfield.py +110 -0
- coredis/commands/constants.py +662 -0
- coredis/commands/core.py +8484 -0
- coredis/commands/function.py +408 -0
- coredis/commands/monitor.py +168 -0
- coredis/commands/pubsub.py +905 -0
- coredis/commands/request.py +108 -0
- coredis/commands/script.py +296 -0
- coredis/commands/sentinel.py +246 -0
- coredis/config.py +50 -0
- coredis/connection.py +906 -0
- coredis/constants.cpython-313-darwin.so +0 -0
- coredis/constants.py +37 -0
- coredis/credentials.py +45 -0
- coredis/exceptions.py +360 -0
- coredis/experimental/__init__.py +1 -0
- coredis/globals.py +23 -0
- coredis/modules/__init__.py +121 -0
- coredis/modules/autocomplete.py +138 -0
- coredis/modules/base.py +262 -0
- coredis/modules/filters.py +1319 -0
- coredis/modules/graph.py +362 -0
- coredis/modules/json.py +691 -0
- coredis/modules/response/__init__.py +0 -0
- coredis/modules/response/_callbacks/__init__.py +0 -0
- coredis/modules/response/_callbacks/autocomplete.py +42 -0
- coredis/modules/response/_callbacks/graph.py +237 -0
- coredis/modules/response/_callbacks/json.py +21 -0
- coredis/modules/response/_callbacks/search.py +221 -0
- coredis/modules/response/_callbacks/timeseries.py +158 -0
- coredis/modules/response/types.py +179 -0
- coredis/modules/search.py +1089 -0
- coredis/modules/timeseries.py +1139 -0
- coredis/parser.cpython-313-darwin.so +0 -0
- coredis/parser.py +344 -0
- coredis/pipeline.py +1225 -0
- coredis/pool/__init__.py +11 -0
- coredis/pool/basic.py +453 -0
- coredis/pool/cluster.py +517 -0
- coredis/pool/nodemanager.py +340 -0
- coredis/py.typed +0 -0
- coredis/recipes/__init__.py +0 -0
- coredis/recipes/credentials/__init__.py +5 -0
- coredis/recipes/credentials/iam_provider.py +63 -0
- coredis/recipes/locks/__init__.py +5 -0
- coredis/recipes/locks/extend.lua +17 -0
- coredis/recipes/locks/lua_lock.py +281 -0
- coredis/recipes/locks/release.lua +10 -0
- coredis/response/__init__.py +5 -0
- coredis/response/_callbacks/__init__.py +538 -0
- coredis/response/_callbacks/acl.py +32 -0
- coredis/response/_callbacks/cluster.py +183 -0
- coredis/response/_callbacks/command.py +86 -0
- coredis/response/_callbacks/connection.py +31 -0
- coredis/response/_callbacks/geo.py +58 -0
- coredis/response/_callbacks/hash.py +85 -0
- coredis/response/_callbacks/keys.py +59 -0
- coredis/response/_callbacks/module.py +33 -0
- coredis/response/_callbacks/script.py +85 -0
- coredis/response/_callbacks/sentinel.py +179 -0
- coredis/response/_callbacks/server.py +241 -0
- coredis/response/_callbacks/sets.py +44 -0
- coredis/response/_callbacks/sorted_set.py +204 -0
- coredis/response/_callbacks/streams.py +185 -0
- coredis/response/_callbacks/strings.py +70 -0
- coredis/response/_callbacks/vector_sets.py +159 -0
- coredis/response/_utils.py +33 -0
- coredis/response/types.py +416 -0
- coredis/retry.py +233 -0
- coredis/sentinel.py +477 -0
- coredis/stream.py +369 -0
- coredis/tokens.py +2286 -0
- coredis/typing.py +593 -0
- coredis-5.5.0.dist-info/METADATA +211 -0
- coredis-5.5.0.dist-info/RECORD +100 -0
- coredis-5.5.0.dist-info/WHEEL +6 -0
- coredis-5.5.0.dist-info/licenses/LICENSE +23 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from coredis._utils import EncodingInsensitiveDict, nativestr
|
|
4
|
+
from coredis.response._callbacks import ResponseCallback
|
|
5
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
6
|
+
from coredis.response.types import ClusterNode, ClusterNodeDetail
|
|
7
|
+
from coredis.typing import (
|
|
8
|
+
AnyStr,
|
|
9
|
+
Mapping,
|
|
10
|
+
RedisValueT,
|
|
11
|
+
ResponsePrimitive,
|
|
12
|
+
ResponseType,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ClusterLinksCallback(
|
|
17
|
+
ResponseCallback[ResponseType, ResponseType, list[dict[AnyStr, ResponsePrimitive]]]
|
|
18
|
+
):
|
|
19
|
+
def transform(
|
|
20
|
+
self,
|
|
21
|
+
response: ResponseType,
|
|
22
|
+
) -> list[dict[AnyStr, ResponsePrimitive]]:
|
|
23
|
+
transformed: list[dict[AnyStr, ResponsePrimitive]] = []
|
|
24
|
+
|
|
25
|
+
for item in response:
|
|
26
|
+
transformed.append(flat_pairs_to_dict(item))
|
|
27
|
+
return transformed
|
|
28
|
+
|
|
29
|
+
def transform_3(
|
|
30
|
+
self,
|
|
31
|
+
response: ResponseType,
|
|
32
|
+
) -> list[dict[AnyStr, ResponsePrimitive]]:
|
|
33
|
+
return response
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ClusterInfoCallback(ResponseCallback[ResponseType, ResponseType, dict[str, str]]):
|
|
37
|
+
def transform(
|
|
38
|
+
self,
|
|
39
|
+
response: ResponseType,
|
|
40
|
+
) -> dict[str, str]:
|
|
41
|
+
response_str = nativestr(response)
|
|
42
|
+
return dict([line.split(":") for line in response_str.splitlines() if line])
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ClusterSlotsCallback(
|
|
46
|
+
ResponseCallback[ResponseType, ResponseType, dict[tuple[int, int], tuple[ClusterNode, ...]]]
|
|
47
|
+
):
|
|
48
|
+
def transform(
|
|
49
|
+
self,
|
|
50
|
+
response: ResponseType,
|
|
51
|
+
) -> dict[tuple[int, int], tuple[ClusterNode, ...]]:
|
|
52
|
+
res: dict[tuple[int, int], tuple[ClusterNode, ...]] = {}
|
|
53
|
+
|
|
54
|
+
for slot_info in response:
|
|
55
|
+
min_slot, max_slot = map(int, slot_info[:2])
|
|
56
|
+
nodes = slot_info[2:]
|
|
57
|
+
res[(min_slot, max_slot)] = tuple(self.parse_node(node) for node in nodes)
|
|
58
|
+
res[(min_slot, max_slot)][0]["server_type"] = "master"
|
|
59
|
+
|
|
60
|
+
return res
|
|
61
|
+
|
|
62
|
+
def parse_node(self, node: list[int | str]) -> ClusterNode:
|
|
63
|
+
return ClusterNode(
|
|
64
|
+
host=nativestr(node[0]),
|
|
65
|
+
port=int(node[1]),
|
|
66
|
+
node_id=nativestr(node[2]) if len(node) > 2 else "",
|
|
67
|
+
server_type="slave",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ClusterNodesCallback(ResponseCallback[ResponseType, ResponseType, list[ClusterNodeDetail]]):
|
|
72
|
+
def transform(
|
|
73
|
+
self,
|
|
74
|
+
response: ResponseType,
|
|
75
|
+
) -> list[ClusterNodeDetail]:
|
|
76
|
+
resp: list[str] | str
|
|
77
|
+
|
|
78
|
+
if isinstance(response, list):
|
|
79
|
+
resp = [nativestr(row) for row in response]
|
|
80
|
+
else:
|
|
81
|
+
resp = nativestr(response)
|
|
82
|
+
current_host = nativestr(self.options.get("current_host", ""))
|
|
83
|
+
|
|
84
|
+
def parse_slots(s: str) -> tuple[list[int], list[dict[str, RedisValueT]]]:
|
|
85
|
+
slots: list[int] = []
|
|
86
|
+
migrations: list[dict[str, RedisValueT]] = []
|
|
87
|
+
|
|
88
|
+
for r in s.split(" "):
|
|
89
|
+
if "->-" in r:
|
|
90
|
+
slot_id, dst_node_id = r[1:-1].split("->-", 1)
|
|
91
|
+
migrations.append(
|
|
92
|
+
{
|
|
93
|
+
"slot": int(slot_id),
|
|
94
|
+
"node_id": dst_node_id,
|
|
95
|
+
"state": "migrating",
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
elif "-<-" in r:
|
|
99
|
+
slot_id, src_node_id = r[1:-1].split("-<-", 1)
|
|
100
|
+
migrations.append(
|
|
101
|
+
{
|
|
102
|
+
"slot": int(slot_id),
|
|
103
|
+
"node_id": src_node_id,
|
|
104
|
+
"state": "importing",
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
elif "-" in r:
|
|
108
|
+
start, end = r.split("-")
|
|
109
|
+
slots.extend(list(range(int(start), int(end) + 1)))
|
|
110
|
+
else:
|
|
111
|
+
slots.append(int(r))
|
|
112
|
+
|
|
113
|
+
return slots, migrations
|
|
114
|
+
|
|
115
|
+
if isinstance(resp, str):
|
|
116
|
+
resp = resp.splitlines()
|
|
117
|
+
|
|
118
|
+
nodes: list[ClusterNodeDetail] = []
|
|
119
|
+
|
|
120
|
+
for line in resp:
|
|
121
|
+
parts = line.split(" ", 8)
|
|
122
|
+
(
|
|
123
|
+
self_id,
|
|
124
|
+
addr,
|
|
125
|
+
flags,
|
|
126
|
+
master_id,
|
|
127
|
+
ping_sent,
|
|
128
|
+
pong_recv,
|
|
129
|
+
_,
|
|
130
|
+
link_state,
|
|
131
|
+
) = parts[:8]
|
|
132
|
+
|
|
133
|
+
host, port = addr.rsplit(":", 1)
|
|
134
|
+
|
|
135
|
+
node: ClusterNodeDetail = {
|
|
136
|
+
"id": self_id,
|
|
137
|
+
"host": host or current_host,
|
|
138
|
+
"port": int(port.split("@")[0]),
|
|
139
|
+
"flags": tuple(flags.split(",")),
|
|
140
|
+
"master": master_id if master_id != "-" else None,
|
|
141
|
+
"ping_sent": int(ping_sent),
|
|
142
|
+
"pong_recv": int(pong_recv),
|
|
143
|
+
"link_state": link_state,
|
|
144
|
+
"slots": [],
|
|
145
|
+
"migrations": [],
|
|
146
|
+
}
|
|
147
|
+
if len(parts) >= 9:
|
|
148
|
+
slots, migrations = parse_slots(parts[8])
|
|
149
|
+
node["slots"], node["migrations"] = slots, migrations
|
|
150
|
+
|
|
151
|
+
nodes.append(node)
|
|
152
|
+
|
|
153
|
+
return nodes
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class ClusterShardsCallback(
|
|
157
|
+
ResponseCallback[
|
|
158
|
+
ResponseType,
|
|
159
|
+
ResponseType,
|
|
160
|
+
list[dict[AnyStr, list[RedisValueT] | Mapping[AnyStr, RedisValueT]]],
|
|
161
|
+
]
|
|
162
|
+
):
|
|
163
|
+
def transform(
|
|
164
|
+
self,
|
|
165
|
+
response: ResponseType,
|
|
166
|
+
) -> list[dict[AnyStr, list[RedisValueT] | Mapping[AnyStr, RedisValueT]]]:
|
|
167
|
+
shard_mapping: list[dict[AnyStr, list[RedisValueT] | Mapping[AnyStr, RedisValueT]]] = []
|
|
168
|
+
|
|
169
|
+
for shard in response:
|
|
170
|
+
transformed = EncodingInsensitiveDict(flat_pairs_to_dict(shard))
|
|
171
|
+
node_mapping: list[dict[AnyStr, RedisValueT]] = []
|
|
172
|
+
for node in transformed["nodes"]:
|
|
173
|
+
node_mapping.append(flat_pairs_to_dict(node))
|
|
174
|
+
|
|
175
|
+
transformed["nodes"] = node_mapping
|
|
176
|
+
shard_mapping.append(transformed.__wrapped__) # type: ignore
|
|
177
|
+
return shard_mapping
|
|
178
|
+
|
|
179
|
+
def transform_3(
|
|
180
|
+
self,
|
|
181
|
+
response: ResponseType,
|
|
182
|
+
) -> list[dict[AnyStr, list[RedisValueT] | Mapping[AnyStr, RedisValueT]]]:
|
|
183
|
+
return response
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from coredis._utils import EncodingInsensitiveDict, nativestr
|
|
4
|
+
from coredis.response._callbacks import ResponseCallback
|
|
5
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
6
|
+
from coredis.response.types import Command
|
|
7
|
+
from coredis.typing import (
|
|
8
|
+
AnyStr,
|
|
9
|
+
ResponsePrimitive,
|
|
10
|
+
ResponseType,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommandCallback(ResponseCallback[list[ResponseType], list[ResponseType], dict[str, Command]]):
|
|
15
|
+
def transform(
|
|
16
|
+
self,
|
|
17
|
+
response: list[ResponseType],
|
|
18
|
+
) -> dict[str, Command]:
|
|
19
|
+
commands: dict[str, Command] = {}
|
|
20
|
+
|
|
21
|
+
for command in response:
|
|
22
|
+
assert isinstance(command, list)
|
|
23
|
+
|
|
24
|
+
if command:
|
|
25
|
+
name = nativestr(command[0])
|
|
26
|
+
|
|
27
|
+
if len(command) >= 6:
|
|
28
|
+
commands[name] = {
|
|
29
|
+
"name": command[0],
|
|
30
|
+
"arity": command[1],
|
|
31
|
+
"flags": command[2],
|
|
32
|
+
"first-key": command[3],
|
|
33
|
+
"last-key": command[4],
|
|
34
|
+
"step": command[5],
|
|
35
|
+
"acl-categories": None,
|
|
36
|
+
"tips": None,
|
|
37
|
+
"key-specifications": None,
|
|
38
|
+
"sub-commands": None,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if len(command) >= 7:
|
|
42
|
+
commands[name]["acl-categories"] = command[6]
|
|
43
|
+
|
|
44
|
+
if len(command) >= 8:
|
|
45
|
+
commands[name]["tips"] = command[7]
|
|
46
|
+
commands[name]["key-specifications"] = command[8]
|
|
47
|
+
commands[name]["sub-commands"] = command[9]
|
|
48
|
+
|
|
49
|
+
return commands
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class CommandKeyFlagCallback(
|
|
53
|
+
ResponseCallback[list[ResponseType], list[ResponseType], dict[AnyStr, set[AnyStr]]]
|
|
54
|
+
):
|
|
55
|
+
def transform(
|
|
56
|
+
self,
|
|
57
|
+
response: list[ResponseType],
|
|
58
|
+
) -> dict[AnyStr, set[AnyStr]]:
|
|
59
|
+
return {k[0]: set(k[1]) for k in response}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CommandDocCallback(
|
|
63
|
+
ResponseCallback[
|
|
64
|
+
list[ResponseType],
|
|
65
|
+
dict[ResponsePrimitive, ResponseType],
|
|
66
|
+
dict[AnyStr, dict[AnyStr, ResponseType]],
|
|
67
|
+
]
|
|
68
|
+
):
|
|
69
|
+
def transform(
|
|
70
|
+
self,
|
|
71
|
+
response: list[ResponseType],
|
|
72
|
+
) -> dict[AnyStr, dict[AnyStr, ResponseType]]:
|
|
73
|
+
cmd_mapping = flat_pairs_to_dict(response)
|
|
74
|
+
for cmd, doc in cmd_mapping.items():
|
|
75
|
+
cmd_mapping[cmd] = EncodingInsensitiveDict(flat_pairs_to_dict(doc))
|
|
76
|
+
cmd_mapping[cmd]["arguments"] = [
|
|
77
|
+
flat_pairs_to_dict(arg) for arg in cmd_mapping[cmd].get("arguments", [])
|
|
78
|
+
]
|
|
79
|
+
cmd_mapping[cmd] = dict(cmd_mapping[cmd])
|
|
80
|
+
return dict(cmd_mapping)
|
|
81
|
+
|
|
82
|
+
def transform_3(
|
|
83
|
+
self,
|
|
84
|
+
response: dict[ResponsePrimitive, ResponseType],
|
|
85
|
+
) -> dict[AnyStr, dict[AnyStr, ResponseType]]:
|
|
86
|
+
return response # noqa
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from coredis._utils import EncodingInsensitiveDict
|
|
4
|
+
from coredis.response._callbacks import ResponseCallback
|
|
5
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
6
|
+
from coredis.typing import (
|
|
7
|
+
AnyStr,
|
|
8
|
+
ResponseType,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ClientTrackingInfoCallback(
|
|
13
|
+
ResponseCallback[
|
|
14
|
+
ResponseType,
|
|
15
|
+
ResponseType,
|
|
16
|
+
dict[AnyStr, AnyStr | set[AnyStr] | list[AnyStr]],
|
|
17
|
+
]
|
|
18
|
+
):
|
|
19
|
+
def transform(
|
|
20
|
+
self,
|
|
21
|
+
response: ResponseType,
|
|
22
|
+
) -> dict[AnyStr, AnyStr | set[AnyStr] | list[AnyStr]]:
|
|
23
|
+
response = EncodingInsensitiveDict(flat_pairs_to_dict(response))
|
|
24
|
+
response["flags"] = set(response["flags"])
|
|
25
|
+
return dict(response)
|
|
26
|
+
|
|
27
|
+
def transform_3(
|
|
28
|
+
self,
|
|
29
|
+
response: ResponseType,
|
|
30
|
+
) -> dict[AnyStr, AnyStr | set[AnyStr] | list[AnyStr]]:
|
|
31
|
+
return response
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from coredis.response._callbacks import ResponseCallback
|
|
6
|
+
from coredis.response.types import GeoCoordinates, GeoSearchResult
|
|
7
|
+
from coredis.typing import AnyStr, Generic, ResponseType
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GeoSearchCallback(
|
|
11
|
+
Generic[AnyStr],
|
|
12
|
+
ResponseCallback[
|
|
13
|
+
ResponseType,
|
|
14
|
+
ResponseType,
|
|
15
|
+
tuple[AnyStr | GeoSearchResult, ...],
|
|
16
|
+
],
|
|
17
|
+
):
|
|
18
|
+
def transform(
|
|
19
|
+
self, response: ResponseType, **options: Any
|
|
20
|
+
) -> tuple[AnyStr | GeoSearchResult, ...]:
|
|
21
|
+
if not (
|
|
22
|
+
self.options.get("withdist")
|
|
23
|
+
or self.options.get("withcoord")
|
|
24
|
+
or self.options.get("withhash")
|
|
25
|
+
):
|
|
26
|
+
return tuple(list(response))
|
|
27
|
+
|
|
28
|
+
results: list[GeoSearchResult] = []
|
|
29
|
+
|
|
30
|
+
for result in response:
|
|
31
|
+
results.append(
|
|
32
|
+
GeoSearchResult(
|
|
33
|
+
result.pop(0),
|
|
34
|
+
float(result.pop(0)) if self.options.get("withdist") else None,
|
|
35
|
+
result.pop(0) if self.options.get("withhash") else None,
|
|
36
|
+
(
|
|
37
|
+
GeoCoordinates(*map(float, result.pop(0)))
|
|
38
|
+
if self.options.get("withcoord")
|
|
39
|
+
else None
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return tuple(results)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class GeoCoordinatessCallback(
|
|
48
|
+
ResponseCallback[ResponseType, ResponseType, tuple[GeoCoordinates | None, ...]]
|
|
49
|
+
):
|
|
50
|
+
def transform(
|
|
51
|
+
self, response: ResponseType, **options: Any
|
|
52
|
+
) -> tuple[GeoCoordinates | None, ...]:
|
|
53
|
+
return tuple(
|
|
54
|
+
map(
|
|
55
|
+
lambda ll: (GeoCoordinates(float(ll[0]), float(ll[1])) if ll is not None else None),
|
|
56
|
+
response,
|
|
57
|
+
)
|
|
58
|
+
)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
from coredis.response._callbacks import ResponseCallback
|
|
6
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
7
|
+
from coredis.typing import (
|
|
8
|
+
AnyStr,
|
|
9
|
+
ResponseType,
|
|
10
|
+
StringT,
|
|
11
|
+
TypeGuard,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HScanCallback(
|
|
16
|
+
ResponseCallback[
|
|
17
|
+
list[ResponseType],
|
|
18
|
+
list[ResponseType],
|
|
19
|
+
tuple[int, dict[AnyStr, AnyStr] | tuple[AnyStr, ...]],
|
|
20
|
+
]
|
|
21
|
+
):
|
|
22
|
+
def guard(self, response: list[ResponseType]) -> TypeGuard[tuple[StringT, list[AnyStr]]]:
|
|
23
|
+
return isinstance(response[0], (str, bytes)) and isinstance(response[1], list)
|
|
24
|
+
|
|
25
|
+
def transform(
|
|
26
|
+
self,
|
|
27
|
+
response: list[ResponseType],
|
|
28
|
+
) -> tuple[int, dict[AnyStr, AnyStr] | tuple[AnyStr, ...]]:
|
|
29
|
+
assert self.guard(response)
|
|
30
|
+
cursor, r = response
|
|
31
|
+
if self.options.get("novalues"):
|
|
32
|
+
return int(cursor), tuple(r)
|
|
33
|
+
else:
|
|
34
|
+
return int(cursor), flat_pairs_to_dict(r)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class HRandFieldCallback(
|
|
38
|
+
ResponseCallback[
|
|
39
|
+
AnyStr | list[AnyStr] | None,
|
|
40
|
+
AnyStr | list[AnyStr] | list[list[AnyStr]] | None,
|
|
41
|
+
AnyStr | tuple[AnyStr, ...] | dict[AnyStr, AnyStr] | None,
|
|
42
|
+
]
|
|
43
|
+
):
|
|
44
|
+
def transform(
|
|
45
|
+
self,
|
|
46
|
+
response: AnyStr | list[AnyStr] | None,
|
|
47
|
+
) -> AnyStr | tuple[AnyStr, ...] | dict[AnyStr, AnyStr] | None:
|
|
48
|
+
if not response:
|
|
49
|
+
return None
|
|
50
|
+
if self.options.get("count"):
|
|
51
|
+
assert isinstance(response, list)
|
|
52
|
+
if self.options.get("withvalues"):
|
|
53
|
+
return flat_pairs_to_dict(response)
|
|
54
|
+
else:
|
|
55
|
+
return tuple(response)
|
|
56
|
+
assert isinstance(response, (str, bytes))
|
|
57
|
+
return response
|
|
58
|
+
|
|
59
|
+
def transform_3(
|
|
60
|
+
self,
|
|
61
|
+
response: AnyStr | list[AnyStr] | list[list[AnyStr]] | None,
|
|
62
|
+
) -> AnyStr | tuple[AnyStr, ...] | dict[AnyStr, AnyStr] | None:
|
|
63
|
+
if not response:
|
|
64
|
+
return None
|
|
65
|
+
if self.options.get("count"):
|
|
66
|
+
assert isinstance(response, list)
|
|
67
|
+
if self.options.get("withvalues"):
|
|
68
|
+
return dict(cast(list[tuple[AnyStr, AnyStr]], response))
|
|
69
|
+
return tuple(cast(tuple[AnyStr, AnyStr], response))
|
|
70
|
+
assert isinstance(response, (str, bytes))
|
|
71
|
+
return response
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class HGetAllCallback(ResponseCallback[list[AnyStr], dict[AnyStr, AnyStr], dict[AnyStr, AnyStr]]):
|
|
75
|
+
def transform(
|
|
76
|
+
self,
|
|
77
|
+
response: list[AnyStr],
|
|
78
|
+
) -> dict[AnyStr, AnyStr]:
|
|
79
|
+
return flat_pairs_to_dict(response) if response else {}
|
|
80
|
+
|
|
81
|
+
def transform_3(
|
|
82
|
+
self,
|
|
83
|
+
response: dict[AnyStr, AnyStr],
|
|
84
|
+
) -> dict[AnyStr, AnyStr]:
|
|
85
|
+
return response
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from coredis.exceptions import DataError, NoKeyError, RedisError
|
|
6
|
+
from coredis.response._callbacks import DateTimeCallback, ResponseCallback
|
|
7
|
+
from coredis.typing import (
|
|
8
|
+
AnyStr,
|
|
9
|
+
ResponseType,
|
|
10
|
+
StringT,
|
|
11
|
+
TypeGuard,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SortCallback(
|
|
16
|
+
ResponseCallback[
|
|
17
|
+
int | list[AnyStr],
|
|
18
|
+
int | list[AnyStr],
|
|
19
|
+
int | tuple[AnyStr, ...],
|
|
20
|
+
]
|
|
21
|
+
):
|
|
22
|
+
def transform(
|
|
23
|
+
self,
|
|
24
|
+
response: int | list[AnyStr],
|
|
25
|
+
) -> int | tuple[AnyStr, ...]:
|
|
26
|
+
if isinstance(response, list):
|
|
27
|
+
return tuple(response)
|
|
28
|
+
return response
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ScanCallback(
|
|
32
|
+
ResponseCallback[list[ResponseType], list[ResponseType], tuple[int, tuple[AnyStr, ...]]]
|
|
33
|
+
):
|
|
34
|
+
def guard(self, response: list[ResponseType]) -> TypeGuard[tuple[StringT, list[AnyStr]]]:
|
|
35
|
+
return isinstance(response[0], (str, bytes)) and isinstance(response[1], list)
|
|
36
|
+
|
|
37
|
+
def transform(
|
|
38
|
+
self,
|
|
39
|
+
response: list[ResponseType],
|
|
40
|
+
) -> tuple[int, tuple[AnyStr, ...]]:
|
|
41
|
+
assert self.guard(response)
|
|
42
|
+
cursor, r = response
|
|
43
|
+
return int(cursor), tuple(r)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExpiryCallback(DateTimeCallback):
|
|
47
|
+
def transform(
|
|
48
|
+
self,
|
|
49
|
+
response: int,
|
|
50
|
+
) -> datetime:
|
|
51
|
+
if response > 0:
|
|
52
|
+
return super().transform(response)
|
|
53
|
+
else:
|
|
54
|
+
if response == -2:
|
|
55
|
+
raise NoKeyError()
|
|
56
|
+
elif response == -1:
|
|
57
|
+
raise DataError()
|
|
58
|
+
else:
|
|
59
|
+
raise RedisError()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
from coredis.response._callbacks import ResponseCallback
|
|
6
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
7
|
+
from coredis.typing import (
|
|
8
|
+
AnyStr,
|
|
9
|
+
ResponsePrimitive,
|
|
10
|
+
ResponseType,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ModuleInfoCallback(
|
|
15
|
+
ResponseCallback[
|
|
16
|
+
list[list[ResponseType]],
|
|
17
|
+
list[dict[AnyStr, ResponsePrimitive]],
|
|
18
|
+
tuple[dict[AnyStr, ResponsePrimitive], ...],
|
|
19
|
+
]
|
|
20
|
+
):
|
|
21
|
+
def transform(
|
|
22
|
+
self,
|
|
23
|
+
response: list[list[ResponseType]],
|
|
24
|
+
) -> tuple[dict[AnyStr, ResponsePrimitive], ...]:
|
|
25
|
+
return tuple(
|
|
26
|
+
cast(dict[AnyStr, ResponsePrimitive], flat_pairs_to_dict(mod)) for mod in response
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def transform_3(
|
|
30
|
+
self,
|
|
31
|
+
response: list[dict[AnyStr, ResponsePrimitive]],
|
|
32
|
+
) -> tuple[dict[AnyStr, ResponsePrimitive], ...]:
|
|
33
|
+
return tuple(response)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
from coredis._utils import EncodingInsensitiveDict
|
|
6
|
+
from coredis.response._callbacks import ResponseCallback
|
|
7
|
+
from coredis.response._utils import flat_pairs_to_dict
|
|
8
|
+
from coredis.response.types import LibraryDefinition
|
|
9
|
+
from coredis.typing import (
|
|
10
|
+
AnyStr,
|
|
11
|
+
Mapping,
|
|
12
|
+
RedisValueT,
|
|
13
|
+
ResponsePrimitive,
|
|
14
|
+
ResponseType,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FunctionListCallback(
|
|
19
|
+
ResponseCallback[list[ResponseType], list[ResponseType], Mapping[AnyStr, LibraryDefinition]]
|
|
20
|
+
):
|
|
21
|
+
def transform(
|
|
22
|
+
self,
|
|
23
|
+
response: list[ResponseType],
|
|
24
|
+
) -> Mapping[AnyStr, LibraryDefinition]:
|
|
25
|
+
libraries = [
|
|
26
|
+
EncodingInsensitiveDict(flat_pairs_to_dict(cast(list[RedisValueT], library)))
|
|
27
|
+
for library in response
|
|
28
|
+
]
|
|
29
|
+
transformed = EncodingInsensitiveDict()
|
|
30
|
+
for library in libraries:
|
|
31
|
+
lib_name = library["library_name"]
|
|
32
|
+
functions = EncodingInsensitiveDict({})
|
|
33
|
+
for function in library.get("functions", []):
|
|
34
|
+
function_definition = EncodingInsensitiveDict(flat_pairs_to_dict(function))
|
|
35
|
+
functions[function_definition["name"]] = function_definition
|
|
36
|
+
functions[function_definition["name"]]["flags"] = set(function_definition["flags"])
|
|
37
|
+
library["functions"] = functions
|
|
38
|
+
transformed[lib_name] = EncodingInsensitiveDict(
|
|
39
|
+
LibraryDefinition(
|
|
40
|
+
name=library["library_name"],
|
|
41
|
+
engine=library["engine"],
|
|
42
|
+
functions=library["functions"],
|
|
43
|
+
library_code=library.get("library_code", None),
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
return transformed
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class FunctionStatsCallback(
|
|
50
|
+
ResponseCallback[
|
|
51
|
+
list[ResponseType],
|
|
52
|
+
dict[
|
|
53
|
+
AnyStr,
|
|
54
|
+
AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]] | None,
|
|
55
|
+
],
|
|
56
|
+
dict[
|
|
57
|
+
AnyStr,
|
|
58
|
+
AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]] | None,
|
|
59
|
+
],
|
|
60
|
+
]
|
|
61
|
+
):
|
|
62
|
+
def transform(
|
|
63
|
+
self,
|
|
64
|
+
response: list[ResponseType],
|
|
65
|
+
) -> dict[AnyStr, AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]] | None]:
|
|
66
|
+
transformed = flat_pairs_to_dict(response)
|
|
67
|
+
key = cast(AnyStr, b"engines" if b"engines" in transformed else "engines")
|
|
68
|
+
engines = flat_pairs_to_dict(cast(list[AnyStr], transformed.pop(key)))
|
|
69
|
+
engines_transformed = {}
|
|
70
|
+
for engine, stats in engines.items():
|
|
71
|
+
engines_transformed[engine] = flat_pairs_to_dict(cast(list[AnyStr], stats))
|
|
72
|
+
transformed[key] = engines_transformed # type: ignore
|
|
73
|
+
return cast(
|
|
74
|
+
dict[AnyStr, AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]]],
|
|
75
|
+
transformed,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def transform_3(
|
|
79
|
+
self,
|
|
80
|
+
response: dict[
|
|
81
|
+
AnyStr,
|
|
82
|
+
AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]] | None,
|
|
83
|
+
],
|
|
84
|
+
) -> dict[AnyStr, AnyStr | dict[AnyStr, dict[AnyStr, ResponsePrimitive]] | None]:
|
|
85
|
+
return response
|