ez-a-sync 0.33.4__cp313-cp313-musllinux_1_2_i686.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.
Files changed (177) hide show
  1. a_sync/ENVIRONMENT_VARIABLES.py +42 -0
  2. a_sync/__init__.pxd +2 -0
  3. a_sync/__init__.py +145 -0
  4. a_sync/_smart.c +22830 -0
  5. a_sync/_smart.cpython-313-i386-linux-musl.so +0 -0
  6. a_sync/_smart.pxd +2 -0
  7. a_sync/_smart.pyi +202 -0
  8. a_sync/_smart.pyx +674 -0
  9. a_sync/_typing.py +258 -0
  10. a_sync/a_sync/__init__.py +60 -0
  11. a_sync/a_sync/_descriptor.c +20537 -0
  12. a_sync/a_sync/_descriptor.cpython-313-i386-linux-musl.so +0 -0
  13. a_sync/a_sync/_descriptor.pyi +33 -0
  14. a_sync/a_sync/_descriptor.pyx +422 -0
  15. a_sync/a_sync/_flags.c +6082 -0
  16. a_sync/a_sync/_flags.cpython-313-i386-linux-musl.so +0 -0
  17. a_sync/a_sync/_flags.pxd +3 -0
  18. a_sync/a_sync/_flags.pyx +92 -0
  19. a_sync/a_sync/_helpers.c +14529 -0
  20. a_sync/a_sync/_helpers.cpython-313-i386-linux-musl.so +0 -0
  21. a_sync/a_sync/_helpers.pxd +3 -0
  22. a_sync/a_sync/_helpers.pyi +10 -0
  23. a_sync/a_sync/_helpers.pyx +167 -0
  24. a_sync/a_sync/_kwargs.c +12202 -0
  25. a_sync/a_sync/_kwargs.cpython-313-i386-linux-musl.so +0 -0
  26. a_sync/a_sync/_kwargs.pxd +2 -0
  27. a_sync/a_sync/_kwargs.pyx +64 -0
  28. a_sync/a_sync/_meta.py +210 -0
  29. a_sync/a_sync/abstract.c +12420 -0
  30. a_sync/a_sync/abstract.cpython-313-i386-linux-musl.so +0 -0
  31. a_sync/a_sync/abstract.pyi +141 -0
  32. a_sync/a_sync/abstract.pyx +221 -0
  33. a_sync/a_sync/base.c +14940 -0
  34. a_sync/a_sync/base.cpython-313-i386-linux-musl.so +0 -0
  35. a_sync/a_sync/base.pyi +60 -0
  36. a_sync/a_sync/base.pyx +271 -0
  37. a_sync/a_sync/config.py +168 -0
  38. a_sync/a_sync/decorator.py +651 -0
  39. a_sync/a_sync/flags.c +5272 -0
  40. a_sync/a_sync/flags.cpython-313-i386-linux-musl.so +0 -0
  41. a_sync/a_sync/flags.pxd +72 -0
  42. a_sync/a_sync/flags.pyi +74 -0
  43. a_sync/a_sync/flags.pyx +72 -0
  44. a_sync/a_sync/function.c +37856 -0
  45. a_sync/a_sync/function.cpython-313-i386-linux-musl.so +0 -0
  46. a_sync/a_sync/function.pxd +28 -0
  47. a_sync/a_sync/function.pyi +571 -0
  48. a_sync/a_sync/function.pyx +1381 -0
  49. a_sync/a_sync/method.c +29662 -0
  50. a_sync/a_sync/method.cpython-313-i386-linux-musl.so +0 -0
  51. a_sync/a_sync/method.pxd +9 -0
  52. a_sync/a_sync/method.pyi +523 -0
  53. a_sync/a_sync/method.pyx +1023 -0
  54. a_sync/a_sync/modifiers/__init__.pxd +1 -0
  55. a_sync/a_sync/modifiers/__init__.py +101 -0
  56. a_sync/a_sync/modifiers/cache/__init__.py +160 -0
  57. a_sync/a_sync/modifiers/cache/memory.py +165 -0
  58. a_sync/a_sync/modifiers/limiter.py +132 -0
  59. a_sync/a_sync/modifiers/manager.c +16157 -0
  60. a_sync/a_sync/modifiers/manager.cpython-313-i386-linux-musl.so +0 -0
  61. a_sync/a_sync/modifiers/manager.pxd +5 -0
  62. a_sync/a_sync/modifiers/manager.pyi +219 -0
  63. a_sync/a_sync/modifiers/manager.pyx +299 -0
  64. a_sync/a_sync/modifiers/semaphores.py +173 -0
  65. a_sync/a_sync/property.c +27268 -0
  66. a_sync/a_sync/property.cpython-313-i386-linux-musl.so +0 -0
  67. a_sync/a_sync/property.pyi +376 -0
  68. a_sync/a_sync/property.pyx +819 -0
  69. a_sync/a_sync/singleton.py +63 -0
  70. a_sync/aliases.py +3 -0
  71. a_sync/async_property/__init__.pxd +1 -0
  72. a_sync/async_property/__init__.py +1 -0
  73. a_sync/async_property/cached.c +20397 -0
  74. a_sync/async_property/cached.cpython-313-i386-linux-musl.so +0 -0
  75. a_sync/async_property/cached.pxd +10 -0
  76. a_sync/async_property/cached.pyi +45 -0
  77. a_sync/async_property/cached.pyx +178 -0
  78. a_sync/async_property/proxy.c +34662 -0
  79. a_sync/async_property/proxy.cpython-313-i386-linux-musl.so +0 -0
  80. a_sync/async_property/proxy.pxd +2 -0
  81. a_sync/async_property/proxy.pyi +124 -0
  82. a_sync/async_property/proxy.pyx +474 -0
  83. a_sync/asyncio/__init__.pxd +6 -0
  84. a_sync/asyncio/__init__.py +164 -0
  85. a_sync/asyncio/as_completed.c +18849 -0
  86. a_sync/asyncio/as_completed.cpython-313-i386-linux-musl.so +0 -0
  87. a_sync/asyncio/as_completed.pxd +8 -0
  88. a_sync/asyncio/as_completed.pyi +109 -0
  89. a_sync/asyncio/as_completed.pyx +269 -0
  90. a_sync/asyncio/create_task.c +15912 -0
  91. a_sync/asyncio/create_task.cpython-313-i386-linux-musl.so +0 -0
  92. a_sync/asyncio/create_task.pxd +2 -0
  93. a_sync/asyncio/create_task.pyi +51 -0
  94. a_sync/asyncio/create_task.pyx +271 -0
  95. a_sync/asyncio/gather.c +16687 -0
  96. a_sync/asyncio/gather.cpython-313-i386-linux-musl.so +0 -0
  97. a_sync/asyncio/gather.pyi +107 -0
  98. a_sync/asyncio/gather.pyx +218 -0
  99. a_sync/asyncio/igather.c +13080 -0
  100. a_sync/asyncio/igather.cpython-313-i386-linux-musl.so +0 -0
  101. a_sync/asyncio/igather.pxd +1 -0
  102. a_sync/asyncio/igather.pyi +8 -0
  103. a_sync/asyncio/igather.pyx +183 -0
  104. a_sync/asyncio/sleep.c +9601 -0
  105. a_sync/asyncio/sleep.cpython-313-i386-linux-musl.so +0 -0
  106. a_sync/asyncio/sleep.pyi +14 -0
  107. a_sync/asyncio/sleep.pyx +49 -0
  108. a_sync/debugging.c +15370 -0
  109. a_sync/debugging.cpython-313-i386-linux-musl.so +0 -0
  110. a_sync/debugging.pyi +76 -0
  111. a_sync/debugging.pyx +107 -0
  112. a_sync/exceptions.c +13320 -0
  113. a_sync/exceptions.cpython-313-i386-linux-musl.so +0 -0
  114. a_sync/exceptions.pyi +376 -0
  115. a_sync/exceptions.pyx +446 -0
  116. a_sync/executor.py +619 -0
  117. a_sync/functools.c +12746 -0
  118. a_sync/functools.cpython-313-i386-linux-musl.so +0 -0
  119. a_sync/functools.pxd +7 -0
  120. a_sync/functools.pyi +33 -0
  121. a_sync/functools.pyx +139 -0
  122. a_sync/future.py +1497 -0
  123. a_sync/iter.c +37279 -0
  124. a_sync/iter.cpython-313-i386-linux-musl.so +0 -0
  125. a_sync/iter.pxd +11 -0
  126. a_sync/iter.pyi +370 -0
  127. a_sync/iter.pyx +981 -0
  128. a_sync/primitives/__init__.pxd +1 -0
  129. a_sync/primitives/__init__.py +53 -0
  130. a_sync/primitives/_debug.c +15765 -0
  131. a_sync/primitives/_debug.cpython-313-i386-linux-musl.so +0 -0
  132. a_sync/primitives/_debug.pxd +12 -0
  133. a_sync/primitives/_debug.pyi +52 -0
  134. a_sync/primitives/_debug.pyx +223 -0
  135. a_sync/primitives/_loggable.c +11538 -0
  136. a_sync/primitives/_loggable.cpython-313-i386-linux-musl.so +0 -0
  137. a_sync/primitives/_loggable.pxd +4 -0
  138. a_sync/primitives/_loggable.pyi +66 -0
  139. a_sync/primitives/_loggable.pyx +102 -0
  140. a_sync/primitives/locks/__init__.pxd +8 -0
  141. a_sync/primitives/locks/__init__.py +17 -0
  142. a_sync/primitives/locks/counter.c +17938 -0
  143. a_sync/primitives/locks/counter.cpython-313-i386-linux-musl.so +0 -0
  144. a_sync/primitives/locks/counter.pxd +12 -0
  145. a_sync/primitives/locks/counter.pyi +151 -0
  146. a_sync/primitives/locks/counter.pyx +267 -0
  147. a_sync/primitives/locks/event.c +17072 -0
  148. a_sync/primitives/locks/event.cpython-313-i386-linux-musl.so +0 -0
  149. a_sync/primitives/locks/event.pxd +22 -0
  150. a_sync/primitives/locks/event.pyi +43 -0
  151. a_sync/primitives/locks/event.pyx +185 -0
  152. a_sync/primitives/locks/prio_semaphore.c +25635 -0
  153. a_sync/primitives/locks/prio_semaphore.cpython-313-i386-linux-musl.so +0 -0
  154. a_sync/primitives/locks/prio_semaphore.pxd +25 -0
  155. a_sync/primitives/locks/prio_semaphore.pyi +217 -0
  156. a_sync/primitives/locks/prio_semaphore.pyx +597 -0
  157. a_sync/primitives/locks/semaphore.c +26553 -0
  158. a_sync/primitives/locks/semaphore.cpython-313-i386-linux-musl.so +0 -0
  159. a_sync/primitives/locks/semaphore.pxd +21 -0
  160. a_sync/primitives/locks/semaphore.pyi +197 -0
  161. a_sync/primitives/locks/semaphore.pyx +454 -0
  162. a_sync/primitives/queue.py +1026 -0
  163. a_sync/py.typed +0 -0
  164. a_sync/sphinx/__init__.py +3 -0
  165. a_sync/sphinx/ext.py +289 -0
  166. a_sync/task.py +934 -0
  167. a_sync/utils/__init__.py +105 -0
  168. a_sync/utils/iterators.py +297 -0
  169. a_sync/utils/repr.c +15866 -0
  170. a_sync/utils/repr.cpython-313-i386-linux-musl.so +0 -0
  171. a_sync/utils/repr.pyi +2 -0
  172. a_sync/utils/repr.pyx +73 -0
  173. ez_a_sync-0.33.4.dist-info/METADATA +368 -0
  174. ez_a_sync-0.33.4.dist-info/RECORD +177 -0
  175. ez_a_sync-0.33.4.dist-info/WHEEL +5 -0
  176. ez_a_sync-0.33.4.dist-info/licenses/LICENSE.txt +17 -0
  177. ez_a_sync-0.33.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,651 @@
1
+ # mypy: disable-error-code=valid-type
2
+ # mypy: disable-error-code=misc
3
+ from concurrent.futures import Executor
4
+ from a_sync._typing import *
5
+ from a_sync.a_sync import config
6
+ from a_sync.a_sync.function import (
7
+ ASyncDecorator,
8
+ ASyncFunction,
9
+ ASyncDecoratorAsyncDefault,
10
+ ASyncDecoratorSyncDefault,
11
+ ASyncFunctionAsyncDefault,
12
+ ASyncFunctionSyncDefault,
13
+ )
14
+
15
+ ########################
16
+ # The a_sync decorator #
17
+ ########################
18
+
19
+ # @a_sync
20
+ # def some_fn():
21
+ # pass
22
+ #
23
+ # @a_sync
24
+ # async def some_fn():
25
+ # pass
26
+
27
+
28
+ @overload
29
+ def a_sync(
30
+ default: Literal["async"],
31
+ executor: Executor,
32
+ **modifiers: Unpack[ModifierKwargs],
33
+ ) -> ASyncDecoratorAsyncDefault:
34
+ """
35
+ Creates an asynchronous default decorator to run a sync function in an executor.
36
+
37
+ Args:
38
+ default: Specifies the default execution mode as 'async'.
39
+ executor: The executor that will be used to call the sync function.
40
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
41
+
42
+ Examples:
43
+ Basic usage with an asynchronous default:
44
+
45
+ >>> @a_sync(default='async', executor=ThreadPoolExecutor(4))
46
+ ... def my_function():
47
+ ... return True
48
+ >>> await my_function()
49
+ True
50
+ >>> my_function(sync=True)
51
+ True
52
+
53
+ See Also:
54
+ :class:`ASyncDecoratorAsyncDefault`
55
+ """
56
+
57
+
58
+ @overload
59
+ def a_sync(
60
+ default: Literal["async"],
61
+ **modifiers: Unpack[ModifierKwargs],
62
+ ) -> ASyncDecoratorAsyncDefault:
63
+ """
64
+ Creates an asynchronous default decorator.
65
+
66
+ Args:
67
+ default: Specifies the default execution mode as 'async'.
68
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
69
+
70
+ Examples:
71
+ Basic usage with an asynchronous default:
72
+
73
+ >>> @a_sync(default='async')
74
+ ... async def my_function():
75
+ ... return True
76
+ >>> await my_function()
77
+ True
78
+ >>> my_function(sync=True)
79
+ True
80
+
81
+ See Also:
82
+ :class:`ASyncDecoratorAsyncDefault`
83
+ """
84
+
85
+
86
+ @overload
87
+ def a_sync(
88
+ default: Literal["sync"],
89
+ executor: Executor,
90
+ **modifiers: Unpack[ModifierKwargs],
91
+ ) -> ASyncDecoratorSyncDefault:
92
+ """
93
+ Creates a synchronous default decorator to run a sync function in an executor when called asynchronously.
94
+
95
+ Args:
96
+ default: Specifies the default execution mode as 'sync'.
97
+ executor: The executor that will be used to call the sync function.
98
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
99
+
100
+ Examples:
101
+ Usage with an executor without specifying a default mode:
102
+
103
+ >>> @a_sync(default="sync", executor=ThreadPoolExecutor(4))
104
+ ... def my_function():
105
+ ... return True
106
+ >>> my_function()
107
+ True
108
+ >>> await my_function(sync=False)
109
+ True
110
+
111
+ See Also:
112
+ :class:`ASyncDecoratorSyncDefault`
113
+ """
114
+
115
+
116
+ @overload
117
+ def a_sync(
118
+ default: Literal["sync"],
119
+ **modifiers: Unpack[ModifierKwargs],
120
+ ) -> ASyncDecoratorSyncDefault:
121
+ """
122
+ Creates a synchronous default decorator.
123
+
124
+ Args:
125
+ default: Specifies the default execution mode as 'sync'.
126
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
127
+
128
+ Examples:
129
+ Basic usage with a synchronous default:
130
+
131
+ >>> @a_sync(default='sync')
132
+ ... def my_function():
133
+ ... return True
134
+ >>> my_function()
135
+ True
136
+ >>> await my_function(sync=False)
137
+ True
138
+
139
+ See Also:
140
+ :class:`ASyncDecoratorSyncDefault`
141
+ """
142
+
143
+
144
+ @overload
145
+ def a_sync(
146
+ executor: Executor,
147
+ **modifiers: Unpack[ModifierKwargs],
148
+ ) -> ASyncDecoratorSyncDefault:
149
+ """
150
+ Creates a synchronous default decorator to run a sync function in an executor when called asynchronously.
151
+
152
+ Args:
153
+ executor: The executor that will be used to call the sync function.
154
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
155
+
156
+ Examples:
157
+ Usage with an executor without specifying a default mode:
158
+
159
+ >>> @a_sync(executor=ThreadPoolExecutor(4))
160
+ ... def my_function():
161
+ ... return True
162
+ >>> my_function()
163
+ True
164
+ >>> await my_function(sync=False)
165
+ True
166
+
167
+ See Also:
168
+ :class:`ASyncDecoratorSyncDefault`
169
+ """
170
+
171
+
172
+ @overload
173
+ def a_sync(
174
+ **modifiers: Unpack[ModifierKwargs],
175
+ ) -> ASyncDecorator:
176
+ """
177
+ Creates a decorator with no default execution mode specified.
178
+
179
+ Args:
180
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
181
+
182
+ Examples:
183
+ Usage without specifying a default mode:
184
+
185
+ >>> @a_sync
186
+ ... async def my_function():
187
+ ... return True
188
+ >>> await my_function()
189
+ True
190
+ >>> my_function(sync=True)
191
+ True
192
+
193
+ See Also:
194
+ :class:`ASyncDecorator`
195
+ """
196
+
197
+
198
+ @overload # async def, None default
199
+ def a_sync(
200
+ coro_fn: CoroFn[P, T],
201
+ default: Literal[None] = None,
202
+ **modifiers: Unpack[ModifierKwargs],
203
+ ) -> "ASyncFunctionAsyncDefault[P, T]":
204
+ """
205
+ Decorates an asynchronous function with no default execution mode specified.
206
+
207
+ Args:
208
+ coro_fn: The coroutine function to be decorated.
209
+ default: Specifies no default execution mode.
210
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
211
+
212
+ Examples:
213
+ Decorating an asynchronous function without a default mode:
214
+
215
+ >>> async def my_function():
216
+ ... return True
217
+ >>> decorated_function = a_sync(my_function)
218
+ >>> await decorated_function()
219
+ True
220
+ >>> decorated_function(sync=True)
221
+ True
222
+
223
+ See Also:
224
+ :class:`ASyncFunctionAsyncDefault`
225
+ """
226
+
227
+
228
+ @overload # sync def none default
229
+ def a_sync(
230
+ coro_fn: SyncFn[P, T],
231
+ default: Literal[None] = None,
232
+ **modifiers: Unpack[ModifierKwargs],
233
+ ) -> "ASyncFunctionSyncDefault[P, T]":
234
+ """
235
+ Decorates a synchronous function with no default execution mode specified.
236
+
237
+ Args:
238
+ coro_fn: The synchronous function to be decorated.
239
+ default: Specifies no default execution mode.
240
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
241
+
242
+ Examples:
243
+ Decorating a synchronous function without a default mode:
244
+
245
+ >>> def my_function():
246
+ ... return True
247
+ >>> decorated_function = a_sync(my_function)
248
+ >>> decorated_function()
249
+ True
250
+ >>> await decorated_function(sync=False)
251
+ True
252
+
253
+ See Also:
254
+ :class:`ASyncFunctionSyncDefault`
255
+ """
256
+
257
+
258
+ @overload
259
+ def a_sync(
260
+ coro_fn: Literal[None],
261
+ default: Literal["async"],
262
+ **modifiers: Unpack[ModifierKwargs],
263
+ ) -> ASyncDecoratorAsyncDefault:
264
+ """
265
+ Creates an asynchronous default decorator with no function specified.
266
+
267
+ Args:
268
+ coro_fn: Specifies no function.
269
+ default: Specifies the default execution mode as 'async'.
270
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
271
+
272
+ Examples:
273
+ Creating an asynchronous default decorator without a function:
274
+
275
+ >>> @a_sync(default='async')
276
+ ... async def my_function():
277
+ ... return True
278
+ >>> await my_function()
279
+ True
280
+ >>> my_function(sync=True)
281
+ True
282
+
283
+ See Also:
284
+ :class:`ASyncDecoratorAsyncDefault`
285
+ """
286
+
287
+
288
+ @overload # if you try to use default as the only arg
289
+ def a_sync(
290
+ coro_fn: Literal["async"],
291
+ default: Literal[None],
292
+ **modifiers: Unpack[ModifierKwargs],
293
+ ) -> ASyncDecoratorAsyncDefault:
294
+ """
295
+ Creates an asynchronous default decorator with no default execution mode specified.
296
+
297
+ Args:
298
+ coro_fn: Specifies the default execution mode as 'async'.
299
+ default: Specifies no default execution mode.
300
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
301
+
302
+ Examples:
303
+ Using 'async' as the only argument:
304
+
305
+ >>> @a_sync('async')
306
+ ... async def my_function():
307
+ ... return True
308
+ >>> await my_function()
309
+ True
310
+ >>> my_function(sync=True)
311
+ True
312
+
313
+ See Also:
314
+ :class:`ASyncDecoratorAsyncDefault`
315
+ """
316
+
317
+
318
+ @overload # async def, async default
319
+ def a_sync(
320
+ coro_fn: CoroFn[P, T],
321
+ default: Literal["async"],
322
+ **modifiers: Unpack[ModifierKwargs],
323
+ ) -> "ASyncFunctionAsyncDefault[P, T]":
324
+ """
325
+ Decorates an asynchronous function with an asynchronous default execution mode.
326
+
327
+ Args:
328
+ coro_fn: The coroutine function to be decorated.
329
+ default: Specifies the default execution mode as 'async'.
330
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
331
+
332
+ Examples:
333
+ Decorating an asynchronous function with an async default:
334
+
335
+ >>> async def my_function():
336
+ ... return True
337
+ >>> decorated_function = a_sync(my_function, default='async')
338
+ >>> await decorated_function()
339
+ True
340
+ >>> decorated_function(sync=True)
341
+ True
342
+
343
+ See Also:
344
+ :class:`ASyncFunctionAsyncDefault`
345
+ """
346
+
347
+
348
+ @overload # sync def async default
349
+ def a_sync(
350
+ coro_fn: SyncFn[P, T],
351
+ default: Literal["async"],
352
+ **modifiers: Unpack[ModifierKwargs],
353
+ ) -> "ASyncFunctionAsyncDefault[P, T]":
354
+ """
355
+ Decorates a synchronous function with an asynchronous default execution mode.
356
+
357
+ Args:
358
+ coro_fn: The synchronous function to be decorated.
359
+ default: Specifies the default execution mode as 'async'.
360
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
361
+
362
+ Examples:
363
+ Decorating a synchronous function with an async default:
364
+
365
+ >>> def my_function():
366
+ ... return True
367
+ >>> decorated_function = a_sync(my_function, default='async')
368
+ >>> await decorated_function()
369
+ True
370
+ >>> decorated_function(sync=True)
371
+ True
372
+
373
+ See Also:
374
+ :class:`ASyncFunctionAsyncDefault`
375
+ """
376
+
377
+
378
+ @overload # async def, sync default
379
+ def a_sync(
380
+ coro_fn: CoroFn[P, T],
381
+ default: Literal["sync"],
382
+ **modifiers: Unpack[ModifierKwargs],
383
+ ) -> ASyncFunctionSyncDefault:
384
+ """
385
+ Decorates an asynchronous function with a synchronous default execution mode.
386
+
387
+ Args:
388
+ coro_fn: The coroutine function to be decorated.
389
+ default: Specifies the default execution mode as 'sync'.
390
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
391
+
392
+ Examples:
393
+ Decorating an asynchronous function with a sync default:
394
+
395
+ >>> async def my_function():
396
+ ... return True
397
+ >>> decorated_function = a_sync(my_function, default='sync')
398
+ >>> decorated_function()
399
+ True
400
+ >>> await decorated_function(sync=False)
401
+ True
402
+
403
+ See Also:
404
+ :class:`ASyncFunctionSyncDefault`
405
+ """
406
+
407
+
408
+ @overload # sync def sync default
409
+ def a_sync(
410
+ coro_fn: SyncFn[P, T],
411
+ default: Literal["sync"],
412
+ **modifiers: Unpack[ModifierKwargs],
413
+ ) -> ASyncFunctionSyncDefault:
414
+ """
415
+ Decorates a synchronous function with a synchronous default execution mode.
416
+
417
+ Args:
418
+ coro_fn: The synchronous function to be decorated.
419
+ default: Specifies the default execution mode as 'sync'.
420
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
421
+
422
+ Examples:
423
+ Decorating a synchronous function with a sync default:
424
+
425
+ >>> def my_function():
426
+ ... return True
427
+ >>> decorated_function = a_sync(my_function, default='sync')
428
+ >>> decorated_function()
429
+ True
430
+ >>> await decorated_function(sync=False)
431
+ True
432
+
433
+ See Also:
434
+ :class:`ASyncFunctionSyncDefault`
435
+ """
436
+
437
+
438
+ @overload
439
+ def a_sync(
440
+ coro_fn: Literal[None],
441
+ default: Literal["sync"],
442
+ **modifiers: Unpack[ModifierKwargs],
443
+ ) -> ASyncDecoratorSyncDefault:
444
+ """
445
+ Creates a synchronous default decorator with no function specified.
446
+
447
+ Args:
448
+ coro_fn: Specifies no function.
449
+ default: Specifies the default execution mode as 'sync'.
450
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
451
+
452
+ Examples:
453
+ Creating a synchronous default decorator without a function:
454
+
455
+ >>> @a_sync(default='sync')
456
+ ... def my_function():
457
+ ... return True
458
+ >>> my_function()
459
+ True
460
+ >>> await my_function(sync=False)
461
+ True
462
+
463
+ See Also:
464
+ :class:`ASyncDecoratorSyncDefault`
465
+ """
466
+
467
+
468
+ @overload # if you try to use default as the only arg
469
+ def a_sync(
470
+ coro_fn: Literal["sync"],
471
+ default: Literal[None] = None,
472
+ **modifiers: Unpack[ModifierKwargs],
473
+ ) -> ASyncDecoratorSyncDefault:
474
+ """
475
+ Creates a synchronous default decorator with no default execution mode specified.
476
+
477
+ Args:
478
+ coro_fn: Specifies the default execution mode as 'sync'.
479
+ default: Specifies no default execution mode.
480
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
481
+
482
+ Examples:
483
+ Using 'sync' as the only argument:
484
+
485
+ >>> @a_sync('sync')
486
+ ... def my_function():
487
+ ... return True
488
+ >>> my_function()
489
+ True
490
+ >>> await my_function(sync=False)
491
+ True
492
+
493
+ See Also:
494
+ :class:`ASyncDecoratorSyncDefault`
495
+ """
496
+
497
+
498
+ @overload # if you try to use default as the only arg
499
+ def a_sync(
500
+ coro_fn: Literal["sync"],
501
+ default: Literal[None],
502
+ **modifiers: Unpack[ModifierKwargs],
503
+ ) -> ASyncDecoratorSyncDefault:
504
+ """
505
+ Creates a synchronous default decorator with no default execution mode specified.
506
+
507
+ Args:
508
+ coro_fn: Specifies the default execution mode as 'sync'.
509
+ default: Specifies no default execution mode.
510
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
511
+
512
+ Examples:
513
+ Using 'sync' as the only argument:
514
+
515
+ >>> @a_sync('sync')
516
+ ... def my_function():
517
+ ... return True
518
+ >>> my_function()
519
+ True
520
+ >>> await my_function(sync=False)
521
+ True
522
+
523
+ See Also:
524
+ :class:`ASyncDecoratorSyncDefault`
525
+ """
526
+
527
+
528
+ # catchall
529
+ def a_sync(
530
+ coro_fn: Optional[AnyFn[P, T]] = None,
531
+ default: DefaultMode = config.DEFAULT_MODE,
532
+ # default values are set by passing these kwargs into a ModifierManager object.
533
+ **modifiers: Unpack[ModifierKwargs],
534
+ ) -> Union[ASyncDecorator, "ASyncFunction[P, T]"]:
535
+ """
536
+ A versatile decorator that enables both synchronous and asynchronous execution of functions.
537
+
538
+ This decorator allows a function to be called either synchronously or asynchronously,
539
+ depending on the context and parameters. It provides a powerful way to write code
540
+ that can be used in both synchronous and asynchronous environments.
541
+
542
+ Args:
543
+ coro_fn: The function to be decorated. Can be either a coroutine function or a regular function.
544
+ default: Determines the default execution mode. Can be 'async', 'sync', or None.
545
+ If None, the mode is inferred from the decorated function type.
546
+ **modifiers: Additional keyword arguments to modify the behavior of the decorated function.
547
+ See :class:`ModifierKwargs` for available options.
548
+
549
+ Modifiers:
550
+ The following modifiers can be used to customize the behavior of the decorator:
551
+
552
+ - cache_type: Can be None or 'memory'. 'memory' is an LRU cache which can be modified with
553
+ the 'cache_typed', 'ram_cache_maxsize', and 'ram_cache_ttl' modifiers.
554
+ - cache_typed: Set to True if you want types considered for cache keys. For example, with
555
+ cache_typed=True, Decimal(0) and 0 will be considered separate keys.
556
+ - ram_cache_maxsize: The max size for your LRU cache. None if the cache is unbounded. If you
557
+ set this value without specifying a cache type, 'memory' will automatically be applied.
558
+ - ram_cache_ttl: The TTL for items in your LRU cache. Set to None. If you set this value
559
+ without specifying a cache type, 'memory' will automatically be applied.
560
+ - runs_per_minute: Setting this value enables a rate limiter for the decorated function.
561
+ - semaphore: Drop in a Semaphore for your async defined functions.
562
+ - executor: The executor for the synchronous function. Set to the library's default of
563
+ config.default_sync_executor.
564
+
565
+ Examples:
566
+ The decorator can be used in several ways.
567
+
568
+ 1. As a simple decorator:
569
+ >>> @a_sync
570
+ ... async def some_async_fn():
571
+ ... return True
572
+ >>> await some_async_fn()
573
+ True
574
+ >>> some_async_fn(sync=True)
575
+ True
576
+
577
+ >>> @a_sync
578
+ ... def some_sync_fn():
579
+ ... return True
580
+ >>> some_sync_fn()
581
+ True
582
+ >>> some_sync_fn(sync=False)
583
+ <coroutine object some_sync_fn at 0x7fb4f5fb49c0>
584
+
585
+ 2. As a decorator with default mode specified:
586
+ >>> @a_sync(default='sync')
587
+ ... async def some_fn():
588
+ ... return True
589
+ ...
590
+ >>> some_fn()
591
+ True
592
+ >>> some_fn(sync=False)
593
+ <coroutine object some_fn at 0x7fb4f5fb49c0>
594
+
595
+ >>> @a_sync('async')
596
+ ... def some_fn():
597
+ ... return True
598
+ ...
599
+ >>> some_fn()
600
+ <coroutine object some_fn at 0x7fb4f5fb49c0>
601
+ >>> some_fn(asynchronous=False)
602
+ True
603
+
604
+ 3. As a decorator with modifiers:
605
+ >>> @a_sync(cache_type='memory', runs_per_minute=60)
606
+ ... async def some_fn():
607
+ ... return True
608
+ ...
609
+ >>> some_fn(sync=True)
610
+ True
611
+
612
+ 4. Applied directly to a function:
613
+ >>> some_fn = a_sync(some_existing_function, default='sync')
614
+ >>> some_fn()
615
+ "some return value"
616
+
617
+ The decorated function can then be called either synchronously or asynchronously:
618
+ >>> result = some_fn() # Synchronous call
619
+ >>> result = await some_fn() # Asynchronous call
620
+
621
+ The execution mode can also be explicitly specified during the call:
622
+ >>> result = some_fn(sync=True) # Force synchronous execution
623
+ >>> result = await some_fn(sync=False) # Force asynchronous execution
624
+
625
+ This decorator is particularly useful for libraries that need to support
626
+ both synchronous and asynchronous usage, or for gradually migrating
627
+ synchronous code to asynchronous without breaking existing interfaces.
628
+
629
+ Note:
630
+ If the `coro_fn` argument is passed as 'async' or 'sync', it is treated as the `default` argument,
631
+ and `coro_fn` is set to `None`.
632
+
633
+ See Also:
634
+ :class:`ASyncFunction`, :class:`ASyncDecorator`
635
+ """
636
+
637
+ # If the dev tried passing a default as an arg instead of a kwarg, ie: @a_sync('sync')...
638
+ if coro_fn in ("async", "sync"):
639
+ default = coro_fn # type: ignore [assignment]
640
+ coro_fn = None
641
+
642
+ if default == "sync":
643
+ deco = ASyncDecoratorSyncDefault(default=default, **modifiers)
644
+ elif default == "async":
645
+ deco = ASyncDecoratorAsyncDefault(default=default, **modifiers)
646
+ else:
647
+ deco = ASyncDecorator(default=default, **modifiers)
648
+ return deco if coro_fn is None else deco(coro_fn) # type: ignore [arg-type]
649
+
650
+
651
+ # TODO: in a future release, I will make this usable with sync functions as well