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/utils/__init__.py CHANGED
@@ -1,17 +1,22 @@
1
+ """
2
+ This module initializes the utility functions for the a_sync library, including functions for handling asynchronous
3
+ iterators and implementing asynchronous versions of the built-in any and all functions.
4
+ """
5
+
1
6
  import asyncio
2
7
 
3
- from a_sync.utils.iterators import (as_yielded, exhaust_iterator,
4
- exhaust_iterators)
8
+ from a_sync.utils.iterators import as_yielded, exhaust_iterator, exhaust_iterators
5
9
 
6
10
 
7
11
  __all__ = [
8
- #"all",
9
- #"any",
12
+ # "all",
13
+ # "any",
10
14
  "as_yielded",
11
15
  "exhaust_iterator",
12
16
  "exhaust_iterators",
13
17
  ]
14
18
 
19
+
15
20
  async def any(*awaitables) -> bool:
16
21
  """
17
22
  Asynchronously evaluates whether any of the given awaitables evaluates to True.
@@ -56,12 +61,13 @@ async def any(*awaitables) -> bool:
56
61
  fut.cancel()
57
62
  return True
58
63
  return False
59
-
64
+
65
+
60
66
  async def all(*awaitables) -> bool:
61
67
  """
62
68
  Asynchronously evaluates whether all of the given awaitables evaluate to True.
63
69
 
64
- This function takes multiple awaitable objects and returns True if all of them evaluate to True. It cancels
70
+ This function takes multiple awaitable objects and returns True if all of them evaluate to True. It cancels
65
71
  the remaining awaitables once a False result is found.
66
72
 
67
73
  Args:
a_sync/utils/iterators.py CHANGED
@@ -1,3 +1,8 @@
1
+ """
2
+ This module provides utility functions for handling and merging asynchronous iterators. It includes functions to
3
+ exhaust async iterators, merge multiple async iterators into a single async iterator, and manage the processing
4
+ flow of items in an asynchronous context.
5
+ """
1
6
 
2
7
  import asyncio
3
8
  import asyncio.futures
@@ -11,40 +16,64 @@ from a_sync.primitives.queue import Queue
11
16
  logger = logging.getLogger(__name__)
12
17
 
13
18
 
14
- async def exhaust_iterator(iterator: AsyncIterator[T], *, queue: Optional[asyncio.Queue] = None) -> None:
19
+ async def exhaust_iterator(
20
+ iterator: AsyncIterator[T], *, queue: Optional[asyncio.Queue] = None
21
+ ) -> None:
15
22
  """
16
23
  Asynchronously iterates over items from the given async iterator and optionally places them into a queue.
17
24
 
18
- This function is a utility to exhaust an async iterator, with an option to forward the iterated items to a provided asyncio.Queue. It's particularly useful when dealing with asynchronous operations that produce items to be consumed by other parts of an application, enabling a producer-consumer pattern.
25
+ This function is a utility to exhaust an async iterator, with an option to forward the iterated items to a provided queue-like object.
26
+ The queue should have a `put_nowait` method. This is particularly useful when dealing with asynchronous operations that produce items
27
+ to be consumed by other parts of an application, enabling a producer-consumer pattern.
19
28
 
20
29
  Args:
21
30
  iterator (AsyncIterator[T]): The async iterator to exhaust.
22
- queue (Optional[asyncio.Queue]): An optional queue where iterated items will be placed. If None, items are simply consumed.
31
+ queue (Optional[asyncio.Queue]): An optional queue-like object where iterated items will be placed.
32
+ The queue should support the `put_nowait` method. If None, items are simply consumed.
23
33
 
24
- Returns:
25
- None
34
+ Example:
35
+ >>> async def example():
36
+ >>> await exhaust_iterator(some_async_iterator, queue=my_queue)
37
+
38
+ See Also:
39
+ - :func:`exhaust_iterators`
40
+ - :func:`as_yielded`
26
41
  """
27
42
  async for thing in iterator:
28
43
  if queue:
29
- logger.debug('putting %s from %s to queue %s', thing, iterator, queue)
44
+ logger.debug("putting %s from %s to queue %s", thing, iterator, queue)
30
45
  queue.put_nowait(thing)
31
46
 
32
47
 
33
- async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None, join: bool = False) -> None:
34
- """
48
+ async def exhaust_iterators(
49
+ iterators, *, queue: Optional[asyncio.Queue] = None, join: bool = False
50
+ ) -> None:
51
+ """
35
52
  Asynchronously iterates over multiple async iterators concurrently and optionally places their items into a queue.
36
53
 
37
- This function leverages asyncio.gather to concurrently exhaust multiple async iterators. It's useful in scenarios where items from multiple async sources need to be processed or collected together, supporting concurrent operations and efficient multitasking.
54
+ This function leverages :func:`asyncio.gather` to concurrently exhaust multiple async iterators. It's useful in scenarios where items
55
+ from multiple async sources need to be processed or collected together, supporting concurrent operations and efficient multitasking.
38
56
 
39
57
  Args:
40
58
  iterators: A sequence of async iterators to be exhausted concurrently.
41
- queue (Optional[asyncio.Queue]): An optional queue where items from all iterators will be placed. If None, items are simply consumed.
59
+ queue (Optional[Queue]): An optional queue-like object where items from all iterators will be placed. If None, items are simply consumed.
42
60
  join (Optional[bool]): If a queue was provided and join is True, this coroutine will continue to run until all queue items have been processed.
43
61
 
44
- Returns:
45
- None
62
+ Raises:
63
+ ValueError: If `join` is True but no `queue` is provided.
64
+
65
+ Example:
66
+ >>> async def example():
67
+ >>> await exhaust_iterators([iterator1, iterator2], queue=my_queue, join=True)
68
+
69
+ See Also:
70
+ - :func:`exhaust_iterator`
71
+ - :func:`as_yielded`
46
72
  """
47
- for x in await asyncio.gather(*[exhaust_iterator(iterator, queue=queue) for iterator in iterators], return_exceptions=True):
73
+ for x in await asyncio.gather(
74
+ *[exhaust_iterator(iterator, queue=queue) for iterator in iterators],
75
+ return_exceptions=True,
76
+ ):
48
77
  if isinstance(x, Exception):
49
78
  # raise it with its original traceback instead of from here
50
79
  raise x.with_traceback(x.__traceback__)
@@ -55,73 +84,154 @@ async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None,
55
84
  elif join:
56
85
  raise ValueError("You must provide a `queue` to use kwarg `join`")
57
86
 
58
-
59
- T0 = TypeVar('T0')
60
- T1 = TypeVar('T1')
61
- T2 = TypeVar('T2')
62
- T3 = TypeVar('T3')
63
- T4 = TypeVar('T4')
64
- T5 = TypeVar('T5')
65
- T6 = TypeVar('T6')
66
- T7 = TypeVar('T7')
67
- T8 = TypeVar('T8')
68
- T9 = TypeVar('T9')
87
+
88
+ T0 = TypeVar("T0")
89
+ T1 = TypeVar("T1")
90
+ T2 = TypeVar("T2")
91
+ T3 = TypeVar("T3")
92
+ T4 = TypeVar("T4")
93
+ T5 = TypeVar("T5")
94
+ T6 = TypeVar("T6")
95
+ T7 = TypeVar("T7")
96
+ T8 = TypeVar("T8")
97
+ T9 = TypeVar("T9")
98
+
69
99
 
70
100
  @overload
71
- def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]:...
101
+ def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: ...
72
102
  @overload
73
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8], iterator9: AsyncIterator[T9]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]:...
103
+ def as_yielded(
104
+ iterator0: AsyncIterator[T0],
105
+ iterator1: AsyncIterator[T1],
106
+ iterator2: AsyncIterator[T2],
107
+ iterator3: AsyncIterator[T3],
108
+ iterator4: AsyncIterator[T4],
109
+ iterator5: AsyncIterator[T5],
110
+ iterator6: AsyncIterator[T6],
111
+ iterator7: AsyncIterator[T7],
112
+ iterator8: AsyncIterator[T8],
113
+ iterator9: AsyncIterator[T9],
114
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]: ...
74
115
  @overload
75
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7], iterator8: AsyncIterator[T8]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8]]:...
116
+ def as_yielded(
117
+ iterator0: AsyncIterator[T0],
118
+ iterator1: AsyncIterator[T1],
119
+ iterator2: AsyncIterator[T2],
120
+ iterator3: AsyncIterator[T3],
121
+ iterator4: AsyncIterator[T4],
122
+ iterator5: AsyncIterator[T5],
123
+ iterator6: AsyncIterator[T6],
124
+ iterator7: AsyncIterator[T7],
125
+ iterator8: AsyncIterator[T8],
126
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8]]: ...
76
127
  @overload
77
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6], iterator7: AsyncIterator[T7]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7]]:...
128
+ def as_yielded(
129
+ iterator0: AsyncIterator[T0],
130
+ iterator1: AsyncIterator[T1],
131
+ iterator2: AsyncIterator[T2],
132
+ iterator3: AsyncIterator[T3],
133
+ iterator4: AsyncIterator[T4],
134
+ iterator5: AsyncIterator[T5],
135
+ iterator6: AsyncIterator[T6],
136
+ iterator7: AsyncIterator[T7],
137
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7]]: ...
78
138
  @overload
79
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5], iterator6: AsyncIterator[T6]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6]]:...
139
+ def as_yielded(
140
+ iterator0: AsyncIterator[T0],
141
+ iterator1: AsyncIterator[T1],
142
+ iterator2: AsyncIterator[T2],
143
+ iterator3: AsyncIterator[T3],
144
+ iterator4: AsyncIterator[T4],
145
+ iterator5: AsyncIterator[T5],
146
+ iterator6: AsyncIterator[T6],
147
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6]]: ...
80
148
  @overload
81
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4], iterator5: AsyncIterator[T5]) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5]]:...
149
+ def as_yielded(
150
+ iterator0: AsyncIterator[T0],
151
+ iterator1: AsyncIterator[T1],
152
+ iterator2: AsyncIterator[T2],
153
+ iterator3: AsyncIterator[T3],
154
+ iterator4: AsyncIterator[T4],
155
+ iterator5: AsyncIterator[T5],
156
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5]]: ...
82
157
  @overload
83
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3], iterator4: AsyncIterator[T4]) -> AsyncIterator[Union[T0, T1, T2, T3, T4]]:...
158
+ def as_yielded(
159
+ iterator0: AsyncIterator[T0],
160
+ iterator1: AsyncIterator[T1],
161
+ iterator2: AsyncIterator[T2],
162
+ iterator3: AsyncIterator[T3],
163
+ iterator4: AsyncIterator[T4],
164
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4]]: ...
84
165
  @overload
85
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3]) -> AsyncIterator[Union[T0, T1, T2, T3]]:...
166
+ def as_yielded(
167
+ iterator0: AsyncIterator[T0],
168
+ iterator1: AsyncIterator[T1],
169
+ iterator2: AsyncIterator[T2],
170
+ iterator3: AsyncIterator[T3],
171
+ ) -> AsyncIterator[Union[T0, T1, T2, T3]]: ...
86
172
  @overload
87
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2]) -> AsyncIterator[Union[T0, T1, T2]]:...
173
+ def as_yielded(
174
+ iterator0: AsyncIterator[T0],
175
+ iterator1: AsyncIterator[T1],
176
+ iterator2: AsyncIterator[T2],
177
+ ) -> AsyncIterator[Union[T0, T1, T2]]: ...
88
178
  @overload
89
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]) -> AsyncIterator[Union[T0, T1]]:...
179
+ def as_yielded(
180
+ iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]
181
+ ) -> AsyncIterator[Union[T0, T1]]: ...
90
182
  @overload
91
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], *iterators: AsyncIterator[T]) -> AsyncIterator[Union[T0, T1, T2, T]]:...
183
+ def as_yielded(
184
+ iterator0: AsyncIterator[T0],
185
+ iterator1: AsyncIterator[T1],
186
+ iterator2: AsyncIterator[T2],
187
+ *iterators: AsyncIterator[T],
188
+ ) -> AsyncIterator[Union[T0, T1, T2, T]]: ...
92
189
  async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type: ignore [misc]
93
190
  """
94
191
  Merges multiple async iterators into a single async iterator that yields items as they become available from any of the source iterators.
95
192
 
96
- This function is designed to streamline the handling of multiple asynchronous data streams by consolidating them into a single asynchronous iteration context. It enables concurrent fetching and processing of items from multiple sources, improving efficiency and simplifying code structure when dealing with asynchronous operations.
193
+ This function is designed to streamline the handling of multiple asynchronous data streams by consolidating them into a single asynchronous iteration context.
194
+ It enables concurrent fetching and processing of items from multiple sources, improving efficiency and simplifying code structure when dealing with asynchronous operations.
97
195
 
98
- The merging process is facilitated by internally managing a queue where items from the source iterators are placed as they are fetched. This mechanism ensures that the merged stream of items is delivered in an order determined by the availability of items from the source iterators, rather than their original sequence.
196
+ The merging process is facilitated by the :func:`exhaust_iterators` function, which concurrently processes the source iterators and places their items into a queue.
197
+ This mechanism ensures that the merged stream of items is delivered in an order determined by the availability of items from the source iterators, rather than their original sequence.
99
198
 
100
- Args:
101
- *iterators: Variable length list of AsyncIterator objects to be merged.
199
+ The function handles exceptions and ensures robustness and reliability by using asyncio tasks and queues. It manages edge cases such as early termination and exception management.
200
+ The :class:`_Done` sentinel class is used internally to signal the completion of processing.
102
201
 
103
- Returns:
104
- AsyncIterator[T]: An async iterator that yields items from the input async iterators as they become available.
202
+ Args:
203
+ *iterators: Variable length list of :class:`~collections.abc.AsyncIterator` objects to be merged.
105
204
 
106
205
  Note:
107
- This implementation leverages asyncio tasks and queues to efficiently manage the asynchronous iteration and merging process. It handles edge cases such as early termination and exception management, ensuring robustness and reliability.
206
+ This implementation leverages asyncio tasks and queues to efficiently manage the asynchronous iteration and merging process.
207
+ It handles edge cases such as early termination and exception management, ensuring robustness and reliability.
208
+ The :class:`_Done` sentinel class is used internally to signal the completion of processing.
209
+
210
+ Example:
211
+ >>> async def example():
212
+ >>> async for item in as_yielded(iterator1, iterator2):
213
+ >>> print(item)
214
+
215
+ See Also:
216
+ - :func:`exhaust_iterator`
217
+ - :func:`exhaust_iterators`
108
218
  """
109
219
  # hypothesis idea: _Done should never be exposed to user, works for all desired input types
110
220
  queue: Queue[Union[T, _Done]] = Queue()
111
-
221
+
112
222
  def _as_yielded_done_callback(t: asyncio.Task) -> None:
113
223
  if t.cancelled():
114
224
  return
115
- if e := t.exception():
225
+ if e := t.exception():
116
226
  traceback.extract_stack
117
227
  traceback.clear_frames(e.__traceback__)
118
228
  queue.put_nowait(_Done(e))
119
229
 
120
230
  task = asyncio.create_task(
121
- coro=exhaust_iterators(iterators, queue=queue, join=True),
231
+ coro=exhaust_iterators(iterators, queue=queue, join=True),
122
232
  name=f"a_sync.as_yielded queue populating task for {iterators}",
123
233
  )
124
-
234
+
125
235
  task.add_done_callback(_as_yielded_done_callback)
126
236
 
127
237
  while not task.done():
@@ -139,24 +249,34 @@ async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type:
139
249
  del task
140
250
  del queue
141
251
  if item._exc:
142
- raise type(item._exc)(*item._exc.args).with_traceback(item._tb) from item._exc.__cause__
252
+ raise type(item._exc)(*item._exc.args).with_traceback(
253
+ item._tb
254
+ ) from item._exc.__cause__
143
255
  return
144
256
  yield item
145
257
 
146
258
  # ensure it isn't done due to an internal exception
147
259
  await task
148
260
 
149
-
261
+
150
262
  class _Done:
151
263
  """
152
- A sentinel class used to signal the completion of processing in the as_yielded function.
264
+ A sentinel class used to signal the completion of processing in the :func:`as_yielded` function.
265
+
266
+ This class acts as a marker to indicate that all items have been processed and the asynchronous iteration can be concluded.
267
+ It is used internally within the implementation of :func:`as_yielded` to efficiently manage the termination of the iteration process once all source iterators have been exhausted.
153
268
 
154
- This class acts as a marker to indicate that all items have been processed and the asynchronous iteration can be concluded. It is used internally within the implementation of as_yielded to efficiently manage the termination of the iteration process once all source iterators have been exhausted.
269
+ Args:
270
+ exc (Optional[Exception]): An optional exception to be associated with the completion.
155
271
  """
272
+
156
273
  def __init__(self, exc: Optional[Exception] = None) -> None:
157
274
  self._exc = exc
275
+
158
276
  @property
159
277
  def _tb(self) -> TracebackType:
278
+ """Returns the traceback associated with the exception, if any."""
160
279
  return self._exc.__traceback__ # type: ignore [union-attr]
161
280
 
281
+
162
282
  __all__ = ["as_yielded", "exhaust_iterator", "exhaust_iterators"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ez-a-sync
3
- Version: 0.22.14
3
+ Version: 0.22.16
4
4
  Summary: A library that makes it easy to define objects that can be used for both sync and async use cases.
5
5
  Home-page: https://github.com/BobTheBuidler/a-sync
6
6
  Author: BobTheBuidler
@@ -0,0 +1,74 @@
1
+ a_sync/ENVIRONMENT_VARIABLES.py,sha256=JHTnvIA5rEXWLqMwNeJ2ewFwVqyg9T6CYcrdxWnnfyo,1309
2
+ a_sync/__init__.py,sha256=wJdpi219HqUD4dN-zLK1VNE-3K_R2aa_R98ZnbVILL8,4787
3
+ a_sync/_smart.py,sha256=qd6hkURaVHZZ1i9L88cJDv6SF7MnJM5bmrVGVQ12KuA,11526
4
+ a_sync/_typing.py,sha256=M7ZzA6iUSl8Ur4zdySJLxWKk9CdA_kSHjbV0j72CRgQ,6628
5
+ a_sync/aliases.py,sha256=TbLyuLeFfJEmcC5-NP6h4DQ9QXlQjGny2NUP_x1tflw,212
6
+ a_sync/exceptions.py,sha256=Zm1YG55ApYF1NWciIkRpTgLMlgyCcAk6MadHTgwvhbs,12680
7
+ a_sync/executor.py,sha256=4YzCSWPbas3sPeOJO-S-cwo1dLk-eq20F6bMVqZvxAA,14994
8
+ a_sync/future.py,sha256=PxR1nm5DOYohDE5CWD7HXgzdP_3GDUg0_oFVBLvn7_A,48827
9
+ a_sync/iter.py,sha256=KelwlPfUU5XIPgMpimIV4VwAjiRhOzRc2fK1TG5tTmY,23225
10
+ a_sync/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ a_sync/task.py,sha256=dqi4TA8uIkONqHDMt1DUmotCbmhGwAR6iSbrA-h3SwI,32376
12
+ a_sync/a_sync/__init__.py,sha256=qENRGhOVdj0uwYHqGZwDdTTYDepvpb0qjzVJn7Nco78,1814
13
+ a_sync/a_sync/_descriptor.py,sha256=oO0AEfPVFGhG-YosH3G8-vUJM3ZU7PRwMDGNCP8XjSI,13537
14
+ a_sync/a_sync/_flags.py,sha256=ZxlbF0OdGP-35dc5VjSh1YIGvbailrXaEOg1ZhYsjgs,3640
15
+ a_sync/a_sync/_helpers.py,sha256=Emy4iiWHCw8e0HmqeihgQHKKCkGFax3tRlnUFjz8fCg,3144
16
+ a_sync/a_sync/_kwargs.py,sha256=130eL6M54DUEDERA9Jn8V2kz8AZqraVsNC55ovyvS5s,2008
17
+ a_sync/a_sync/_meta.py,sha256=psCfXKFY85OH8biUr-KT6Ew_YE0UOjficWtPdq4qMCE,9577
18
+ a_sync/a_sync/abstract.py,sha256=OAkIqO6Zqm6QZfrmclpn85nsXJhI0v1aBFQwfwYsqoQ,7347
19
+ a_sync/a_sync/base.py,sha256=rZolx0B4Dof84ahC3pfTDTQe4laZppNnAcliAmNkjDw,7431
20
+ a_sync/a_sync/config.py,sha256=K7KunG2cvOfKic8BzShgvIgOY7GFa0p_S4S1lzPkqeY,5251
21
+ a_sync/a_sync/decorator.py,sha256=O1m6kTBMCjV5coZRLHZoEsjbw0R4DQXD2huDehAi2qg,17039
22
+ a_sync/a_sync/function.py,sha256=06kgIoYISmEc4AbvxL_G_d-3inc7V6atdE5HVZsXowA,40721
23
+ a_sync/a_sync/method.py,sha256=s3nA1VrOo-wwiZd3gEosL1ERYLlps-IAhppgOJptzAw,32448
24
+ a_sync/a_sync/property.py,sha256=llVqhVksV717ejaDBne7DHBuuMUmHdlsW83wcTElQJQ,25203
25
+ a_sync/a_sync/singleton.py,sha256=fdzGGX8QeUTndE_7VQSzvZUe0NAWQ1vWLq_y2Ruo1Ws,2414
26
+ a_sync/a_sync/modifiers/__init__.py,sha256=zi1qI3paHjXxFGx2J2fX5EuWAgvY_-5MYFLwv931he4,4120
27
+ a_sync/a_sync/modifiers/limiter.py,sha256=YCEgmu_Cm06kq16F5YA2wMie9pgS-VZQ3U_WhgkO-Ps,4308
28
+ a_sync/a_sync/modifiers/manager.py,sha256=5VWhsP1xF5zxZwq8q2IICqIRwnqD_lvqVsaVHB_eY3k,7152
29
+ a_sync/a_sync/modifiers/semaphores.py,sha256=a6pUablxdXkSVpXpzUFk1lnfsu0U4yFXAoKZyt-u26Q,6796
30
+ a_sync/a_sync/modifiers/cache/__init__.py,sha256=PMydVB29OhcBqhHGZnRDwdoObIvEYxkbqcbko4ZY8g8,5389
31
+ a_sync/a_sync/modifiers/cache/memory.py,sha256=6w-C7q_K_ccPvYd6Jl0W2xYsg2JKLR_FmrWrfyIebfE,5394
32
+ a_sync/asyncio/__init__.py,sha256=IBAciQTCGADpg3Omwnb9zw-MXUk40Gu6Yo_7ZMZk8sA,6135
33
+ a_sync/asyncio/as_completed.py,sha256=xIvgyuN20JKMFakLlyJ_Vm1LpAZIU5KdQUkkKqMQT20,9402
34
+ a_sync/asyncio/create_task.py,sha256=f3_PPdhK4lqDvJWSiI2SWaV0oa6iYliUlLnWi6JalZM,5078
35
+ a_sync/asyncio/gather.py,sha256=AcqE0RGCCDA9SMtIgIMRZmfm0rjHEkREibA2L40Mx3Y,8072
36
+ a_sync/asyncio/utils.py,sha256=C9XmHO_zU0-Cgob9_YYmqGfyjYyskKqySqyvUcWo7LU,391
37
+ a_sync/primitives/__init__.py,sha256=zpmDwVSUOknQyIOTedyhwRWygiXSmYvjdl83oFAr1Rk,737
38
+ a_sync/primitives/_debug.py,sha256=utZn33eYUzZAlf1VG5OPkBpHVCYV8gdj_YAJHQhvVsM,5073
39
+ a_sync/primitives/_loggable.py,sha256=Ki7lLrTwdCXhnZ18Ns3mEOCJJcLFp8SVntzwzjVFjAM,2067
40
+ a_sync/primitives/queue.py,sha256=BmgYNFm3k3czTkjFwwcH3rTNyUMXDRyEaRpqLohjAc4,30261
41
+ a_sync/primitives/locks/__init__.py,sha256=zKSLeCUgMGSbuXN6ehb2dm0-4lbk-Ze8_ldatWEjy4Y,283
42
+ a_sync/primitives/locks/counter.py,sha256=o7aAnEEG04Yybcbr1FbSpzjVM3JzXwXDvDTlZeNtZ6I,7276
43
+ a_sync/primitives/locks/event.py,sha256=U1suI0OZEH8X3jxF_MChGUtuhemLzROqqd6a7bpHM8E,2974
44
+ a_sync/primitives/locks/prio_semaphore.py,sha256=QNVOVk0m9509viBqEzruze_IKnIKBOarKj_xs42AERA,14755
45
+ a_sync/primitives/locks/semaphore.py,sha256=8EZExO0L_bFCmSFzxaZO9oIqWNTIS4LMnYvukQncZwQ,8120
46
+ a_sync/sphinx/__init__.py,sha256=UvdsakVmkn0Lw4vEd3jA3_Acymde95-78o87lel8ikk,49
47
+ a_sync/sphinx/ext.py,sha256=3ktEWH1brCbHZi2m4BGwglfLyA5JjF05cB0e_c-MVTg,8997
48
+ a_sync/utils/__init__.py,sha256=4JiGSyL5Jj2G7cAmeQN6fxwFnzyOtWYd9IeX8BhrR2k,3223
49
+ a_sync/utils/iterators.py,sha256=jTeLdR5sAqUcB20ZnKZkwVNjJH3QBKgv4kw4yqlV5yI,10723
50
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ tests/conftest.py,sha256=cZPQoOF3h1OtsFzEb7Jkx54COExVdf0XfD0LZBrmqcg,57
52
+ tests/executor.py,sha256=7B1SWNM--gYcqgTgFXL_e0yHGGY2xuC5Fo6hozkOWqw,8594
53
+ tests/fixtures.py,sha256=4j3GsopNo6tMFOyhWOb8Hnwcwiw2Xdjee4r1YLH1JBE,5774
54
+ tests/test_abstract.py,sha256=bYV06gMvdnjU3KQJZEU5pvljgeaGcbnQnIQQn8yuVo8,1158
55
+ tests/test_as_completed.py,sha256=_oy8L4xmK7NvpAaNPLdM6wwPtSD54nGxwQucK9pDvMg,4527
56
+ tests/test_base.py,sha256=FkcDjam4wR3Bm5TDx5ZI6mlEENSXlzDruIP6YIt4_MI,16630
57
+ tests/test_cache.py,sha256=lgcULExF1Nw4cjvujVvxub5CROqatf6TOkluUSVypIY,2562
58
+ tests/test_decorator.py,sha256=OMV2H6JjmGftdIFd5hgHBt80SF29AX8HtvvdyL8covg,3670
59
+ tests/test_executor.py,sha256=OG3cUeTq0MQkMg-hTsAh8qQqEqYMUaslX3xhXE_zkxA,1950
60
+ tests/test_future.py,sha256=9UUFAh6eP1HFkLchprpcnBjKH7TETZr48k-WUt2PKGc,3433
61
+ tests/test_gather.py,sha256=cjl20RIGbLNMn8hhEw9hFQ7qjWpLHIXVDVrAm6H5u4w,1382
62
+ tests/test_helpers.py,sha256=68DBihIMqAIQLkAS89yutfDv3bPsrgIShad7JS6Bqv0,349
63
+ tests/test_iter.py,sha256=jUaRiZMbfOu3HbGPXnijI2C11uXqde62gcPGG71v6m4,8995
64
+ tests/test_limiter.py,sha256=3nyrikkThrTXrx_7J4gR9ZCNXTYIdrgkXF9Av_T1wqc,829
65
+ tests/test_meta.py,sha256=NZyt6tjzypSJO2byY8NuthCXi545SdSeSDp8KBUkp1Q,3663
66
+ tests/test_modified.py,sha256=_O0-HUJLCC4Ok12QtDjT1_OyLJYDgP0K3O0XhrZTGYs,250
67
+ tests/test_semaphore.py,sha256=8WxfS-0eSlrWyRi-x_-KopsGEp_9oX4TgH2QB1DOnCM,1666
68
+ tests/test_singleton.py,sha256=krzO5QOhLIEV4PPpiHnNw-dFisTCemFcggWxh6lXAZw,1033
69
+ tests/test_task.py,sha256=xtTXdKHUEwQnNIZcMcAk_Xto5YJ0G-qt9Pkq9Dfdmwk,10271
70
+ ez_a_sync-0.22.16.dist-info/LICENSE.txt,sha256=1on6-17OUMlja6vSPTcmlmeT_DwujCZJijYxaplBvZk,1075
71
+ ez_a_sync-0.22.16.dist-info/METADATA,sha256=7IGGj1Gj5HHVv7Z5Fu1NZNeKZDgMZW_p2O_ZwRLBjw0,533
72
+ ez_a_sync-0.22.16.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
73
+ ez_a_sync-0.22.16.dist-info/top_level.txt,sha256=GVK_7kp7dgBLeHp84iIQdsJmiXnrXd-5sIf2x0Q-VKc,13
74
+ ez_a_sync-0.22.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
tests/conftest.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  import sys, os
3
2
 
4
- sys.path.insert(0, os.path.abspath('.'))
3
+ sys.path.insert(0, os.path.abspath("."))