limits 4.1__py3-none-any.whl → 4.3__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.
limits/typing.py CHANGED
@@ -1,21 +1,21 @@
1
+ from __future__ import annotations
2
+
1
3
  from collections import Counter
2
- from collections.abc import Awaitable, Iterable
4
+ from collections.abc import Awaitable, Callable, Iterable
3
5
  from typing import (
4
6
  TYPE_CHECKING,
5
7
  Any,
6
- Callable,
7
8
  ClassVar,
9
+ Literal,
8
10
  NamedTuple,
9
- Optional,
10
- Type,
11
+ ParamSpec,
12
+ Protocol,
13
+ TypeAlias,
11
14
  TypeVar,
12
- Union,
13
15
  cast,
14
16
  )
15
17
 
16
- from typing_extensions import ParamSpec, Protocol, TypeAlias
17
-
18
- Serializable = Union[int, str, float]
18
+ Serializable = int | str | float
19
19
 
20
20
  R = TypeVar("R")
21
21
  R_co = TypeVar("R_co", covariant=True)
@@ -24,16 +24,16 @@ P = ParamSpec("P")
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  import coredis
27
- import coredis.commands.script
28
27
  import pymongo.collection
29
28
  import pymongo.database
29
+ import pymongo.mongo_client
30
30
  import redis
31
31
 
32
32
 
33
33
  class ItemP(Protocol):
34
34
  value: bytes
35
- flags: Optional[int]
36
- cas: Optional[int]
35
+ flags: int | None
36
+ cas: int | None
37
37
 
38
38
 
39
39
  class EmcacheClientP(Protocol):
@@ -47,19 +47,19 @@ class EmcacheClientP(Protocol):
47
47
  noreply: bool = False,
48
48
  ) -> None: ...
49
49
 
50
- async def get(self, key: bytes, return_flags: bool = False) -> Optional[ItemP]: ...
50
+ async def get(self, key: bytes, return_flags: bool = False) -> ItemP | None: ...
51
51
 
52
52
  async def get_many(self, keys: Iterable[bytes]) -> dict[bytes, ItemP]: ...
53
53
 
54
- async def gets(self, key: bytes, return_flags: bool = False) -> Optional[ItemP]: ...
54
+ async def gets(self, key: bytes, return_flags: bool = False) -> ItemP | None: ...
55
55
 
56
56
  async def increment(
57
57
  self, key: bytes, value: int, *, noreply: bool = False
58
- ) -> Optional[int]: ...
58
+ ) -> int | None: ...
59
59
 
60
60
  async def decrement(
61
61
  self, key: bytes, value: int, *, noreply: bool = False
62
- ) -> Optional[int]: ...
62
+ ) -> int | None: ...
63
63
 
64
64
  async def delete(self, key: bytes, *, noreply: bool = False) -> None: ...
65
65
 
@@ -83,65 +83,72 @@ class MemcachedClientP(Protocol):
83
83
  self,
84
84
  key: str,
85
85
  value: Serializable,
86
- expire: Optional[int] = 0,
87
- noreply: Optional[bool] = None,
88
- flags: Optional[int] = None,
86
+ expire: int | None = 0,
87
+ noreply: bool | None = None,
88
+ flags: int | None = None,
89
89
  ) -> bool: ...
90
90
 
91
- def get(self, key: str, default: Optional[str] = None) -> bytes: ...
91
+ def get(self, key: str, default: str | None = None) -> bytes: ...
92
92
 
93
93
  def get_many(self, keys: Iterable[str]) -> dict[str, Any]: ... # type:ignore[explicit-any]
94
94
 
95
95
  def incr(
96
- self, key: str, value: int, noreply: Optional[bool] = False
97
- ) -> Optional[int]: ...
96
+ self, key: str, value: int, noreply: bool | None = False
97
+ ) -> int | None: ...
98
98
 
99
99
  def decr(
100
100
  self,
101
101
  key: str,
102
102
  value: int,
103
- noreply: Optional[bool] = False,
104
- ) -> Optional[int]: ...
103
+ noreply: bool | None = False,
104
+ ) -> int | None: ...
105
105
 
106
- def delete(self, key: str, noreply: Optional[bool] = None) -> Optional[bool]: ...
106
+ def delete(self, key: str, noreply: bool | None = None) -> bool | None: ...
107
107
 
108
108
  def set(
109
109
  self,
110
110
  key: str,
111
111
  value: Serializable,
112
112
  expire: int = 0,
113
- noreply: Optional[bool] = None,
114
- flags: Optional[int] = None,
113
+ noreply: bool | None = None,
114
+ flags: int | None = None,
115
115
  ) -> bool: ...
116
116
 
117
117
  def touch(
118
- self, key: str, expire: Optional[int] = 0, noreply: Optional[bool] = None
118
+ self, key: str, expire: int | None = 0, noreply: bool | None = None
119
119
  ) -> bool: ...
120
120
 
121
121
 
122
122
  class RedisClientP(Protocol):
123
123
  def incrby(self, key: str, amount: int) -> int: ...
124
- def get(self, key: str) -> Optional[bytes]: ...
124
+ def get(self, key: str) -> bytes | None: ...
125
125
  def delete(self, key: str) -> int: ...
126
126
  def ttl(self, key: str) -> int: ...
127
127
  def expire(self, key: str, seconds: int) -> bool: ...
128
128
  def ping(self) -> bool: ...
129
- def register_script(self, script: bytes) -> "redis.commands.core.Script": ...
129
+ def register_script(self, script: bytes) -> redis.commands.core.Script: ...
130
130
 
131
131
 
132
- AsyncRedisClient = Union["coredis.Redis[bytes]", "coredis.RedisCluster[bytes]"]
133
- RedisClient = RedisClientP
132
+ class AsyncRedisClientP(Protocol):
133
+ async def incrby(self, key: str, amount: int) -> int: ...
134
+ async def get(self, key: str) -> bytes | None: ...
135
+ async def delete(self, key: str) -> int: ...
136
+ async def ttl(self, key: str) -> int: ...
137
+ async def expire(self, key: str, seconds: int) -> bool: ...
138
+ async def ping(self) -> bool: ...
139
+ def register_script(self, script: bytes) -> redis.commands.core.Script: ...
134
140
 
135
141
 
136
- class ScriptP(Protocol[R_co]):
137
- def __call__(self, keys: list[Serializable], args: list[Serializable]) -> R_co: ...
142
+ RedisClient: TypeAlias = RedisClientP
143
+ AsyncRedisClient: TypeAlias = AsyncRedisClientP
144
+ AsyncCoRedisClient: TypeAlias = "coredis.Redis[bytes] | coredis.RedisCluster[bytes]"
138
145
 
139
-
140
- MongoClient: TypeAlias = "pymongo.MongoClient[dict[str, Any]]" # type:ignore[explicit-any]
146
+ MongoClient: TypeAlias = "pymongo.mongo_client.MongoClient[dict[str, Any]]" # type:ignore[explicit-any]
141
147
  MongoDatabase: TypeAlias = "pymongo.database.Database[dict[str, Any]]" # type:ignore[explicit-any]
142
148
  MongoCollection: TypeAlias = "pymongo.collection.Collection[dict[str, Any]]" # type:ignore[explicit-any]
143
149
 
144
150
  __all__ = [
151
+ "TYPE_CHECKING",
145
152
  "Any",
146
153
  "AsyncRedisClient",
147
154
  "Awaitable",
@@ -150,24 +157,20 @@ __all__ = [
150
157
  "Counter",
151
158
  "EmcacheClientP",
152
159
  "ItemP",
160
+ "Literal",
153
161
  "MemcachedClientP",
154
162
  "MongoClient",
155
163
  "MongoCollection",
156
164
  "MongoDatabase",
157
165
  "NamedTuple",
158
- "Optional",
159
166
  "P",
160
167
  "ParamSpec",
161
168
  "Protocol",
162
- "ScriptP",
163
- "Serializable",
164
- "TypeVar",
165
169
  "R",
166
170
  "R_co",
167
171
  "RedisClient",
168
- "Type",
172
+ "Serializable",
173
+ "TypeAlias",
169
174
  "TypeVar",
170
- "TYPE_CHECKING",
171
- "Union",
172
175
  "cast",
173
176
  ]
limits/util.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """ """
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import dataclasses
4
6
  import importlib.resources
5
7
  import re
@@ -10,7 +12,7 @@ from typing import TYPE_CHECKING
10
12
 
11
13
  from packaging.version import Version
12
14
 
13
- from limits.typing import NamedTuple, Optional, Type, Union
15
+ from limits.typing import NamedTuple
14
16
 
15
17
  from .errors import ConfigurationError
16
18
  from .limits import GRANULARITIES, RateLimitItem
@@ -25,9 +27,7 @@ SINGLE_EXPR = re.compile(
25
27
  re.IGNORECASE | re.VERBOSE,
26
28
  )
27
29
  EXPR = re.compile(
28
- r"^{SINGLE}(:?{SEPARATORS}{SINGLE})*$".format(
29
- SINGLE=SINGLE_EXPR.pattern, SEPARATORS=SEPARATORS.pattern
30
- ),
30
+ rf"^{SINGLE_EXPR.pattern}(:?{SEPARATORS.pattern}{SINGLE_EXPR.pattern})*$",
31
31
  re.IGNORECASE | re.VERBOSE,
32
32
  )
33
33
 
@@ -46,8 +46,8 @@ class WindowStats(NamedTuple):
46
46
  @dataclasses.dataclass
47
47
  class Dependency:
48
48
  name: str
49
- version_required: Optional[Version]
50
- version_found: Optional[Version]
49
+ version_required: Version | None
50
+ version_found: Version | None
51
51
  module: ModuleType
52
52
 
53
53
 
@@ -96,7 +96,7 @@ class LazyDependency:
96
96
  without having to import them explicitly.
97
97
  """
98
98
 
99
- DEPENDENCIES: Union[dict[str, Optional[Version]], list[str]] = []
99
+ DEPENDENCIES: dict[str, Version | None] | list[str] = []
100
100
  """
101
101
  The python modules this class has a dependency on.
102
102
  Used to lazily populate the :attr:`dependencies`
@@ -117,7 +117,7 @@ class LazyDependency:
117
117
 
118
118
  if not getattr(self, "_dependencies", None):
119
119
  dependencies = DependencyDict()
120
- mapping: dict[str, Optional[Version]]
120
+ mapping: dict[str, Version | None]
121
121
 
122
122
  if isinstance(self.DEPENDENCIES, list):
123
123
  mapping = {dependency: None for dependency in self.DEPENDENCIES}
@@ -135,7 +135,7 @@ class LazyDependency:
135
135
  return self._dependencies
136
136
 
137
137
 
138
- def get_dependency(module_path: str) -> tuple[ModuleType, Optional[Version]]:
138
+ def get_dependency(module_path: str) -> tuple[ModuleType, Version | None]:
139
139
  """
140
140
  safe function to import a module at runtime
141
141
  """
@@ -165,7 +165,7 @@ def parse_many(limit_string: str) -> list[RateLimitItem]:
165
165
  """
166
166
 
167
167
  if not (isinstance(limit_string, str) and EXPR.match(limit_string)):
168
- raise ValueError("couldn't parse rate limit string '%s'" % limit_string)
168
+ raise ValueError(f"couldn't parse rate limit string '{limit_string}'")
169
169
  limits = []
170
170
 
171
171
  for limit in SEPARATORS.split(limit_string):
@@ -194,7 +194,7 @@ def parse(limit_string: str) -> RateLimitItem:
194
194
  return list(parse_many(limit_string))[0]
195
195
 
196
196
 
197
- def granularity_from_string(granularity_string: str) -> Type[RateLimitItem]:
197
+ def granularity_from_string(granularity_string: str) -> type[RateLimitItem]:
198
198
  """
199
199
 
200
200
  :param granularity_string:
@@ -204,4 +204,4 @@ def granularity_from_string(granularity_string: str) -> Type[RateLimitItem]:
204
204
  for granularity in GRANULARITIES.values():
205
205
  if granularity.check_granularity_string(granularity_string):
206
206
  return granularity
207
- raise ValueError("no granularity matched for %s" % granularity_string)
207
+ raise ValueError(f"no granularity matched for {granularity_string}")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: limits
3
- Version: 4.1
3
+ Version: 4.3
4
4
  Summary: Rate limiting utilities
5
5
  Home-page: https://limits.readthedocs.org
6
6
  Author: Ali-Akber Saifee
@@ -14,47 +14,63 @@ Classifier: Operating System :: MacOS
14
14
  Classifier: Operating System :: POSIX :: Linux
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
- Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
22
21
  Classifier: Programming Language :: Python :: Implementation :: PyPy
23
- Requires-Python: >=3.9
22
+ Requires-Python: >=3.10
24
23
  License-File: LICENSE.txt
25
- Requires-Dist: deprecated >=1.2
26
- Requires-Dist: packaging <25,>=21
27
- Requires-Dist: typing-extensions
28
- Provides-Extra: all
29
- Requires-Dist: redis !=4.5.2,!=4.5.3,<6.0.0,>3 ; extra == 'all'
30
- Requires-Dist: redis !=4.5.2,!=4.5.3,>=4.2.0 ; extra == 'all'
31
- Requires-Dist: pymemcache <5.0.0,>3 ; extra == 'all'
32
- Requires-Dist: pymongo <5,>4.1 ; extra == 'all'
33
- Requires-Dist: etcd3 ; extra == 'all'
34
- Requires-Dist: coredis <5,>=3.4.0 ; extra == 'all'
35
- Requires-Dist: motor <4,>=3 ; extra == 'all'
36
- Requires-Dist: aetcd ; extra == 'all'
37
- Requires-Dist: emcache >=0.6.1 ; (python_version < "3.11") and extra == 'all'
38
- Requires-Dist: emcache >=1 ; (python_version >= "3.11" and python_version < "3.13.0") and extra == 'all'
39
- Provides-Extra: async-etcd
40
- Requires-Dist: aetcd ; extra == 'async-etcd'
41
- Provides-Extra: async-memcached
42
- Requires-Dist: emcache >=0.6.1 ; (python_version < "3.11") and extra == 'async-memcached'
43
- Requires-Dist: emcache >=1 ; (python_version >= "3.11" and python_version < "3.13.0") and extra == 'async-memcached'
44
- Provides-Extra: async-mongodb
45
- Requires-Dist: motor <4,>=3 ; extra == 'async-mongodb'
46
- Provides-Extra: async-redis
47
- Requires-Dist: coredis <5,>=3.4.0 ; extra == 'async-redis'
48
- Provides-Extra: etcd
49
- Requires-Dist: etcd3 ; extra == 'etcd'
50
- Provides-Extra: memcached
51
- Requires-Dist: pymemcache <5.0.0,>3 ; extra == 'memcached'
52
- Provides-Extra: mongodb
53
- Requires-Dist: pymongo <5,>4.1 ; extra == 'mongodb'
24
+ Requires-Dist: deprecated>=1.2
25
+ Requires-Dist: packaging<25,>=21
26
+ Requires-Dist: typing_extensions
54
27
  Provides-Extra: redis
55
- Requires-Dist: redis !=4.5.2,!=4.5.3,<6.0.0,>3 ; extra == 'redis'
28
+ Requires-Dist: redis!=4.5.2,!=4.5.3,<6.0.0,>3; extra == "redis"
56
29
  Provides-Extra: rediscluster
57
- Requires-Dist: redis !=4.5.2,!=4.5.3,>=4.2.0 ; extra == 'rediscluster'
30
+ Requires-Dist: redis!=4.5.2,!=4.5.3,>=4.2.0; extra == "rediscluster"
31
+ Provides-Extra: memcached
32
+ Requires-Dist: pymemcache<5.0.0,>3; extra == "memcached"
33
+ Provides-Extra: mongodb
34
+ Requires-Dist: pymongo<5,>4.1; extra == "mongodb"
35
+ Provides-Extra: etcd
36
+ Requires-Dist: etcd3; extra == "etcd"
37
+ Provides-Extra: valkey
38
+ Requires-Dist: valkey>=6; extra == "valkey"
39
+ Provides-Extra: async-redis
40
+ Requires-Dist: coredis<5,>=3.4.0; extra == "async-redis"
41
+ Provides-Extra: async-memcached
42
+ Requires-Dist: emcache>=0.6.1; python_version < "3.11" and extra == "async-memcached"
43
+ Requires-Dist: emcache>=1; (python_version >= "3.11" and python_version < "3.13.0") and extra == "async-memcached"
44
+ Provides-Extra: async-mongodb
45
+ Requires-Dist: motor<4,>=3; extra == "async-mongodb"
46
+ Provides-Extra: async-etcd
47
+ Requires-Dist: aetcd; extra == "async-etcd"
48
+ Provides-Extra: async-valkey
49
+ Requires-Dist: valkey>=6; extra == "async-valkey"
50
+ Provides-Extra: all
51
+ Requires-Dist: redis!=4.5.2,!=4.5.3,<6.0.0,>3; extra == "all"
52
+ Requires-Dist: redis!=4.5.2,!=4.5.3,>=4.2.0; extra == "all"
53
+ Requires-Dist: pymemcache<5.0.0,>3; extra == "all"
54
+ Requires-Dist: pymongo<5,>4.1; extra == "all"
55
+ Requires-Dist: etcd3; extra == "all"
56
+ Requires-Dist: valkey>=6; extra == "all"
57
+ Requires-Dist: coredis<5,>=3.4.0; extra == "all"
58
+ Requires-Dist: emcache>=0.6.1; python_version < "3.11" and extra == "all"
59
+ Requires-Dist: emcache>=1; (python_version >= "3.11" and python_version < "3.13.0") and extra == "all"
60
+ Requires-Dist: motor<4,>=3; extra == "all"
61
+ Requires-Dist: aetcd; extra == "all"
62
+ Requires-Dist: valkey>=6; extra == "all"
63
+ Dynamic: author
64
+ Dynamic: author-email
65
+ Dynamic: classifier
66
+ Dynamic: description
67
+ Dynamic: home-page
68
+ Dynamic: license
69
+ Dynamic: project-url
70
+ Dynamic: provides-extra
71
+ Dynamic: requires-dist
72
+ Dynamic: requires-python
73
+ Dynamic: summary
58
74
 
59
75
  .. |ci| image:: https://github.com/alisaifee/limits/actions/workflows/main.yml/badge.svg?branch=master
60
76
  :target: https://github.com/alisaifee/limits/actions?query=branch%3Amaster+workflow%3ACI
@@ -115,7 +131,7 @@ Moving Window
115
131
 
116
132
  This strategy adds each request’s timestamp to a log if the ``nth`` oldest entry (where ``n``
117
133
  is the limit) is either not present or is older than the duration of the window (for example with a rate limit of
118
- ``10 requests per minute`` if there are either less than 10 entries or the 10th oldest entry is atleast
134
+ ``10 requests per minute`` if there are either less than 10 entries or the 10th oldest entry is at least
119
135
  60 seconds old). Upon adding a new entry to the log "expired" entries are truncated.
120
136
 
121
137
  For example, with a rate limit of 10 requests per minute:
@@ -0,0 +1,43 @@
1
+ limits/__init__.py,sha256=gPUFrt02kHF_syLjiVRSs-S4UVGpRMcM2VMFNhF6G24,748
2
+ limits/_version.py,sha256=LXQLnVdyn9TpqfaPWYkIpMLktR3ythlsHOPlSYBiX70,495
3
+ limits/errors.py,sha256=s1el9Vg0ly-z92guvnvYNgKi3_aVqpiw_sufemiLLTI,662
4
+ limits/limits.py,sha256=YzzZP8_ay_zlMMnnY2xhAcFTTFvFe5HEk8NQlvUTru4,4907
5
+ limits/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ limits/strategies.py,sha256=14k8CFu9mfoVokEVxD48MjF61gBl-hr895brpL4XZUc,10899
7
+ limits/typing.py,sha256=7G4-1MIh0pLOjBMG-gjNhpAqmX-hgQRzhD5_8ROVkls,4459
8
+ limits/util.py,sha256=nk5QYvezFuXPq1OTEj04RrZFSWIH-khT0e_Dim6zGCw,6002
9
+ limits/version.py,sha256=YwkF3dtq1KGzvmL3iVGctA8NNtGlK_0arrzZkZGVjUs,47
10
+ limits/aio/__init__.py,sha256=yxvWb_ZmV245Hg2LqD365WC5IDllcGDMw6udJ1jNp1g,118
11
+ limits/aio/strategies.py,sha256=9jnVU_nynm0zL1EjQLE3fus1vFbLqA-19ZRQhhexAGo,10776
12
+ limits/aio/storage/__init__.py,sha256=gL4DGTV-XDksZxofaP__sGvwehN8MuuJQuRZeuGwiOQ,695
13
+ limits/aio/storage/base.py,sha256=376Bs7l285vRTRa3-DqcVRnqOPdf3BpoCqbJr3XA9u8,6439
14
+ limits/aio/storage/etcd.py,sha256=9Mp2mvLKOZhuozVC6pBB7-85WMbPytmtZyS6Wg7KUPI,5012
15
+ limits/aio/storage/memcached.py,sha256=kSX7B0CRS-qDVCQot4AW0rF3YwomXRyWg6W0_RyaHhM,10361
16
+ limits/aio/storage/memory.py,sha256=cBWk9P8_Dtm8YJpsZWScVuJQN93IJyno0fFVd5ubcRc,9759
17
+ limits/aio/storage/mongodb.py,sha256=EvwYBu9YoNX7j6A8XB8ik8SqMx0n4oWmBYhh4LHMYaI,19310
18
+ limits/aio/storage/redis/__init__.py,sha256=p6amEcujcImDUxcYCsfBaLBKp1qH9xDXDjv3FWWfGow,14203
19
+ limits/aio/storage/redis/bridge.py,sha256=cKs77RoCxUPfYD6_o1AiHfqpkeq_DFqMtVQKMLhEWdY,3183
20
+ limits/aio/storage/redis/coredis.py,sha256=YT8cBx25MeSy9ApSJBfOK8VKduABTRefsnd9GhWscsI,7494
21
+ limits/aio/storage/redis/redispy.py,sha256=ZAxHOFGAjRHsPzjfLowq5nMlVkK_YhVGHOOV8K4gMmU,8547
22
+ limits/aio/storage/redis/valkey.py,sha256=f_-HPZhzNspywGybMNIL0F5uDZk76v8_K9wuC5ZeKhc,248
23
+ limits/resources/redis/lua_scripts/acquire_moving_window.lua,sha256=5CFJX7D6T6RG5SFr6eVZ6zepmI1EkGWmKeVEO4QNrWo,483
24
+ limits/resources/redis/lua_scripts/acquire_sliding_window.lua,sha256=OhVI1MAN_gT92P6r-2CEmvy1yvQVjYCCZxWIxfXYceY,1329
25
+ limits/resources/redis/lua_scripts/clear_keys.lua,sha256=zU0cVfLGmapRQF9x9u0GclapM_IB2pJLszNzVQ1QRK4,184
26
+ limits/resources/redis/lua_scripts/incr_expire.lua,sha256=Uq9NcrrcDI-F87TDAJexoSJn2SDgeXIUEYozCp9S3oA,195
27
+ limits/resources/redis/lua_scripts/moving_window.lua,sha256=5hUZghISDh8Cbg8HJediM_OKjjNMF-0CBywWmsc93vA,430
28
+ limits/resources/redis/lua_scripts/sliding_window.lua,sha256=qG3Yg30Dq54QpRUcR9AOrKQ5bdJiaYpCacTm6Kxblvc,713
29
+ limits/storage/__init__.py,sha256=DArgeRfGilHWsfKz5qT_6OimP3S5u2E9lnzVst0n8Bw,2701
30
+ limits/storage/base.py,sha256=6MprvcdNaTIPyN0ei9emcJLajYq07vDGSIKrmiaU6dU,7003
31
+ limits/storage/etcd.py,sha256=-Zg3KUeXSI8m6VujgIUfa5VeaaiB8Ytbq30p7Voucxk,4676
32
+ limits/storage/memcached.py,sha256=NJqHpbfZjT7YpjlK0dUX1-k_nb7HxPMQvBBapgUaHhY,11217
33
+ limits/storage/memory.py,sha256=xLg3NDsnVEI3ds4QGS7MpH-VjjEJqwroOnz3LA8UQQ8,9226
34
+ limits/storage/mongodb.py,sha256=NqXFRj6h8fk8r_dznV-h9gqh95MLNtd5VRmtFncdzT0,18224
35
+ limits/storage/redis.py,sha256=b2m5TrPNwS7NBY5btwCN0esGyCVQTwwgCn6f-sTcgFQ,10613
36
+ limits/storage/redis_cluster.py,sha256=z6aONMl4p1AY78G3J0BbtK--uztz88krwnpiOsU61BM,4447
37
+ limits/storage/redis_sentinel.py,sha256=AN0WtwHN88TvXk0C2uUE8l5Jhsd1ZxU8XSqrEyQSR20,4327
38
+ limits/storage/registry.py,sha256=CxSaDBGR5aBJPFAIsfX9axCnbcThN3Bu-EH4wHrXtu8,650
39
+ limits-4.3.dist-info/LICENSE.txt,sha256=T6i7kq7F5gIPfcno9FCxU5Hcwm22Bjq0uHZV3ElcjsQ,1061
40
+ limits-4.3.dist-info/METADATA,sha256=ykP0e77goPvIVXKgonDLMcTA95Me_zpbrlfDtFC96Vs,11355
41
+ limits-4.3.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
42
+ limits-4.3.dist-info/top_level.txt,sha256=C7g5ahldPoU2s6iWTaJayUrbGmPK1d6e9t5Nn0vQ2jM,7
43
+ limits-4.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5