ez-a-sync 0.32.24__cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_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.

Potentially problematic release.


This version of ez-a-sync might be problematic. Click here for more details.

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 +22686 -0
  5. a_sync/_smart.cpython-39-i386-linux-gnu.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 +19749 -0
  12. a_sync/a_sync/_descriptor.cpython-39-i386-linux-gnu.so +0 -0
  13. a_sync/a_sync/_descriptor.pyi +34 -0
  14. a_sync/a_sync/_descriptor.pyx +422 -0
  15. a_sync/a_sync/_flags.c +5687 -0
  16. a_sync/a_sync/_flags.cpython-39-i386-linux-gnu.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 +13722 -0
  20. a_sync/a_sync/_helpers.cpython-39-i386-linux-gnu.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 +10672 -0
  25. a_sync/a_sync/_kwargs.cpython-39-i386-linux-gnu.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 +11350 -0
  30. a_sync/a_sync/abstract.cpython-39-i386-linux-gnu.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 +14066 -0
  34. a_sync/a_sync/base.cpython-39-i386-linux-gnu.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 +4471 -0
  40. a_sync/a_sync/flags.cpython-39-i386-linux-gnu.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 +38189 -0
  45. a_sync/a_sync/function.cpython-39-i386-linux-gnu.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 +30587 -0
  50. a_sync/a_sync/method.cpython-39-i386-linux-gnu.so +0 -0
  51. a_sync/a_sync/method.pxd +9 -0
  52. a_sync/a_sync/method.pyi +524 -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 +14939 -0
  60. a_sync/a_sync/modifiers/manager.cpython-39-i386-linux-gnu.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 +28130 -0
  66. a_sync/a_sync/property.cpython-39-i386-linux-gnu.so +0 -0
  67. a_sync/a_sync/property.pyi +376 -0
  68. a_sync/a_sync/property.pyx +820 -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 +20542 -0
  74. a_sync/async_property/cached.cpython-39-i386-linux-gnu.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 +36410 -0
  79. a_sync/async_property/proxy.cpython-39-i386-linux-gnu.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 +18198 -0
  86. a_sync/asyncio/as_completed.cpython-39-i386-linux-gnu.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 +15109 -0
  91. a_sync/asyncio/create_task.cpython-39-i386-linux-gnu.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 +276 -0
  95. a_sync/asyncio/gather.c +15735 -0
  96. a_sync/asyncio/gather.cpython-39-i386-linux-gnu.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 +11984 -0
  100. a_sync/asyncio/igather.cpython-39-i386-linux-gnu.so +0 -0
  101. a_sync/asyncio/igather.pxd +1 -0
  102. a_sync/asyncio/igather.pyi +7 -0
  103. a_sync/asyncio/igather.pyx +182 -0
  104. a_sync/asyncio/sleep.c +8916 -0
  105. a_sync/asyncio/sleep.cpython-39-i386-linux-gnu.so +0 -0
  106. a_sync/asyncio/sleep.pyi +14 -0
  107. a_sync/asyncio/sleep.pyx +49 -0
  108. a_sync/debugging.c +15157 -0
  109. a_sync/debugging.cpython-39-i386-linux-gnu.so +0 -0
  110. a_sync/debugging.pyi +76 -0
  111. a_sync/debugging.pyx +107 -0
  112. a_sync/exceptions.c +13169 -0
  113. a_sync/exceptions.cpython-39-i386-linux-gnu.so +0 -0
  114. a_sync/exceptions.pyi +376 -0
  115. a_sync/exceptions.pyx +446 -0
  116. a_sync/executor.py +575 -0
  117. a_sync/functools.c +11489 -0
  118. a_sync/functools.cpython-39-i386-linux-gnu.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 +37702 -0
  124. a_sync/iter.cpython-39-i386-linux-gnu.so +0 -0
  125. a_sync/iter.pxd +11 -0
  126. a_sync/iter.pyi +366 -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 +14737 -0
  131. a_sync/primitives/_debug.cpython-39-i386-linux-gnu.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 +10569 -0
  136. a_sync/primitives/_loggable.cpython-39-i386-linux-gnu.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 +16972 -0
  143. a_sync/primitives/locks/counter.cpython-39-i386-linux-gnu.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 +260 -0
  147. a_sync/primitives/locks/event.c +16125 -0
  148. a_sync/primitives/locks/event.cpython-39-i386-linux-gnu.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 +25204 -0
  153. a_sync/primitives/locks/prio_semaphore.cpython-39-i386-linux-gnu.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 +25813 -0
  158. a_sync/primitives/locks/semaphore.cpython-39-i386-linux-gnu.so +0 -0
  159. a_sync/primitives/locks/semaphore.pxd +21 -0
  160. a_sync/primitives/locks/semaphore.pyi +196 -0
  161. a_sync/primitives/locks/semaphore.pyx +454 -0
  162. a_sync/primitives/queue.py +1018 -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 +932 -0
  167. a_sync/utils/__init__.py +105 -0
  168. a_sync/utils/iterators.py +297 -0
  169. a_sync/utils/repr.c +14354 -0
  170. a_sync/utils/repr.cpython-39-i386-linux-gnu.so +0 -0
  171. a_sync/utils/repr.pyi +2 -0
  172. a_sync/utils/repr.pyx +73 -0
  173. ez_a_sync-0.32.24.dist-info/METADATA +367 -0
  174. ez_a_sync-0.32.24.dist-info/RECORD +177 -0
  175. ez_a_sync-0.32.24.dist-info/WHEEL +7 -0
  176. ez_a_sync-0.32.24.dist-info/licenses/LICENSE.txt +17 -0
  177. ez_a_sync-0.32.24.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2 @@
1
+ cdef object ccreate_task_simple(object coro)
2
+ cdef object ccreate_task(object coro, str name, bint skip_gc_until_done, bint log_destroy_pending)
@@ -0,0 +1,51 @@
1
+ """
2
+ This module extends :func:`asyncio.create_task` to support any :class:`Awaitable`,
3
+ manage task lifecycle, and enhance error handling.
4
+ """
5
+
6
+ from a_sync._typing import *
7
+ import asyncio
8
+
9
+ __all__ = ["create_task"]
10
+
11
+ def create_task(
12
+ coro: Awaitable[T],
13
+ *,
14
+ name: Optional[str] = None,
15
+ skip_gc_until_done: bool = False,
16
+ log_destroy_pending: bool = True
17
+ ) -> asyncio.Task[T]:
18
+ """
19
+ Extends :func:`asyncio.create_task` to support any :class:`Awaitable`, manage task lifecycle, and enhance error handling.
20
+
21
+ This function accepts any :class:`Awaitable`, ensuring broader compatibility. If the Awaitable is not a coroutine,
22
+ it is awaited directly using a private helper function `__await`, which can handle non-coroutine Awaitable objects.
23
+
24
+ Note:
25
+ The `__await` function is designed to handle non-coroutine Awaitables by awaiting them directly.
26
+
27
+ Args:
28
+ coro: An :class:`Awaitable` object from which to create the task.
29
+ name: Optional name for the task, aiding in debugging.
30
+ skip_gc_until_done: If True, the task is kept alive until it completes, preventing garbage collection.
31
+ Exceptions are wrapped in :class:`PersistedTaskException` for special handling within the
32
+ `__persisted_task_exc_wrap` function.
33
+ log_destroy_pending: If False, asyncio\'s default error log when a pending task is destroyed is suppressed.
34
+
35
+ Examples:
36
+ Create a simple task with a coroutine:
37
+
38
+ >>> async def my_coroutine():
39
+ ... return "Hello, World!"
40
+ >>> task = create_task(my_coroutine())
41
+
42
+ Create a task with a non-coroutine Awaitable:
43
+
44
+ >>> from concurrent.futures import Future
45
+ >>> future = Future()
46
+ >>> task = create_task(future)
47
+
48
+ See Also:
49
+ - :func:`asyncio.create_task`
50
+ - :class:`asyncio.Task`
51
+ """
@@ -0,0 +1,276 @@
1
+ """
2
+ This module extends :func:`asyncio.create_task` to support any :class:`Awaitable`,
3
+ manage task lifecycle, and enhance error handling.
4
+ """
5
+
6
+ import asyncio
7
+ import asyncio.tasks as aiotasks
8
+ import logging
9
+ import typing
10
+
11
+ from cpython.unicode cimport PyUnicode_CompareWithASCIIString
12
+ from cpython.version cimport PY_VERSION_HEX
13
+
14
+ from a_sync import _smart, exceptions
15
+ from a_sync._typing import T
16
+
17
+
18
+ # cdef asyncio
19
+ cdef object get_running_loop = asyncio.get_running_loop
20
+ cdef object iscoroutine = asyncio.iscoroutine
21
+ cdef object Future = asyncio.Future
22
+ cdef object CancelledError = asyncio.CancelledError
23
+ cdef object InvalidStateError = asyncio.InvalidStateError
24
+ cdef object Task = asyncio.Task
25
+ cdef object _GatheringFuture = aiotasks._GatheringFuture
26
+ del asyncio, aiotasks
27
+
28
+ # cdef logging
29
+ cdef public object logger = logging.getLogger(__name__)
30
+ del logging
31
+
32
+ # cdef typing
33
+ cdef object Awaitable = typing.Awaitable
34
+ cdef object Optional = typing.Optional
35
+ cdef object Tuple = typing.Tuple
36
+ cdef object Set = typing.Set
37
+ del typing
38
+
39
+ # cdef _smart
40
+ cdef object SmartTask = _smart.SmartTask
41
+ cdef object smart_task_factory = _smart.smart_task_factory
42
+ del _smart
43
+
44
+ # cdef exceptions
45
+ cdef object PersistedTaskException = exceptions.PersistedTaskException
46
+ del exceptions
47
+
48
+
49
+ def create_task(
50
+ coro: Awaitable[T],
51
+ *,
52
+ name: str = "",
53
+ skip_gc_until_done: bint = False,
54
+ log_destroy_pending: bint = True,
55
+ ) -> "Task[T]":
56
+ """
57
+ Extends :func:`asyncio.create_task` to support any :class:`Awaitable`, manage task lifecycle, and enhance error handling.
58
+
59
+ This function accepts any :class:`Awaitable`, ensuring broader compatibility. If the Awaitable is not a coroutine,
60
+ it is awaited directly using a private helper function `__await`, which can handle non-coroutine Awaitable objects.
61
+
62
+ Note:
63
+ The `__await` function is designed to handle non-coroutine Awaitables by awaiting them directly.
64
+
65
+ Args:
66
+ coro: An :class:`Awaitable` object from which to create the task.
67
+ name: Optional name for the task, aiding in debugging.
68
+ skip_gc_until_done: If True, the task is kept alive until it completes, preventing garbage collection.
69
+ Exceptions are wrapped in :class:`PersistedTaskException` for special handling within the
70
+ `__persisted_task_exc_wrap` function.
71
+ log_destroy_pending: If False, asyncio's default error log when a pending task is destroyed is suppressed.
72
+
73
+ Examples:
74
+ Create a simple task with a coroutine:
75
+
76
+ >>> async def my_coroutine():
77
+ ... return "Hello, World!"
78
+ >>> task = create_task(my_coroutine())
79
+
80
+ Create a task with a non-coroutine Awaitable:
81
+
82
+ >>> from concurrent.futures import Future
83
+ >>> future = Future()
84
+ >>> task = create_task(future)
85
+
86
+ See Also:
87
+ - :func:`asyncio.create_task`
88
+ - :class:`Task`
89
+ """
90
+ return ccreate_task(coro, name, skip_gc_until_done, log_destroy_pending)
91
+
92
+ cdef object ccreate_task_simple(object coro):
93
+ return ccreate_task(coro, "", False, True)
94
+
95
+ cdef object ccreate_task(object coro, str name, bint skip_gc_until_done, bint log_destroy_pending):
96
+ cdef object loop = get_running_loop()
97
+ cdef object task_factory = loop._task_factory
98
+ cdef object task, persisted
99
+
100
+ if not iscoroutine(coro):
101
+ coro = __await(coro)
102
+
103
+ if task_factory is None:
104
+ task = Task(coro, loop=loop, name=name)
105
+ if task._source_traceback:
106
+ del task._source_traceback[-1]
107
+ elif task_factory is smart_task_factory:
108
+ task = SmartTask(coro, loop=loop, name=name)
109
+ if task._source_traceback:
110
+ del task._source_traceback[-1]
111
+ else:
112
+ task = task_factory(loop, coro)
113
+ if name:
114
+ __set_task_name(task, name)
115
+
116
+ if skip_gc_until_done:
117
+ persisted = __persisted_task_exc_wrap(task)
118
+
119
+ if task_factory is None:
120
+ persisted = Task(persisted, loop=loop, name=name)
121
+ if persisted._source_traceback:
122
+ del persisted._source_traceback[-1]
123
+ elif task_factory is smart_task_factory:
124
+ persisted = SmartTask(persisted, loop=loop, name=name)
125
+ if persisted._source_traceback:
126
+ del persisted._source_traceback[-1]
127
+ else:
128
+ persisted = task_factory(loop, persisted)
129
+ if name:
130
+ __set_task_name(persisted, name)
131
+
132
+ _persisted_tasks.add(persisted)
133
+
134
+ if log_destroy_pending is False:
135
+ task._log_destroy_pending = False
136
+
137
+ if _persisted_tasks:
138
+ __prune_persisted_tasks()
139
+
140
+ return task
141
+
142
+
143
+ cdef inline void __set_task_name(object task, str name):
144
+ if set_name := getattr(task, "set_name", None):
145
+ set_name(name)
146
+
147
+
148
+ cdef public set[object] _persisted_tasks = set()
149
+
150
+ cdef object __await
151
+
152
+ async def __await(awaitable: Awaitable[T]) -> T:
153
+ """Wait for the completion of a non-coroutine Awaitable.
154
+
155
+ Args:
156
+ awaitable: The :class:`Awaitable` object to wait for.
157
+
158
+ Raises:
159
+ RuntimeError: If a RuntimeError occurs during the await, it is raised with additional context.
160
+
161
+ Examples:
162
+ Await a simple coroutine:
163
+
164
+ >>> async def my_coroutine():
165
+ ... return "Hello, World!"
166
+ >>> result = await __await(my_coroutine())
167
+
168
+ See Also:
169
+ - :class:`Awaitable`
170
+ """
171
+ try:
172
+ return await awaitable
173
+ except RuntimeError as e:
174
+ args = [e, awaitable]
175
+ if isinstance(awaitable, _GatheringFuture):
176
+ args.append(awaitable._children)
177
+ raise RuntimeError(*args) from None
178
+
179
+
180
+ cdef object __log_exception = logger.exception
181
+
182
+
183
+ cdef void __prune_persisted_tasks():
184
+ """Remove completed tasks from the set of persisted tasks.
185
+
186
+ This function checks each task in the persisted tasks set. If a task is done and has an exception,
187
+ it logs the exception and raises it if it's not a :class:`PersistedTaskException`. It also logs the traceback
188
+ manually since the usual handler will not run after retrieving the exception.
189
+
190
+ See Also:
191
+ - :class:`PersistedTaskException`
192
+ """
193
+ cdef object task
194
+ cdef dict context
195
+ cdef list done = list(filter(_is_done, _persisted_tasks))
196
+ if not done:
197
+ return
198
+ _persisted_tasks.difference_update(done)
199
+ for task in done:
200
+ exc = _get_exception(task)
201
+ if exc is None:
202
+ continue
203
+ # force exceptions related to this lib to bubble up
204
+ if not isinstance(exc, PersistedTaskException):
205
+ __log_exception(exc)
206
+ raise exc
207
+ # we have to manually log the traceback that asyncio would usually log
208
+ # since we already got the exception from the task and the usual handler will now not run
209
+ context = {
210
+ "message": f"{task.__class__.__name__} exception was never retrieved",
211
+ "exception": exc,
212
+ "future": task,
213
+ }
214
+ if task._source_traceback:
215
+ context["source_traceback"] = task._source_traceback
216
+ task._loop.call_exception_handler(context)
217
+
218
+
219
+ cdef inline bint _is_done(fut: Future):
220
+ return PyUnicode_CompareWithASCIIString(fut._state, b"PENDING") != 0
221
+
222
+
223
+ cdef object _get_exception(fut: Future):
224
+ """Return the exception that was set on this future.
225
+
226
+ The exception (or None if no exception was set) is returned only if
227
+ the future is done. If the future has been cancelled, raises
228
+ CancelledError. If the future isn't done yet, raises
229
+ InvalidStateError.
230
+ """
231
+ cdef str state = fut._state
232
+ if PyUnicode_CompareWithASCIIString(state, b"FINISHED") == 0:
233
+ fut._Future__log_traceback = False
234
+ return fut._exception
235
+ if PyUnicode_CompareWithASCIIString(state, b"CANCELLED") == 0:
236
+ raise (
237
+ CancelledError()
238
+ if PY_VERSION_HEX < 0x03090000 # Python 3.9
239
+ else fut._make_cancelled_error()
240
+ )
241
+ raise InvalidStateError('Exception is not set.')
242
+
243
+
244
+ cdef inline bint _exc_exists(tup: Tuple[Future, Optional[Exception]]):
245
+ return tup[1] is not None
246
+
247
+
248
+ cdef object __persisted_task_exc_wrap
249
+
250
+ async def __persisted_task_exc_wrap(task: "Task[T]") -> T:
251
+ """
252
+ Wrap a task to handle its exception in a specialized manner.
253
+
254
+ Args:
255
+ task: The :class:`Task` to wrap.
256
+
257
+ Raises:
258
+ PersistedTaskException: Wraps any exception raised by the task for special handling.
259
+
260
+ See Also:
261
+ - :class:`PersistedTaskException`
262
+ """
263
+ try:
264
+ return await task
265
+ except Exception as e:
266
+ raise PersistedTaskException(e, task) from e
267
+
268
+
269
+ __all__ = ["create_task"]
270
+
271
+
272
+ # For testing purposes only
273
+
274
+ def _get_persisted_tasks() -> Set[Task]:
275
+ # we can't import this directly to the .py test file
276
+ return _persisted_tasks