ez-a-sync 0.32.29__cp310-cp310-win32.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.
Potentially problematic release.
This version of ez-a-sync might be problematic. Click here for more details.
- a_sync/ENVIRONMENT_VARIABLES.py +42 -0
- a_sync/__init__.pxd +2 -0
- a_sync/__init__.py +145 -0
- a_sync/_smart.c +22803 -0
- a_sync/_smart.cp310-win32.pyd +0 -0
- a_sync/_smart.pxd +2 -0
- a_sync/_smart.pyi +202 -0
- a_sync/_smart.pyx +674 -0
- a_sync/_typing.py +258 -0
- a_sync/a_sync/__init__.py +60 -0
- a_sync/a_sync/_descriptor.c +20528 -0
- a_sync/a_sync/_descriptor.cp310-win32.pyd +0 -0
- a_sync/a_sync/_descriptor.pyi +33 -0
- a_sync/a_sync/_descriptor.pyx +422 -0
- a_sync/a_sync/_flags.c +6074 -0
- a_sync/a_sync/_flags.cp310-win32.pyd +0 -0
- a_sync/a_sync/_flags.pxd +3 -0
- a_sync/a_sync/_flags.pyx +92 -0
- a_sync/a_sync/_helpers.c +14521 -0
- a_sync/a_sync/_helpers.cp310-win32.pyd +0 -0
- a_sync/a_sync/_helpers.pxd +3 -0
- a_sync/a_sync/_helpers.pyi +10 -0
- a_sync/a_sync/_helpers.pyx +167 -0
- a_sync/a_sync/_kwargs.c +12194 -0
- a_sync/a_sync/_kwargs.cp310-win32.pyd +0 -0
- a_sync/a_sync/_kwargs.pxd +2 -0
- a_sync/a_sync/_kwargs.pyx +64 -0
- a_sync/a_sync/_meta.py +210 -0
- a_sync/a_sync/abstract.c +12411 -0
- a_sync/a_sync/abstract.cp310-win32.pyd +0 -0
- a_sync/a_sync/abstract.pyi +141 -0
- a_sync/a_sync/abstract.pyx +221 -0
- a_sync/a_sync/base.c +14932 -0
- a_sync/a_sync/base.cp310-win32.pyd +0 -0
- a_sync/a_sync/base.pyi +60 -0
- a_sync/a_sync/base.pyx +271 -0
- a_sync/a_sync/config.py +168 -0
- a_sync/a_sync/decorator.py +651 -0
- a_sync/a_sync/flags.c +5272 -0
- a_sync/a_sync/flags.cp310-win32.pyd +0 -0
- a_sync/a_sync/flags.pxd +72 -0
- a_sync/a_sync/flags.pyi +74 -0
- a_sync/a_sync/flags.pyx +72 -0
- a_sync/a_sync/function.c +37846 -0
- a_sync/a_sync/function.cp310-win32.pyd +0 -0
- a_sync/a_sync/function.pxd +28 -0
- a_sync/a_sync/function.pyi +571 -0
- a_sync/a_sync/function.pyx +1381 -0
- a_sync/a_sync/method.c +29774 -0
- a_sync/a_sync/method.cp310-win32.pyd +0 -0
- a_sync/a_sync/method.pxd +9 -0
- a_sync/a_sync/method.pyi +525 -0
- a_sync/a_sync/method.pyx +1023 -0
- a_sync/a_sync/modifiers/__init__.pxd +1 -0
- a_sync/a_sync/modifiers/__init__.py +101 -0
- a_sync/a_sync/modifiers/cache/__init__.py +160 -0
- a_sync/a_sync/modifiers/cache/memory.py +165 -0
- a_sync/a_sync/modifiers/limiter.py +132 -0
- a_sync/a_sync/modifiers/manager.c +16149 -0
- a_sync/a_sync/modifiers/manager.cp310-win32.pyd +0 -0
- a_sync/a_sync/modifiers/manager.pxd +5 -0
- a_sync/a_sync/modifiers/manager.pyi +219 -0
- a_sync/a_sync/modifiers/manager.pyx +299 -0
- a_sync/a_sync/modifiers/semaphores.py +173 -0
- a_sync/a_sync/property.c +27260 -0
- a_sync/a_sync/property.cp310-win32.pyd +0 -0
- a_sync/a_sync/property.pyi +376 -0
- a_sync/a_sync/property.pyx +819 -0
- a_sync/a_sync/singleton.py +63 -0
- a_sync/aliases.py +3 -0
- a_sync/async_property/__init__.pxd +1 -0
- a_sync/async_property/__init__.py +1 -0
- a_sync/async_property/cached.c +20386 -0
- a_sync/async_property/cached.cp310-win32.pyd +0 -0
- a_sync/async_property/cached.pxd +10 -0
- a_sync/async_property/cached.pyi +45 -0
- a_sync/async_property/cached.pyx +178 -0
- a_sync/async_property/proxy.c +34654 -0
- a_sync/async_property/proxy.cp310-win32.pyd +0 -0
- a_sync/async_property/proxy.pxd +2 -0
- a_sync/async_property/proxy.pyi +124 -0
- a_sync/async_property/proxy.pyx +474 -0
- a_sync/asyncio/__init__.pxd +6 -0
- a_sync/asyncio/__init__.py +164 -0
- a_sync/asyncio/as_completed.c +18841 -0
- a_sync/asyncio/as_completed.cp310-win32.pyd +0 -0
- a_sync/asyncio/as_completed.pxd +8 -0
- a_sync/asyncio/as_completed.pyi +109 -0
- a_sync/asyncio/as_completed.pyx +269 -0
- a_sync/asyncio/create_task.c +15902 -0
- a_sync/asyncio/create_task.cp310-win32.pyd +0 -0
- a_sync/asyncio/create_task.pxd +2 -0
- a_sync/asyncio/create_task.pyi +51 -0
- a_sync/asyncio/create_task.pyx +271 -0
- a_sync/asyncio/gather.c +16679 -0
- a_sync/asyncio/gather.cp310-win32.pyd +0 -0
- a_sync/asyncio/gather.pyi +107 -0
- a_sync/asyncio/gather.pyx +218 -0
- a_sync/asyncio/igather.c +12676 -0
- a_sync/asyncio/igather.cp310-win32.pyd +0 -0
- a_sync/asyncio/igather.pxd +1 -0
- a_sync/asyncio/igather.pyi +7 -0
- a_sync/asyncio/igather.pyx +182 -0
- a_sync/asyncio/sleep.c +9593 -0
- a_sync/asyncio/sleep.cp310-win32.pyd +0 -0
- a_sync/asyncio/sleep.pyi +14 -0
- a_sync/asyncio/sleep.pyx +49 -0
- a_sync/debugging.c +15362 -0
- a_sync/debugging.cp310-win32.pyd +0 -0
- a_sync/debugging.pyi +76 -0
- a_sync/debugging.pyx +107 -0
- a_sync/exceptions.c +13312 -0
- a_sync/exceptions.cp310-win32.pyd +0 -0
- a_sync/exceptions.pyi +376 -0
- a_sync/exceptions.pyx +446 -0
- a_sync/executor.py +619 -0
- a_sync/functools.c +12738 -0
- a_sync/functools.cp310-win32.pyd +0 -0
- a_sync/functools.pxd +7 -0
- a_sync/functools.pyi +33 -0
- a_sync/functools.pyx +139 -0
- a_sync/future.py +1497 -0
- a_sync/iter.c +37271 -0
- a_sync/iter.cp310-win32.pyd +0 -0
- a_sync/iter.pxd +11 -0
- a_sync/iter.pyi +370 -0
- a_sync/iter.pyx +981 -0
- a_sync/primitives/__init__.pxd +1 -0
- a_sync/primitives/__init__.py +53 -0
- a_sync/primitives/_debug.c +15757 -0
- a_sync/primitives/_debug.cp310-win32.pyd +0 -0
- a_sync/primitives/_debug.pxd +12 -0
- a_sync/primitives/_debug.pyi +52 -0
- a_sync/primitives/_debug.pyx +223 -0
- a_sync/primitives/_loggable.c +11529 -0
- a_sync/primitives/_loggable.cp310-win32.pyd +0 -0
- a_sync/primitives/_loggable.pxd +4 -0
- a_sync/primitives/_loggable.pyi +66 -0
- a_sync/primitives/_loggable.pyx +102 -0
- a_sync/primitives/locks/__init__.pxd +8 -0
- a_sync/primitives/locks/__init__.py +17 -0
- a_sync/primitives/locks/counter.c +17679 -0
- a_sync/primitives/locks/counter.cp310-win32.pyd +0 -0
- a_sync/primitives/locks/counter.pxd +12 -0
- a_sync/primitives/locks/counter.pyi +151 -0
- a_sync/primitives/locks/counter.pyx +260 -0
- a_sync/primitives/locks/event.c +17063 -0
- a_sync/primitives/locks/event.cp310-win32.pyd +0 -0
- a_sync/primitives/locks/event.pxd +22 -0
- a_sync/primitives/locks/event.pyi +43 -0
- a_sync/primitives/locks/event.pyx +185 -0
- a_sync/primitives/locks/prio_semaphore.c +25590 -0
- a_sync/primitives/locks/prio_semaphore.cp310-win32.pyd +0 -0
- a_sync/primitives/locks/prio_semaphore.pxd +25 -0
- a_sync/primitives/locks/prio_semaphore.pyi +217 -0
- a_sync/primitives/locks/prio_semaphore.pyx +597 -0
- a_sync/primitives/locks/semaphore.c +26509 -0
- a_sync/primitives/locks/semaphore.cp310-win32.pyd +0 -0
- a_sync/primitives/locks/semaphore.pxd +21 -0
- a_sync/primitives/locks/semaphore.pyi +197 -0
- a_sync/primitives/locks/semaphore.pyx +454 -0
- a_sync/primitives/queue.py +1022 -0
- a_sync/py.typed +0 -0
- a_sync/sphinx/__init__.py +3 -0
- a_sync/sphinx/ext.py +289 -0
- a_sync/task.py +932 -0
- a_sync/utils/__init__.py +105 -0
- a_sync/utils/iterators.py +297 -0
- a_sync/utils/repr.c +15799 -0
- a_sync/utils/repr.cp310-win32.pyd +0 -0
- a_sync/utils/repr.pyi +2 -0
- a_sync/utils/repr.pyx +73 -0
- ez_a_sync-0.32.29.dist-info/METADATA +367 -0
- ez_a_sync-0.32.29.dist-info/RECORD +177 -0
- ez_a_sync-0.32.29.dist-info/WHEEL +5 -0
- ez_a_sync-0.32.29.dist-info/licenses/LICENSE.txt +17 -0
- ez_a_sync-0.32.29.dist-info/top_level.txt +1 -0
|
Binary file
|
a_sync/iter.pxd
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from cpython.object cimport PyObject
|
|
2
|
+
|
|
3
|
+
cdef class _ASyncGeneratorFunction:
|
|
4
|
+
cdef readonly object _cache_handle
|
|
5
|
+
# must be public for functools.wraps
|
|
6
|
+
cdef public object __wrapped__
|
|
7
|
+
cdef readonly object __weakself__
|
|
8
|
+
cdef PyObject *__weakself_ptr
|
|
9
|
+
cdef inline void _set_cache_handle(self, object handle)
|
|
10
|
+
cdef inline object _get_cache_handle(self, object instance)
|
|
11
|
+
cdef void __cancel_cache_handle(self)
|
a_sync/iter.pyi
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import weakref
|
|
2
|
+
from collections.abc import Generator
|
|
3
|
+
from typing import (
|
|
4
|
+
Any,
|
|
5
|
+
AsyncGenerator,
|
|
6
|
+
AsyncIterable,
|
|
7
|
+
AsyncIterator,
|
|
8
|
+
Callable,
|
|
9
|
+
Coroutine,
|
|
10
|
+
Iterable,
|
|
11
|
+
Iterator,
|
|
12
|
+
Generic,
|
|
13
|
+
List,
|
|
14
|
+
Optional,
|
|
15
|
+
Type,
|
|
16
|
+
TypeVar,
|
|
17
|
+
Union,
|
|
18
|
+
final,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from typing_extensions import ParamSpec, Self
|
|
22
|
+
|
|
23
|
+
from a_sync._typing import AnyFn, AnyIterable, SyncFn
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"ASyncIterable",
|
|
27
|
+
"ASyncIterator",
|
|
28
|
+
"ASyncFilter",
|
|
29
|
+
"ASyncSorter",
|
|
30
|
+
"ASyncGeneratorFunction",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
T = TypeVar("T")
|
|
34
|
+
V = TypeVar("V")
|
|
35
|
+
P = ParamSpec("P")
|
|
36
|
+
|
|
37
|
+
SortKey = SyncFn[[T], bool]
|
|
38
|
+
ViewFn = AnyFn[[T], bool]
|
|
39
|
+
AsyncGenFunc = Callable[P, Union[AsyncGenerator[T, None], AsyncIterator[T]]]
|
|
40
|
+
|
|
41
|
+
class _AwaitableAsyncIterableMixin(AsyncIterable[T]):
|
|
42
|
+
"""
|
|
43
|
+
A mixin class defining logic for making an AsyncIterable awaitable.
|
|
44
|
+
|
|
45
|
+
When awaited, a list of all elements will be returned.
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
You must subclass this mixin class and define your own `__aiter__` method as shown below.
|
|
49
|
+
|
|
50
|
+
>>> class MyAwaitableAIterable(_AwaitableAsyncIterableMixin):
|
|
51
|
+
... async def __aiter__(self):
|
|
52
|
+
... for i in range(4):
|
|
53
|
+
... yield i
|
|
54
|
+
|
|
55
|
+
>>> aiterable = MyAwaitableAIterable()
|
|
56
|
+
>>> await aiterable
|
|
57
|
+
[0, 1, 2, 3]
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
__wrapped__: AsyncIterable[T]
|
|
61
|
+
def __await__(self) -> Generator[Any, Any, List[T]]:
|
|
62
|
+
"""
|
|
63
|
+
Asynchronously iterate through the {cls} and return all {obj}.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
A list of the {obj} yielded by the {cls}.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def materialized(self) -> List[T]:
|
|
71
|
+
"""
|
|
72
|
+
Synchronously iterate through the {cls} and return all {obj}.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
A list of the {obj} yielded by the {cls}.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def sort(self, *, key: SortKey[T] = None, reverse: bool = False) -> ASyncSorter[T]:
|
|
79
|
+
"""
|
|
80
|
+
Sort the {obj} yielded by the {cls}.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
key (optional): A function of one argument that is used to extract a comparison key from each list element. If None, the elements themselves will be sorted. Defaults to None.
|
|
84
|
+
reverse (optional): If True, the yielded elements will be sorted in reverse order. Defaults to False.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
An instance of :class:`~ASyncSorter` that will yield the {obj} yielded from this {cls}, but sorted.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def filter(self, function: ViewFn[T]) -> ASyncFilter[T]:
|
|
91
|
+
"""
|
|
92
|
+
Filters the {obj} yielded by the {cls} based on a function.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
function: A function that returns a boolean that indicates if an item should be included in the filtered result. Can be sync or async.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
An instance of :class:`~ASyncFilter` that yields the filtered {obj} from the {cls}.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
def __init_subclass__(cls, **kwargs) -> None: ...
|
|
102
|
+
|
|
103
|
+
class ASyncIterable(_AwaitableAsyncIterableMixin[T], Iterable[T]):
|
|
104
|
+
"""
|
|
105
|
+
A hybrid Iterable/AsyncIterable implementation designed to offer
|
|
106
|
+
dual compatibility with both synchronous and asynchronous
|
|
107
|
+
iteration protocols.
|
|
108
|
+
|
|
109
|
+
This class allows objects to be iterated over using either a
|
|
110
|
+
standard `for` loop or an `async for` loop, making it versatile
|
|
111
|
+
in scenarios where the mode of iteration (synchronous or asynchronous)
|
|
112
|
+
needs to be flexible or is determined at runtime.
|
|
113
|
+
|
|
114
|
+
The class achieves this by implementing both `__iter__` and `__aiter__`
|
|
115
|
+
methods, enabling it to return appropriate iterator objects that can
|
|
116
|
+
handle synchronous and asynchronous iteration, respectively. However,
|
|
117
|
+
note that synchronous iteration relies on the :class:`ASyncIterator`
|
|
118
|
+
class, which uses `asyncio.get_event_loop().run_until_complete` to
|
|
119
|
+
fetch items. This can raise a `RuntimeError` if the event loop is
|
|
120
|
+
already running, and in such cases, a :class:`~a_sync.exceptions.SyncModeInAsyncContextError`
|
|
121
|
+
is raised from the `RuntimeError`.
|
|
122
|
+
|
|
123
|
+
Example:
|
|
124
|
+
>>> async_iterable = ASyncIterable(some_async_iterable)
|
|
125
|
+
>>> async for item in async_iterable:
|
|
126
|
+
... print(item)
|
|
127
|
+
>>> for item in async_iterable:
|
|
128
|
+
... print(item)
|
|
129
|
+
|
|
130
|
+
See Also:
|
|
131
|
+
- :class:`ASyncIterator`
|
|
132
|
+
- :class:`ASyncFilter`
|
|
133
|
+
- :class:`ASyncSorter`
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def wrap(cls, wrapped: AsyncIterable[T]) -> ASyncIterable[T]:
|
|
138
|
+
"""Class method to wrap an AsyncIterable for backward compatibility."""
|
|
139
|
+
__wrapped__: AsyncIterable[T]
|
|
140
|
+
def __init__(self, async_iterable: AsyncIterable[T]) -> None:
|
|
141
|
+
"""
|
|
142
|
+
Initializes the ASyncIterable with an async iterable.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
async_iterable: The async iterable to wrap.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
def __aiter__(self) -> AsyncIterator[T]:
|
|
149
|
+
"""
|
|
150
|
+
Return an async iterator that yields {obj} from the {cls}.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
def __iter__(self) -> Iterator[T]:
|
|
154
|
+
"""
|
|
155
|
+
Return an iterator that yields {obj} from the {cls}.
|
|
156
|
+
|
|
157
|
+
Note:
|
|
158
|
+
Synchronous iteration leverages :class:`ASyncIterator`, which uses :meth:`asyncio.BaseEventLoop.run_until_complete` to fetch items.
|
|
159
|
+
:meth:`ASyncIterator.__next__` raises a :class:`~a_sync.exceptions.SyncModeInAsyncContextError` if the event loop is already running.
|
|
160
|
+
|
|
161
|
+
If you encounter a :class:`~a_sync.exceptions.SyncModeInAsyncContextError`, you are likely working in an async codebase
|
|
162
|
+
and should consider asynchronous iteration using :meth:`__aiter__` and :meth:`__anext__` instead.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
class ASyncIterator(_AwaitableAsyncIterableMixin[T], Iterator[T]):
|
|
166
|
+
"""
|
|
167
|
+
A hybrid Iterator/AsyncIterator implementation that bridges the gap between synchronous and asynchronous iteration. This class provides a unified interface for iteration that can seamlessly operate in both synchronous (`for` loop) and asynchronous (`async for` loop) contexts. It allows the wrapping of asynchronous iterable objects or async generator functions, making them usable in synchronous code without explicitly managing event loops or asynchronous context switches.
|
|
168
|
+
|
|
169
|
+
By implementing both `__next__` and `__anext__` methods, ASyncIterator enables objects to be iterated using standard iteration protocols while internally managing the complexities of asynchronous iteration. This design simplifies the use of asynchronous iterables in environments or frameworks that are not inherently asynchronous, such as standard synchronous functions or older codebases being gradually migrated to asynchronous IO.
|
|
170
|
+
|
|
171
|
+
Note:
|
|
172
|
+
Synchronous iteration with `ASyncIterator` uses `asyncio.get_event_loop().run_until_complete`, which can raise a `RuntimeError` if the event loop is already running. In such cases, a :class:`~a_sync.exceptions.SyncModeInAsyncContextError` is raised from the `RuntimeError`, indicating that synchronous iteration is not possible in an already running event loop.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> async_iterator = ASyncIterator(some_async_iterator)
|
|
176
|
+
>>> async for item in async_iterator:
|
|
177
|
+
... print(item)
|
|
178
|
+
>>> for item in async_iterator:
|
|
179
|
+
... print(item)
|
|
180
|
+
|
|
181
|
+
See Also:
|
|
182
|
+
- :class:`ASyncIterable`
|
|
183
|
+
- :class:`ASyncFilter`
|
|
184
|
+
- :class:`ASyncSorter`
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
def __next__(self) -> T:
|
|
188
|
+
"""
|
|
189
|
+
Synchronously fetch the next item from the {cls}.
|
|
190
|
+
|
|
191
|
+
Note:
|
|
192
|
+
This method uses :meth:`asyncio.BaseEventLoop.run_until_complete` to fetch {obj}.
|
|
193
|
+
This raises a :class:`RuntimeError` if the event loop is already running.
|
|
194
|
+
This RuntimeError will be caught and a more descriptive :class:`~a_sync.exceptions.SyncModeInAsyncContextError` will be raised in its place.
|
|
195
|
+
|
|
196
|
+
If you encounter a :class:`~a_sync.exceptions.SyncModeInAsyncContextError`, you are likely working in an async codebase
|
|
197
|
+
and should consider asynchronous iteration using :meth:`__aiter__` and :meth:`__anext__` instead.
|
|
198
|
+
|
|
199
|
+
Raises:
|
|
200
|
+
StopIteration: Once all {obj} have been fetched from the {cls}.
|
|
201
|
+
SyncModeInAsyncContextError: If the event loop is already running.
|
|
202
|
+
|
|
203
|
+
"""
|
|
204
|
+
__wrapped__: AsyncIterator[T]
|
|
205
|
+
def __init__(self, async_iterator: AsyncIterator[T]) -> None:
|
|
206
|
+
"""
|
|
207
|
+
Initializes the ASyncIterator with an async iterator.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
async_iterator: The async iterator to wrap.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
def __anext__(self) -> Coroutine[Any, Any, T]:
|
|
214
|
+
"""
|
|
215
|
+
Asynchronously fetch the next item from the {cls}.
|
|
216
|
+
|
|
217
|
+
Raises:
|
|
218
|
+
:class:`StopAsyncIteration`: Once all {obj} have been fetched from the {cls}.
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
def __iter__(self) -> Self:
|
|
222
|
+
"""
|
|
223
|
+
Return the {cls} for iteration.
|
|
224
|
+
|
|
225
|
+
Note:
|
|
226
|
+
Synchronous iteration uses :meth:`asyncio.BaseEventLoop.run_until_complete` to fetch {obj}.
|
|
227
|
+
This raises a :class:`RuntimeError` if the event loop is already running.
|
|
228
|
+
This RuntimeError will be caught and a more descriptive :class:`~a_sync.exceptions.SyncModeInAsyncContextError` will be raised in its place.
|
|
229
|
+
|
|
230
|
+
If you encounter a :class:`~a_sync.exceptions.SyncModeInAsyncContextError`, you are likely working in an async codebase
|
|
231
|
+
and should consider asynchronous iteration using :meth:`__aiter__` and :meth:`__anext__` instead.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
def __aiter__(self) -> Self:
|
|
235
|
+
"""Return the {cls} for aiteration."""
|
|
236
|
+
|
|
237
|
+
class ASyncGeneratorFunction(Generic[P, T]):
|
|
238
|
+
"""
|
|
239
|
+
Encapsulates an asynchronous generator function, providing a mechanism to use it as an asynchronous iterator with enhanced capabilities. This class wraps an async generator function, allowing it to be called with parameters and return an :class:`~ASyncIterator` object. It is particularly useful for situations where an async generator function needs to be used in a manner that is consistent with both synchronous and asynchronous execution contexts.
|
|
240
|
+
|
|
241
|
+
The ASyncGeneratorFunction class supports dynamic binding to instances, enabling it to be used as a method on class instances. When accessed as a descriptor, it automatically handles the binding to the instance, thereby allowing the wrapped async generator function to be invoked with instance context ('self') automatically provided. This feature is invaluable for designing classes that need to expose asynchronous generators as part of their interface while maintaining the ease of use and calling semantics similar to regular methods.
|
|
242
|
+
|
|
243
|
+
By providing a unified interface to asynchronous generator functions, this class facilitates the creation of APIs that are flexible and easy to use in a wide range of asynchronous programming scenarios. It abstracts away the complexities involved in managing asynchronous generator lifecycles and invocation semantics, making it easier for developers to integrate asynchronous iteration patterns into their applications.
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
>>> async def my_async_gen():
|
|
247
|
+
... yield 1
|
|
248
|
+
... yield 2
|
|
249
|
+
>>> async_gen_func = ASyncGeneratorFunction(my_async_gen)
|
|
250
|
+
>>> for item in async_gen_func():
|
|
251
|
+
... print(item)
|
|
252
|
+
|
|
253
|
+
See Also:
|
|
254
|
+
- :class:`ASyncIterator`
|
|
255
|
+
- :class:`ASyncIterable`
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
__weakself__: weakref.ref[object]
|
|
259
|
+
field_name: str
|
|
260
|
+
__wrapped__: AsyncGenFunc[P, T]
|
|
261
|
+
def __init__(self, async_gen_func: AsyncGenFunc[P, T], instance: Any = None) -> None:
|
|
262
|
+
"""
|
|
263
|
+
Initializes the ASyncGeneratorFunction with the given async generator function and optionally an instance.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
async_gen_func: The async generator function to wrap.
|
|
267
|
+
instance (optional): The object to bind to the function, if applicable.
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> ASyncIterator[T]:
|
|
271
|
+
"""
|
|
272
|
+
Calls the wrapped async generator function with the given arguments and keyword arguments, returning an :class:`ASyncIterator`.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
*args: Positional arguments for the function.
|
|
276
|
+
**kwargs: Keyword arguments for the function.
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
def __get__(self, instance: V, owner: Type[V]) -> ASyncGeneratorFunction[P, T]:
|
|
280
|
+
"""Descriptor method to make the function act like a non-data descriptor."""
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
def __self__(self) -> object: ...
|
|
284
|
+
|
|
285
|
+
class _ASyncView(ASyncIterator[T]):
|
|
286
|
+
"""
|
|
287
|
+
Internal mixin class containing logic for creating specialized views for :class:`~ASyncIterable` objects.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
__aiterator__: Optional[AsyncIterator[T]]
|
|
291
|
+
__iterator__: Optional[Iterator[T]]
|
|
292
|
+
__wrapped__: ViewFn[T]
|
|
293
|
+
def __init__(self, function: ViewFn[T], iterable: AnyIterable[T]) -> None:
|
|
294
|
+
"""
|
|
295
|
+
Initializes the {cls} with a function and an iterable.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
function: A function to apply to the items in the iterable.
|
|
299
|
+
iterable: An iterable or an async iterable yielding objects to which `function` will be applied.
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
@final
|
|
303
|
+
class ASyncFilter(_ASyncView[T]):
|
|
304
|
+
"""
|
|
305
|
+
An async filter class that filters items of an async iterable based on a provided function.
|
|
306
|
+
|
|
307
|
+
This class inherits from :class:`~_ASyncView` and provides the functionality to asynchronously
|
|
308
|
+
iterate over items, applying the filter function to each item to determine if it should be
|
|
309
|
+
included in the result. The filter function can be either synchronous or asynchronous.
|
|
310
|
+
|
|
311
|
+
Example:
|
|
312
|
+
>>> async def is_even(x):
|
|
313
|
+
... return x % 2 == 0
|
|
314
|
+
>>> filtered_iterable = ASyncFilter(is_even, some_async_iterable)
|
|
315
|
+
>>> async for item in filtered_iterable:
|
|
316
|
+
... print(item)
|
|
317
|
+
|
|
318
|
+
See Also:
|
|
319
|
+
- :class:`ASyncIterable`
|
|
320
|
+
- :class:`ASyncIterator`
|
|
321
|
+
- :class:`ASyncSorter`
|
|
322
|
+
"""
|
|
323
|
+
|
|
324
|
+
async def __anext__(self) -> T: ...
|
|
325
|
+
|
|
326
|
+
@final
|
|
327
|
+
class ASyncSorter(_ASyncView[T]):
|
|
328
|
+
"""
|
|
329
|
+
An async sorter class that sorts items of an async iterable based on a provided key function.
|
|
330
|
+
|
|
331
|
+
This class inherits from :class:`~_ASyncView` and provides the functionality to asynchronously
|
|
332
|
+
iterate over items, applying the key function to each item for sorting. The key function can be
|
|
333
|
+
either synchronous or asynchronous. Note that the ASyncSorter instance can only be consumed once.
|
|
334
|
+
|
|
335
|
+
Example:
|
|
336
|
+
>>> sorted_iterable = ASyncSorter(some_async_iterable, key=lambda x: x.value)
|
|
337
|
+
>>> async for item in sorted_iterable:
|
|
338
|
+
... print(item)
|
|
339
|
+
|
|
340
|
+
See Also:
|
|
341
|
+
- :class:`ASyncIterable`
|
|
342
|
+
- :class:`ASyncIterator`
|
|
343
|
+
- :class:`ASyncFilter`
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
reversed: bool
|
|
347
|
+
def __init__(
|
|
348
|
+
self, iterable: AsyncIterable[T], *, key: SortKey[T] = None, reverse: bool = False
|
|
349
|
+
) -> None:
|
|
350
|
+
"""
|
|
351
|
+
Initializes the ASyncSorter with an iterable and an optional sorting configuration (key function, and reverse flag).
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
iterable: The async iterable to sort.
|
|
355
|
+
key (optional): A function of one argument that is used to extract a comparison key from each list element. If none is provided, elements themselves will be sorted. Defaults to None.
|
|
356
|
+
reverse (optional): If True, the list elements will be sorted in reverse order. Defaults to False.
|
|
357
|
+
"""
|
|
358
|
+
|
|
359
|
+
def __aiter__(self) -> AsyncIterator[T]:
|
|
360
|
+
"""
|
|
361
|
+
Return an async iterator for the {cls}.
|
|
362
|
+
|
|
363
|
+
Raises:
|
|
364
|
+
RuntimeError: If the ASyncSorter instance has already been consumed.
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
An async iterator that will yield the sorted {obj}.
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
def __anext__(self) -> T: ...
|