ez-a-sync 0.22.15__py3-none-any.whl → 0.22.16__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.
Potentially problematic release.
This version of ez-a-sync might be problematic. Click here for more details.
- a_sync/ENVIRONMENT_VARIABLES.py +34 -3
- a_sync/__init__.py +32 -9
- a_sync/_smart.py +105 -6
- a_sync/_typing.py +56 -3
- a_sync/a_sync/_descriptor.py +174 -12
- a_sync/a_sync/_flags.py +64 -3
- a_sync/a_sync/_helpers.py +40 -8
- a_sync/a_sync/_kwargs.py +30 -6
- a_sync/a_sync/_meta.py +35 -6
- a_sync/a_sync/abstract.py +57 -9
- a_sync/a_sync/config.py +44 -7
- a_sync/a_sync/decorator.py +217 -37
- a_sync/a_sync/function.py +339 -47
- a_sync/a_sync/method.py +241 -52
- a_sync/a_sync/modifiers/__init__.py +39 -1
- a_sync/a_sync/modifiers/cache/__init__.py +75 -5
- a_sync/a_sync/modifiers/cache/memory.py +50 -6
- a_sync/a_sync/modifiers/limiter.py +55 -6
- a_sync/a_sync/modifiers/manager.py +46 -2
- a_sync/a_sync/modifiers/semaphores.py +84 -11
- a_sync/a_sync/singleton.py +43 -19
- a_sync/asyncio/__init__.py +137 -1
- a_sync/asyncio/as_completed.py +44 -38
- a_sync/asyncio/create_task.py +46 -10
- a_sync/asyncio/gather.py +72 -25
- a_sync/exceptions.py +178 -11
- a_sync/executor.py +51 -3
- a_sync/future.py +671 -29
- a_sync/iter.py +64 -7
- a_sync/primitives/_debug.py +59 -5
- a_sync/primitives/_loggable.py +36 -6
- a_sync/primitives/locks/counter.py +74 -7
- a_sync/primitives/locks/prio_semaphore.py +87 -8
- a_sync/primitives/locks/semaphore.py +68 -20
- a_sync/primitives/queue.py +65 -26
- a_sync/task.py +51 -15
- a_sync/utils/iterators.py +52 -16
- {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/METADATA +1 -1
- ez_a_sync-0.22.16.dist-info/RECORD +74 -0
- {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/WHEEL +1 -1
- tests/executor.py +150 -12
- tests/test_abstract.py +15 -0
- tests/test_base.py +198 -2
- tests/test_executor.py +23 -0
- tests/test_singleton.py +13 -1
- tests/test_task.py +45 -17
- ez_a_sync-0.22.15.dist-info/RECORD +0 -74
- {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/LICENSE.txt +0 -0
- {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/top_level.txt +0 -0
a_sync/a_sync/function.py
CHANGED
|
@@ -30,9 +30,15 @@ class _ModifiedMixin:
|
|
|
30
30
|
`ASyncFunctionAsyncDefault` and `ASyncFunctionSyncDefault`, to handle the application
|
|
31
31
|
of async and sync modifiers to functions. Modifiers can alter the behavior of functions,
|
|
32
32
|
such as converting sync functions to async, applying caching, or rate limiting.
|
|
33
|
+
|
|
34
|
+
See Also:
|
|
35
|
+
- :class:`~ASyncFunction`
|
|
36
|
+
- :class:`~ModifierManager`
|
|
33
37
|
"""
|
|
34
38
|
|
|
39
|
+
# TODO: give me a docstring
|
|
35
40
|
modifiers: ModifierManager
|
|
41
|
+
|
|
36
42
|
__slots__ = "modifiers", "wrapped"
|
|
37
43
|
|
|
38
44
|
def _asyncify(self, func: SyncFn[P, T]) -> CoroFn[P, T]:
|
|
@@ -44,6 +50,10 @@ class _ModifiedMixin:
|
|
|
44
50
|
|
|
45
51
|
Returns:
|
|
46
52
|
The asynchronous version of the function with applied modifiers.
|
|
53
|
+
|
|
54
|
+
See Also:
|
|
55
|
+
- :func:`_helpers._asyncify`
|
|
56
|
+
- :meth:`ModifierManager.apply_async_modifiers`
|
|
47
57
|
"""
|
|
48
58
|
coro_fn = _helpers._asyncify(func, self.modifiers.executor)
|
|
49
59
|
return self.modifiers.apply_async_modifiers(coro_fn)
|
|
@@ -55,6 +65,10 @@ class _ModifiedMixin:
|
|
|
55
65
|
|
|
56
66
|
Returns:
|
|
57
67
|
The modified _await function.
|
|
68
|
+
|
|
69
|
+
See Also:
|
|
70
|
+
- :func:`_helpers._await`
|
|
71
|
+
- :meth:`ModifierManager.apply_sync_modifiers`
|
|
58
72
|
"""
|
|
59
73
|
return self.modifiers.apply_sync_modifiers(_helpers._await)
|
|
60
74
|
|
|
@@ -65,6 +79,9 @@ class _ModifiedMixin:
|
|
|
65
79
|
|
|
66
80
|
Returns:
|
|
67
81
|
The default execution mode.
|
|
82
|
+
|
|
83
|
+
See Also:
|
|
84
|
+
- :attr:`ModifierManager.default`
|
|
68
85
|
"""
|
|
69
86
|
return self.modifiers.default
|
|
70
87
|
|
|
@@ -78,6 +95,9 @@ def _validate_wrapped_fn(fn: Callable) -> None:
|
|
|
78
95
|
Raises:
|
|
79
96
|
TypeError: If the input is not callable.
|
|
80
97
|
RuntimeError: If the function has arguments with names that conflict with viable flags.
|
|
98
|
+
|
|
99
|
+
See Also:
|
|
100
|
+
- :func:`_check_not_genfunc`
|
|
81
101
|
"""
|
|
82
102
|
if isinstance(fn, (AsyncPropertyDescriptor, AsyncCachedPropertyDescriptor)):
|
|
83
103
|
return # These are always valid
|
|
@@ -105,6 +125,11 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
105
125
|
The class supports various modifiers that can alter the behavior of the function,
|
|
106
126
|
such as caching, rate limiting, and execution in specific contexts (e.g., thread pools).
|
|
107
127
|
|
|
128
|
+
Note:
|
|
129
|
+
The logic for determining whether to execute the function synchronously or asynchronously
|
|
130
|
+
is handled by the `_run_sync` method, which checks for flags in the `kwargs` and defers
|
|
131
|
+
to the default execution mode if no flags are specified.
|
|
132
|
+
|
|
108
133
|
Example:
|
|
109
134
|
async def my_coroutine(x: int) -> str:
|
|
110
135
|
return str(x)
|
|
@@ -116,19 +141,45 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
116
141
|
|
|
117
142
|
# Asynchronous call
|
|
118
143
|
result = await func(5) # returns "5"
|
|
144
|
+
|
|
145
|
+
See Also:
|
|
146
|
+
- :class:`_ModifiedMixin`
|
|
147
|
+
- :class:`ModifierManager`
|
|
119
148
|
"""
|
|
120
149
|
|
|
121
150
|
# NOTE: We can't use __slots__ here because it breaks functools.update_wrapper
|
|
122
151
|
|
|
123
152
|
@overload
|
|
124
153
|
def __init__(self, fn: CoroFn[P, T], **modifiers: Unpack[ModifierKwargs]) -> None:
|
|
125
|
-
|
|
126
|
-
|
|
154
|
+
"""
|
|
155
|
+
Initializes an ASyncFunction instance for a coroutine function.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
fn: The coroutine function to wrap.
|
|
159
|
+
**modifiers: Keyword arguments for function modifiers.
|
|
160
|
+
|
|
161
|
+
Example:
|
|
162
|
+
async def my_coroutine(x: int) -> str:
|
|
163
|
+
return str(x)
|
|
164
|
+
|
|
165
|
+
func = ASyncFunction(my_coroutine, cache_type='memory')
|
|
166
|
+
"""
|
|
127
167
|
|
|
128
168
|
@overload
|
|
129
169
|
def __init__(self, fn: SyncFn[P, T], **modifiers: Unpack[ModifierKwargs]) -> None:
|
|
130
|
-
|
|
131
|
-
|
|
170
|
+
"""
|
|
171
|
+
Initializes an ASyncFunction instance for a synchronous function.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
fn: The synchronous function to wrap.
|
|
175
|
+
**modifiers: Keyword arguments for function modifiers.
|
|
176
|
+
|
|
177
|
+
Example:
|
|
178
|
+
def my_function(x: int) -> str:
|
|
179
|
+
return str(x)
|
|
180
|
+
|
|
181
|
+
func = ASyncFunction(my_function, runs_per_minute=60)
|
|
182
|
+
"""
|
|
132
183
|
|
|
133
184
|
def __init__(self, fn: AnyFn[P, T], **modifiers: Unpack[ModifierKwargs]) -> None:
|
|
134
185
|
"""
|
|
@@ -137,6 +188,10 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
137
188
|
Args:
|
|
138
189
|
fn: The function to wrap.
|
|
139
190
|
**modifiers: Keyword arguments for function modifiers.
|
|
191
|
+
|
|
192
|
+
See Also:
|
|
193
|
+
- :func:`_validate_wrapped_fn`
|
|
194
|
+
- :class:`ModifierManager`
|
|
140
195
|
"""
|
|
141
196
|
_validate_wrapped_fn(fn)
|
|
142
197
|
|
|
@@ -156,34 +211,78 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
156
211
|
|
|
157
212
|
@overload
|
|
158
213
|
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T:
|
|
159
|
-
|
|
160
|
-
|
|
214
|
+
"""
|
|
215
|
+
Calls the wrapped function synchronously.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
*args: Positional arguments to pass to the wrapped function.
|
|
219
|
+
sync: Must be True to indicate synchronous execution.
|
|
220
|
+
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
221
|
+
|
|
222
|
+
Example:
|
|
223
|
+
result = func(5, sync=True)
|
|
224
|
+
"""
|
|
161
225
|
|
|
162
226
|
@overload
|
|
163
227
|
def __call__(
|
|
164
228
|
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
165
229
|
) -> Coroutine[Any, Any, T]:
|
|
166
|
-
|
|
167
|
-
|
|
230
|
+
"""
|
|
231
|
+
Calls the wrapped function asynchronously.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
*args: Positional arguments to pass to the wrapped function.
|
|
235
|
+
sync: Must be False to indicate asynchronous execution.
|
|
236
|
+
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
result = await func(5, sync=False)
|
|
240
|
+
"""
|
|
168
241
|
|
|
169
242
|
@overload
|
|
170
243
|
def __call__(
|
|
171
244
|
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
172
245
|
) -> T:
|
|
173
|
-
|
|
174
|
-
|
|
246
|
+
"""
|
|
247
|
+
Calls the wrapped function synchronously.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
*args: Positional arguments to pass to the wrapped function.
|
|
251
|
+
asynchronous: Must be False to indicate synchronous execution.
|
|
252
|
+
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
253
|
+
|
|
254
|
+
Example:
|
|
255
|
+
result = func(5, asynchronous=False)
|
|
256
|
+
"""
|
|
175
257
|
|
|
176
258
|
@overload
|
|
177
259
|
def __call__(
|
|
178
260
|
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
179
261
|
) -> Coroutine[Any, Any, T]:
|
|
180
|
-
|
|
181
|
-
|
|
262
|
+
"""
|
|
263
|
+
Calls the wrapped function asynchronously.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
*args: Positional arguments to pass to the wrapped function.
|
|
267
|
+
asynchronous: Must be True to indicate asynchronous execution.
|
|
268
|
+
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
269
|
+
|
|
270
|
+
Example:
|
|
271
|
+
result = await func(5, asynchronous=True)
|
|
272
|
+
"""
|
|
182
273
|
|
|
183
274
|
@overload
|
|
184
275
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]:
|
|
185
|
-
|
|
186
|
-
|
|
276
|
+
"""
|
|
277
|
+
Calls the wrapped function using the default execution mode.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
*args: Positional arguments to pass to the wrapped function.
|
|
281
|
+
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
282
|
+
|
|
283
|
+
Example:
|
|
284
|
+
result = func(5)
|
|
285
|
+
"""
|
|
187
286
|
|
|
188
287
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]:
|
|
189
288
|
"""
|
|
@@ -192,12 +291,21 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
192
291
|
This method determines whether to execute the wrapped function synchronously
|
|
193
292
|
or asynchronously based on the default mode and any provided flags.
|
|
194
293
|
|
|
294
|
+
Note:
|
|
295
|
+
The logic for determining the execution mode is handled by the
|
|
296
|
+
:meth:`_run_sync` method, which checks for flags in the kwargs and
|
|
297
|
+
defers to the default execution mode if no flags are specified.
|
|
298
|
+
|
|
195
299
|
Args:
|
|
196
300
|
*args: Positional arguments to pass to the wrapped function.
|
|
197
301
|
**kwargs: Keyword arguments to pass to the wrapped function.
|
|
198
302
|
|
|
199
303
|
Raises:
|
|
200
304
|
Exception: Any exception that may be raised by the wrapped function.
|
|
305
|
+
|
|
306
|
+
See Also:
|
|
307
|
+
- :attr:`default`
|
|
308
|
+
- :meth:`_run_sync`
|
|
201
309
|
"""
|
|
202
310
|
logger.debug(
|
|
203
311
|
"calling %s fn: %s with args: %s kwargs: %s", self, self.fn, args, kwargs
|
|
@@ -208,14 +316,18 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
208
316
|
return f"<{self.__class__.__name__} {self.__module__}.{self.__name__} at {hex(id(self))}>"
|
|
209
317
|
|
|
210
318
|
@functools.cached_property
|
|
211
|
-
def fn(
|
|
212
|
-
|
|
213
|
-
|
|
319
|
+
def fn(self):
|
|
320
|
+
# NOTE type hint doesnt work in py3.8 or py3.9, debug later
|
|
321
|
+
# -> Union[SyncFn[[CoroFn[P, T]], MaybeAwaitable[T]], SyncFn[[SyncFn[P, T]], MaybeAwaitable[T]]]:
|
|
214
322
|
"""
|
|
215
323
|
Returns the final wrapped version of :attr:`ASyncFunction._fn` decorated with all of the a_sync goodness.
|
|
216
324
|
|
|
217
325
|
Returns:
|
|
218
326
|
The final wrapped function.
|
|
327
|
+
|
|
328
|
+
See Also:
|
|
329
|
+
- :meth:`_async_wrap`
|
|
330
|
+
- :meth:`_sync_wrap`
|
|
219
331
|
"""
|
|
220
332
|
return self._async_wrap if self._async_def else self._sync_wrap
|
|
221
333
|
|
|
@@ -239,6 +351,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
239
351
|
|
|
240
352
|
Returns:
|
|
241
353
|
A TaskMapping object for managing concurrent execution.
|
|
354
|
+
|
|
355
|
+
See Also:
|
|
356
|
+
- :class:`TaskMapping`
|
|
242
357
|
"""
|
|
243
358
|
from a_sync import TaskMapping
|
|
244
359
|
|
|
@@ -268,6 +383,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
268
383
|
|
|
269
384
|
Returns:
|
|
270
385
|
True if any result is truthy, otherwise False.
|
|
386
|
+
|
|
387
|
+
See Also:
|
|
388
|
+
- :meth:`map`
|
|
271
389
|
"""
|
|
272
390
|
return await self.map(
|
|
273
391
|
*iterables,
|
|
@@ -294,6 +412,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
294
412
|
|
|
295
413
|
Returns:
|
|
296
414
|
True if all results are truthy, otherwise False.
|
|
415
|
+
|
|
416
|
+
See Also:
|
|
417
|
+
- :meth:`map`
|
|
297
418
|
"""
|
|
298
419
|
return await self.map(
|
|
299
420
|
*iterables,
|
|
@@ -320,6 +441,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
320
441
|
|
|
321
442
|
Returns:
|
|
322
443
|
The minimum result.
|
|
444
|
+
|
|
445
|
+
See Also:
|
|
446
|
+
- :meth:`map`
|
|
323
447
|
"""
|
|
324
448
|
return await self.map(
|
|
325
449
|
*iterables,
|
|
@@ -346,6 +470,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
346
470
|
|
|
347
471
|
Returns:
|
|
348
472
|
The maximum result.
|
|
473
|
+
|
|
474
|
+
See Also:
|
|
475
|
+
- :meth:`map`
|
|
349
476
|
"""
|
|
350
477
|
return await self.map(
|
|
351
478
|
*iterables,
|
|
@@ -372,6 +499,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
372
499
|
|
|
373
500
|
Returns:
|
|
374
501
|
The sum of the results.
|
|
502
|
+
|
|
503
|
+
See Also:
|
|
504
|
+
- :meth:`map`
|
|
375
505
|
"""
|
|
376
506
|
return await self.map(
|
|
377
507
|
*iterables,
|
|
@@ -400,6 +530,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
400
530
|
|
|
401
531
|
Returns:
|
|
402
532
|
A TaskMapping object for managing concurrent execution.
|
|
533
|
+
|
|
534
|
+
See Also:
|
|
535
|
+
- :class:`TaskMapping`
|
|
403
536
|
"""
|
|
404
537
|
from a_sync import TaskMapping
|
|
405
538
|
|
|
@@ -429,6 +562,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
429
562
|
|
|
430
563
|
Returns:
|
|
431
564
|
True if any result is truthy, otherwise False.
|
|
565
|
+
|
|
566
|
+
See Also:
|
|
567
|
+
- :meth:`map`
|
|
432
568
|
"""
|
|
433
569
|
return await self.map(
|
|
434
570
|
*iterables,
|
|
@@ -455,6 +591,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
455
591
|
|
|
456
592
|
Returns:
|
|
457
593
|
True if all results are truthy, otherwise False.
|
|
594
|
+
|
|
595
|
+
See Also:
|
|
596
|
+
- :meth:`map`
|
|
458
597
|
"""
|
|
459
598
|
return await self.map(
|
|
460
599
|
*iterables,
|
|
@@ -481,6 +620,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
481
620
|
|
|
482
621
|
Returns:
|
|
483
622
|
The minimum result.
|
|
623
|
+
|
|
624
|
+
See Also:
|
|
625
|
+
- :meth:`map`
|
|
484
626
|
"""
|
|
485
627
|
return await self.map(
|
|
486
628
|
*iterables,
|
|
@@ -507,6 +649,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
507
649
|
|
|
508
650
|
Returns:
|
|
509
651
|
The maximum result.
|
|
652
|
+
|
|
653
|
+
See Also:
|
|
654
|
+
- :meth:`map`
|
|
510
655
|
"""
|
|
511
656
|
return await self.map(
|
|
512
657
|
*iterables,
|
|
@@ -533,6 +678,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
533
678
|
|
|
534
679
|
Returns:
|
|
535
680
|
The sum of the results.
|
|
681
|
+
|
|
682
|
+
See Also:
|
|
683
|
+
- :meth:`map`
|
|
536
684
|
"""
|
|
537
685
|
return await self.map(
|
|
538
686
|
*iterables,
|
|
@@ -551,6 +699,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
551
699
|
|
|
552
700
|
Returns:
|
|
553
701
|
True if the default is sync, False if async.
|
|
702
|
+
|
|
703
|
+
See Also:
|
|
704
|
+
- :attr:`default`
|
|
554
705
|
"""
|
|
555
706
|
return (
|
|
556
707
|
True
|
|
@@ -565,6 +716,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
565
716
|
|
|
566
717
|
Returns:
|
|
567
718
|
True if the function is asynchronous, otherwise False.
|
|
719
|
+
|
|
720
|
+
See Also:
|
|
721
|
+
- :func:`asyncio.iscoroutinefunction`
|
|
568
722
|
"""
|
|
569
723
|
return asyncio.iscoroutinefunction(self.__wrapped__)
|
|
570
724
|
|
|
@@ -580,6 +734,10 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
580
734
|
|
|
581
735
|
Returns:
|
|
582
736
|
True if the function should run synchronously, otherwise False.
|
|
737
|
+
|
|
738
|
+
See Also:
|
|
739
|
+
- :func:`_kwargs.get_flag_name`
|
|
740
|
+
- :func:`_kwargs.is_sync`
|
|
583
741
|
"""
|
|
584
742
|
if flag := _kwargs.get_flag_name(kwargs):
|
|
585
743
|
# If a flag was specified in the kwargs, we will defer to it.
|
|
@@ -598,6 +756,9 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
598
756
|
|
|
599
757
|
Returns:
|
|
600
758
|
The asynchronous version of the wrapped function.
|
|
759
|
+
|
|
760
|
+
See Also:
|
|
761
|
+
- :meth:`_asyncify`
|
|
601
762
|
"""
|
|
602
763
|
if self._async_def:
|
|
603
764
|
raise TypeError(
|
|
@@ -615,6 +776,10 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
615
776
|
|
|
616
777
|
Returns:
|
|
617
778
|
The modified function.
|
|
779
|
+
|
|
780
|
+
See Also:
|
|
781
|
+
- :meth:`ModifierManager.apply_async_modifiers`
|
|
782
|
+
- :meth:`ModifierManager.apply_sync_modifiers`
|
|
618
783
|
"""
|
|
619
784
|
if self._async_def:
|
|
620
785
|
return self.modifiers.apply_async_modifiers(self.__wrapped__) # type: ignore [arg-type]
|
|
@@ -629,6 +794,10 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
629
794
|
|
|
630
795
|
Returns:
|
|
631
796
|
The wrapped function with async handling.
|
|
797
|
+
|
|
798
|
+
See Also:
|
|
799
|
+
- :meth:`_run_sync`
|
|
800
|
+
- :meth:`_await`
|
|
632
801
|
"""
|
|
633
802
|
|
|
634
803
|
@functools.wraps(self._modified_fn)
|
|
@@ -650,6 +819,10 @@ class ASyncFunction(_ModifiedMixin, Generic[P, T]):
|
|
|
650
819
|
|
|
651
820
|
Returns:
|
|
652
821
|
The wrapped function with sync handling.
|
|
822
|
+
|
|
823
|
+
See Also:
|
|
824
|
+
- :meth:`_run_sync`
|
|
825
|
+
- :meth:`_asyncified`
|
|
653
826
|
"""
|
|
654
827
|
|
|
655
828
|
@functools.wraps(self._modified_fn)
|
|
@@ -679,6 +852,9 @@ class ASyncDecorator(_ModifiedMixin):
|
|
|
679
852
|
|
|
680
853
|
Raises:
|
|
681
854
|
ValueError: If 'default' is not 'sync', 'async', or None.
|
|
855
|
+
|
|
856
|
+
See Also:
|
|
857
|
+
- :class:`ModifierManager`
|
|
682
858
|
"""
|
|
683
859
|
assert "default" in modifiers, modifiers
|
|
684
860
|
self.modifiers = ModifierManager(modifiers)
|
|
@@ -690,6 +866,9 @@ class ASyncDecorator(_ModifiedMixin):
|
|
|
690
866
|
|
|
691
867
|
Raises:
|
|
692
868
|
ValueError: If 'default' is not 'sync', 'async', or None.
|
|
869
|
+
|
|
870
|
+
See Also:
|
|
871
|
+
- :attr:`ModifierManager.default`
|
|
693
872
|
"""
|
|
694
873
|
if self.modifiers.default not in ["sync", "async", None]:
|
|
695
874
|
raise ValueError(
|
|
@@ -698,11 +877,33 @@ class ASyncDecorator(_ModifiedMixin):
|
|
|
698
877
|
|
|
699
878
|
@overload
|
|
700
879
|
def __call__(self, func: AnyFn[Concatenate[B, P], T]) -> "ASyncBoundMethod[B, P, T]": # type: ignore [override]
|
|
701
|
-
|
|
880
|
+
"""
|
|
881
|
+
Decorates a bound method with async or sync behavior based on the default modifier.
|
|
882
|
+
|
|
883
|
+
Args:
|
|
884
|
+
func: The bound method to decorate.
|
|
885
|
+
|
|
886
|
+
Returns:
|
|
887
|
+
An ASyncBoundMethod instance with the appropriate default behavior.
|
|
888
|
+
|
|
889
|
+
See Also:
|
|
890
|
+
- :class:`ASyncBoundMethod`
|
|
891
|
+
"""
|
|
702
892
|
|
|
703
893
|
@overload
|
|
704
894
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunction[P, T]: # type: ignore [override]
|
|
705
|
-
|
|
895
|
+
"""
|
|
896
|
+
Decorates a function with async or sync behavior based on the default modifier.
|
|
897
|
+
|
|
898
|
+
Args:
|
|
899
|
+
func: The function to decorate.
|
|
900
|
+
|
|
901
|
+
Returns:
|
|
902
|
+
An ASyncFunction instance with the appropriate default behavior.
|
|
903
|
+
|
|
904
|
+
See Also:
|
|
905
|
+
- :class:`ASyncFunction`
|
|
906
|
+
"""
|
|
706
907
|
|
|
707
908
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunction[P, T]: # type: ignore [override]
|
|
708
909
|
"""
|
|
@@ -713,6 +914,9 @@ class ASyncDecorator(_ModifiedMixin):
|
|
|
713
914
|
|
|
714
915
|
Returns:
|
|
715
916
|
An ASyncFunction instance with the appropriate default behavior.
|
|
917
|
+
|
|
918
|
+
See Also:
|
|
919
|
+
- :class:`ASyncFunction`
|
|
716
920
|
"""
|
|
717
921
|
if self.default == "async":
|
|
718
922
|
return ASyncFunctionAsyncDefault(func, **self.modifiers)
|
|
@@ -732,6 +936,10 @@ def _check_not_genfunc(func: Callable) -> None:
|
|
|
732
936
|
|
|
733
937
|
Raises:
|
|
734
938
|
ValueError: If the function is a generator or async generator.
|
|
939
|
+
|
|
940
|
+
See Also:
|
|
941
|
+
- :func:`inspect.isasyncgenfunction`
|
|
942
|
+
- :func:`inspect.isgeneratorfunction`
|
|
735
943
|
"""
|
|
736
944
|
if inspect.isasyncgenfunction(func) or inspect.isgeneratorfunction(func):
|
|
737
945
|
raise ValueError("unable to decorate generator functions with this decorator")
|
|
@@ -763,25 +971,36 @@ class ASyncFunctionSyncDefault(ASyncFunction[P, T]):
|
|
|
763
971
|
"""
|
|
764
972
|
|
|
765
973
|
@overload
|
|
766
|
-
def __call__(
|
|
767
|
-
|
|
768
|
-
|
|
974
|
+
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T:
|
|
975
|
+
# TODO write specific docs for this overload
|
|
976
|
+
...
|
|
977
|
+
|
|
769
978
|
@overload
|
|
770
979
|
def __call__(
|
|
771
980
|
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
772
|
-
) -> Coroutine[Any, Any, T]:
|
|
981
|
+
) -> Coroutine[Any, Any, T]:
|
|
982
|
+
# TODO write specific docs for this overload
|
|
983
|
+
...
|
|
984
|
+
|
|
773
985
|
@overload
|
|
774
986
|
def __call__(
|
|
775
987
|
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
776
|
-
) -> T:
|
|
988
|
+
) -> T:
|
|
989
|
+
# TODO write specific docs for this overload
|
|
990
|
+
...
|
|
991
|
+
|
|
777
992
|
@overload
|
|
778
993
|
def __call__(
|
|
779
994
|
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
780
|
-
) -> Coroutine[Any, Any, T]:
|
|
995
|
+
) -> Coroutine[Any, Any, T]:
|
|
996
|
+
# TODO write specific docs for this overload
|
|
997
|
+
...
|
|
998
|
+
|
|
781
999
|
@overload
|
|
782
|
-
def __call__(
|
|
783
|
-
|
|
784
|
-
|
|
1000
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T:
|
|
1001
|
+
# TODO write specific docs for this overload
|
|
1002
|
+
...
|
|
1003
|
+
|
|
785
1004
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]:
|
|
786
1005
|
"""Calls the wrapped function, defaulting to synchronous execution.
|
|
787
1006
|
|
|
@@ -797,6 +1016,9 @@ class ASyncFunctionSyncDefault(ASyncFunction[P, T]):
|
|
|
797
1016
|
|
|
798
1017
|
Returns:
|
|
799
1018
|
The result of the function call.
|
|
1019
|
+
|
|
1020
|
+
See Also:
|
|
1021
|
+
- :meth:`ASyncFunction.__call__`
|
|
800
1022
|
"""
|
|
801
1023
|
return self.fn(*args, **kwargs)
|
|
802
1024
|
|
|
@@ -827,31 +1049,33 @@ class ASyncFunctionAsyncDefault(ASyncFunction[P, T]):
|
|
|
827
1049
|
"""
|
|
828
1050
|
|
|
829
1051
|
@overload
|
|
830
|
-
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T:
|
|
1052
|
+
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T:
|
|
1053
|
+
# TODO write specific docs for this overload
|
|
1054
|
+
...
|
|
831
1055
|
|
|
832
|
-
# TODO write specific docs for this overload
|
|
833
1056
|
@overload
|
|
834
1057
|
def __call__(
|
|
835
1058
|
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
836
|
-
) -> Coroutine[Any, Any, T]:
|
|
1059
|
+
) -> Coroutine[Any, Any, T]:
|
|
1060
|
+
# TODO write specific docs for this overload
|
|
1061
|
+
...
|
|
837
1062
|
|
|
838
|
-
# TODO write specific docs for this overload
|
|
839
1063
|
@overload
|
|
840
1064
|
def __call__(
|
|
841
1065
|
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
842
|
-
) -> T:
|
|
1066
|
+
) -> T:
|
|
1067
|
+
# TODO write specific docs for this overload
|
|
1068
|
+
...
|
|
843
1069
|
|
|
844
|
-
# TODO write specific docs for this overload
|
|
845
1070
|
@overload
|
|
846
1071
|
def __call__(
|
|
847
1072
|
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
848
|
-
) -> Coroutine[Any, Any, T]:
|
|
1073
|
+
) -> Coroutine[Any, Any, T]:
|
|
1074
|
+
# TODO write specific docs for this overload
|
|
1075
|
+
...
|
|
849
1076
|
|
|
850
|
-
# TODO write specific docs for this overload
|
|
851
1077
|
@overload
|
|
852
1078
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, T]: ...
|
|
853
|
-
|
|
854
|
-
# TODO write specific docs for this overload
|
|
855
1079
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]:
|
|
856
1080
|
"""Calls the wrapped function, defaulting to asynchronous execution.
|
|
857
1081
|
|
|
@@ -867,6 +1091,9 @@ class ASyncFunctionAsyncDefault(ASyncFunction[P, T]):
|
|
|
867
1091
|
|
|
868
1092
|
Returns:
|
|
869
1093
|
The result of the function call.
|
|
1094
|
+
|
|
1095
|
+
See Also:
|
|
1096
|
+
- :meth:`ASyncFunction.__call__`
|
|
870
1097
|
"""
|
|
871
1098
|
return self.fn(*args, **kwargs)
|
|
872
1099
|
|
|
@@ -876,35 +1103,100 @@ class ASyncFunctionAsyncDefault(ASyncFunction[P, T]):
|
|
|
876
1103
|
class ASyncDecoratorSyncDefault(ASyncDecorator):
|
|
877
1104
|
@overload
|
|
878
1105
|
def __call__(self, func: AnyFn[Concatenate[B, P], T]) -> "ASyncBoundMethodSyncDefault[P, T]": # type: ignore [override]
|
|
879
|
-
|
|
880
|
-
|
|
1106
|
+
"""
|
|
1107
|
+
Decorates a bound method with synchronous default behavior.
|
|
1108
|
+
|
|
1109
|
+
Args:
|
|
1110
|
+
func: The bound method to decorate.
|
|
1111
|
+
|
|
1112
|
+
Returns:
|
|
1113
|
+
An ASyncBoundMethodSyncDefault instance with synchronous default behavior.
|
|
1114
|
+
|
|
1115
|
+
See Also:
|
|
1116
|
+
- :class:`ASyncBoundMethodSyncDefault`
|
|
1117
|
+
"""
|
|
881
1118
|
|
|
882
1119
|
@overload
|
|
883
1120
|
def __call__(self, func: AnyBoundMethod[P, T]) -> ASyncFunctionSyncDefault[P, T]: # type: ignore [override]
|
|
884
|
-
|
|
1121
|
+
"""
|
|
1122
|
+
Decorates a bound method with synchronous default behavior.
|
|
1123
|
+
|
|
1124
|
+
Args:
|
|
1125
|
+
func: The bound method to decorate.
|
|
1126
|
+
|
|
1127
|
+
Returns:
|
|
1128
|
+
An ASyncFunctionSyncDefault instance with synchronous default behavior.
|
|
1129
|
+
|
|
1130
|
+
See Also:
|
|
1131
|
+
- :class:`ASyncFunctionSyncDefault`
|
|
1132
|
+
"""
|
|
885
1133
|
|
|
886
1134
|
@overload
|
|
887
1135
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunctionSyncDefault[P, T]: # type: ignore [override]
|
|
888
|
-
|
|
1136
|
+
"""
|
|
1137
|
+
Decorates a function with synchronous default behavior.
|
|
1138
|
+
|
|
1139
|
+
Args:
|
|
1140
|
+
func: The function to decorate.
|
|
1141
|
+
|
|
1142
|
+
Returns:
|
|
1143
|
+
An ASyncFunctionSyncDefault instance with synchronous default behavior.
|
|
1144
|
+
|
|
1145
|
+
See Also:
|
|
1146
|
+
- :class:`ASyncFunctionSyncDefault`
|
|
1147
|
+
"""
|
|
889
1148
|
|
|
890
1149
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunctionSyncDefault[P, T]:
|
|
891
|
-
|
|
1150
|
+
# TODO write specific docs for this implementation
|
|
892
1151
|
return ASyncFunctionSyncDefault(func, **self.modifiers)
|
|
893
1152
|
|
|
894
1153
|
|
|
895
1154
|
class ASyncDecoratorAsyncDefault(ASyncDecorator):
|
|
896
1155
|
@overload
|
|
897
1156
|
def __call__(self, func: AnyFn[Concatenate[B, P], T]) -> "ASyncBoundMethodAsyncDefault[P, T]": # type: ignore [override]
|
|
898
|
-
|
|
1157
|
+
"""
|
|
1158
|
+
Decorates a bound method with asynchronous default behavior.
|
|
1159
|
+
|
|
1160
|
+
Args:
|
|
1161
|
+
func: The bound method to decorate.
|
|
1162
|
+
|
|
1163
|
+
Returns:
|
|
1164
|
+
An ASyncBoundMethodAsyncDefault instance with asynchronous default behavior.
|
|
1165
|
+
|
|
1166
|
+
See Also:
|
|
1167
|
+
- :class:`ASyncBoundMethodAsyncDefault`
|
|
1168
|
+
"""
|
|
899
1169
|
|
|
900
1170
|
@overload
|
|
901
1171
|
def __call__(self, func: AnyBoundMethod[P, T]) -> ASyncFunctionAsyncDefault[P, T]: # type: ignore [override]
|
|
902
|
-
|
|
1172
|
+
"""
|
|
1173
|
+
Decorates a bound method with asynchronous default behavior.
|
|
1174
|
+
|
|
1175
|
+
Args:
|
|
1176
|
+
func: The bound method to decorate.
|
|
1177
|
+
|
|
1178
|
+
Returns:
|
|
1179
|
+
An ASyncFunctionAsyncDefault instance with asynchronous default behavior.
|
|
1180
|
+
|
|
1181
|
+
See Also:
|
|
1182
|
+
- :class:`ASyncFunctionAsyncDefault`
|
|
1183
|
+
"""
|
|
903
1184
|
|
|
904
1185
|
@overload
|
|
905
1186
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunctionAsyncDefault[P, T]: # type: ignore [override]
|
|
906
|
-
|
|
1187
|
+
"""
|
|
1188
|
+
Decorates a function with asynchronous default behavior.
|
|
1189
|
+
|
|
1190
|
+
Args:
|
|
1191
|
+
func: The function to decorate.
|
|
1192
|
+
|
|
1193
|
+
Returns:
|
|
1194
|
+
An ASyncFunctionAsyncDefault instance with asynchronous default behavior.
|
|
1195
|
+
|
|
1196
|
+
See Also:
|
|
1197
|
+
- :class:`ASyncFunctionAsyncDefault`
|
|
1198
|
+
"""
|
|
907
1199
|
|
|
908
1200
|
def __call__(self, func: AnyFn[P, T]) -> ASyncFunctionAsyncDefault[P, T]:
|
|
909
|
-
# TODO write specific docs for this
|
|
1201
|
+
# TODO write specific docs for this implementation
|
|
910
1202
|
return ASyncFunctionAsyncDefault(func, **self.modifiers)
|