ez-a-sync 0.22.14__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 +37 -5
- a_sync/__init__.py +53 -12
- a_sync/_smart.py +231 -28
- a_sync/_typing.py +112 -15
- a_sync/a_sync/__init__.py +35 -10
- a_sync/a_sync/_descriptor.py +248 -38
- a_sync/a_sync/_flags.py +78 -9
- a_sync/a_sync/_helpers.py +46 -13
- a_sync/a_sync/_kwargs.py +33 -8
- a_sync/a_sync/_meta.py +149 -28
- a_sync/a_sync/abstract.py +150 -28
- a_sync/a_sync/base.py +34 -16
- a_sync/a_sync/config.py +85 -14
- a_sync/a_sync/decorator.py +441 -139
- a_sync/a_sync/function.py +709 -147
- a_sync/a_sync/method.py +437 -110
- a_sync/a_sync/modifiers/__init__.py +85 -5
- a_sync/a_sync/modifiers/cache/__init__.py +116 -17
- a_sync/a_sync/modifiers/cache/memory.py +130 -20
- a_sync/a_sync/modifiers/limiter.py +101 -22
- a_sync/a_sync/modifiers/manager.py +142 -16
- a_sync/a_sync/modifiers/semaphores.py +121 -15
- a_sync/a_sync/property.py +383 -82
- a_sync/a_sync/singleton.py +44 -19
- a_sync/aliases.py +0 -1
- a_sync/asyncio/__init__.py +140 -1
- a_sync/asyncio/as_completed.py +213 -79
- a_sync/asyncio/create_task.py +70 -20
- a_sync/asyncio/gather.py +125 -58
- a_sync/asyncio/utils.py +3 -3
- a_sync/exceptions.py +248 -26
- a_sync/executor.py +164 -69
- a_sync/future.py +1227 -168
- a_sync/iter.py +173 -56
- a_sync/primitives/__init__.py +14 -2
- a_sync/primitives/_debug.py +72 -18
- a_sync/primitives/_loggable.py +41 -10
- a_sync/primitives/locks/__init__.py +5 -2
- a_sync/primitives/locks/counter.py +107 -38
- a_sync/primitives/locks/event.py +21 -7
- a_sync/primitives/locks/prio_semaphore.py +262 -63
- a_sync/primitives/locks/semaphore.py +138 -89
- a_sync/primitives/queue.py +601 -60
- a_sync/sphinx/__init__.py +0 -1
- a_sync/sphinx/ext.py +160 -50
- a_sync/task.py +313 -112
- a_sync/utils/__init__.py +12 -6
- a_sync/utils/iterators.py +170 -50
- {ez_a_sync-0.22.14.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.14.dist-info → ez_a_sync-0.22.16.dist-info}/WHEEL +1 -1
- tests/conftest.py +1 -2
- tests/executor.py +250 -9
- tests/fixtures.py +61 -32
- tests/test_abstract.py +22 -4
- tests/test_as_completed.py +54 -21
- tests/test_base.py +264 -19
- tests/test_cache.py +31 -15
- tests/test_decorator.py +54 -28
- tests/test_executor.py +31 -13
- tests/test_future.py +45 -8
- tests/test_gather.py +8 -2
- tests/test_helpers.py +2 -0
- tests/test_iter.py +55 -13
- tests/test_limiter.py +5 -3
- tests/test_meta.py +23 -9
- tests/test_modified.py +4 -1
- tests/test_semaphore.py +15 -8
- tests/test_singleton.py +28 -11
- tests/test_task.py +162 -36
- ez_a_sync-0.22.14.dist-info/RECORD +0 -74
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/LICENSE.txt +0 -0
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/top_level.txt +0 -0
a_sync/a_sync/method.py
CHANGED
|
@@ -16,7 +16,11 @@ from inspect import isawaitable
|
|
|
16
16
|
from a_sync._typing import *
|
|
17
17
|
from a_sync.a_sync import _helpers, _kwargs
|
|
18
18
|
from a_sync.a_sync._descriptor import ASyncDescriptor
|
|
19
|
-
from a_sync.a_sync.function import
|
|
19
|
+
from a_sync.a_sync.function import (
|
|
20
|
+
ASyncFunction,
|
|
21
|
+
ASyncFunctionAsyncDefault,
|
|
22
|
+
ASyncFunctionSyncDefault,
|
|
23
|
+
)
|
|
20
24
|
|
|
21
25
|
if TYPE_CHECKING:
|
|
22
26
|
from a_sync import TaskMapping
|
|
@@ -24,10 +28,37 @@ if TYPE_CHECKING:
|
|
|
24
28
|
|
|
25
29
|
logger = logging.getLogger(__name__)
|
|
26
30
|
|
|
31
|
+
|
|
27
32
|
class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
28
33
|
"""
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
A descriptor for managing methods that can be called both synchronously and asynchronously.
|
|
35
|
+
|
|
36
|
+
This class provides the core functionality for binding methods to instances and determining
|
|
37
|
+
the execution mode ("sync" or "async") based on various conditions, such as the instance type,
|
|
38
|
+
the method's default setting, or specific flags passed during the method call.
|
|
39
|
+
|
|
40
|
+
The descriptor is responsible for creating an appropriate bound method when accessed,
|
|
41
|
+
which is the actual object that can be called in both synchronous and asynchronous contexts.
|
|
42
|
+
It can create different types of bound methods (`ASyncBoundMethodSyncDefault`,
|
|
43
|
+
`ASyncBoundMethodAsyncDefault`, or `ASyncBoundMethod`) based on the default mode or instance type.
|
|
44
|
+
|
|
45
|
+
It also manages cache handles for bound methods and prevents setting or deleting the descriptor.
|
|
46
|
+
|
|
47
|
+
Examples:
|
|
48
|
+
>>> class MyClass:
|
|
49
|
+
... @ASyncMethodDescriptor
|
|
50
|
+
... async def my_method(self):
|
|
51
|
+
... return "Hello, World!"
|
|
52
|
+
...
|
|
53
|
+
>>> obj = MyClass()
|
|
54
|
+
>>> await obj.my_method()
|
|
55
|
+
'Hello, World!'
|
|
56
|
+
>>> obj.my_method(sync=True)
|
|
57
|
+
'Hello, World!'
|
|
58
|
+
|
|
59
|
+
See Also:
|
|
60
|
+
- :class:`ASyncBoundMethod`
|
|
61
|
+
- :class:`ASyncFunction`
|
|
31
62
|
"""
|
|
32
63
|
|
|
33
64
|
__wrapped__: AnyFn[P, T]
|
|
@@ -42,18 +73,27 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
42
73
|
*args: Positional arguments.
|
|
43
74
|
**kwargs: Keyword arguments.
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
Examples:
|
|
77
|
+
>>> descriptor = ASyncMethodDescriptor(my_async_function)
|
|
78
|
+
>>> await descriptor(instance, arg1, arg2, kwarg1=value1)
|
|
47
79
|
"""
|
|
48
80
|
# NOTE: This is only used by TaskMapping atm # TODO: use it elsewhere
|
|
49
|
-
logger.debug(
|
|
81
|
+
logger.debug(
|
|
82
|
+
"awaiting %s for instance: %s args: %s kwargs: %s",
|
|
83
|
+
self,
|
|
84
|
+
instance,
|
|
85
|
+
args,
|
|
86
|
+
kwargs,
|
|
87
|
+
)
|
|
50
88
|
return await self.__get__(instance, None)(*args, **kwargs)
|
|
51
89
|
|
|
52
90
|
@overload
|
|
53
|
-
def __get__(self, instance: None, owner: Type[I]) -> Self
|
|
91
|
+
def __get__(self, instance: None, owner: Type[I]) -> Self: ...
|
|
54
92
|
@overload
|
|
55
|
-
def __get__(self, instance: I, owner: Type[I]) -> "ASyncBoundMethod[I, P, T]"
|
|
56
|
-
def __get__(
|
|
93
|
+
def __get__(self, instance: I, owner: Type[I]) -> "ASyncBoundMethod[I, P, T]": ...
|
|
94
|
+
def __get__(
|
|
95
|
+
self, instance: Optional[I], owner: Type[I]
|
|
96
|
+
) -> Union[Self, "ASyncBoundMethod[I, P, T]"]:
|
|
57
97
|
"""
|
|
58
98
|
Get the bound method or the descriptor itself.
|
|
59
99
|
|
|
@@ -61,8 +101,9 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
61
101
|
instance: The instance to bind the method to, or None.
|
|
62
102
|
owner: The owner class.
|
|
63
103
|
|
|
64
|
-
|
|
65
|
-
|
|
104
|
+
Examples:
|
|
105
|
+
>>> descriptor = ASyncMethodDescriptor(my_function)
|
|
106
|
+
>>> bound_method = descriptor.__get__(instance, MyClass)
|
|
66
107
|
"""
|
|
67
108
|
if instance is None:
|
|
68
109
|
return self
|
|
@@ -72,20 +113,42 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
72
113
|
bound._cache_handle.cancel()
|
|
73
114
|
except KeyError:
|
|
74
115
|
from a_sync.a_sync.abstract import ASyncABC
|
|
116
|
+
|
|
75
117
|
if self.default == "sync":
|
|
76
|
-
bound = ASyncBoundMethodSyncDefault(
|
|
118
|
+
bound = ASyncBoundMethodSyncDefault(
|
|
119
|
+
instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
|
|
120
|
+
)
|
|
77
121
|
elif self.default == "async":
|
|
78
|
-
bound = ASyncBoundMethodAsyncDefault(
|
|
122
|
+
bound = ASyncBoundMethodAsyncDefault(
|
|
123
|
+
instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
|
|
124
|
+
)
|
|
79
125
|
elif isinstance(instance, ASyncABC):
|
|
80
126
|
try:
|
|
81
127
|
if instance.__a_sync_instance_should_await__:
|
|
82
|
-
bound = ASyncBoundMethodSyncDefault(
|
|
128
|
+
bound = ASyncBoundMethodSyncDefault(
|
|
129
|
+
instance,
|
|
130
|
+
self.__wrapped__,
|
|
131
|
+
self.__is_async_def__,
|
|
132
|
+
**self.modifiers,
|
|
133
|
+
)
|
|
83
134
|
else:
|
|
84
|
-
bound = ASyncBoundMethodAsyncDefault(
|
|
135
|
+
bound = ASyncBoundMethodAsyncDefault(
|
|
136
|
+
instance,
|
|
137
|
+
self.__wrapped__,
|
|
138
|
+
self.__is_async_def__,
|
|
139
|
+
**self.modifiers,
|
|
140
|
+
)
|
|
85
141
|
except AttributeError:
|
|
86
|
-
bound = ASyncBoundMethod(
|
|
142
|
+
bound = ASyncBoundMethod(
|
|
143
|
+
instance,
|
|
144
|
+
self.__wrapped__,
|
|
145
|
+
self.__is_async_def__,
|
|
146
|
+
**self.modifiers,
|
|
147
|
+
)
|
|
87
148
|
else:
|
|
88
|
-
bound = ASyncBoundMethod(
|
|
149
|
+
bound = ASyncBoundMethod(
|
|
150
|
+
instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
|
|
151
|
+
)
|
|
89
152
|
instance.__dict__[self.field_name] = bound
|
|
90
153
|
logger.debug("new bound method: %s", bound)
|
|
91
154
|
# Handler for popping unused bound methods from bound method cache
|
|
@@ -101,9 +164,16 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
101
164
|
value: The value to set.
|
|
102
165
|
|
|
103
166
|
Raises:
|
|
104
|
-
:
|
|
167
|
+
RuntimeError: Always raised to prevent setting.
|
|
168
|
+
|
|
169
|
+
Examples:
|
|
170
|
+
>>> descriptor = ASyncMethodDescriptor(my_function)
|
|
171
|
+
>>> descriptor.__set__(instance, value)
|
|
172
|
+
RuntimeError: cannot set field_name, descriptor is what you get. sorry.
|
|
105
173
|
"""
|
|
106
|
-
raise RuntimeError(
|
|
174
|
+
raise RuntimeError(
|
|
175
|
+
f"cannot set {self.field_name}, {self} is what you get. sorry."
|
|
176
|
+
)
|
|
107
177
|
|
|
108
178
|
def __delete__(self, instance):
|
|
109
179
|
"""
|
|
@@ -113,17 +183,26 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
113
183
|
instance: The instance.
|
|
114
184
|
|
|
115
185
|
Raises:
|
|
116
|
-
:
|
|
186
|
+
RuntimeError: Always raised to prevent deletion.
|
|
187
|
+
|
|
188
|
+
Examples:
|
|
189
|
+
>>> descriptor = ASyncMethodDescriptor(my_function)
|
|
190
|
+
>>> descriptor.__delete__(instance)
|
|
191
|
+
RuntimeError: cannot delete field_name, you're stuck with descriptor forever. sorry.
|
|
117
192
|
"""
|
|
118
|
-
raise RuntimeError(
|
|
193
|
+
raise RuntimeError(
|
|
194
|
+
f"cannot delete {self.field_name}, you're stuck with {self} forever. sorry."
|
|
195
|
+
)
|
|
119
196
|
|
|
120
197
|
@functools.cached_property
|
|
121
198
|
def __is_async_def__(self) -> bool:
|
|
122
199
|
"""
|
|
123
200
|
Check if the wrapped function is a coroutine function.
|
|
124
201
|
|
|
125
|
-
|
|
126
|
-
|
|
202
|
+
Examples:
|
|
203
|
+
>>> descriptor = ASyncMethodDescriptor(my_function)
|
|
204
|
+
>>> descriptor.__is_async_def__
|
|
205
|
+
True
|
|
127
206
|
"""
|
|
128
207
|
return asyncio.iscoroutinefunction(self.__wrapped__)
|
|
129
208
|
|
|
@@ -136,17 +215,44 @@ class ASyncMethodDescriptor(ASyncDescriptor[I, P, T]):
|
|
|
136
215
|
|
|
137
216
|
Returns:
|
|
138
217
|
A timer handle for cache management.
|
|
218
|
+
|
|
219
|
+
Examples:
|
|
220
|
+
>>> descriptor = ASyncMethodDescriptor(my_function)
|
|
221
|
+
>>> cache_handle = descriptor._get_cache_handle(instance)
|
|
139
222
|
"""
|
|
140
223
|
# NOTE: use `instance.__dict__.pop` instead of `delattr` so we don't create a strong ref to `instance`
|
|
141
|
-
return asyncio.get_event_loop().call_later(
|
|
224
|
+
return asyncio.get_event_loop().call_later(
|
|
225
|
+
300, instance.__dict__.pop, self.field_name
|
|
226
|
+
)
|
|
227
|
+
|
|
142
228
|
|
|
143
229
|
@final
|
|
144
230
|
class ASyncMethodDescriptorSyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
145
231
|
"""
|
|
146
232
|
A descriptor for :class:`ASyncBoundMethodSyncDefault` objects.
|
|
147
233
|
|
|
148
|
-
This class extends ASyncMethodDescriptor to provide a synchronous
|
|
149
|
-
default behavior for method calls.
|
|
234
|
+
This class extends :class:`ASyncMethodDescriptor` to provide a synchronous
|
|
235
|
+
default behavior for method calls. It specifically creates `ASyncBoundMethodSyncDefault`
|
|
236
|
+
instances, which are specialized versions of `ASyncBoundMethod` with synchronous default behavior.
|
|
237
|
+
|
|
238
|
+
Examples:
|
|
239
|
+
>>> class MyClass:
|
|
240
|
+
... @ASyncMethodDescriptorSyncDefault
|
|
241
|
+
... def my_method(self):
|
|
242
|
+
... return "Hello, World!"
|
|
243
|
+
...
|
|
244
|
+
>>> obj = MyClass()
|
|
245
|
+
>>> obj.my_method()
|
|
246
|
+
'Hello, World!'
|
|
247
|
+
>>> coro = obj.my_method(sync=False)
|
|
248
|
+
>>> coro
|
|
249
|
+
<coroutine object MyClass.my_method at 0x7fb4f5fb49c0>
|
|
250
|
+
>>> await coro
|
|
251
|
+
'Hello, World!'
|
|
252
|
+
|
|
253
|
+
See Also:
|
|
254
|
+
- :class:`ASyncBoundMethodSyncDefault`
|
|
255
|
+
- :class:`ASyncFunctionSyncDefault`
|
|
150
256
|
"""
|
|
151
257
|
|
|
152
258
|
default = "sync"
|
|
@@ -168,10 +274,18 @@ class ASyncMethodDescriptorSyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
168
274
|
"""Synchronous default version of the :meth:`~ASyncMethodDescriptor.sum` method."""
|
|
169
275
|
|
|
170
276
|
@overload
|
|
171
|
-
def __get__(
|
|
277
|
+
def __get__(
|
|
278
|
+
self, instance: None, owner: Type[I] = None
|
|
279
|
+
) -> "ASyncMethodDescriptorSyncDefault[I, P, T]": ...
|
|
172
280
|
@overload
|
|
173
|
-
def __get__(
|
|
174
|
-
|
|
281
|
+
def __get__(
|
|
282
|
+
self, instance: I, owner: Type[I] = None
|
|
283
|
+
) -> "ASyncBoundMethodSyncDefault[I, P, T]": ...
|
|
284
|
+
def __get__(
|
|
285
|
+
self, instance: Optional[I], owner: Type[I] = None
|
|
286
|
+
) -> (
|
|
287
|
+
"Union[ASyncMethodDescriptorSyncDefault, ASyncBoundMethodSyncDefault[I, P, T]]"
|
|
288
|
+
):
|
|
175
289
|
"""
|
|
176
290
|
Get the bound method or the descriptor itself.
|
|
177
291
|
|
|
@@ -179,8 +293,9 @@ class ASyncMethodDescriptorSyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
179
293
|
instance: The instance to bind the method to, or None.
|
|
180
294
|
owner: The owner class.
|
|
181
295
|
|
|
182
|
-
|
|
183
|
-
|
|
296
|
+
Examples:
|
|
297
|
+
>>> descriptor = ASyncMethodDescriptorSyncDefault(my_function)
|
|
298
|
+
>>> bound_method = descriptor.__get__(instance, MyClass)
|
|
184
299
|
"""
|
|
185
300
|
if instance is None:
|
|
186
301
|
return self
|
|
@@ -189,20 +304,42 @@ class ASyncMethodDescriptorSyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
189
304
|
# we will set a new one in the finally block
|
|
190
305
|
bound._cache_handle.cancel()
|
|
191
306
|
except KeyError:
|
|
192
|
-
bound = ASyncBoundMethodSyncDefault(
|
|
307
|
+
bound = ASyncBoundMethodSyncDefault(
|
|
308
|
+
instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
|
|
309
|
+
)
|
|
193
310
|
instance.__dict__[self.field_name] = bound
|
|
194
311
|
logger.debug("new bound method: %s", bound)
|
|
195
312
|
# Handler for popping unused bound methods from bound method cache
|
|
196
313
|
bound._cache_handle = self._get_cache_handle(instance)
|
|
197
314
|
return bound
|
|
198
315
|
|
|
316
|
+
|
|
199
317
|
@final
|
|
200
318
|
class ASyncMethodDescriptorAsyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
201
319
|
"""
|
|
202
320
|
A descriptor for asynchronous methods with an asynchronous default.
|
|
203
321
|
|
|
204
|
-
This class extends ASyncMethodDescriptor to provide an asynchronous default
|
|
205
|
-
behavior for method calls.
|
|
322
|
+
This class extends :class:`ASyncMethodDescriptor` to provide an asynchronous default
|
|
323
|
+
behavior for method calls. It specifically creates `ASyncBoundMethodAsyncDefault`
|
|
324
|
+
instances, which are specialized versions of `ASyncBoundMethod` with asynchronous default behavior.
|
|
325
|
+
|
|
326
|
+
Examples:
|
|
327
|
+
>>> class MyClass:
|
|
328
|
+
... @ASyncMethodDescriptorAsyncDefault
|
|
329
|
+
... async def my_method(self):
|
|
330
|
+
... return "Hello, World!"
|
|
331
|
+
...
|
|
332
|
+
>>> obj = MyClass()
|
|
333
|
+
>>> coro = obj.my_method()
|
|
334
|
+
>>> coro
|
|
335
|
+
<coroutine object MyClass.my_method at 0x7fb4f5fb49c0>
|
|
336
|
+
>>> await coro
|
|
337
|
+
>>> obj.my_method(sync=True)
|
|
338
|
+
'Hello, World!'
|
|
339
|
+
|
|
340
|
+
See Also:
|
|
341
|
+
- :class:`ASyncBoundMethodAsyncDefault`
|
|
342
|
+
- :class:`ASyncFunctionAsyncDefault`
|
|
206
343
|
"""
|
|
207
344
|
|
|
208
345
|
default = "async"
|
|
@@ -213,21 +350,27 @@ class ASyncMethodDescriptorAsyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
213
350
|
|
|
214
351
|
all: ASyncFunctionAsyncDefault[Concatenate[AnyIterable[I], P], bool]
|
|
215
352
|
"""Asynchronous default version of the :meth:`~ASyncMethodDescriptor.all` method."""
|
|
216
|
-
|
|
353
|
+
|
|
217
354
|
min: ASyncFunctionAsyncDefault[Concatenate[AnyIterable[I], P], T]
|
|
218
355
|
"""Asynchronous default version of the :meth:`~ASyncMethodDescriptor.min` method."""
|
|
219
|
-
|
|
356
|
+
|
|
220
357
|
max: ASyncFunctionAsyncDefault[Concatenate[AnyIterable[I], P], T]
|
|
221
358
|
"""Asynchronous default version of the :meth:`~ASyncMethodDescriptor.max` method."""
|
|
222
|
-
|
|
359
|
+
|
|
223
360
|
sum: ASyncFunctionAsyncDefault[Concatenate[AnyIterable[I], P], T]
|
|
224
361
|
"""Asynchronous default version of the :meth:`~ASyncMethodDescriptor.sum` method."""
|
|
225
362
|
|
|
226
363
|
@overload
|
|
227
|
-
def __get__(
|
|
364
|
+
def __get__(
|
|
365
|
+
self, instance: None, owner: Type[I]
|
|
366
|
+
) -> "ASyncMethodDescriptorAsyncDefault[I, P, T]": ...
|
|
228
367
|
@overload
|
|
229
|
-
def __get__(
|
|
230
|
-
|
|
368
|
+
def __get__(
|
|
369
|
+
self, instance: I, owner: Type[I]
|
|
370
|
+
) -> "ASyncBoundMethodAsyncDefault[I, P, T]": ...
|
|
371
|
+
def __get__(
|
|
372
|
+
self, instance: Optional[I], owner: Type[I]
|
|
373
|
+
) -> "Union[ASyncMethodDescriptorAsyncDefault, ASyncBoundMethodAsyncDefault[I, P, T]]":
|
|
231
374
|
"""
|
|
232
375
|
Get the bound method or the descriptor itself.
|
|
233
376
|
|
|
@@ -235,8 +378,9 @@ class ASyncMethodDescriptorAsyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
235
378
|
instance: The instance to bind the method to, or None.
|
|
236
379
|
owner: The owner class.
|
|
237
380
|
|
|
238
|
-
|
|
239
|
-
|
|
381
|
+
Examples:
|
|
382
|
+
>>> descriptor = ASyncMethodDescriptorAsyncDefault(my_function)
|
|
383
|
+
>>> bound_method = descriptor.__get__(instance, MyClass)
|
|
240
384
|
"""
|
|
241
385
|
if instance is None:
|
|
242
386
|
return self
|
|
@@ -245,27 +389,52 @@ class ASyncMethodDescriptorAsyncDefault(ASyncMethodDescriptor[I, P, T]):
|
|
|
245
389
|
# we will set a new one in the finally block
|
|
246
390
|
bound._cache_handle.cancel()
|
|
247
391
|
except KeyError:
|
|
248
|
-
bound = ASyncBoundMethodAsyncDefault(
|
|
392
|
+
bound = ASyncBoundMethodAsyncDefault(
|
|
393
|
+
instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
|
|
394
|
+
)
|
|
249
395
|
instance.__dict__[self.field_name] = bound
|
|
250
396
|
logger.debug("new bound method: %s", bound)
|
|
251
397
|
# Handler for popping unused bound methods from bound method cache
|
|
252
398
|
bound._cache_handle = self._get_cache_handle(instance)
|
|
253
399
|
return bound
|
|
254
400
|
|
|
401
|
+
|
|
255
402
|
class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
256
403
|
"""
|
|
257
404
|
A bound method that can be called both synchronously and asynchronously.
|
|
258
405
|
|
|
259
406
|
This class represents a method bound to an instance, which can be called
|
|
260
|
-
either synchronously or asynchronously based on various conditions.
|
|
407
|
+
either synchronously or asynchronously based on various conditions. It handles
|
|
408
|
+
caching of bound methods and includes logic for determining whether to await
|
|
409
|
+
the method call based on flags or default settings.
|
|
410
|
+
|
|
411
|
+
Examples:
|
|
412
|
+
>>> class MyClass:
|
|
413
|
+
... def __init__(self, value):
|
|
414
|
+
... self.value = value
|
|
415
|
+
...
|
|
416
|
+
... @ASyncMethodDescriptor
|
|
417
|
+
... async def my_method(self):
|
|
418
|
+
... return self.value
|
|
419
|
+
...
|
|
420
|
+
>>> obj = MyClass(42)
|
|
421
|
+
>>> await obj.my_method()
|
|
422
|
+
42
|
|
423
|
+
>>> obj.my_method(sync=True)
|
|
424
|
+
42
|
|
425
|
+
|
|
426
|
+
See Also:
|
|
427
|
+
- :class:`ASyncMethodDescriptor`
|
|
428
|
+
- :class:`ASyncFunction`
|
|
261
429
|
"""
|
|
430
|
+
|
|
262
431
|
# NOTE: this is created by the Descriptor
|
|
263
432
|
|
|
264
433
|
_cache_handle: asyncio.TimerHandle
|
|
265
|
-
"An asyncio handle used to pop the bound method from `instance.__dict__` 5 minutes after its last use."
|
|
434
|
+
"""An asyncio handle used to pop the bound method from `instance.__dict__` 5 minutes after its last use."""
|
|
266
435
|
|
|
267
436
|
__weakself__: "weakref.ref[I]"
|
|
268
|
-
"A weak reference to the instance the function is bound to."
|
|
437
|
+
"""A weak reference to the instance the function is bound to."""
|
|
269
438
|
|
|
270
439
|
__wrapped__: AnyFn[Concatenate[I, P], T]
|
|
271
440
|
"""The original unbound method that was wrapped."""
|
|
@@ -273,9 +442,9 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
273
442
|
__slots__ = "_is_async_def", "__weakself__"
|
|
274
443
|
|
|
275
444
|
def __init__(
|
|
276
|
-
self,
|
|
277
|
-
instance: I,
|
|
278
|
-
unbound: AnyFn[Concatenate[I, P], T],
|
|
445
|
+
self,
|
|
446
|
+
instance: I,
|
|
447
|
+
unbound: AnyFn[Concatenate[I, P], T],
|
|
279
448
|
async_def: bool,
|
|
280
449
|
**modifiers: Unpack[ModifierKwargs],
|
|
281
450
|
) -> None:
|
|
@@ -287,6 +456,18 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
287
456
|
unbound: The unbound function.
|
|
288
457
|
async_def: Whether the original function is an async def.
|
|
289
458
|
**modifiers: Additional modifiers for the function.
|
|
459
|
+
|
|
460
|
+
Examples:
|
|
461
|
+
>>> class MyClass:
|
|
462
|
+
... def __init__(self, value):
|
|
463
|
+
... self.value = value
|
|
464
|
+
...
|
|
465
|
+
... @ASyncMethodDescriptor
|
|
466
|
+
... async def my_method(self):
|
|
467
|
+
... return self.value
|
|
468
|
+
...
|
|
469
|
+
>>> obj = MyClass(42)
|
|
470
|
+
>>> bound_method = ASyncBoundMethod(obj, MyClass.my_method, True)
|
|
290
471
|
"""
|
|
291
472
|
self.__weakself__ = weakref.ref(instance, self.__cancel_cache_handle)
|
|
292
473
|
# First we unwrap the coro_fn and rewrap it so overriding flag kwargs are handled automagically.
|
|
@@ -295,15 +476,17 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
295
476
|
unbound = unbound.__wrapped__
|
|
296
477
|
ASyncFunction.__init__(self, unbound, **modifiers)
|
|
297
478
|
self._is_async_def = async_def
|
|
298
|
-
"True if `self.__wrapped__` is a coroutine function, False otherwise."
|
|
479
|
+
"""True if `self.__wrapped__` is a coroutine function, False otherwise."""
|
|
299
480
|
functools.update_wrapper(self, unbound)
|
|
300
481
|
|
|
301
482
|
def __repr__(self) -> str:
|
|
302
483
|
"""
|
|
303
484
|
Return a string representation of the bound method.
|
|
304
485
|
|
|
305
|
-
|
|
306
|
-
|
|
486
|
+
Examples:
|
|
487
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
488
|
+
>>> repr(bound_method)
|
|
489
|
+
'<ASyncBoundMethod for function module.ClassName.method_name bound to instance>'
|
|
307
490
|
"""
|
|
308
491
|
try:
|
|
309
492
|
instance_type = type(self.__self__)
|
|
@@ -312,15 +495,21 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
312
495
|
return f"<{self.__class__.__name__} for function COLLECTED.COLLECTED.{self.__name__} bound to {self.__weakself__}>"
|
|
313
496
|
|
|
314
497
|
@overload
|
|
315
|
-
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T
|
|
498
|
+
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T: ...
|
|
316
499
|
@overload
|
|
317
|
-
def __call__(
|
|
500
|
+
def __call__(
|
|
501
|
+
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
502
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
318
503
|
@overload
|
|
319
|
-
def __call__(
|
|
504
|
+
def __call__(
|
|
505
|
+
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
506
|
+
) -> T: ...
|
|
320
507
|
@overload
|
|
321
|
-
def __call__(
|
|
508
|
+
def __call__(
|
|
509
|
+
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
510
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
322
511
|
@overload
|
|
323
|
-
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]
|
|
512
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]: ...
|
|
324
513
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> MaybeCoro[T]:
|
|
325
514
|
"""
|
|
326
515
|
Call the bound method.
|
|
@@ -332,8 +521,10 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
332
521
|
*args: Positional arguments.
|
|
333
522
|
**kwargs: Keyword arguments.
|
|
334
523
|
|
|
335
|
-
|
|
336
|
-
|
|
524
|
+
Examples:
|
|
525
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
526
|
+
>>> await bound_method(arg1, arg2, kwarg1=value1)
|
|
527
|
+
>>> bound_method(arg1, arg2, kwarg1=value1, sync=True)
|
|
337
528
|
"""
|
|
338
529
|
logger.debug("calling %s with args: %s kwargs: %s", self, args, kwargs)
|
|
339
530
|
# This could either be a coroutine or a return value from an awaited coroutine,
|
|
@@ -345,9 +536,13 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
345
536
|
pass
|
|
346
537
|
elif self._should_await(kwargs):
|
|
347
538
|
# The awaitable was not awaited, so now we need to check the flag as defined on 'self' and await if appropriate.
|
|
348
|
-
logger.debug(
|
|
539
|
+
logger.debug(
|
|
540
|
+
"awaiting %s for %s args: %s kwargs: %s", coro, self, args, kwargs
|
|
541
|
+
)
|
|
349
542
|
retval = _helpers._await(coro)
|
|
350
|
-
logger.debug(
|
|
543
|
+
logger.debug(
|
|
544
|
+
"returning %s for %s args: %s kwargs: %s", retval, self, args, kwargs
|
|
545
|
+
)
|
|
351
546
|
return retval # type: ignore [call-overload, return-value]
|
|
352
547
|
|
|
353
548
|
@property
|
|
@@ -355,11 +550,13 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
355
550
|
"""
|
|
356
551
|
Get the instance the method is bound to.
|
|
357
552
|
|
|
358
|
-
Returns:
|
|
359
|
-
The instance the method is bound to.
|
|
360
|
-
|
|
361
553
|
Raises:
|
|
362
|
-
:
|
|
554
|
+
ReferenceError: If the instance has been garbage collected.
|
|
555
|
+
|
|
556
|
+
Examples:
|
|
557
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
558
|
+
>>> bound_method.__self__
|
|
559
|
+
<MyClass instance>
|
|
363
560
|
"""
|
|
364
561
|
instance = self.__weakself__()
|
|
365
562
|
if instance is not None:
|
|
@@ -371,13 +568,22 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
371
568
|
"""
|
|
372
569
|
Check if the method is bound to an ASyncABC instance.
|
|
373
570
|
|
|
374
|
-
|
|
375
|
-
|
|
571
|
+
Examples:
|
|
572
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
573
|
+
>>> bound_method.__bound_to_a_sync_instance__
|
|
574
|
+
True
|
|
376
575
|
"""
|
|
377
576
|
from a_sync.a_sync.abstract import ASyncABC
|
|
577
|
+
|
|
378
578
|
return isinstance(self.__self__, ASyncABC)
|
|
379
579
|
|
|
380
|
-
def map(
|
|
580
|
+
def map(
|
|
581
|
+
self,
|
|
582
|
+
*iterables: AnyIterable[I],
|
|
583
|
+
concurrency: Optional[int] = None,
|
|
584
|
+
task_name: str = "",
|
|
585
|
+
**kwargs: P.kwargs,
|
|
586
|
+
) -> "TaskMapping[I, T]":
|
|
381
587
|
"""
|
|
382
588
|
Create a TaskMapping for this method.
|
|
383
589
|
|
|
@@ -389,11 +595,25 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
389
595
|
|
|
390
596
|
Returns:
|
|
391
597
|
A TaskMapping instance for this method.
|
|
598
|
+
|
|
599
|
+
Examples:
|
|
600
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
601
|
+
>>> task_mapping = bound_method.map(iterable1, iterable2, concurrency=5)
|
|
602
|
+
TODO briefly include how someone would then use task_mapping
|
|
392
603
|
"""
|
|
393
604
|
from a_sync import TaskMapping
|
|
394
|
-
return TaskMapping(self, *iterables, concurrency=concurrency, name=task_name, **kwargs)
|
|
395
605
|
|
|
396
|
-
|
|
606
|
+
return TaskMapping(
|
|
607
|
+
self, *iterables, concurrency=concurrency, name=task_name, **kwargs
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
async def any(
|
|
611
|
+
self,
|
|
612
|
+
*iterables: AnyIterable[I],
|
|
613
|
+
concurrency: Optional[int] = None,
|
|
614
|
+
task_name: str = "",
|
|
615
|
+
**kwargs: P.kwargs,
|
|
616
|
+
) -> bool:
|
|
397
617
|
"""
|
|
398
618
|
Check if any of the results are truthy.
|
|
399
619
|
|
|
@@ -403,12 +623,21 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
403
623
|
task_name: Optional name for the task.
|
|
404
624
|
**kwargs: Additional keyword arguments.
|
|
405
625
|
|
|
406
|
-
|
|
407
|
-
|
|
626
|
+
Examples:
|
|
627
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
628
|
+
>>> result = await bound_method.any(iterable1, iterable2)
|
|
408
629
|
"""
|
|
409
|
-
return await self.map(
|
|
630
|
+
return await self.map(
|
|
631
|
+
*iterables, concurrency=concurrency, task_name=task_name, **kwargs
|
|
632
|
+
).any(pop=True, sync=False)
|
|
410
633
|
|
|
411
|
-
async def all(
|
|
634
|
+
async def all(
|
|
635
|
+
self,
|
|
636
|
+
*iterables: AnyIterable[I],
|
|
637
|
+
concurrency: Optional[int] = None,
|
|
638
|
+
task_name: str = "",
|
|
639
|
+
**kwargs: P.kwargs,
|
|
640
|
+
) -> bool:
|
|
412
641
|
"""
|
|
413
642
|
Check if all of the results are truthy.
|
|
414
643
|
|
|
@@ -418,12 +647,21 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
418
647
|
task_name: Optional name for the task.
|
|
419
648
|
**kwargs: Additional keyword arguments.
|
|
420
649
|
|
|
421
|
-
|
|
422
|
-
|
|
650
|
+
Examples:
|
|
651
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
652
|
+
>>> result = await bound_method.all(iterable1, iterable2)
|
|
423
653
|
"""
|
|
424
|
-
return await self.map(
|
|
654
|
+
return await self.map(
|
|
655
|
+
*iterables, concurrency=concurrency, task_name=task_name, **kwargs
|
|
656
|
+
).all(pop=True, sync=False)
|
|
425
657
|
|
|
426
|
-
async def min(
|
|
658
|
+
async def min(
|
|
659
|
+
self,
|
|
660
|
+
*iterables: AnyIterable[I],
|
|
661
|
+
concurrency: Optional[int] = None,
|
|
662
|
+
task_name: str = "",
|
|
663
|
+
**kwargs: P.kwargs,
|
|
664
|
+
) -> T:
|
|
427
665
|
"""
|
|
428
666
|
Find the minimum result.
|
|
429
667
|
|
|
@@ -433,12 +671,21 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
433
671
|
task_name: Optional name for the task.
|
|
434
672
|
**kwargs: Additional keyword arguments.
|
|
435
673
|
|
|
436
|
-
|
|
437
|
-
|
|
674
|
+
Examples:
|
|
675
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
676
|
+
>>> result = await bound_method.min(iterable1, iterable2)
|
|
438
677
|
"""
|
|
439
|
-
return await self.map(
|
|
678
|
+
return await self.map(
|
|
679
|
+
*iterables, concurrency=concurrency, task_name=task_name, **kwargs
|
|
680
|
+
).min(pop=True, sync=False)
|
|
440
681
|
|
|
441
|
-
async def max(
|
|
682
|
+
async def max(
|
|
683
|
+
self,
|
|
684
|
+
*iterables: AnyIterable[I],
|
|
685
|
+
concurrency: Optional[int] = None,
|
|
686
|
+
task_name: str = "",
|
|
687
|
+
**kwargs: P.kwargs,
|
|
688
|
+
) -> T:
|
|
442
689
|
"""
|
|
443
690
|
Find the maximum result.
|
|
444
691
|
|
|
@@ -448,12 +695,21 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
448
695
|
task_name: Optional name for the task.
|
|
449
696
|
**kwargs: Additional keyword arguments.
|
|
450
697
|
|
|
451
|
-
|
|
452
|
-
|
|
698
|
+
Examples:
|
|
699
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
700
|
+
>>> result = await bound_method.max(iterable1, iterable2)
|
|
453
701
|
"""
|
|
454
|
-
return await self.map(
|
|
702
|
+
return await self.map(
|
|
703
|
+
*iterables, concurrency=concurrency, task_name=task_name, **kwargs
|
|
704
|
+
).max(pop=True, sync=False)
|
|
455
705
|
|
|
456
|
-
async def sum(
|
|
706
|
+
async def sum(
|
|
707
|
+
self,
|
|
708
|
+
*iterables: AnyIterable[I],
|
|
709
|
+
concurrency: Optional[int] = None,
|
|
710
|
+
task_name: str = "",
|
|
711
|
+
**kwargs: P.kwargs,
|
|
712
|
+
) -> T:
|
|
457
713
|
"""
|
|
458
714
|
Calculate the sum of the results.
|
|
459
715
|
|
|
@@ -463,10 +719,13 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
463
719
|
task_name: Optional name for the task.
|
|
464
720
|
**kwargs: Additional keyword arguments.
|
|
465
721
|
|
|
466
|
-
|
|
467
|
-
|
|
722
|
+
Examples:
|
|
723
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
724
|
+
>>> result = await bound_method.sum(iterable1, iterable2)
|
|
468
725
|
"""
|
|
469
|
-
return await self.map(
|
|
726
|
+
return await self.map(
|
|
727
|
+
*iterables, concurrency=concurrency, task_name=task_name, **kwargs
|
|
728
|
+
).sum(pop=True, sync=False)
|
|
470
729
|
|
|
471
730
|
def _should_await(self, kwargs: dict) -> bool:
|
|
472
731
|
"""
|
|
@@ -475,8 +734,9 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
475
734
|
Args:
|
|
476
735
|
kwargs: Keyword arguments passed to the method.
|
|
477
736
|
|
|
478
|
-
|
|
479
|
-
|
|
737
|
+
Examples:
|
|
738
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
739
|
+
>>> should_await = bound_method._should_await(kwargs)
|
|
480
740
|
"""
|
|
481
741
|
if flag := _kwargs.get_flag_name(kwargs):
|
|
482
742
|
return _kwargs.is_sync(flag, kwargs, pop_flag=True) # type: ignore [arg-type]
|
|
@@ -493,6 +753,10 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
493
753
|
|
|
494
754
|
Args:
|
|
495
755
|
instance: The instance associated with the cache handle.
|
|
756
|
+
|
|
757
|
+
Examples:
|
|
758
|
+
>>> bound_method = ASyncBoundMethod(instance, my_function, True)
|
|
759
|
+
>>> bound_method.__cancel_cache_handle(instance)
|
|
496
760
|
"""
|
|
497
761
|
cache_handle: asyncio.TimerHandle = self._cache_handle
|
|
498
762
|
cache_handle.cancel()
|
|
@@ -501,9 +765,33 @@ class ASyncBoundMethod(ASyncFunction[P, T], Generic[I, P, T]):
|
|
|
501
765
|
class ASyncBoundMethodSyncDefault(ASyncBoundMethod[I, P, T]):
|
|
502
766
|
"""
|
|
503
767
|
A bound method with synchronous default behavior.
|
|
768
|
+
|
|
769
|
+
This class is a specialized version of :class:`ASyncBoundMethod` that defaults to synchronous execution.
|
|
770
|
+
It overrides the `__call__` method to enforce synchronous default behavior.
|
|
771
|
+
|
|
772
|
+
Examples:
|
|
773
|
+
>>> class MyClass:
|
|
774
|
+
... def __init__(self, value):
|
|
775
|
+
... self.value = value
|
|
776
|
+
...
|
|
777
|
+
... @ASyncMethodDescriptorSyncDefault
|
|
778
|
+
... def my_method(self):
|
|
779
|
+
... return self.value
|
|
780
|
+
...
|
|
781
|
+
>>> obj = MyClass(42)
|
|
782
|
+
>>> obj.my_method()
|
|
783
|
+
42
|
|
784
|
+
>>> await obj.my_method(sync=False)
|
|
785
|
+
42
|
|
786
|
+
|
|
787
|
+
See Also:
|
|
788
|
+
- :class:`ASyncBoundMethod`
|
|
789
|
+
- :class:`ASyncMethodDescriptorSyncDefault`
|
|
504
790
|
"""
|
|
505
791
|
|
|
506
|
-
def __get__(
|
|
792
|
+
def __get__(
|
|
793
|
+
self, instance: Optional[I], owner: Type[I]
|
|
794
|
+
) -> ASyncFunctionSyncDefault[P, T]:
|
|
507
795
|
"""
|
|
508
796
|
Get the bound method or descriptor.
|
|
509
797
|
|
|
@@ -511,21 +799,28 @@ class ASyncBoundMethodSyncDefault(ASyncBoundMethod[I, P, T]):
|
|
|
511
799
|
instance: The instance to bind the method to, or None.
|
|
512
800
|
owner: The owner class.
|
|
513
801
|
|
|
514
|
-
|
|
515
|
-
|
|
802
|
+
Examples:
|
|
803
|
+
>>> descriptor = ASyncMethodDescriptorSyncDefault(my_function)
|
|
804
|
+
>>> bound_method = descriptor.__get__(instance, MyClass)
|
|
516
805
|
"""
|
|
517
806
|
return ASyncBoundMethod.__get__(self, instance, owner)
|
|
518
807
|
|
|
519
808
|
@overload
|
|
520
|
-
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T
|
|
809
|
+
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T: ...
|
|
521
810
|
@overload
|
|
522
|
-
def __call__(
|
|
811
|
+
def __call__(
|
|
812
|
+
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
813
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
523
814
|
@overload
|
|
524
|
-
def __call__(
|
|
815
|
+
def __call__(
|
|
816
|
+
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
817
|
+
) -> T: ...
|
|
525
818
|
@overload
|
|
526
|
-
def __call__(
|
|
819
|
+
def __call__(
|
|
820
|
+
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
821
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
527
822
|
@overload
|
|
528
|
-
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T
|
|
823
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T: ...
|
|
529
824
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T:
|
|
530
825
|
"""
|
|
531
826
|
Call the bound method with synchronous default behavior.
|
|
@@ -534,14 +829,38 @@ class ASyncBoundMethodSyncDefault(ASyncBoundMethod[I, P, T]):
|
|
|
534
829
|
*args: Positional arguments.
|
|
535
830
|
**kwargs: Keyword arguments.
|
|
536
831
|
|
|
537
|
-
|
|
538
|
-
|
|
832
|
+
Examples:
|
|
833
|
+
>>> bound_method = ASyncBoundMethodSyncDefault(instance, my_function, True)
|
|
834
|
+
>>> bound_method(arg1, arg2, kwarg1=value1)
|
|
539
835
|
"""
|
|
540
836
|
return ASyncBoundMethod.__call__(self, *args, **kwargs)
|
|
541
837
|
|
|
838
|
+
|
|
542
839
|
class ASyncBoundMethodAsyncDefault(ASyncBoundMethod[I, P, T]):
|
|
543
840
|
"""
|
|
544
841
|
A bound method with asynchronous default behavior.
|
|
842
|
+
|
|
843
|
+
This class is a specialized version of :class:`ASyncBoundMethod` that defaults to asynchronous execution.
|
|
844
|
+
It overrides the `__call__` method to enforce asynchronous default behavior.
|
|
845
|
+
|
|
846
|
+
Examples:
|
|
847
|
+
>>> class MyClass:
|
|
848
|
+
... def __init__(self, value):
|
|
849
|
+
... self.value = value
|
|
850
|
+
...
|
|
851
|
+
... @ASyncMethodDescriptorAsyncDefault
|
|
852
|
+
... async def my_method(self):
|
|
853
|
+
... return self.value
|
|
854
|
+
...
|
|
855
|
+
>>> obj = MyClass(42)
|
|
856
|
+
>>> await obj.my_method()
|
|
857
|
+
42
|
|
858
|
+
>>> obj.my_method(sync=True)
|
|
859
|
+
42
|
|
860
|
+
|
|
861
|
+
See Also:
|
|
862
|
+
- :class:`ASyncBoundMethod`
|
|
863
|
+
- :class:`ASyncMethodDescriptorAsyncDefault`
|
|
545
864
|
"""
|
|
546
865
|
|
|
547
866
|
def __get__(self, instance: I, owner: Type[I]) -> ASyncFunctionAsyncDefault[P, T]:
|
|
@@ -552,21 +871,28 @@ class ASyncBoundMethodAsyncDefault(ASyncBoundMethod[I, P, T]):
|
|
|
552
871
|
instance: The instance to bind the method to.
|
|
553
872
|
owner: The owner class.
|
|
554
873
|
|
|
555
|
-
|
|
556
|
-
|
|
874
|
+
Examples:
|
|
875
|
+
>>> descriptor = ASyncMethodDescriptorAsyncDefault(my_function)
|
|
876
|
+
>>> bound_method = descriptor.__get__(instance, MyClass)
|
|
557
877
|
"""
|
|
558
878
|
return ASyncBoundMethod.__get__(self, instance, owner)
|
|
559
879
|
|
|
560
880
|
@overload
|
|
561
|
-
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T
|
|
881
|
+
def __call__(self, *args: P.args, sync: Literal[True], **kwargs: P.kwargs) -> T: ...
|
|
562
882
|
@overload
|
|
563
|
-
def __call__(
|
|
883
|
+
def __call__(
|
|
884
|
+
self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs
|
|
885
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
564
886
|
@overload
|
|
565
|
-
def __call__(
|
|
887
|
+
def __call__(
|
|
888
|
+
self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
|
|
889
|
+
) -> T: ...
|
|
566
890
|
@overload
|
|
567
|
-
def __call__(
|
|
891
|
+
def __call__(
|
|
892
|
+
self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs
|
|
893
|
+
) -> Coroutine[Any, Any, T]: ...
|
|
568
894
|
@overload
|
|
569
|
-
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, T]
|
|
895
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, T]: ...
|
|
570
896
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:
|
|
571
897
|
"""
|
|
572
898
|
Call the bound method with asynchronous default behavior.
|
|
@@ -575,7 +901,8 @@ class ASyncBoundMethodAsyncDefault(ASyncBoundMethod[I, P, T]):
|
|
|
575
901
|
*args: Positional arguments.
|
|
576
902
|
**kwargs: Keyword arguments.
|
|
577
903
|
|
|
578
|
-
|
|
579
|
-
|
|
904
|
+
Examples:
|
|
905
|
+
>>> bound_method = ASyncBoundMethodAsyncDefault(instance, my_function, True)
|
|
906
|
+
>>> await bound_method(arg1, arg2, kwarg1=value1)
|
|
580
907
|
"""
|
|
581
908
|
return ASyncBoundMethod.__call__(self, *args, **kwargs)
|