asyncstdlib 3.12.0__tar.gz → 3.12.2__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.
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/PKG-INFO +3 -5
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/__init__.py +10 -2
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/_core.py +22 -16
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/_lrucache.py +47 -28
- asyncstdlib-3.12.2/asyncstdlib/_lrucache.pyi +90 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/_typing.py +17 -12
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/_utility.py +1 -19
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/asynctools.py +49 -61
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/builtins.py +8 -313
- asyncstdlib-3.12.2/asyncstdlib/builtins.pyi +239 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/contextlib.py +81 -58
- asyncstdlib-3.12.2/asyncstdlib/contextlib.pyi +115 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/functools.py +15 -8
- asyncstdlib-3.12.2/asyncstdlib/functools.pyi +26 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/heapq.py +15 -43
- asyncstdlib-3.12.2/asyncstdlib/heapq.pyi +40 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/itertools.py +25 -157
- asyncstdlib-3.12.2/asyncstdlib/itertools.pyi +238 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/pyproject.toml +3 -4
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_contextlib.py +22 -3
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_functools.py +3 -1
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_helpers.py +4 -19
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/utility.py +8 -8
- asyncstdlib-3.12.0/asyncstdlib/_lrucache.pyi +0 -61
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/LICENSE +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/README.rst +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/asyncstdlib/py.typed +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/__init__.py +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_asynctools.py +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_builtins.py +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_functools_lru.py +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_heapq.py +0 -0
- {asyncstdlib-3.12.0 → asyncstdlib-3.12.2}/unittests/test_itertools.py +0 -0
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: asyncstdlib
|
|
3
|
-
Version: 3.12.
|
|
3
|
+
Version: 3.12.2
|
|
4
4
|
Summary: The missing async toolbox
|
|
5
5
|
Keywords: async,enumerate,itertools,builtins,functools,contextlib
|
|
6
6
|
Author-email: Max Fischer <maxfischer2781@gmail.com>
|
|
7
|
-
Requires-Python: ~=3.
|
|
7
|
+
Requires-Python: ~=3.8
|
|
8
8
|
Description-Content-Type: text/x-rst
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Framework :: AsyncIO
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Requires-Dist: typing_extensions; python_version<'3.8'
|
|
22
19
|
Requires-Dist: sphinx ; extra == "doc"
|
|
23
20
|
Requires-Dist: sphinxcontrib-trio ; extra == "doc"
|
|
24
21
|
Requires-Dist: pytest ; extra == "test"
|
|
@@ -29,6 +26,7 @@ Requires-Dist: coverage ; extra == "test"
|
|
|
29
26
|
Requires-Dist: pytest-cov ; extra == "test"
|
|
30
27
|
Requires-Dist: flake8-2020 ; extra == "test"
|
|
31
28
|
Requires-Dist: mypy ; extra == "test" and ( implementation_name=='cpython')
|
|
29
|
+
Requires-Dist: typing-extensions ; extra == "test"
|
|
32
30
|
Project-URL: Documentation, https://asyncstdlib.readthedocs.io/en/latest/
|
|
33
31
|
Project-URL: Source, https://github.com/maxfischer2781/asyncstdlib
|
|
34
32
|
Provides-Extra: doc
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""The missing async toolbox"""
|
|
2
|
+
|
|
2
3
|
from .builtins import (
|
|
3
4
|
anext,
|
|
4
5
|
zip,
|
|
@@ -18,7 +19,13 @@ from .builtins import (
|
|
|
18
19
|
sorted,
|
|
19
20
|
)
|
|
20
21
|
from .functools import reduce, lru_cache, cache, cached_property
|
|
21
|
-
from .contextlib import
|
|
22
|
+
from .contextlib import (
|
|
23
|
+
closing,
|
|
24
|
+
ContextDecorator,
|
|
25
|
+
contextmanager,
|
|
26
|
+
nullcontext,
|
|
27
|
+
ExitStack,
|
|
28
|
+
)
|
|
22
29
|
from .itertools import (
|
|
23
30
|
accumulate,
|
|
24
31
|
batched,
|
|
@@ -38,7 +45,7 @@ from .itertools import (
|
|
|
38
45
|
from .asynctools import borrow, scoped_iter, await_each, any_iter, apply, sync
|
|
39
46
|
from .heapq import merge, nlargest, nsmallest
|
|
40
47
|
|
|
41
|
-
__version__ = "3.12.
|
|
48
|
+
__version__ = "3.12.2"
|
|
42
49
|
|
|
43
50
|
__all__ = [
|
|
44
51
|
"anext",
|
|
@@ -64,6 +71,7 @@ __all__ = [
|
|
|
64
71
|
"cached_property",
|
|
65
72
|
# contextlib
|
|
66
73
|
"closing",
|
|
74
|
+
"ContextDecorator",
|
|
67
75
|
"contextmanager",
|
|
68
76
|
"nullcontext",
|
|
69
77
|
"ExitStack",
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Internal helpers to safely build async abstractions
|
|
3
|
+
|
|
4
|
+
While some of these helpers have public siblings
|
|
5
|
+
(e.g. :py:class:`~.ScopedIter` and :py:func:`~.asynctools.scoped_iter`)
|
|
6
|
+
they are purposely kept separate.
|
|
7
|
+
Any helpers in this module are *not* bound to maintaining a public interface,
|
|
8
|
+
and offer less convenience to save on overhead.
|
|
9
|
+
"""
|
|
10
|
+
|
|
1
11
|
from inspect import iscoroutinefunction
|
|
2
12
|
from typing import (
|
|
3
13
|
Any,
|
|
@@ -55,20 +65,19 @@ async def _aiter_sync(iterable: Iterable[T]) -> AsyncIterator[T]:
|
|
|
55
65
|
|
|
56
66
|
|
|
57
67
|
class ScopedIter(Generic[T]):
|
|
58
|
-
"""
|
|
68
|
+
"""
|
|
69
|
+
Context manager that provides and cleans up an iterator for an iterable
|
|
59
70
|
|
|
60
|
-
|
|
71
|
+
Note that unlike :py:func:`~.asynctools.scoped_iter`, this helper does
|
|
72
|
+
*not* borrow the iterator automatically. Use :py:func:`~.borrow` if needed.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
__slots__ = ("_iterator",)
|
|
61
76
|
|
|
62
77
|
def __init__(self, iterable: AnyIterable[T]):
|
|
63
|
-
self.
|
|
64
|
-
self._iterator: Optional[AsyncIterator[T]] = None
|
|
78
|
+
self._iterator: AsyncIterator[T] = aiter(iterable)
|
|
65
79
|
|
|
66
80
|
async def __aenter__(self) -> AsyncIterator[T]:
|
|
67
|
-
assert (
|
|
68
|
-
self._iterable is not None
|
|
69
|
-
), f"{self.__class__.__name__} is not re-entrant"
|
|
70
|
-
self._iterator = aiter(self._iterable)
|
|
71
|
-
self._iterable = None
|
|
72
81
|
return self._iterator
|
|
73
82
|
|
|
74
83
|
async def __aexit__(
|
|
@@ -76,20 +85,18 @@ class ScopedIter(Generic[T]):
|
|
|
76
85
|
exc_type: Optional[Type[BaseException]],
|
|
77
86
|
exc_val: Optional[BaseException],
|
|
78
87
|
exc_tb: Optional[TracebackType],
|
|
79
|
-
) ->
|
|
88
|
+
) -> None:
|
|
80
89
|
try:
|
|
81
90
|
aclose = self._iterator.aclose() # type: ignore
|
|
82
91
|
except AttributeError:
|
|
83
92
|
pass
|
|
84
93
|
else:
|
|
85
94
|
await aclose
|
|
86
|
-
return False
|
|
87
95
|
|
|
88
96
|
|
|
89
|
-
|
|
97
|
+
def borrow(iterator: AsyncIterator[T]) -> AsyncGenerator[T, None]:
|
|
90
98
|
"""Borrow an async iterator for iteration, preventing it from being closed"""
|
|
91
|
-
async for item in iterator
|
|
92
|
-
yield item
|
|
99
|
+
return (item async for item in iterator)
|
|
93
100
|
|
|
94
101
|
|
|
95
102
|
def awaitify(
|
|
@@ -112,8 +119,7 @@ class Awaitify(Generic[T]):
|
|
|
112
119
|
self._async_call: Optional[Callable[..., Awaitable[T]]] = None
|
|
113
120
|
|
|
114
121
|
def __call__(self, *args: Any, **kwargs: Any) -> Awaitable[T]:
|
|
115
|
-
async_call
|
|
116
|
-
if async_call is None:
|
|
122
|
+
if (async_call := self._async_call) is None:
|
|
117
123
|
value = self.__wrapped__(*args, **kwargs)
|
|
118
124
|
if isinstance(value, Awaitable):
|
|
119
125
|
self._async_call = self.__wrapped__ # type: ignore
|
|
@@ -5,7 +5,11 @@ This is loosely based on the CPython 3.8 implementation. In specific,
|
|
|
5
5
|
several performance hacks are skipped in favour of maintainability,
|
|
6
6
|
especially when they might not apply to PyPy.
|
|
7
7
|
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
8
10
|
from typing import (
|
|
11
|
+
Generic,
|
|
12
|
+
TypeVar,
|
|
9
13
|
NamedTuple,
|
|
10
14
|
Callable,
|
|
11
15
|
Any,
|
|
@@ -71,20 +75,31 @@ class LRUAsyncCallable(Protocol[AC]):
|
|
|
71
75
|
"""The callable wrapped by this cache"""
|
|
72
76
|
raise NotImplementedError
|
|
73
77
|
|
|
78
|
+
def __get__(
|
|
79
|
+
self: LRUAsyncCallable[Any], instance: object, owner: Optional[type] = None
|
|
80
|
+
) -> Any:
|
|
81
|
+
"""Descriptor ``__get__`` for caches to bind them on lookup"""
|
|
82
|
+
if instance is None:
|
|
83
|
+
return self
|
|
84
|
+
return LRUAsyncBoundCallable(self, instance)
|
|
85
|
+
|
|
74
86
|
#: Get the result of ``await __wrapped__(...)`` from the cache or evaluation
|
|
75
87
|
__call__: AC
|
|
76
88
|
|
|
77
89
|
def cache_parameters(self) -> CacheParameters:
|
|
78
90
|
"""Get the parameters of the cache"""
|
|
91
|
+
...
|
|
79
92
|
|
|
80
93
|
def cache_info(self) -> CacheInfo:
|
|
81
94
|
"""
|
|
82
95
|
Get the current performance and boundary of the cache
|
|
83
96
|
as a :py:class:`~typing.NamedTuple`
|
|
84
97
|
"""
|
|
98
|
+
...
|
|
85
99
|
|
|
86
100
|
def cache_clear(self) -> None:
|
|
87
101
|
"""Evict all call argument patterns and their results from the cache"""
|
|
102
|
+
...
|
|
88
103
|
|
|
89
104
|
def cache_discard(self, *args: Any, **kwargs: Any) -> None:
|
|
90
105
|
"""
|
|
@@ -95,28 +110,44 @@ class LRUAsyncCallable(Protocol[AC]):
|
|
|
95
110
|
the descriptor must support wrapping descriptors for this method
|
|
96
111
|
to detect implicit arguments such as ``self``.
|
|
97
112
|
"""
|
|
113
|
+
# Maintainers note:
|
|
98
114
|
# "support wrapping descriptors" means that the wrapping descriptor has to use
|
|
99
115
|
# the cache as a descriptor as well, i.e. invoke its ``__get__`` method instead
|
|
100
116
|
# of just passing in `self`/`cls`/... directly.
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# these are fake and only exist for placeholders
|
|
121
|
+
S = TypeVar("S")
|
|
122
|
+
S2 = TypeVar("S2")
|
|
123
|
+
P = TypeVar("P")
|
|
124
|
+
R = TypeVar("R")
|
|
101
125
|
|
|
102
126
|
|
|
103
|
-
class LRUAsyncBoundCallable(
|
|
127
|
+
class LRUAsyncBoundCallable(Generic[S, P, R]): # type: ignore[reportInvalidTypeVarUse]
|
|
104
128
|
"""A :py:class:`~.LRUAsyncCallable` that is bound like a method"""
|
|
105
129
|
|
|
106
130
|
__slots__ = ("__weakref__", "_lru", "__self__")
|
|
107
131
|
|
|
108
|
-
def __init__(self, lru: LRUAsyncCallable[
|
|
132
|
+
def __init__(self, lru: LRUAsyncCallable[Any], __self__: object):
|
|
109
133
|
self._lru = lru
|
|
110
134
|
self.__self__ = __self__
|
|
111
135
|
|
|
112
136
|
@property
|
|
113
|
-
def __wrapped__(self) ->
|
|
137
|
+
def __wrapped__(self) -> Any:
|
|
114
138
|
return self._lru.__wrapped__
|
|
115
139
|
|
|
116
140
|
@property
|
|
117
|
-
def __func__(self) -> LRUAsyncCallable[
|
|
141
|
+
def __func__(self) -> LRUAsyncCallable[Any]:
|
|
118
142
|
return self._lru
|
|
119
143
|
|
|
144
|
+
def __get__(
|
|
145
|
+
self: LRUAsyncBoundCallable[S, P, R],
|
|
146
|
+
instance: S2,
|
|
147
|
+
owner: Optional[type] = None,
|
|
148
|
+
) -> LRUAsyncBoundCallable[S2, P, R]:
|
|
149
|
+
return LRUAsyncBoundCallable(self._lru, instance)
|
|
150
|
+
|
|
120
151
|
def __call__(self, *args, **kwargs): # type: ignore
|
|
121
152
|
return self._lru(self.__self__, *args, **kwargs)
|
|
122
153
|
|
|
@@ -149,15 +180,13 @@ class LRUAsyncBoundCallable(LRUAsyncCallable[AC]):
|
|
|
149
180
|
|
|
150
181
|
|
|
151
182
|
@overload
|
|
152
|
-
def lru_cache(maxsize: AC, typed: bool = ...) -> LRUAsyncCallable[AC]:
|
|
153
|
-
...
|
|
183
|
+
def lru_cache(maxsize: AC, typed: bool = ...) -> LRUAsyncCallable[AC]: ...
|
|
154
184
|
|
|
155
185
|
|
|
156
186
|
@overload
|
|
157
187
|
def lru_cache(
|
|
158
188
|
maxsize: Optional[int] = ..., typed: bool = ...
|
|
159
|
-
) -> Callable[[AC], LRUAsyncCallable[AC]]:
|
|
160
|
-
...
|
|
189
|
+
) -> Callable[[AC], LRUAsyncCallable[AC]]: ...
|
|
161
190
|
|
|
162
191
|
|
|
163
192
|
@public_module("asyncstdlib.functools")
|
|
@@ -212,7 +241,8 @@ def lru_cache(
|
|
|
212
241
|
elif callable(maxsize):
|
|
213
242
|
# used as function decorator, first arg is the function to be wrapped
|
|
214
243
|
fast_wrapper = CachedLRUAsyncCallable(cast(AC, maxsize), typed, 128)
|
|
215
|
-
|
|
244
|
+
update_wrapper(fast_wrapper, maxsize)
|
|
245
|
+
return fast_wrapper
|
|
216
246
|
elif maxsize is not None:
|
|
217
247
|
raise TypeError(
|
|
218
248
|
"first argument to 'lru_cache' must be an int, a callable or None"
|
|
@@ -227,7 +257,8 @@ def lru_cache(
|
|
|
227
257
|
wrapper = UncachedLRUAsyncCallable(function, typed)
|
|
228
258
|
else:
|
|
229
259
|
wrapper = CachedLRUAsyncCallable(function, typed, maxsize)
|
|
230
|
-
|
|
260
|
+
update_wrapper(wrapper, function)
|
|
261
|
+
return wrapper
|
|
231
262
|
|
|
232
263
|
return lru_decorator
|
|
233
264
|
|
|
@@ -283,29 +314,19 @@ class CallKey:
|
|
|
283
314
|
return cls(key)
|
|
284
315
|
|
|
285
316
|
|
|
286
|
-
def cache__get(
|
|
287
|
-
self: LRUAsyncCallable[AC], instance: object, owner: Optional[type] = None
|
|
288
|
-
) -> LRUAsyncCallable[AC]:
|
|
289
|
-
"""Descriptor ``__get__`` for caches to bind them on lookup"""
|
|
290
|
-
if instance is None:
|
|
291
|
-
return self
|
|
292
|
-
return LRUAsyncBoundCallable(self, instance)
|
|
293
|
-
|
|
294
|
-
|
|
295
317
|
class UncachedLRUAsyncCallable(LRUAsyncCallable[AC]):
|
|
296
318
|
"""Wrap the async ``call`` to track accesses as for caching/memoization"""
|
|
297
319
|
|
|
298
320
|
__slots__ = ("__weakref__", "__dict__", "__wrapped__", "__misses", "__typed")
|
|
299
321
|
|
|
300
322
|
__wrapped__: AC
|
|
301
|
-
__get__ = cache__get
|
|
302
323
|
|
|
303
324
|
def __init__(self, call: AC, typed: bool):
|
|
304
|
-
self.__wrapped__ = call
|
|
325
|
+
self.__wrapped__ = call # type: ignore[reportIncompatibleMethodOverride]
|
|
305
326
|
self.__misses = 0
|
|
306
327
|
self.__typed = typed
|
|
307
328
|
|
|
308
|
-
async def __call__(self, *args, **kwargs): # type: ignore
|
|
329
|
+
async def __call__(self, *args: Any, **kwargs: Any) -> Any: # type: ignore[reportIncompatibleVariableOverride]
|
|
309
330
|
self.__misses += 1
|
|
310
331
|
return await self.__wrapped__(*args, **kwargs)
|
|
311
332
|
|
|
@@ -336,16 +357,15 @@ class MemoizedLRUAsyncCallable(LRUAsyncCallable[AC]):
|
|
|
336
357
|
)
|
|
337
358
|
|
|
338
359
|
__wrapped__: AC
|
|
339
|
-
__get__ = cache__get
|
|
340
360
|
|
|
341
361
|
def __init__(self, call: AC, typed: bool):
|
|
342
|
-
self.__wrapped__ = call
|
|
362
|
+
self.__wrapped__ = call # type: ignore[reportIncompatibleMethodOverride]
|
|
343
363
|
self.__hits = 0
|
|
344
364
|
self.__misses = 0
|
|
345
365
|
self.__typed = typed
|
|
346
366
|
self.__cache: Dict[Union[CallKey, int, str], Any] = {}
|
|
347
367
|
|
|
348
|
-
async def __call__(self, *args, **kwargs): # type: ignore
|
|
368
|
+
async def __call__(self, *args: Any, **kwargs: Any) -> Any: # type: ignore[reportIncompatibleVariableOverride]
|
|
349
369
|
key = CallKey.from_call(args, kwargs, typed=self.__typed)
|
|
350
370
|
try:
|
|
351
371
|
result = self.__cache[key]
|
|
@@ -391,17 +411,16 @@ class CachedLRUAsyncCallable(LRUAsyncCallable[AC]):
|
|
|
391
411
|
)
|
|
392
412
|
|
|
393
413
|
__wrapped__: AC
|
|
394
|
-
__get__ = cache__get
|
|
395
414
|
|
|
396
415
|
def __init__(self, call: AC, typed: bool, maxsize: int):
|
|
397
|
-
self.__wrapped__ = call
|
|
416
|
+
self.__wrapped__ = call # type: ignore[reportIncompatibleMethodOverride]
|
|
398
417
|
self.__hits = 0
|
|
399
418
|
self.__misses = 0
|
|
400
419
|
self.__typed = typed
|
|
401
420
|
self.__maxsize = maxsize
|
|
402
421
|
self.__cache: OrderedDict[Union[int, str, CallKey], Any] = OrderedDict()
|
|
403
422
|
|
|
404
|
-
async def __call__(self, *args, **kwargs): # type: ignore
|
|
423
|
+
async def __call__(self, *args: Any, **kwargs: Any) -> Any: # type: ignore[reportIncompatibleVariableOverride]
|
|
405
424
|
key = CallKey.from_call(args, kwargs, typed=self.__typed)
|
|
406
425
|
try:
|
|
407
426
|
result = self.__cache[key]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
TypeVar,
|
|
3
|
+
Any,
|
|
4
|
+
Awaitable,
|
|
5
|
+
Callable,
|
|
6
|
+
Coroutine,
|
|
7
|
+
Generic,
|
|
8
|
+
NamedTuple,
|
|
9
|
+
overload,
|
|
10
|
+
Protocol,
|
|
11
|
+
)
|
|
12
|
+
from typing_extensions import ParamSpec, Concatenate
|
|
13
|
+
|
|
14
|
+
from ._typing import AC, TypedDict
|
|
15
|
+
|
|
16
|
+
class CacheInfo(NamedTuple):
|
|
17
|
+
hits: int
|
|
18
|
+
misses: int
|
|
19
|
+
maxsize: int | None
|
|
20
|
+
currsize: int
|
|
21
|
+
|
|
22
|
+
class CacheParameters(TypedDict):
|
|
23
|
+
maxsize: int | None
|
|
24
|
+
typed: bool
|
|
25
|
+
|
|
26
|
+
R = TypeVar("R")
|
|
27
|
+
P = ParamSpec("P")
|
|
28
|
+
S = TypeVar("S")
|
|
29
|
+
S2 = TypeVar("S2")
|
|
30
|
+
|
|
31
|
+
class LRUAsyncCallable(Protocol[AC]):
|
|
32
|
+
__slots__: tuple[str, ...]
|
|
33
|
+
__call__: AC
|
|
34
|
+
@overload
|
|
35
|
+
def __get__(
|
|
36
|
+
self: LRUAsyncCallable[AC], instance: None, owner: type | None = ...
|
|
37
|
+
) -> LRUAsyncCallable[AC]: ...
|
|
38
|
+
@overload
|
|
39
|
+
def __get__(
|
|
40
|
+
self: LRUAsyncCallable[Callable[Concatenate[S, P], Coroutine[Any, Any, R]]],
|
|
41
|
+
instance: S,
|
|
42
|
+
owner: type | None = ...,
|
|
43
|
+
) -> LRUAsyncBoundCallable[S, P, R]: ...
|
|
44
|
+
@overload
|
|
45
|
+
def __get__(
|
|
46
|
+
self: LRUAsyncCallable[Callable[Concatenate[S, P], Awaitable[R]]],
|
|
47
|
+
instance: S,
|
|
48
|
+
owner: type | None = ...,
|
|
49
|
+
) -> LRUAsyncBoundCallable[S, P, R]: ...
|
|
50
|
+
@property
|
|
51
|
+
def __wrapped__(self) -> AC: ...
|
|
52
|
+
def cache_parameters(self) -> CacheParameters: ...
|
|
53
|
+
def cache_info(self) -> CacheInfo: ...
|
|
54
|
+
def cache_clear(self) -> None: ...
|
|
55
|
+
def cache_discard(self, *args: Any, **kwargs: Any) -> None: ...
|
|
56
|
+
|
|
57
|
+
class LRUAsyncBoundCallable(Generic[S, P, R]):
|
|
58
|
+
__slots__: tuple[str, ...]
|
|
59
|
+
__self__: S
|
|
60
|
+
__call__: Callable[P, Awaitable[R]]
|
|
61
|
+
@overload
|
|
62
|
+
def __get__(
|
|
63
|
+
self, instance: None, owner: type | None = ...
|
|
64
|
+
) -> LRUAsyncBoundCallable[S, P, R]: ...
|
|
65
|
+
@overload
|
|
66
|
+
def __get__(
|
|
67
|
+
self, instance: S2, owner: type | None = ...
|
|
68
|
+
) -> LRUAsyncBoundCallable[S2, P, R]: ...
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
lru: LRUAsyncCallable[Callable[Concatenate[S, P], Awaitable[R]]],
|
|
72
|
+
__self__: S,
|
|
73
|
+
) -> None: ...
|
|
74
|
+
@property
|
|
75
|
+
def __wrapped__(self) -> Callable[Concatenate[S, P], Awaitable[R]]: ...
|
|
76
|
+
@property
|
|
77
|
+
def __func__(
|
|
78
|
+
self,
|
|
79
|
+
) -> LRUAsyncCallable[Callable[Concatenate[S, P], Awaitable[R]]]: ...
|
|
80
|
+
def cache_parameters(self) -> CacheParameters: ...
|
|
81
|
+
def cache_info(self) -> CacheInfo: ...
|
|
82
|
+
def cache_clear(self) -> None: ...
|
|
83
|
+
def cache_discard(self, *args: Any, **kwargs: Any) -> None: ...
|
|
84
|
+
|
|
85
|
+
@overload
|
|
86
|
+
def lru_cache(maxsize: AC, typed: bool = ...) -> LRUAsyncCallable[AC]: ...
|
|
87
|
+
@overload
|
|
88
|
+
def lru_cache(
|
|
89
|
+
maxsize: int | None = ..., typed: bool = ...
|
|
90
|
+
) -> Callable[[AC], LRUAsyncCallable[AC]]: ...
|
|
@@ -4,7 +4,7 @@ Helper module to simplify version specific typing imports
|
|
|
4
4
|
This module is for internal use only. Do *not* put any new
|
|
5
5
|
"async typing" definitions here.
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
from typing import (
|
|
9
9
|
TypeVar,
|
|
10
10
|
Hashable,
|
|
@@ -14,21 +14,14 @@ from typing import (
|
|
|
14
14
|
Callable,
|
|
15
15
|
Any,
|
|
16
16
|
Awaitable,
|
|
17
|
+
runtime_checkable,
|
|
18
|
+
Protocol,
|
|
19
|
+
ContextManager,
|
|
20
|
+
TypedDict,
|
|
17
21
|
)
|
|
18
22
|
|
|
19
|
-
if sys.version_info >= (3, 8):
|
|
20
|
-
from typing import Protocol, AsyncContextManager, ContextManager, TypedDict
|
|
21
|
-
else:
|
|
22
|
-
from typing_extensions import (
|
|
23
|
-
Protocol,
|
|
24
|
-
AsyncContextManager,
|
|
25
|
-
ContextManager,
|
|
26
|
-
TypedDict,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
23
|
__all__ = [
|
|
30
24
|
"Protocol",
|
|
31
|
-
"AsyncContextManager",
|
|
32
25
|
"ContextManager",
|
|
33
26
|
"TypedDict",
|
|
34
27
|
"T",
|
|
@@ -43,6 +36,8 @@ __all__ = [
|
|
|
43
36
|
"HK",
|
|
44
37
|
"LT",
|
|
45
38
|
"ADD",
|
|
39
|
+
"AClose",
|
|
40
|
+
"ACloseable",
|
|
46
41
|
"AnyIterable",
|
|
47
42
|
]
|
|
48
43
|
|
|
@@ -78,5 +73,15 @@ class SupportsAdd(Protocol):
|
|
|
78
73
|
raise NotImplementedError
|
|
79
74
|
|
|
80
75
|
|
|
76
|
+
# await AClose.aclose()
|
|
77
|
+
AClose = TypeVar("AClose", bound="ACloseable")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@runtime_checkable
|
|
81
|
+
class ACloseable(Protocol):
|
|
82
|
+
async def aclose(self) -> None:
|
|
83
|
+
"""Asynchronously close this object"""
|
|
84
|
+
|
|
85
|
+
|
|
81
86
|
#: (async) iter T
|
|
82
87
|
AnyIterable = Union[Iterable[T], AsyncIterable[T]]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TypeVar,
|
|
1
|
+
from typing import TypeVar, Optional, Callable
|
|
2
2
|
|
|
3
3
|
from ._typing import Protocol
|
|
4
4
|
|
|
@@ -29,21 +29,3 @@ def public_module(
|
|
|
29
29
|
return thing
|
|
30
30
|
|
|
31
31
|
return decorator
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def slot_get(instance: object, name: str) -> Any:
|
|
35
|
-
"""
|
|
36
|
-
Emulate ``instance.name`` using slot lookup as used for special methods
|
|
37
|
-
|
|
38
|
-
This invokes the descriptor protocol, i.e. it calls the attribute's
|
|
39
|
-
``__get__`` if available.
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
owner = type(instance)
|
|
43
|
-
attribute = getattr(owner, name)
|
|
44
|
-
try:
|
|
45
|
-
descriptor_get = attribute.__get__
|
|
46
|
-
except AttributeError:
|
|
47
|
-
return attribute
|
|
48
|
-
else:
|
|
49
|
-
return descriptor_get(instance, owner)
|