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.

Files changed (73) hide show
  1. a_sync/ENVIRONMENT_VARIABLES.py +37 -5
  2. a_sync/__init__.py +53 -12
  3. a_sync/_smart.py +231 -28
  4. a_sync/_typing.py +112 -15
  5. a_sync/a_sync/__init__.py +35 -10
  6. a_sync/a_sync/_descriptor.py +248 -38
  7. a_sync/a_sync/_flags.py +78 -9
  8. a_sync/a_sync/_helpers.py +46 -13
  9. a_sync/a_sync/_kwargs.py +33 -8
  10. a_sync/a_sync/_meta.py +149 -28
  11. a_sync/a_sync/abstract.py +150 -28
  12. a_sync/a_sync/base.py +34 -16
  13. a_sync/a_sync/config.py +85 -14
  14. a_sync/a_sync/decorator.py +441 -139
  15. a_sync/a_sync/function.py +709 -147
  16. a_sync/a_sync/method.py +437 -110
  17. a_sync/a_sync/modifiers/__init__.py +85 -5
  18. a_sync/a_sync/modifiers/cache/__init__.py +116 -17
  19. a_sync/a_sync/modifiers/cache/memory.py +130 -20
  20. a_sync/a_sync/modifiers/limiter.py +101 -22
  21. a_sync/a_sync/modifiers/manager.py +142 -16
  22. a_sync/a_sync/modifiers/semaphores.py +121 -15
  23. a_sync/a_sync/property.py +383 -82
  24. a_sync/a_sync/singleton.py +44 -19
  25. a_sync/aliases.py +0 -1
  26. a_sync/asyncio/__init__.py +140 -1
  27. a_sync/asyncio/as_completed.py +213 -79
  28. a_sync/asyncio/create_task.py +70 -20
  29. a_sync/asyncio/gather.py +125 -58
  30. a_sync/asyncio/utils.py +3 -3
  31. a_sync/exceptions.py +248 -26
  32. a_sync/executor.py +164 -69
  33. a_sync/future.py +1227 -168
  34. a_sync/iter.py +173 -56
  35. a_sync/primitives/__init__.py +14 -2
  36. a_sync/primitives/_debug.py +72 -18
  37. a_sync/primitives/_loggable.py +41 -10
  38. a_sync/primitives/locks/__init__.py +5 -2
  39. a_sync/primitives/locks/counter.py +107 -38
  40. a_sync/primitives/locks/event.py +21 -7
  41. a_sync/primitives/locks/prio_semaphore.py +262 -63
  42. a_sync/primitives/locks/semaphore.py +138 -89
  43. a_sync/primitives/queue.py +601 -60
  44. a_sync/sphinx/__init__.py +0 -1
  45. a_sync/sphinx/ext.py +160 -50
  46. a_sync/task.py +313 -112
  47. a_sync/utils/__init__.py +12 -6
  48. a_sync/utils/iterators.py +170 -50
  49. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/METADATA +1 -1
  50. ez_a_sync-0.22.16.dist-info/RECORD +74 -0
  51. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/WHEEL +1 -1
  52. tests/conftest.py +1 -2
  53. tests/executor.py +250 -9
  54. tests/fixtures.py +61 -32
  55. tests/test_abstract.py +22 -4
  56. tests/test_as_completed.py +54 -21
  57. tests/test_base.py +264 -19
  58. tests/test_cache.py +31 -15
  59. tests/test_decorator.py +54 -28
  60. tests/test_executor.py +31 -13
  61. tests/test_future.py +45 -8
  62. tests/test_gather.py +8 -2
  63. tests/test_helpers.py +2 -0
  64. tests/test_iter.py +55 -13
  65. tests/test_limiter.py +5 -3
  66. tests/test_meta.py +23 -9
  67. tests/test_modified.py +4 -1
  68. tests/test_semaphore.py +15 -8
  69. tests/test_singleton.py +28 -11
  70. tests/test_task.py +162 -36
  71. ez_a_sync-0.22.14.dist-info/RECORD +0 -74
  72. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/LICENSE.txt +0 -0
  73. {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 ASyncFunction, ASyncFunctionAsyncDefault, ASyncFunctionSyncDefault
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
- This class provides the core functionality for creating :class:`ASyncBoundMethod` objects,
30
- which can be used to define methods that can be called both synchronously and asynchronously.
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
- Returns:
46
- The result of the method call.
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("awaiting %s for instance: %s args: %s kwargs: %s", self, instance, args, kwargs)
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__(self, instance: Optional[I], owner: Type[I]) -> Union[Self, "ASyncBoundMethod[I, P, T]"]:
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
- Returns:
65
- The descriptor or bound method.
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(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
118
+ bound = ASyncBoundMethodSyncDefault(
119
+ instance, self.__wrapped__, self.__is_async_def__, **self.modifiers
120
+ )
77
121
  elif self.default == "async":
78
- bound = ASyncBoundMethodAsyncDefault(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
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(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
128
+ bound = ASyncBoundMethodSyncDefault(
129
+ instance,
130
+ self.__wrapped__,
131
+ self.__is_async_def__,
132
+ **self.modifiers,
133
+ )
83
134
  else:
84
- bound = ASyncBoundMethodAsyncDefault(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
135
+ bound = ASyncBoundMethodAsyncDefault(
136
+ instance,
137
+ self.__wrapped__,
138
+ self.__is_async_def__,
139
+ **self.modifiers,
140
+ )
85
141
  except AttributeError:
86
- bound = ASyncBoundMethod(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
142
+ bound = ASyncBoundMethod(
143
+ instance,
144
+ self.__wrapped__,
145
+ self.__is_async_def__,
146
+ **self.modifiers,
147
+ )
87
148
  else:
88
- bound = ASyncBoundMethod(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
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
- :class:`RuntimeError`: Always raised to prevent setting.
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(f"cannot set {self.field_name}, {self} is what you get. sorry.")
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
- :class:`RuntimeError`: Always raised to prevent deletion.
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(f"cannot delete {self.field_name}, you're stuck with {self} forever. sorry.")
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
- Returns:
126
- True if the wrapped function is a coroutine function, False otherwise.
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(300, instance.__dict__.pop, self.field_name)
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__(self, instance: None, owner: Type[I] = None) -> "ASyncMethodDescriptorSyncDefault[I, P, T]":...
277
+ def __get__(
278
+ self, instance: None, owner: Type[I] = None
279
+ ) -> "ASyncMethodDescriptorSyncDefault[I, P, T]": ...
172
280
  @overload
173
- def __get__(self, instance: I, owner: Type[I] = None) -> "ASyncBoundMethodSyncDefault[I, P, T]":...
174
- def __get__(self, instance: Optional[I], owner: Type[I] = None) -> "Union[ASyncMethodDescriptorSyncDefault, ASyncBoundMethodSyncDefault[I, P, T]]":
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
- Returns:
183
- The descriptor or bound method with synchronous default.
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(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
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__(self, instance: None, owner: Type[I]) -> "ASyncMethodDescriptorAsyncDefault[I, P, T]":...
364
+ def __get__(
365
+ self, instance: None, owner: Type[I]
366
+ ) -> "ASyncMethodDescriptorAsyncDefault[I, P, T]": ...
228
367
  @overload
229
- def __get__(self, instance: I, owner: Type[I]) -> "ASyncBoundMethodAsyncDefault[I, P, T]":...
230
- def __get__(self, instance: Optional[I], owner: Type[I]) -> "Union[ASyncMethodDescriptorAsyncDefault, ASyncBoundMethodAsyncDefault[I, P, T]]":
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
- Returns:
239
- The descriptor or bound method with asynchronous default.
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(instance, self.__wrapped__, self.__is_async_def__, **self.modifiers)
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
- Returns:
306
- A string representation of the bound method.
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__(self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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__(self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs) -> T:...
504
+ def __call__(
505
+ self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
506
+ ) -> T: ...
320
507
  @overload
321
- def __call__(self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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
- Returns:
336
- The result of the method call, which may be a coroutine.
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("awaiting %s for %s args: %s kwargs: %s", coro, self, args, kwargs)
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("returning %s for %s args: %s kwargs: %s", retval, self, args, kwargs)
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
- :class:`ReferenceError`: If the instance has been garbage collected.
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
- Returns:
375
- True if bound to an ASyncABC instance, False otherwise.
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(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> "TaskMapping[I, T]":
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
- async def any(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> bool:
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
- Returns:
407
- True if any result is truthy, False otherwise.
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(*iterables, concurrency=concurrency, task_name=task_name, **kwargs).any(pop=True, sync=False)
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(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> bool:
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
- Returns:
422
- True if all results are truthy, False otherwise.
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(*iterables, concurrency=concurrency, task_name=task_name, **kwargs).all(pop=True, sync=False)
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(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> T:
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
- Returns:
437
- The minimum result.
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(*iterables, concurrency=concurrency, task_name=task_name, **kwargs).min(pop=True, sync=False)
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(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> T:
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
- Returns:
452
- The maximum result.
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(*iterables, concurrency=concurrency, task_name=task_name, **kwargs).max(pop=True, sync=False)
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(self, *iterables: AnyIterable[I], concurrency: Optional[int] = None, task_name: str = "", **kwargs: P.kwargs) -> T:
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
- Returns:
467
- The sum of the results.
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(*iterables, concurrency=concurrency, task_name=task_name, **kwargs).sum(pop=True, sync=False)
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
- Returns:
479
- True if the method should be awaited, False otherwise.
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__(self, instance: Optional[I], owner: Type[I]) -> ASyncFunctionSyncDefault[P, T]:
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
- Returns:
515
- The bound method with synchronous default behavior.
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__(self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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__(self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs) -> T:...
815
+ def __call__(
816
+ self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
817
+ ) -> T: ...
525
818
  @overload
526
- def __call__(self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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
- Returns:
538
- The result of the method call.
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
- Returns:
556
- The bound method with asynchronous default behavior.
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__(self, *args: P.args, sync: Literal[False], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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__(self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs) -> T:...
887
+ def __call__(
888
+ self, *args: P.args, asynchronous: Literal[False], **kwargs: P.kwargs
889
+ ) -> T: ...
566
890
  @overload
567
- def __call__(self, *args: P.args, asynchronous: Literal[True], **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:...
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
- Returns:
579
- A coroutine representing the asynchronous method call.
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)