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
@@ -2,9 +2,14 @@
2
2
  # mypy: disable-error-code=misc
3
3
  from a_sync._typing import *
4
4
  from a_sync.a_sync import _flags, config
5
- from a_sync.a_sync.function import (ASyncDecorator, ASyncFunction, ASyncDecoratorAsyncDefault,
6
- ASyncDecoratorSyncDefault, ASyncFunctionAsyncDefault,
7
- ASyncFunctionSyncDefault)
5
+ from a_sync.a_sync.function import (
6
+ ASyncDecorator,
7
+ ASyncFunction,
8
+ ASyncDecoratorAsyncDefault,
9
+ ASyncDecoratorSyncDefault,
10
+ ASyncFunctionAsyncDefault,
11
+ ASyncFunctionSyncDefault,
12
+ )
8
13
 
9
14
  ########################
10
15
  # The a_sync decorator #
@@ -18,129 +23,426 @@ from a_sync.a_sync.function import (ASyncDecorator, ASyncFunction, ASyncDecorato
18
23
  # async def some_fn():
19
24
  # pass
20
25
 
26
+
21
27
  @overload
22
28
  def a_sync(
23
29
  default: Literal["async"],
24
30
  **modifiers: Unpack[ModifierKwargs],
25
- ) -> ASyncDecoratorAsyncDefault:...
31
+ ) -> ASyncDecoratorAsyncDefault:
32
+ """
33
+ Creates an asynchronous default decorator.
34
+
35
+ Args:
36
+ default: Specifies the default execution mode as 'async'.
37
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
38
+
39
+ Examples:
40
+ Basic usage with an asynchronous default:
41
+
42
+ >>> @a_sync(default='async')
43
+ ... async def my_function():
44
+ ... return True
45
+ >>> await my_function()
46
+ True
47
+ >>> my_function(sync=True)
48
+ True
49
+
50
+ See Also:
51
+ :class:`ASyncDecoratorAsyncDefault`
52
+ """
53
+
26
54
 
27
55
  @overload
28
56
  def a_sync(
29
57
  default: Literal["sync"],
30
58
  **modifiers: Unpack[ModifierKwargs],
31
- ) -> ASyncDecoratorSyncDefault:...
59
+ ) -> ASyncDecoratorSyncDefault:
60
+ """
61
+ Creates a synchronous default decorator.
62
+
63
+ Args:
64
+ default: Specifies the default execution mode as 'sync'.
65
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
66
+
67
+ Examples:
68
+ Basic usage with a synchronous default:
69
+
70
+ >>> @a_sync(default='sync')
71
+ ... def my_function():
72
+ ... return True
73
+ >>> my_function()
74
+ True
75
+ >>> await my_function(sync=False)
76
+ True
77
+
78
+ See Also:
79
+ :class:`ASyncDecoratorSyncDefault`
80
+ """
81
+
32
82
 
33
83
  @overload
34
84
  def a_sync(
35
85
  **modifiers: Unpack[ModifierKwargs],
36
- ) -> ASyncDecorator:...
86
+ ) -> ASyncDecorator:
87
+ """
88
+ Creates a decorator with no default execution mode specified.
37
89
 
38
- @overload # async def, None default
39
- def a_sync(
90
+ Args:
91
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
92
+
93
+ Examples:
94
+ Usage without specifying a default mode:
95
+
96
+ >>> @a_sync
97
+ ... async def my_function():
98
+ ... return True
99
+ >>> await my_function()
100
+ True
101
+ >>> my_function(sync=True)
102
+ True
103
+
104
+ See Also:
105
+ :class:`ASyncDecorator`
106
+ """
107
+
108
+
109
+ @overload # async def, None default
110
+ def a_sync(
40
111
  coro_fn: CoroFn[P, T],
41
112
  default: Literal[None] = None,
42
113
  **modifiers: Unpack[ModifierKwargs],
43
- ) -> ASyncFunctionAsyncDefault[P, T]:...
114
+ ) -> ASyncFunctionAsyncDefault[P, T]:
115
+ """
116
+ Decorates an asynchronous function with no default execution mode specified.
44
117
 
45
- @overload # sync def none default
46
- def a_sync(
118
+ Args:
119
+ coro_fn: The coroutine function to be decorated.
120
+ default: Specifies no default execution mode.
121
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
122
+
123
+ Examples:
124
+ Decorating an asynchronous function without a default mode:
125
+
126
+ >>> async def my_function():
127
+ ... return True
128
+ >>> decorated_function = a_sync(my_function)
129
+ >>> await decorated_function()
130
+ True
131
+ >>> decorated_function(sync=True)
132
+ True
133
+
134
+ See Also:
135
+ :class:`ASyncFunctionAsyncDefault`
136
+ """
137
+
138
+
139
+ @overload # sync def none default
140
+ def a_sync(
47
141
  coro_fn: SyncFn[P, T],
48
142
  default: Literal[None] = None,
49
143
  **modifiers: Unpack[ModifierKwargs],
50
- ) -> ASyncFunctionSyncDefault[P, T]:...
144
+ ) -> ASyncFunctionSyncDefault[P, T]:
145
+ """
146
+ Decorates a synchronous function with no default execution mode specified.
51
147
 
52
- # @a_sync(default='async')
53
- # def some_fn():
54
- # pass
55
- #
56
- # @a_sync(default='async')
57
- # async def some_fn():
58
- # pass
59
- #
60
- # NOTE These should output a decorator that will be applied to 'some_fn'
148
+ Args:
149
+ coro_fn: The synchronous function to be decorated.
150
+ default: Specifies no default execution mode.
151
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
152
+
153
+ Examples:
154
+ Decorating a synchronous function without a default mode:
155
+
156
+ >>> def my_function():
157
+ ... return True
158
+ >>> decorated_function = a_sync(my_function)
159
+ >>> decorated_function()
160
+ True
161
+ >>> await decorated_function(sync=False)
162
+ True
163
+
164
+ See Also:
165
+ :class:`ASyncFunctionSyncDefault`
166
+ """
61
167
 
62
- @overload
63
- def a_sync(
168
+
169
+ @overload
170
+ def a_sync(
64
171
  coro_fn: Literal[None],
65
- default: Literal['async'],
172
+ default: Literal["async"],
66
173
  **modifiers: Unpack[ModifierKwargs],
67
- ) -> ASyncDecoratorAsyncDefault:...
174
+ ) -> ASyncDecoratorAsyncDefault:
175
+ """
176
+ Creates an asynchronous default decorator with no function specified.
177
+
178
+ Args:
179
+ coro_fn: Specifies no function.
180
+ default: Specifies the default execution mode as 'async'.
181
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
182
+
183
+ Examples:
184
+ Creating an asynchronous default decorator without a function:
185
+
186
+ >>> @a_sync(default='async')
187
+ ... async def my_function():
188
+ ... return True
189
+ >>> await my_function()
190
+ True
191
+ >>> my_function(sync=True)
192
+ True
68
193
 
69
- @overload # if you try to use default as the only arg
70
- def a_sync(
71
- coro_fn: Literal['async'],
194
+ See Also:
195
+ :class:`ASyncDecoratorAsyncDefault`
196
+ """
197
+
198
+
199
+ @overload # if you try to use default as the only arg
200
+ def a_sync(
201
+ coro_fn: Literal["async"],
72
202
  default: Literal[None],
73
203
  **modifiers: Unpack[ModifierKwargs],
74
- ) -> ASyncDecoratorAsyncDefault:...
204
+ ) -> ASyncDecoratorAsyncDefault:
205
+ """
206
+ Creates an asynchronous default decorator with no default execution mode specified.
207
+
208
+ Args:
209
+ coro_fn: Specifies the default execution mode as 'async'.
210
+ default: Specifies no default execution mode.
211
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
75
212
 
76
- # a_sync(some_fn, default='async')
213
+ Examples:
214
+ Using 'async' as the only argument:
215
+
216
+ >>> @a_sync('async')
217
+ ... async def my_function():
218
+ ... return True
219
+ >>> await my_function()
220
+ True
221
+ >>> my_function(sync=True)
222
+ True
223
+
224
+ See Also:
225
+ :class:`ASyncDecoratorAsyncDefault`
226
+ """
77
227
 
78
- @overload # async def, async default
79
- def a_sync(
228
+
229
+ @overload # async def, async default
230
+ def a_sync(
80
231
  coro_fn: CoroFn[P, T],
81
- default: Literal['async'],
232
+ default: Literal["async"],
82
233
  **modifiers: Unpack[ModifierKwargs],
83
- ) -> ASyncFunctionAsyncDefault[P, T]:...
234
+ ) -> ASyncFunctionAsyncDefault[P, T]:
235
+ """
236
+ Decorates an asynchronous function with an asynchronous default execution mode.
237
+
238
+ Args:
239
+ coro_fn: The coroutine function to be decorated.
240
+ default: Specifies the default execution mode as 'async'.
241
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
84
242
 
85
- @overload # sync def async default
86
- def a_sync(
243
+ Examples:
244
+ Decorating an asynchronous function with an async default:
245
+
246
+ >>> async def my_function():
247
+ ... return True
248
+ >>> decorated_function = a_sync(my_function, default='async')
249
+ >>> await decorated_function()
250
+ True
251
+ >>> decorated_function(sync=True)
252
+ True
253
+
254
+ See Also:
255
+ :class:`ASyncFunctionAsyncDefault`
256
+ """
257
+
258
+
259
+ @overload # sync def async default
260
+ def a_sync(
87
261
  coro_fn: SyncFn[P, T],
88
- default: Literal['async'],
262
+ default: Literal["async"],
89
263
  **modifiers: Unpack[ModifierKwargs],
90
- ) -> ASyncFunctionAsyncDefault[P, T]:...
264
+ ) -> ASyncFunctionAsyncDefault[P, T]:
265
+ """
266
+ Decorates a synchronous function with an asynchronous default execution mode.
267
+
268
+ Args:
269
+ coro_fn: The synchronous function to be decorated.
270
+ default: Specifies the default execution mode as 'async'.
271
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
91
272
 
92
- # a_sync(some_fn, default='sync')
273
+ Examples:
274
+ Decorating a synchronous function with an async default:
275
+
276
+ >>> def my_function():
277
+ ... return True
278
+ >>> decorated_function = a_sync(my_function, default='async')
279
+ >>> await decorated_function()
280
+ True
281
+ >>> decorated_function(sync=True)
282
+ True
283
+
284
+ See Also:
285
+ :class:`ASyncFunctionAsyncDefault`
286
+ """
93
287
 
94
- @overload # async def, sync default
95
- def a_sync(
288
+
289
+ @overload # async def, sync default
290
+ def a_sync(
96
291
  coro_fn: CoroFn[P, T],
97
- default: Literal['sync'],
292
+ default: Literal["sync"],
98
293
  **modifiers: Unpack[ModifierKwargs],
99
- ) -> ASyncFunctionSyncDefault:...
294
+ ) -> ASyncFunctionSyncDefault:
295
+ """
296
+ Decorates an asynchronous function with a synchronous default execution mode.
297
+
298
+ Args:
299
+ coro_fn: The coroutine function to be decorated.
300
+ default: Specifies the default execution mode as 'sync'.
301
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
302
+
303
+ Examples:
304
+ Decorating an asynchronous function with a sync default:
305
+
306
+ >>> async def my_function():
307
+ ... return True
308
+ >>> decorated_function = a_sync(my_function, default='sync')
309
+ >>> decorated_function()
310
+ True
311
+ >>> await decorated_function(sync=False)
312
+ True
313
+
314
+ See Also:
315
+ :class:`ASyncFunctionSyncDefault`
316
+ """
317
+
100
318
 
101
- @overload # sync def sync default
102
- def a_sync(
319
+ @overload # sync def sync default
320
+ def a_sync(
103
321
  coro_fn: SyncFn[P, T],
104
- default: Literal['sync'],
322
+ default: Literal["sync"],
105
323
  **modifiers: Unpack[ModifierKwargs],
106
- ) -> ASyncFunctionSyncDefault:...
324
+ ) -> ASyncFunctionSyncDefault:
325
+ """
326
+ Decorates a synchronous function with a synchronous default execution mode.
107
327
 
108
- # @a_sync(default='sync')
109
- # def some_fn():
110
- # pass
111
- #
112
- # @a_sync(default='sync')
113
- # async def some_fn():
114
- # pass
115
- #
116
- # NOTE These should output a decorator that will be applied to 'some_fn'
328
+ Args:
329
+ coro_fn: The synchronous function to be decorated.
330
+ default: Specifies the default execution mode as 'sync'.
331
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
332
+
333
+ Examples:
334
+ Decorating a synchronous function with a sync default:
117
335
 
118
- @overload
119
- def a_sync(
336
+ >>> def my_function():
337
+ ... return True
338
+ >>> decorated_function = a_sync(my_function, default='sync')
339
+ >>> decorated_function()
340
+ True
341
+ >>> await decorated_function(sync=False)
342
+ True
343
+
344
+ See Also:
345
+ :class:`ASyncFunctionSyncDefault`
346
+ """
347
+
348
+
349
+ @overload
350
+ def a_sync(
120
351
  coro_fn: Literal[None],
121
- default: Literal['sync'],
352
+ default: Literal["sync"],
122
353
  **modifiers: Unpack[ModifierKwargs],
123
- ) -> ASyncDecoratorSyncDefault:...
354
+ ) -> ASyncDecoratorSyncDefault:
355
+ """
356
+ Creates a synchronous default decorator with no function specified.
357
+
358
+ Args:
359
+ coro_fn: Specifies no function.
360
+ default: Specifies the default execution mode as 'sync'.
361
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
124
362
 
125
- @overload # if you try to use default as the only arg
126
- def a_sync(
127
- coro_fn: Literal['sync'],
363
+ Examples:
364
+ Creating a synchronous default decorator without a function:
365
+
366
+ >>> @a_sync(default='sync')
367
+ ... def my_function():
368
+ ... return True
369
+ >>> my_function()
370
+ True
371
+ >>> await my_function(sync=False)
372
+ True
373
+
374
+ See Also:
375
+ :class:`ASyncDecoratorSyncDefault`
376
+ """
377
+
378
+
379
+ @overload # if you try to use default as the only arg
380
+ def a_sync(
381
+ coro_fn: Literal["sync"],
128
382
  default: Literal[None] = None,
129
383
  **modifiers: Unpack[ModifierKwargs],
130
- ) -> ASyncDecoratorSyncDefault:...
384
+ ) -> ASyncDecoratorSyncDefault:
385
+ """
386
+ Creates a synchronous default decorator with no default execution mode specified.
387
+
388
+ Args:
389
+ coro_fn: Specifies the default execution mode as 'sync'.
390
+ default: Specifies no default execution mode.
391
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
131
392
 
132
- @overload # if you try to use default as the only arg
133
- def a_sync(
134
- coro_fn: Literal['sync'],
393
+ Examples:
394
+ Using 'sync' as the only argument:
395
+
396
+ >>> @a_sync('sync')
397
+ ... def my_function():
398
+ ... return True
399
+ >>> my_function()
400
+ True
401
+ >>> await my_function(sync=False)
402
+ True
403
+
404
+ See Also:
405
+ :class:`ASyncDecoratorSyncDefault`
406
+ """
407
+
408
+
409
+ @overload # if you try to use default as the only arg
410
+ def a_sync(
411
+ coro_fn: Literal["sync"],
135
412
  default: Literal[None],
136
413
  **modifiers: Unpack[ModifierKwargs],
137
- ) -> ASyncDecoratorSyncDefault:...
138
-
414
+ ) -> ASyncDecoratorSyncDefault:
415
+ """
416
+ Creates a synchronous default decorator with no default execution mode specified.
417
+
418
+ Args:
419
+ coro_fn: Specifies the default execution mode as 'sync'.
420
+ default: Specifies no default execution mode.
421
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
422
+
423
+ Examples:
424
+ Using 'sync' as the only argument:
425
+
426
+ >>> @a_sync('sync')
427
+ ... def my_function():
428
+ ... return True
429
+ >>> my_function()
430
+ True
431
+ >>> await my_function(sync=False)
432
+ True
433
+
434
+ See Also:
435
+ :class:`ASyncDecoratorSyncDefault`
436
+ """
437
+
438
+
139
439
  # catchall
140
- def a_sync(
440
+ def a_sync(
141
441
  coro_fn: Optional[AnyFn[P, T]] = None,
142
442
  default: DefaultMode = config.DEFAULT_MODE,
143
- **modifiers: Unpack[ModifierKwargs], # default values are set by passing these kwargs into a ModifierManager object.
443
+ **modifiers: Unpack[
444
+ ModifierKwargs
445
+ ], # default values are set by passing these kwargs into a ModifierManager object.
144
446
  ) -> Union[ASyncDecorator, ASyncFunction[P, T]]:
145
447
  """
146
448
  A versatile decorator that enables both synchronous and asynchronous execution of functions.
@@ -155,97 +457,96 @@ def a_sync(
155
457
  If None, the mode is inferred from the decorated function type.
156
458
  **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
157
459
  See :class:`ModifierKwargs` for available options.
158
-
460
+
159
461
  Modifiers:
160
- lib defaults:
161
- async settings
162
- cache_type: CacheType = None, - This can be None or 'memory'. 'memory' is a lru cache which can be modified with the 'cache_typed','ram_cache_maxsize','ram_cache_ttl' modifiers.
163
- cache_typed: bool = False, - Set to True if you want types considered treated for cache keys. ie with cache_typed=True, Decimal(0) and 0 will be considered separate keys.
164
- ram_cache_maxsize: Optional[int] = -1, - The maxsize for your lru cache. None if cache is unbounded. If you set this value without specifying a cache type, 'memory' will automatically be applied.
165
- ram_cache_ttl: Optional[int] = None, - The ttl for items in your lru cache. Set to None. If you set this value without specifying a cache type, 'memory' will automatically be applied.
166
- runs_per_minute: Optional[int] = None, - Setting this value enables a rate limiter for the decorated function.
167
- semaphore: SemaphoreSpec = None, - drop in a Semaphore for your async defined functions.
168
- sync settings
169
- executor: Executor = config.default_sync_executor
170
-
171
- Returns:
172
- An :class:`~ASyncDecorator` if used as a decorator factory, or an :class:`~ASyncFunction`
173
- if used directly on a function.
462
+ The following modifiers can be used to customize the behavior of the decorator:
463
+
464
+ - cache_type: Can be None or 'memory'. 'memory' is an LRU cache which can be modified with
465
+ the 'cache_typed', 'ram_cache_maxsize', and 'ram_cache_ttl' modifiers.
466
+ - cache_typed: Set to True if you want types considered for cache keys. For example, with
467
+ cache_typed=True, Decimal(0) and 0 will be considered separate keys.
468
+ - ram_cache_maxsize: The max size for your LRU cache. None if the cache is unbounded. If you
469
+ set this value without specifying a cache type, 'memory' will automatically be applied.
470
+ - ram_cache_ttl: The TTL for items in your LRU cache. Set to None. If you set this value
471
+ without specifying a cache type, 'memory' will automatically be applied.
472
+ - runs_per_minute: Setting this value enables a rate limiter for the decorated function.
473
+ - semaphore: Drop in a Semaphore for your async defined functions.
474
+ - executor: The executor for the synchronous function. Set to the library's default of
475
+ config.default_sync_executor.
174
476
 
175
477
  Examples:
176
478
  The decorator can be used in several ways.
177
479
 
178
480
  1. As a simple decorator:
179
- ```python
180
- >>> @a_sync
181
- ... async def some_async_fn():
182
- ... return True
183
- >>> await some_fn()
184
- True
185
- >>> some_fn(sync=True)
186
- True
187
- ```
188
- ```
189
- >>> @a_sync
190
- ... def some_sync_fn():
191
- ... return True
192
- >>> some_sync_fn()
193
- True
194
- >>> some_sync_fn(sync=False)
195
- <coroutine object some_sync_fn at 0x12345678>
196
- ```
481
+ >>> @a_sync
482
+ ... async def some_async_fn():
483
+ ... return True
484
+ >>> await some_async_fn()
485
+ True
486
+ >>> some_async_fn(sync=True)
487
+ True
488
+
489
+ >>> @a_sync
490
+ ... def some_sync_fn():
491
+ ... return True
492
+ >>> some_sync_fn()
493
+ True
494
+ >>> some_sync_fn(sync=False)
495
+ <coroutine object some_sync_fn at 0x7fb4f5fb49c0>
197
496
 
198
497
  2. As a decorator with default mode specified:
199
- ```python
200
- >>> @a_sync(default='sync')
201
- ... async def some_fn():
202
- ... return True
203
- ...
204
- >>> some_fn()
205
- True
206
- ```
498
+ >>> @a_sync(default='sync')
499
+ ... async def some_fn():
500
+ ... return True
501
+ ...
502
+ >>> some_fn()
503
+ True
504
+ >>> some_fn(sync=False)
505
+ <coroutine object some_fn at 0x7fb4f5fb49c0>
506
+
507
+ >>> @a_sync('async')
508
+ ... def some_fn():
509
+ ... return True
510
+ ...
511
+ >>> some_fn()
512
+ <coroutine object some_fn at 0x7fb4f5fb49c0>
513
+ >>> some_fn(asynchronous=False)
514
+ True
207
515
 
208
516
  3. As a decorator with modifiers:
209
- ```python
210
- >>> @a_sync(cache_type='memory', runs_per_minute=60)
211
- ... async def some_fn():
212
- ... return True
213
- ...
214
- >>> some_fn(sync=True)
215
- True
216
- ```
517
+ >>> @a_sync(cache_type='memory', runs_per_minute=60)
518
+ ... async def some_fn():
519
+ ... return True
520
+ ...
521
+ >>> some_fn(sync=True)
522
+ True
217
523
 
218
524
  4. Applied directly to a function:
219
- ```python
220
- >>> some_fn = a_sync(some_existing_function, default='sync')
221
- >>> some_fn()
222
- "some return value"
223
- ```
525
+ >>> some_fn = a_sync(some_existing_function, default='sync')
526
+ >>> some_fn()
527
+ "some return value"
224
528
 
225
529
  The decorated function can then be called either synchronously or asynchronously:
226
-
227
- ```python
228
- result = some_fn() # Synchronous call
229
- result = await some_fn() # Asynchronous call
230
- ```
530
+ >>> result = some_fn() # Synchronous call
531
+ >>> result = await some_fn() # Asynchronous call
231
532
 
232
533
  The execution mode can also be explicitly specified during the call:
233
-
234
- ```python
235
- result = some_fn(sync=True) # Force synchronous execution
236
- result = await some_fn(sync=False) # Force asynchronous execution
237
- ```
534
+ >>> result = some_fn(sync=True) # Force synchronous execution
535
+ >>> result = await some_fn(sync=False) # Force asynchronous execution
238
536
 
239
537
  This decorator is particularly useful for libraries that need to support
240
538
  both synchronous and asynchronous usage, or for gradually migrating
241
539
  synchronous code to asynchronous without breaking existing interfaces.
540
+
541
+ See Also:
542
+ :class:`ASyncFunction`, :class:`ASyncDecorator`
242
543
  """
243
-
544
+
244
545
  # If the dev tried passing a default as an arg instead of a kwarg, ie: @a_sync('sync')...
245
- if coro_fn in ['async', 'sync']:
546
+ if coro_fn in ["async", "sync"]:
246
547
  default = coro_fn # type: ignore [assignment]
247
548
  coro_fn = None
248
-
549
+
249
550
  if default == "sync":
250
551
  deco = ASyncDecoratorSyncDefault(default=default, **modifiers)
251
552
  elif default == "async":
@@ -254,4 +555,5 @@ def a_sync(
254
555
  deco = ASyncDecorator(default=default, **modifiers)
255
556
  return deco if coro_fn is None else deco(coro_fn) # type: ignore [arg-type]
256
557
 
257
- # TODO: in a future release, I will make this usable with sync functions as well
558
+
559
+ # TODO: in a future release, I will make this usable with sync functions as well