redis 5.2.0__py3-none-any.whl → 5.3.0__py3-none-any.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.
redis/event.py ADDED
@@ -0,0 +1,394 @@
1
+ import asyncio
2
+ import threading
3
+ from abc import ABC, abstractmethod
4
+ from enum import Enum
5
+ from typing import List, Optional, Union
6
+
7
+ from redis.auth.token import TokenInterface
8
+ from redis.credentials import CredentialProvider, StreamingCredentialProvider
9
+
10
+
11
+ class EventListenerInterface(ABC):
12
+ """
13
+ Represents a listener for given event object.
14
+ """
15
+
16
+ @abstractmethod
17
+ def listen(self, event: object):
18
+ pass
19
+
20
+
21
+ class AsyncEventListenerInterface(ABC):
22
+ """
23
+ Represents an async listener for given event object.
24
+ """
25
+
26
+ @abstractmethod
27
+ async def listen(self, event: object):
28
+ pass
29
+
30
+
31
+ class EventDispatcherInterface(ABC):
32
+ """
33
+ Represents a dispatcher that dispatches events to listeners
34
+ associated with given event.
35
+ """
36
+
37
+ @abstractmethod
38
+ def dispatch(self, event: object):
39
+ pass
40
+
41
+ @abstractmethod
42
+ async def dispatch_async(self, event: object):
43
+ pass
44
+
45
+
46
+ class EventException(Exception):
47
+ """
48
+ Exception wrapper that adds an event object into exception context.
49
+ """
50
+
51
+ def __init__(self, exception: Exception, event: object):
52
+ self.exception = exception
53
+ self.event = event
54
+ super().__init__(exception)
55
+
56
+
57
+ class EventDispatcher(EventDispatcherInterface):
58
+ # TODO: Make dispatcher to accept external mappings.
59
+ def __init__(self):
60
+ """
61
+ Mapping should be extended for any new events or listeners to be added.
62
+ """
63
+ self._event_listeners_mapping = {
64
+ AfterConnectionReleasedEvent: [
65
+ ReAuthConnectionListener(),
66
+ ],
67
+ AfterPooledConnectionsInstantiationEvent: [
68
+ RegisterReAuthForPooledConnections()
69
+ ],
70
+ AfterSingleConnectionInstantiationEvent: [
71
+ RegisterReAuthForSingleConnection()
72
+ ],
73
+ AfterPubSubConnectionInstantiationEvent: [RegisterReAuthForPubSub()],
74
+ AfterAsyncClusterInstantiationEvent: [RegisterReAuthForAsyncClusterNodes()],
75
+ AsyncAfterConnectionReleasedEvent: [
76
+ AsyncReAuthConnectionListener(),
77
+ ],
78
+ }
79
+
80
+ def dispatch(self, event: object):
81
+ listeners = self._event_listeners_mapping.get(type(event))
82
+
83
+ for listener in listeners:
84
+ listener.listen(event)
85
+
86
+ async def dispatch_async(self, event: object):
87
+ listeners = self._event_listeners_mapping.get(type(event))
88
+
89
+ for listener in listeners:
90
+ await listener.listen(event)
91
+
92
+
93
+ class AfterConnectionReleasedEvent:
94
+ """
95
+ Event that will be fired before each command execution.
96
+ """
97
+
98
+ def __init__(self, connection):
99
+ self._connection = connection
100
+
101
+ @property
102
+ def connection(self):
103
+ return self._connection
104
+
105
+
106
+ class AsyncAfterConnectionReleasedEvent(AfterConnectionReleasedEvent):
107
+ pass
108
+
109
+
110
+ class ClientType(Enum):
111
+ SYNC = ("sync",)
112
+ ASYNC = ("async",)
113
+
114
+
115
+ class AfterPooledConnectionsInstantiationEvent:
116
+ """
117
+ Event that will be fired after pooled connection instances was created.
118
+ """
119
+
120
+ def __init__(
121
+ self,
122
+ connection_pools: List,
123
+ client_type: ClientType,
124
+ credential_provider: Optional[CredentialProvider] = None,
125
+ ):
126
+ self._connection_pools = connection_pools
127
+ self._client_type = client_type
128
+ self._credential_provider = credential_provider
129
+
130
+ @property
131
+ def connection_pools(self):
132
+ return self._connection_pools
133
+
134
+ @property
135
+ def client_type(self) -> ClientType:
136
+ return self._client_type
137
+
138
+ @property
139
+ def credential_provider(self) -> Union[CredentialProvider, None]:
140
+ return self._credential_provider
141
+
142
+
143
+ class AfterSingleConnectionInstantiationEvent:
144
+ """
145
+ Event that will be fired after single connection instances was created.
146
+
147
+ :param connection_lock: For sync client thread-lock should be provided,
148
+ for async asyncio.Lock
149
+ """
150
+
151
+ def __init__(
152
+ self,
153
+ connection,
154
+ client_type: ClientType,
155
+ connection_lock: Union[threading.Lock, asyncio.Lock],
156
+ ):
157
+ self._connection = connection
158
+ self._client_type = client_type
159
+ self._connection_lock = connection_lock
160
+
161
+ @property
162
+ def connection(self):
163
+ return self._connection
164
+
165
+ @property
166
+ def client_type(self) -> ClientType:
167
+ return self._client_type
168
+
169
+ @property
170
+ def connection_lock(self) -> Union[threading.Lock, asyncio.Lock]:
171
+ return self._connection_lock
172
+
173
+
174
+ class AfterPubSubConnectionInstantiationEvent:
175
+ def __init__(
176
+ self,
177
+ pubsub_connection,
178
+ connection_pool,
179
+ client_type: ClientType,
180
+ connection_lock: Union[threading.Lock, asyncio.Lock],
181
+ ):
182
+ self._pubsub_connection = pubsub_connection
183
+ self._connection_pool = connection_pool
184
+ self._client_type = client_type
185
+ self._connection_lock = connection_lock
186
+
187
+ @property
188
+ def pubsub_connection(self):
189
+ return self._pubsub_connection
190
+
191
+ @property
192
+ def connection_pool(self):
193
+ return self._connection_pool
194
+
195
+ @property
196
+ def client_type(self) -> ClientType:
197
+ return self._client_type
198
+
199
+ @property
200
+ def connection_lock(self) -> Union[threading.Lock, asyncio.Lock]:
201
+ return self._connection_lock
202
+
203
+
204
+ class AfterAsyncClusterInstantiationEvent:
205
+ """
206
+ Event that will be fired after async cluster instance was created.
207
+
208
+ Async cluster doesn't use connection pools,
209
+ instead ClusterNode object manages connections.
210
+ """
211
+
212
+ def __init__(
213
+ self,
214
+ nodes: dict,
215
+ credential_provider: Optional[CredentialProvider] = None,
216
+ ):
217
+ self._nodes = nodes
218
+ self._credential_provider = credential_provider
219
+
220
+ @property
221
+ def nodes(self) -> dict:
222
+ return self._nodes
223
+
224
+ @property
225
+ def credential_provider(self) -> Union[CredentialProvider, None]:
226
+ return self._credential_provider
227
+
228
+
229
+ class ReAuthConnectionListener(EventListenerInterface):
230
+ """
231
+ Listener that performs re-authentication of given connection.
232
+ """
233
+
234
+ def listen(self, event: AfterConnectionReleasedEvent):
235
+ event.connection.re_auth()
236
+
237
+
238
+ class AsyncReAuthConnectionListener(AsyncEventListenerInterface):
239
+ """
240
+ Async listener that performs re-authentication of given connection.
241
+ """
242
+
243
+ async def listen(self, event: AsyncAfterConnectionReleasedEvent):
244
+ await event.connection.re_auth()
245
+
246
+
247
+ class RegisterReAuthForPooledConnections(EventListenerInterface):
248
+ """
249
+ Listener that registers a re-authentication callback for pooled connections.
250
+ Required by :class:`StreamingCredentialProvider`.
251
+ """
252
+
253
+ def __init__(self):
254
+ self._event = None
255
+
256
+ def listen(self, event: AfterPooledConnectionsInstantiationEvent):
257
+ if isinstance(event.credential_provider, StreamingCredentialProvider):
258
+ self._event = event
259
+
260
+ if event.client_type == ClientType.SYNC:
261
+ event.credential_provider.on_next(self._re_auth)
262
+ event.credential_provider.on_error(self._raise_on_error)
263
+ else:
264
+ event.credential_provider.on_next(self._re_auth_async)
265
+ event.credential_provider.on_error(self._raise_on_error_async)
266
+
267
+ def _re_auth(self, token):
268
+ for pool in self._event.connection_pools:
269
+ pool.re_auth_callback(token)
270
+
271
+ async def _re_auth_async(self, token):
272
+ for pool in self._event.connection_pools:
273
+ await pool.re_auth_callback(token)
274
+
275
+ def _raise_on_error(self, error: Exception):
276
+ raise EventException(error, self._event)
277
+
278
+ async def _raise_on_error_async(self, error: Exception):
279
+ raise EventException(error, self._event)
280
+
281
+
282
+ class RegisterReAuthForSingleConnection(EventListenerInterface):
283
+ """
284
+ Listener that registers a re-authentication callback for single connection.
285
+ Required by :class:`StreamingCredentialProvider`.
286
+ """
287
+
288
+ def __init__(self):
289
+ self._event = None
290
+
291
+ def listen(self, event: AfterSingleConnectionInstantiationEvent):
292
+ if isinstance(
293
+ event.connection.credential_provider, StreamingCredentialProvider
294
+ ):
295
+ self._event = event
296
+
297
+ if event.client_type == ClientType.SYNC:
298
+ event.connection.credential_provider.on_next(self._re_auth)
299
+ event.connection.credential_provider.on_error(self._raise_on_error)
300
+ else:
301
+ event.connection.credential_provider.on_next(self._re_auth_async)
302
+ event.connection.credential_provider.on_error(
303
+ self._raise_on_error_async
304
+ )
305
+
306
+ def _re_auth(self, token):
307
+ with self._event.connection_lock:
308
+ self._event.connection.send_command(
309
+ "AUTH", token.try_get("oid"), token.get_value()
310
+ )
311
+ self._event.connection.read_response()
312
+
313
+ async def _re_auth_async(self, token):
314
+ async with self._event.connection_lock:
315
+ await self._event.connection.send_command(
316
+ "AUTH", token.try_get("oid"), token.get_value()
317
+ )
318
+ await self._event.connection.read_response()
319
+
320
+ def _raise_on_error(self, error: Exception):
321
+ raise EventException(error, self._event)
322
+
323
+ async def _raise_on_error_async(self, error: Exception):
324
+ raise EventException(error, self._event)
325
+
326
+
327
+ class RegisterReAuthForAsyncClusterNodes(EventListenerInterface):
328
+ def __init__(self):
329
+ self._event = None
330
+
331
+ def listen(self, event: AfterAsyncClusterInstantiationEvent):
332
+ if isinstance(event.credential_provider, StreamingCredentialProvider):
333
+ self._event = event
334
+ event.credential_provider.on_next(self._re_auth)
335
+ event.credential_provider.on_error(self._raise_on_error)
336
+
337
+ async def _re_auth(self, token: TokenInterface):
338
+ for key in self._event.nodes:
339
+ await self._event.nodes[key].re_auth_callback(token)
340
+
341
+ async def _raise_on_error(self, error: Exception):
342
+ raise EventException(error, self._event)
343
+
344
+
345
+ class RegisterReAuthForPubSub(EventListenerInterface):
346
+ def __init__(self):
347
+ self._connection = None
348
+ self._connection_pool = None
349
+ self._client_type = None
350
+ self._connection_lock = None
351
+ self._event = None
352
+
353
+ def listen(self, event: AfterPubSubConnectionInstantiationEvent):
354
+ if isinstance(
355
+ event.pubsub_connection.credential_provider, StreamingCredentialProvider
356
+ ) and event.pubsub_connection.get_protocol() in [3, "3"]:
357
+ self._event = event
358
+ self._connection = event.pubsub_connection
359
+ self._connection_pool = event.connection_pool
360
+ self._client_type = event.client_type
361
+ self._connection_lock = event.connection_lock
362
+
363
+ if self._client_type == ClientType.SYNC:
364
+ self._connection.credential_provider.on_next(self._re_auth)
365
+ self._connection.credential_provider.on_error(self._raise_on_error)
366
+ else:
367
+ self._connection.credential_provider.on_next(self._re_auth_async)
368
+ self._connection.credential_provider.on_error(
369
+ self._raise_on_error_async
370
+ )
371
+
372
+ def _re_auth(self, token: TokenInterface):
373
+ with self._connection_lock:
374
+ self._connection.send_command(
375
+ "AUTH", token.try_get("oid"), token.get_value()
376
+ )
377
+ self._connection.read_response()
378
+
379
+ self._connection_pool.re_auth_callback(token)
380
+
381
+ async def _re_auth_async(self, token: TokenInterface):
382
+ async with self._connection_lock:
383
+ await self._connection.send_command(
384
+ "AUTH", token.try_get("oid"), token.get_value()
385
+ )
386
+ await self._connection.read_response()
387
+
388
+ await self._connection_pool.re_auth_callback(token)
389
+
390
+ def _raise_on_error(self, error: Exception):
391
+ raise EventException(error, self._event)
392
+
393
+ async def _raise_on_error_async(self, error: Exception):
394
+ raise EventException(error, self._event)
redis/typing.py CHANGED
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
20
20
 
21
21
 
22
22
  Number = Union[int, float]
23
- EncodedT = Union[bytes, memoryview]
23
+ EncodedT = Union[bytes, bytearray, memoryview]
24
24
  DecodedT = Union[str, int, float]
25
25
  EncodableT = Union[EncodedT, DecodedT]
26
26
  AbsExpiryT = Union[int, datetime]
redis/utils.py CHANGED
@@ -122,6 +122,71 @@ def deprecated_function(reason="", version="", name=None):
122
122
  return decorator
123
123
 
124
124
 
125
+ def warn_deprecated_arg_usage(
126
+ arg_name: Union[list, str],
127
+ function_name: str,
128
+ reason: str = "",
129
+ version: str = "",
130
+ stacklevel: int = 2,
131
+ ):
132
+ import warnings
133
+
134
+ msg = (
135
+ f"Call to '{function_name}' function with deprecated"
136
+ f" usage of input argument/s '{arg_name}'."
137
+ )
138
+ if reason:
139
+ msg += f" ({reason})"
140
+ if version:
141
+ msg += f" -- Deprecated since version {version}."
142
+ warnings.warn(msg, category=DeprecationWarning, stacklevel=stacklevel)
143
+
144
+
145
+ def deprecated_args(
146
+ args_to_warn: list = ["*"],
147
+ allowed_args: list = [],
148
+ reason: str = "",
149
+ version: str = "",
150
+ ):
151
+ """
152
+ Decorator to mark specified args of a function as deprecated.
153
+ If '*' is in args_to_warn, all arguments will be marked as deprecated.
154
+ """
155
+
156
+ def decorator(func):
157
+ @wraps(func)
158
+ def wrapper(*args, **kwargs):
159
+ # Get function argument names
160
+ arg_names = func.__code__.co_varnames[: func.__code__.co_argcount]
161
+
162
+ provided_args = dict(zip(arg_names, args))
163
+ provided_args.update(kwargs)
164
+
165
+ provided_args.pop("self", None)
166
+ for allowed_arg in allowed_args:
167
+ provided_args.pop(allowed_arg, None)
168
+
169
+ for arg in args_to_warn:
170
+ if arg == "*" and len(provided_args) > 0:
171
+ warn_deprecated_arg_usage(
172
+ list(provided_args.keys()),
173
+ func.__name__,
174
+ reason,
175
+ version,
176
+ stacklevel=3,
177
+ )
178
+ elif arg in provided_args:
179
+ warn_deprecated_arg_usage(
180
+ arg, func.__name__, reason, version, stacklevel=3
181
+ )
182
+
183
+ return func(*args, **kwargs)
184
+
185
+ return wrapper
186
+
187
+ return decorator
188
+
189
+
125
190
  def _set_info_logger():
126
191
  """
127
192
  Set up a logger that log info logs to stdout.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: redis
3
- Version: 5.2.0
3
+ Version: 5.3.0
4
4
  Summary: Python client for Redis database and key-value store
5
5
  Home-page: https://github.com/redis/redis-py
6
6
  Author: Redis Inc.
@@ -30,6 +30,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
30
30
  Requires-Python: >=3.8
31
31
  Description-Content-Type: text/markdown
32
32
  License-File: LICENSE
33
+ Requires-Dist: PyJWT~=2.9.0
33
34
  Requires-Dist: async-timeout>=4.0.3; python_full_version < "3.11.3"
34
35
  Provides-Extra: hiredis
35
36
  Requires-Dist: hiredis>=3.0.0; extra == "hiredis"
@@ -1,36 +1,42 @@
1
1
  redis/__init__.py,sha256=WlARnwwst8oaEyjXV5XTcmSGyEKVCn3S9N1MrHyJ8U8,2015
2
- redis/backoff.py,sha256=N2CZXkB3cdoHeMZ01r0zVry0bRKe8mk0ybi8hE7PvzU,3177
2
+ redis/backoff.py,sha256=d22h74LEatJiFd_5o8HvFW3biFBotYOFZHddHt45ydc,3663
3
3
  redis/cache.py,sha256=68rJDNogvNwgdgBel6zSX9QziL11qsKIMhmvQvHvznM,9549
4
- redis/client.py,sha256=HbcVPvRKOA8Hd6zeMmmU7eAJ9xkSX9oqLR0ZW7r5AHI,59101
5
- redis/cluster.py,sha256=ECId2H3NdWmxktcHWRk1lWHFgRMipdj143i26xaNhaU,94317
6
- redis/connection.py,sha256=xjd9mfHGR6s0EoF80Rz1EWdzA8aBkYLI2XDhL4UGdhI,62323
4
+ redis/client.py,sha256=5KynKSwVK7YPKWwOItEfNpJsVlu_oSchm2lNc_xJnVc,61733
5
+ redis/cluster.py,sha256=YzGkte85bSJOYeqs_WESFam_gtaWgEZ6CijPIdldVis,99287
6
+ redis/connection.py,sha256=sZiKny4EQ8BtReUYtB4zBQ5D3Tk0SOjbjD3j56jrb0g,65270
7
7
  redis/crc.py,sha256=Z3kXFtkY2LdgefnQMud1xr4vG5UYvA9LCMqNMX1ywu4,729
8
- redis/credentials.py,sha256=6VvFeReFp6vernGIWlIVOm8OmbNgoFYdd1wgsjZTnlk,738
8
+ redis/credentials.py,sha256=GOnO3-LSW34efHaIrUbS742Mw8l70mRzF6UrKiKZsMY,1828
9
+ redis/event.py,sha256=urOK241IdgmCQ3fq7GqXRstZ2vcXRV14bBBMdN3latk,12129
9
10
  redis/exceptions.py,sha256=OmOGoS9EPInuTZPJT0BuDeIYuYrtRGEUT_Pu6NtEQNI,5211
10
11
  redis/lock.py,sha256=3JOC3AmYJ10zbq0blOtV4uNwuEhw4K7xuJ6nM-qv5Ig,11976
11
12
  redis/ocsp.py,sha256=4b1s43x-DJ859zRKtwGTIbNys_dyGv5YyOdWnOvigyM,11451
12
13
  redis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  redis/retry.py,sha256=JiIDxeD890vgi_me8pwypO1LixwhU0Fv3A5NEay8SAY,2206
14
15
  redis/sentinel.py,sha256=ya1aPeAvUcY9qXMSpV_wA3081vUqkIqcyXG9SqAvU88,14661
15
- redis/typing.py,sha256=skQl2VuyL7fPpg2BRDlGYMmwDQ2BLwwxxR8u_V1Kbm4,2138
16
- redis/utils.py,sha256=oTonIc6DbbB-ZT-mL14ChhcFk2y4qnK3UNORMKPj2oI,4787
16
+ redis/typing.py,sha256=k7F_3Vtsexeb7mUl6txlwrY1veGDLEhtcHe9FwIJOOo,2149
17
+ redis/utils.py,sha256=ErCe0V4nMTWTfeCI1Pg6X3WZeuxG0E-AirsI1AYaGF4,6664
17
18
  redis/_parsers/__init__.py,sha256=qkfgV2X9iyvQAvbLdSelwgz0dCk9SGAosCvuZC9-qDc,550
18
19
  redis/_parsers/base.py,sha256=0j3qIhLjQZOzYGc4n1IesNegckomVhvDsEZD6-yb3Ns,7475
19
20
  redis/_parsers/commands.py,sha256=pmR4hl4u93UvCmeDgePHFc6pWDr4slrKEvCsdMmtj_M,11052
20
21
  redis/_parsers/encoders.py,sha256=X0jvTp-E4TZUlZxV5LJJ88TuVrF1vly5tuC0xjxGaSc,1734
21
- redis/_parsers/helpers.py,sha256=XFKGPQUlh5gJfE6D0rJ_qgJDFEKX9aX5vV3NouHv-00,28973
22
+ redis/_parsers/helpers.py,sha256=X5wkGDtuzseeCz23_t3FJpzy1ltIvh7zO1uD3cypiOs,29184
22
23
  redis/_parsers/hiredis.py,sha256=qL1iCkWlxI63PiP99u_MY5-V6zKaesW2fD-IMNtc0QI,8189
23
24
  redis/_parsers/resp2.py,sha256=f22kH-_ZP2iNtOn6xOe65MSy_fJpu8OEn1u_hgeeojI,4813
24
25
  redis/_parsers/resp3.py,sha256=jHtL1LYJegJ_LiNTsjzIvS-kZyNR58jZ_YV4cRfwuN0,11127
25
26
  redis/_parsers/socket.py,sha256=CKD8QW_wFSNlIZzxlbNduaGpiv0I8wBcsGuAIojDfJg,5403
26
27
  redis/asyncio/__init__.py,sha256=uoDD8XYVi0Kj6mcufYwLDUTQXmBRx7a0bhKF9stZr7I,1489
27
- redis/asyncio/client.py,sha256=WIkebQoxn8GUMv2UmhQ4s81Cal6INwMc5mUohfNSTRk,59630
28
- redis/asyncio/cluster.py,sha256=qgBglEl7410K5M1CJxPH1-G3Mv2ed-S134uSJ2mmxng,63177
29
- redis/asyncio/connection.py,sha256=8xn0-RpgHyc3LIM-TjM538QZ0MHv_1j92dNLzD8MJsE,44878
28
+ redis/asyncio/client.py,sha256=Ef2yknTMQrTJ0bvi3-4payHGsDqU0cRZLytHrPxHNuE,61016
29
+ redis/asyncio/cluster.py,sha256=4uV8uTRDFeAY25BbgagX1ykwnPLMuXzOtxzUH5SC8Q0,66922
30
+ redis/asyncio/connection.py,sha256=NKzj0LNn27ZR9A4sh3KtOiPuKkFwujc9dTegodHaHAo,47512
30
31
  redis/asyncio/lock.py,sha256=lLasXEO2E1CskhX5ZZoaSGpmwZP1Q782R3HAUNG3wD4,11967
31
32
  redis/asyncio/retry.py,sha256=SnPPOlo5gcyIFtkC4DY7HFvmDgUaILsJ3DeHioogdB8,2219
32
- redis/asyncio/sentinel.py,sha256=KOfuEsUZjwtL4jVEfpxh8jvzsCbC3fXzjSLiSghs1MY,14397
33
+ redis/asyncio/sentinel.py,sha256=QBpsrdlhZlFqENy_rK1IuasSicox55_xSvP_IywbhbQ,14293
33
34
  redis/asyncio/utils.py,sha256=Yxc5YQumhLjtDDwCS4mgxI6yy2Z21AzLlFxVbxCohic,704
35
+ redis/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ redis/auth/err.py,sha256=WYkbuDIzwp1S-eAvsya6QMlO6g9QIXbzMITOsTWX0xk,694
37
+ redis/auth/idp.py,sha256=IMDIIb9q72vbIwtFN8vPdaAKZVTdh0HuC5uj5ufqmw4,631
38
+ redis/auth/token.py,sha256=DslJx_wN8yPcrmcF-Ui8E5emcamP6OUwi9PTGSvsXQw,3125
39
+ redis/auth/token_manager.py,sha256=ShBsYXiBZBJBOMB_Y-pXfLwEOAmc9s1okaCECinNZ7g,12018
34
40
  redis/commands/__init__.py,sha256=cTUH-MGvaLYS0WuoytyqtN1wniw2A1KbkUXcpvOSY3I,576
35
41
  redis/commands/cluster.py,sha256=BBHSyXfl3OETIJs4JC5DrcfzqgF2Kt4WMEcd0WMILOU,31598
36
42
  redis/commands/core.py,sha256=YlCzD44YJnFzdEKIFDBloPh1ivgHKcFMZsxPzamE9JM,238528
@@ -69,8 +75,8 @@ redis/commands/timeseries/__init__.py,sha256=gkz6wshEzzQQryBOnrAqqQzttS-AHfXmuN_
69
75
  redis/commands/timeseries/commands.py,sha256=8Z2BEyP23qTYCJR_e9zdG11yWmIDwGBMO2PJNLtK2BA,47147
70
76
  redis/commands/timeseries/info.py,sha256=meZYdu7IV9KaUWMKZs9qW4vo3Q9MwhdY-EBtKQzls5o,3223
71
77
  redis/commands/timeseries/utils.py,sha256=NLwSOS5Dz9N8dYQSzEyBIvrItOWwfQ0xgDj8un6x3dU,1319
72
- redis-5.2.0.dist-info/LICENSE,sha256=pXslClvwPXr-VbdAYzE_Ktt7ANVGwKsUmok5gzP-PMg,1074
73
- redis-5.2.0.dist-info/METADATA,sha256=qwgjp9OwwLNWqXHlpONSrTGFiFX1E43jET9K0UNihXU,9138
74
- redis-5.2.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
75
- redis-5.2.0.dist-info/top_level.txt,sha256=OMAefszlde6ZoOtlM35AWzpRIrwtcqAMHGlRit-w2-4,6
76
- redis-5.2.0.dist-info/RECORD,,
78
+ redis-5.3.0.dist-info/LICENSE,sha256=pXslClvwPXr-VbdAYzE_Ktt7ANVGwKsUmok5gzP-PMg,1074
79
+ redis-5.3.0.dist-info/METADATA,sha256=ql3ziX3Hi71hXv26oLIMfFNqOCfAMtA8izDvb-NHQvI,9166
80
+ redis-5.3.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
81
+ redis-5.3.0.dist-info/top_level.txt,sha256=OMAefszlde6ZoOtlM35AWzpRIrwtcqAMHGlRit-w2-4,6
82
+ redis-5.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.44.0)
2
+ Generator: bdist_wheel (0.45.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
File without changes