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.
Files changed (100) hide show
  1. 22fe76227e35f92ab5c3__mypyc.cpython-313-darwin.so +0 -0
  2. coredis/__init__.py +42 -0
  3. coredis/_enum.py +42 -0
  4. coredis/_json.py +11 -0
  5. coredis/_packer.cpython-313-darwin.so +0 -0
  6. coredis/_packer.py +71 -0
  7. coredis/_protocols.py +50 -0
  8. coredis/_py_311_typing.py +20 -0
  9. coredis/_py_312_typing.py +17 -0
  10. coredis/_sidecar.py +114 -0
  11. coredis/_utils.cpython-313-darwin.so +0 -0
  12. coredis/_utils.py +440 -0
  13. coredis/_version.py +34 -0
  14. coredis/_version.pyi +1 -0
  15. coredis/cache.py +801 -0
  16. coredis/client/__init__.py +6 -0
  17. coredis/client/basic.py +1240 -0
  18. coredis/client/cluster.py +1265 -0
  19. coredis/commands/__init__.py +64 -0
  20. coredis/commands/_key_spec.py +517 -0
  21. coredis/commands/_utils.py +108 -0
  22. coredis/commands/_validators.py +159 -0
  23. coredis/commands/_wrappers.py +175 -0
  24. coredis/commands/bitfield.py +110 -0
  25. coredis/commands/constants.py +662 -0
  26. coredis/commands/core.py +8484 -0
  27. coredis/commands/function.py +408 -0
  28. coredis/commands/monitor.py +168 -0
  29. coredis/commands/pubsub.py +905 -0
  30. coredis/commands/request.py +108 -0
  31. coredis/commands/script.py +296 -0
  32. coredis/commands/sentinel.py +246 -0
  33. coredis/config.py +50 -0
  34. coredis/connection.py +906 -0
  35. coredis/constants.cpython-313-darwin.so +0 -0
  36. coredis/constants.py +37 -0
  37. coredis/credentials.py +45 -0
  38. coredis/exceptions.py +360 -0
  39. coredis/experimental/__init__.py +1 -0
  40. coredis/globals.py +23 -0
  41. coredis/modules/__init__.py +121 -0
  42. coredis/modules/autocomplete.py +138 -0
  43. coredis/modules/base.py +262 -0
  44. coredis/modules/filters.py +1319 -0
  45. coredis/modules/graph.py +362 -0
  46. coredis/modules/json.py +691 -0
  47. coredis/modules/response/__init__.py +0 -0
  48. coredis/modules/response/_callbacks/__init__.py +0 -0
  49. coredis/modules/response/_callbacks/autocomplete.py +42 -0
  50. coredis/modules/response/_callbacks/graph.py +237 -0
  51. coredis/modules/response/_callbacks/json.py +21 -0
  52. coredis/modules/response/_callbacks/search.py +221 -0
  53. coredis/modules/response/_callbacks/timeseries.py +158 -0
  54. coredis/modules/response/types.py +179 -0
  55. coredis/modules/search.py +1089 -0
  56. coredis/modules/timeseries.py +1139 -0
  57. coredis/parser.cpython-313-darwin.so +0 -0
  58. coredis/parser.py +344 -0
  59. coredis/pipeline.py +1225 -0
  60. coredis/pool/__init__.py +11 -0
  61. coredis/pool/basic.py +453 -0
  62. coredis/pool/cluster.py +517 -0
  63. coredis/pool/nodemanager.py +340 -0
  64. coredis/py.typed +0 -0
  65. coredis/recipes/__init__.py +0 -0
  66. coredis/recipes/credentials/__init__.py +5 -0
  67. coredis/recipes/credentials/iam_provider.py +63 -0
  68. coredis/recipes/locks/__init__.py +5 -0
  69. coredis/recipes/locks/extend.lua +17 -0
  70. coredis/recipes/locks/lua_lock.py +281 -0
  71. coredis/recipes/locks/release.lua +10 -0
  72. coredis/response/__init__.py +5 -0
  73. coredis/response/_callbacks/__init__.py +538 -0
  74. coredis/response/_callbacks/acl.py +32 -0
  75. coredis/response/_callbacks/cluster.py +183 -0
  76. coredis/response/_callbacks/command.py +86 -0
  77. coredis/response/_callbacks/connection.py +31 -0
  78. coredis/response/_callbacks/geo.py +58 -0
  79. coredis/response/_callbacks/hash.py +85 -0
  80. coredis/response/_callbacks/keys.py +59 -0
  81. coredis/response/_callbacks/module.py +33 -0
  82. coredis/response/_callbacks/script.py +85 -0
  83. coredis/response/_callbacks/sentinel.py +179 -0
  84. coredis/response/_callbacks/server.py +241 -0
  85. coredis/response/_callbacks/sets.py +44 -0
  86. coredis/response/_callbacks/sorted_set.py +204 -0
  87. coredis/response/_callbacks/streams.py +185 -0
  88. coredis/response/_callbacks/strings.py +70 -0
  89. coredis/response/_callbacks/vector_sets.py +159 -0
  90. coredis/response/_utils.py +33 -0
  91. coredis/response/types.py +416 -0
  92. coredis/retry.py +233 -0
  93. coredis/sentinel.py +477 -0
  94. coredis/stream.py +369 -0
  95. coredis/tokens.py +2286 -0
  96. coredis/typing.py +593 -0
  97. coredis-5.5.0.dist-info/METADATA +211 -0
  98. coredis-5.5.0.dist-info/RECORD +100 -0
  99. coredis-5.5.0.dist-info/WHEEL +6 -0
  100. 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