ez-a-sync 0.22.14__py3-none-any.whl → 0.22.15__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 +4 -3
  2. a_sync/__init__.py +30 -12
  3. a_sync/_smart.py +132 -28
  4. a_sync/_typing.py +56 -12
  5. a_sync/a_sync/__init__.py +35 -10
  6. a_sync/a_sync/_descriptor.py +74 -26
  7. a_sync/a_sync/_flags.py +14 -6
  8. a_sync/a_sync/_helpers.py +8 -7
  9. a_sync/a_sync/_kwargs.py +3 -2
  10. a_sync/a_sync/_meta.py +120 -28
  11. a_sync/a_sync/abstract.py +102 -28
  12. a_sync/a_sync/base.py +34 -16
  13. a_sync/a_sync/config.py +47 -13
  14. a_sync/a_sync/decorator.py +239 -117
  15. a_sync/a_sync/function.py +416 -146
  16. a_sync/a_sync/method.py +197 -59
  17. a_sync/a_sync/modifiers/__init__.py +47 -5
  18. a_sync/a_sync/modifiers/cache/__init__.py +46 -17
  19. a_sync/a_sync/modifiers/cache/memory.py +86 -20
  20. a_sync/a_sync/modifiers/limiter.py +52 -22
  21. a_sync/a_sync/modifiers/manager.py +98 -16
  22. a_sync/a_sync/modifiers/semaphores.py +48 -15
  23. a_sync/a_sync/property.py +383 -82
  24. a_sync/a_sync/singleton.py +1 -0
  25. a_sync/aliases.py +0 -1
  26. a_sync/asyncio/__init__.py +4 -1
  27. a_sync/asyncio/as_completed.py +177 -49
  28. a_sync/asyncio/create_task.py +31 -17
  29. a_sync/asyncio/gather.py +72 -52
  30. a_sync/asyncio/utils.py +3 -3
  31. a_sync/exceptions.py +78 -23
  32. a_sync/executor.py +118 -71
  33. a_sync/future.py +575 -158
  34. a_sync/iter.py +110 -50
  35. a_sync/primitives/__init__.py +14 -2
  36. a_sync/primitives/_debug.py +13 -13
  37. a_sync/primitives/_loggable.py +5 -4
  38. a_sync/primitives/locks/__init__.py +5 -2
  39. a_sync/primitives/locks/counter.py +38 -36
  40. a_sync/primitives/locks/event.py +21 -7
  41. a_sync/primitives/locks/prio_semaphore.py +182 -62
  42. a_sync/primitives/locks/semaphore.py +78 -77
  43. a_sync/primitives/queue.py +560 -58
  44. a_sync/sphinx/__init__.py +0 -1
  45. a_sync/sphinx/ext.py +160 -50
  46. a_sync/task.py +262 -97
  47. a_sync/utils/__init__.py +12 -6
  48. a_sync/utils/iterators.py +127 -43
  49. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/METADATA +1 -1
  50. ez_a_sync-0.22.15.dist-info/RECORD +74 -0
  51. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/WHEEL +1 -1
  52. tests/conftest.py +1 -2
  53. tests/executor.py +112 -9
  54. tests/fixtures.py +61 -32
  55. tests/test_abstract.py +7 -4
  56. tests/test_as_completed.py +54 -21
  57. tests/test_base.py +66 -17
  58. tests/test_cache.py +31 -15
  59. tests/test_decorator.py +54 -28
  60. tests/test_executor.py +8 -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 +15 -10
  70. tests/test_task.py +126 -28
  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.15.dist-info}/LICENSE.txt +0 -0
  73. {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.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,7 +16,9 @@ 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
 
@@ -20,18 +27,17 @@ async def exhaust_iterator(iterator: AsyncIterator[T], *, queue: Optional[asynci
20
27
  Args:
21
28
  iterator (AsyncIterator[T]): The async iterator to exhaust.
22
29
  queue (Optional[asyncio.Queue]): An optional queue where iterated items will be placed. If None, items are simply consumed.
23
-
24
- Returns:
25
- None
26
30
  """
27
31
  async for thing in iterator:
28
32
  if queue:
29
- logger.debug('putting %s from %s to queue %s', thing, iterator, queue)
33
+ logger.debug("putting %s from %s to queue %s", thing, iterator, queue)
30
34
  queue.put_nowait(thing)
31
35
 
32
36
 
33
- async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None, join: bool = False) -> None:
34
- """
37
+ async def exhaust_iterators(
38
+ iterators, *, queue: Optional[asyncio.Queue] = None, join: bool = False
39
+ ) -> None:
40
+ """
35
41
  Asynchronously iterates over multiple async iterators concurrently and optionally places their items into a queue.
36
42
 
37
43
  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.
@@ -40,11 +46,11 @@ async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None,
40
46
  iterators: A sequence of async iterators to be exhausted concurrently.
41
47
  queue (Optional[asyncio.Queue]): An optional queue where items from all iterators will be placed. If None, items are simply consumed.
42
48
  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
-
44
- Returns:
45
- None
46
49
  """
47
- for x in await asyncio.gather(*[exhaust_iterator(iterator, queue=queue) for iterator in iterators], return_exceptions=True):
50
+ for x in await asyncio.gather(
51
+ *[exhaust_iterator(iterator, queue=queue) for iterator in iterators],
52
+ return_exceptions=True,
53
+ ):
48
54
  if isinstance(x, Exception):
49
55
  # raise it with its original traceback instead of from here
50
56
  raise x.with_traceback(x.__traceback__)
@@ -55,40 +61,108 @@ async def exhaust_iterators(iterators, *, queue: Optional[asyncio.Queue] = None,
55
61
  elif join:
56
62
  raise ValueError("You must provide a `queue` to use kwarg `join`")
57
63
 
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')
64
+
65
+ T0 = TypeVar("T0")
66
+ T1 = TypeVar("T1")
67
+ T2 = TypeVar("T2")
68
+ T3 = TypeVar("T3")
69
+ T4 = TypeVar("T4")
70
+ T5 = TypeVar("T5")
71
+ T6 = TypeVar("T6")
72
+ T7 = TypeVar("T7")
73
+ T8 = TypeVar("T8")
74
+ T9 = TypeVar("T9")
75
+
69
76
 
70
77
  @overload
71
- def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]:...
78
+ def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: ...
72
79
  @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]]:...
80
+ def as_yielded(
81
+ iterator0: AsyncIterator[T0],
82
+ iterator1: AsyncIterator[T1],
83
+ iterator2: AsyncIterator[T2],
84
+ iterator3: AsyncIterator[T3],
85
+ iterator4: AsyncIterator[T4],
86
+ iterator5: AsyncIterator[T5],
87
+ iterator6: AsyncIterator[T6],
88
+ iterator7: AsyncIterator[T7],
89
+ iterator8: AsyncIterator[T8],
90
+ iterator9: AsyncIterator[T9],
91
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]: ...
74
92
  @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]]:...
93
+ def as_yielded(
94
+ iterator0: AsyncIterator[T0],
95
+ iterator1: AsyncIterator[T1],
96
+ iterator2: AsyncIterator[T2],
97
+ iterator3: AsyncIterator[T3],
98
+ iterator4: AsyncIterator[T4],
99
+ iterator5: AsyncIterator[T5],
100
+ iterator6: AsyncIterator[T6],
101
+ iterator7: AsyncIterator[T7],
102
+ iterator8: AsyncIterator[T8],
103
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7, T8]]: ...
76
104
  @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]]:...
105
+ def as_yielded(
106
+ iterator0: AsyncIterator[T0],
107
+ iterator1: AsyncIterator[T1],
108
+ iterator2: AsyncIterator[T2],
109
+ iterator3: AsyncIterator[T3],
110
+ iterator4: AsyncIterator[T4],
111
+ iterator5: AsyncIterator[T5],
112
+ iterator6: AsyncIterator[T6],
113
+ iterator7: AsyncIterator[T7],
114
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6, T7]]: ...
78
115
  @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]]:...
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
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5, T6]]: ...
80
125
  @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]]:...
126
+ def as_yielded(
127
+ iterator0: AsyncIterator[T0],
128
+ iterator1: AsyncIterator[T1],
129
+ iterator2: AsyncIterator[T2],
130
+ iterator3: AsyncIterator[T3],
131
+ iterator4: AsyncIterator[T4],
132
+ iterator5: AsyncIterator[T5],
133
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4, T5]]: ...
82
134
  @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]]:...
135
+ def as_yielded(
136
+ iterator0: AsyncIterator[T0],
137
+ iterator1: AsyncIterator[T1],
138
+ iterator2: AsyncIterator[T2],
139
+ iterator3: AsyncIterator[T3],
140
+ iterator4: AsyncIterator[T4],
141
+ ) -> AsyncIterator[Union[T0, T1, T2, T3, T4]]: ...
84
142
  @overload
85
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], iterator3: AsyncIterator[T3]) -> AsyncIterator[Union[T0, T1, T2, T3]]:...
143
+ def as_yielded(
144
+ iterator0: AsyncIterator[T0],
145
+ iterator1: AsyncIterator[T1],
146
+ iterator2: AsyncIterator[T2],
147
+ iterator3: AsyncIterator[T3],
148
+ ) -> AsyncIterator[Union[T0, T1, T2, T3]]: ...
86
149
  @overload
87
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2]) -> AsyncIterator[Union[T0, T1, T2]]:...
150
+ def as_yielded(
151
+ iterator0: AsyncIterator[T0],
152
+ iterator1: AsyncIterator[T1],
153
+ iterator2: AsyncIterator[T2],
154
+ ) -> AsyncIterator[Union[T0, T1, T2]]: ...
88
155
  @overload
89
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]) -> AsyncIterator[Union[T0, T1]]:...
156
+ def as_yielded(
157
+ iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1]
158
+ ) -> AsyncIterator[Union[T0, T1]]: ...
90
159
  @overload
91
- def as_yielded(iterator0: AsyncIterator[T0], iterator1: AsyncIterator[T1], iterator2: AsyncIterator[T2], *iterators: AsyncIterator[T]) -> AsyncIterator[Union[T0, T1, T2, T]]:...
160
+ def as_yielded(
161
+ iterator0: AsyncIterator[T0],
162
+ iterator1: AsyncIterator[T1],
163
+ iterator2: AsyncIterator[T2],
164
+ *iterators: AsyncIterator[T],
165
+ ) -> AsyncIterator[Union[T0, T1, T2, T]]: ...
92
166
  async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type: ignore [misc]
93
167
  """
94
168
  Merges multiple async iterators into a single async iterator that yields items as they become available from any of the source iterators.
@@ -97,31 +171,30 @@ async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type:
97
171
 
98
172
  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.
99
173
 
174
+ 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. The `_Done` sentinel class is used internally to signal the completion of processing.
175
+
100
176
  Args:
101
177
  *iterators: Variable length list of AsyncIterator objects to be merged.
102
178
 
103
- Returns:
104
- AsyncIterator[T]: An async iterator that yields items from the input async iterators as they become available.
105
-
106
179
  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.
180
+ 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. The `_Done` sentinel class is used internally to signal the completion of processing.
108
181
  """
109
182
  # hypothesis idea: _Done should never be exposed to user, works for all desired input types
110
183
  queue: Queue[Union[T, _Done]] = Queue()
111
-
184
+
112
185
  def _as_yielded_done_callback(t: asyncio.Task) -> None:
113
186
  if t.cancelled():
114
187
  return
115
- if e := t.exception():
188
+ if e := t.exception():
116
189
  traceback.extract_stack
117
190
  traceback.clear_frames(e.__traceback__)
118
191
  queue.put_nowait(_Done(e))
119
192
 
120
193
  task = asyncio.create_task(
121
- coro=exhaust_iterators(iterators, queue=queue, join=True),
194
+ coro=exhaust_iterators(iterators, queue=queue, join=True),
122
195
  name=f"a_sync.as_yielded queue populating task for {iterators}",
123
196
  )
124
-
197
+
125
198
  task.add_done_callback(_as_yielded_done_callback)
126
199
 
127
200
  while not task.done():
@@ -139,24 +212,35 @@ async def as_yielded(*iterators: AsyncIterator[T]) -> AsyncIterator[T]: # type:
139
212
  del task
140
213
  del queue
141
214
  if item._exc:
142
- raise type(item._exc)(*item._exc.args).with_traceback(item._tb) from item._exc.__cause__
215
+ raise type(item._exc)(*item._exc.args).with_traceback(
216
+ item._tb
217
+ ) from item._exc.__cause__
143
218
  return
144
219
  yield item
145
220
 
146
221
  # ensure it isn't done due to an internal exception
147
222
  await task
148
223
 
149
-
224
+
150
225
  class _Done:
151
226
  """
152
227
  A sentinel class used to signal the completion of processing in the as_yielded function.
153
228
 
154
229
  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.
155
230
  """
231
+
156
232
  def __init__(self, exc: Optional[Exception] = None) -> None:
233
+ """Initializes the _Done sentinel.
234
+
235
+ Args:
236
+ exc (Optional[Exception]): An optional exception to be associated with the completion.
237
+ """
157
238
  self._exc = exc
239
+
158
240
  @property
159
241
  def _tb(self) -> TracebackType:
242
+ """Returns the traceback associated with the exception, if any."""
160
243
  return self._exc.__traceback__ # type: ignore [union-attr]
161
244
 
245
+
162
246
  __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.15
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=WNRUCRH5RwqGbVVYST_JuJb2MUOMtdf3GW3lsGomp5s,466
2
+ a_sync/__init__.py,sha256=r9VTp-p3GJND5KcotrQGZRoub5eiA-O_ZpgDw15ua2U,3778
3
+ a_sync/_smart.py,sha256=DyHISh-F_xKwoTuGCw3QY6HaGMoA122A5yh2ZUWCTMc,9331
4
+ a_sync/_typing.py,sha256=6oc5XAt9KNMzX91qrmnaGMXe_EH-uNFcuRwczcCtDkA,5411
5
+ a_sync/aliases.py,sha256=TbLyuLeFfJEmcC5-NP6h4DQ9QXlQjGny2NUP_x1tflw,212
6
+ a_sync/exceptions.py,sha256=Qym1qjw35bcD9QxSFvb8D02PjQ_qRiCWGWHABbC8qbI,7290
7
+ a_sync/executor.py,sha256=f8tbcThk1rhuR6smrh7tmna8qOnAZFoaSLe72TRYSWo,13204
8
+ a_sync/future.py,sha256=2gB_-WMZIrXnwT7zgO75czVDqQso6kqZp7pbKItjHKQ,31748
9
+ a_sync/iter.py,sha256=BSFFH3fp3pEyA-8PHcjh4nqwjmh0OLNtyYKVz_XUcbU,21466
10
+ a_sync/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ a_sync/task.py,sha256=jg0H2Stsxp3iMSda5v2PRM253SINXbNRgK16teKm8SQ,31035
12
+ a_sync/a_sync/__init__.py,sha256=qENRGhOVdj0uwYHqGZwDdTTYDepvpb0qjzVJn7Nco78,1814
13
+ a_sync/a_sync/_descriptor.py,sha256=puij54vKOOf5jDl_lSmOSOTfNiHHk_VKZlEBFo-7eDM,8413
14
+ a_sync/a_sync/_flags.py,sha256=UAzMesvTnvc3bqFzSS7A66kNCMf4S7LbQejdtq7TnNA,1959
15
+ a_sync/a_sync/_helpers.py,sha256=yKInVqquvx0KkY2YlLAi86CumiC8dwsA15TTNLlcrsQ,1808
16
+ a_sync/a_sync/_kwargs.py,sha256=tfx0pVe32PAk1m2LmkyDqBVsHbmnNM9gqQ8s0_DNd-s,1380
17
+ a_sync/a_sync/_meta.py,sha256=xMP9LUsdk8M8It2Rc1_HjBI5NZBDf7Y6bt74ljfNuSg,8245
18
+ a_sync/a_sync/abstract.py,sha256=sBmVssbek0OZyxm1Cc-42IcTpahCS0teiVAGWIxzzpM,5787
19
+ a_sync/a_sync/base.py,sha256=rZolx0B4Dof84ahC3pfTDTQe4laZppNnAcliAmNkjDw,7431
20
+ a_sync/a_sync/config.py,sha256=Wvk9oJa8hPrio-meJX4hsRXx0TSIe_UavH7F1cZ-Ptk,3868
21
+ a_sync/a_sync/decorator.py,sha256=eHTpyMJOEBx42s-8Asu4MCTY-VbDBKWo4AK0XuoaIwQ,12317
22
+ a_sync/a_sync/function.py,sha256=rUq43E5qM8j2hN5iZPAYhbBq1NA57OepDEpeNSHkGsc,33369
23
+ a_sync/a_sync/method.py,sha256=yS9Vn6k4BkSExGlZQLC3KPG_qfRCEacKInnHxNDVZpo,24750
24
+ a_sync/a_sync/property.py,sha256=llVqhVksV717ejaDBne7DHBuuMUmHdlsW83wcTElQJQ,25203
25
+ a_sync/a_sync/singleton.py,sha256=tG8E_gT7Qw5Hzgib53TVdMYZa05D5yhLYiHccSZHItc,1460
26
+ a_sync/a_sync/modifiers/__init__.py,sha256=IBDKhGu7XBp7u4ONy6Kmn0Wxdk7WqZoBwHs3590mQuk,2743
27
+ a_sync/a_sync/modifiers/limiter.py,sha256=K-WW4M45oEVvL84Pf11nUVws3hWwflqhyp-VSwLzDMU,2914
28
+ a_sync/a_sync/modifiers/manager.py,sha256=te5BtXw9wm-Zgxn5m3ffFnEkrS7f1xrtBpPpc5fMlmE,5676
29
+ a_sync/a_sync/modifiers/semaphores.py,sha256=GFVYF0n52eet8b1Y0sR0UhZPu43Joj-aQURV9JrZPf8,3921
30
+ a_sync/a_sync/modifiers/cache/__init__.py,sha256=HDs9tBoQyU_DKfam-UGgQUC7Hb3jdHH7vvR0LonoHdw,2889
31
+ a_sync/a_sync/modifiers/cache/memory.py,sha256=V0o_PbFrUlTkom0x013ZZ0oyFLZ0msjxH9Hf0IsmlA4,4266
32
+ a_sync/asyncio/__init__.py,sha256=8xKXPz8Vk4ytvti9zNUgRtGmI5KF3EndgwGHCB5oBHg,519
33
+ a_sync/asyncio/as_completed.py,sha256=I64-uIDKalh20cHC24Mvg71K_NVGRK4KPbYipvDXBXU,8901
34
+ a_sync/asyncio/create_task.py,sha256=kwaDrb8UIqBFv5fZoFmbJfeZvGt6oCbqX9rHXMwqw1Y,4199
35
+ a_sync/asyncio/gather.py,sha256=x1IzwqhP4YatiBLMiZhI7K6mGtVspMggEdeti9X8itU,5885
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=7TfPphc3e7I46rkLiiLVqxdAS-bBgRvxr5evRaWYYhQ,3077
39
+ a_sync/primitives/_loggable.py,sha256=ngiLMRxQcQP3S4bt8VmBXA52YO9x5bZ0-XEM8sJojPE,1206
40
+ a_sync/primitives/queue.py,sha256=f3lXhk3RyfOMidv5d8C34VYwVjP_hVv67dG-q36lr0E,28577
41
+ a_sync/primitives/locks/__init__.py,sha256=zKSLeCUgMGSbuXN6ehb2dm0-4lbk-Ze8_ldatWEjy4Y,283
42
+ a_sync/primitives/locks/counter.py,sha256=3_4MMKLQtXUzJuuQfr5mrk-rxrv6O2Y8mO66cMH8H0Q,4876
43
+ a_sync/primitives/locks/event.py,sha256=U1suI0OZEH8X3jxF_MChGUtuhemLzROqqd6a7bpHM8E,2974
44
+ a_sync/primitives/locks/prio_semaphore.py,sha256=UnH1uAwxiERdmxvKH8SyF-kq0T76L15ehskOERs4cBo,11982
45
+ a_sync/primitives/locks/semaphore.py,sha256=TnR49MYI_VTvMRN0WAtvF7T9MKqUrUtWlm3CB9g7_XU,6572
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=W1EGSBOZy_k7VOiJZyPafqE6vZxzeLO0aeWHfAKur0w,9787
50
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ tests/conftest.py,sha256=cZPQoOF3h1OtsFzEb7Jkx54COExVdf0XfD0LZBrmqcg,57
52
+ tests/executor.py,sha256=vnfaQXP2EmPEQ6SmOgUW0haIq1QSDY-jMxfxyjEeed4,3781
53
+ tests/fixtures.py,sha256=4j3GsopNo6tMFOyhWOb8Hnwcwiw2Xdjee4r1YLH1JBE,5774
54
+ tests/test_abstract.py,sha256=85QVvLeoN7Pvtrjhy0oXmwwmXEctrzvkGWkntXveksQ,542
55
+ tests/test_as_completed.py,sha256=_oy8L4xmK7NvpAaNPLdM6wwPtSD54nGxwQucK9pDvMg,4527
56
+ tests/test_base.py,sha256=aPdg9Oh9wdfcy3pFNyJplbJxwi7x8h2Mmj7jperqTu0,9009
57
+ tests/test_cache.py,sha256=lgcULExF1Nw4cjvujVvxub5CROqatf6TOkluUSVypIY,2562
58
+ tests/test_decorator.py,sha256=OMV2H6JjmGftdIFd5hgHBt80SF29AX8HtvvdyL8covg,3670
59
+ tests/test_executor.py,sha256=s03kTOJBtc8-idsoyCZcS5TGfT9PnioVmJuytKgkcIE,1071
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=ANhe76xyBIyFzKQcEnSkJTUZICDgf1JGDIMEE4T6dt8,524
69
+ tests/test_task.py,sha256=KFnEFTeKHQHFQD_etxE5_VnfbnGJFsvfSitQ3Mj3U3Q,9616
70
+ ez_a_sync-0.22.15.dist-info/LICENSE.txt,sha256=1on6-17OUMlja6vSPTcmlmeT_DwujCZJijYxaplBvZk,1075
71
+ ez_a_sync-0.22.15.dist-info/METADATA,sha256=PKhUn0WI0kvWKVF2qfRPJKHdPkH7K3CErdT9KhMO8FM,533
72
+ ez_a_sync-0.22.15.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
73
+ ez_a_sync-0.22.15.dist-info/top_level.txt,sha256=GVK_7kp7dgBLeHp84iIQdsJmiXnrXd-5sIf2x0Q-VKc,13
74
+ ez_a_sync-0.22.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.4.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("."))
tests/executor.py CHANGED
@@ -1,11 +1,114 @@
1
- def work():
2
- import time
3
- time.sleep(5)
1
+ import asyncio
2
+ import time
4
3
 
5
- from a_sync import ProcessPoolExecutor
4
+ import pytest
6
5
 
7
- @pytest.marks.asyncio
8
- async def test_executor():
9
- executor = ProcessPoolExecutor(6)
10
- await executor.run(work())
11
- await executor.submit(work())
6
+ from a_sync import ProcessPoolExecutor, ThreadPoolExecutor, PruningThreadPoolExecutor
7
+
8
+
9
+ @pytest.mark.asyncio
10
+ async def test_process_pool_executor_run():
11
+ """Tests the ProcessPoolExecutor by running and submitting the work function asynchronously."""
12
+ executor = ProcessPoolExecutor(1)
13
+ coro = executor.run(time.sleep, 0.1)
14
+ assert asyncio.iscoroutine(coro)
15
+ await coro
16
+
17
+
18
+ @pytest.mark.asyncio
19
+ async def test_thread_pool_executor_run():
20
+ """Tests the ThreadPoolExecutor by running and submitting the work function asynchronously."""
21
+ executor = ThreadPoolExecutor(1)
22
+ coro = executor.run(time.sleep, 0.1)
23
+ assert asyncio.iscoroutine(coro)
24
+ await coro
25
+
26
+
27
+ @pytest.mark.asyncio
28
+ async def test_pruning_thread_pool_executor_run():
29
+ """Tests the PruningThreadPoolExecutor by running and submitting the work function asynchronously."""
30
+ executor = PruningThreadPoolExecutor(1)
31
+ coro = executor.run(time.sleep, 0.1)
32
+ assert asyncio.iscoroutine(coro)
33
+ await coro
34
+
35
+
36
+ @pytest.mark.asyncio
37
+ async def test_process_pool_executor_submit():
38
+ """Tests the ProcessPoolExecutor by submitting the work function asynchronously."""
39
+ executor = ProcessPoolExecutor(1)
40
+ fut = executor.submit(time.sleep, 0.1)
41
+ assert isinstance(fut, asyncio.Future)
42
+ await fut
43
+
44
+
45
+ @pytest.mark.asyncio
46
+ async def test_thread_pool_executor_submit():
47
+ """Tests the ThreadPoolExecutor by submitting the work function asynchronously."""
48
+ executor = ThreadPoolExecutor(1)
49
+ fut = executor.submit(time.sleep, 0.1)
50
+ assert isinstance(fut, asyncio.Future)
51
+ await fut
52
+
53
+
54
+ @pytest.mark.asyncio
55
+ async def test_pruning_thread_pool_executor_submit():
56
+ """Tests the PruningThreadPoolExecutor by submitting the work function asynchronously."""
57
+ executor = PruningThreadPoolExecutor(1)
58
+ fut = executor.submit(time.sleep, 0.1)
59
+ assert isinstance(fut, asyncio.Future)
60
+ await fut
61
+
62
+
63
+ @pytest.mark.asyncio
64
+ async def test_process_pool_executor_sync_run():
65
+ """Tests the ProcessPoolExecutor by running and submitting the work function synchronously."""
66
+ executor = ProcessPoolExecutor(0)
67
+ coro = executor.run(time.sleep, 0.1)
68
+ assert asyncio.iscoroutine(coro)
69
+ await coro
70
+
71
+
72
+ @pytest.mark.asyncio
73
+ async def test_thread_pool_executor_sync_run():
74
+ """Tests the ThreadPoolExecutor by running and submitting the work function synchronously."""
75
+ executor = ThreadPoolExecutor(0)
76
+ coro = executor.run(time.sleep, 0.1)
77
+ assert asyncio.iscoroutine(coro)
78
+ await coro
79
+
80
+
81
+ @pytest.mark.asyncio
82
+ async def test_pruning_thread_pool_executor_sync_run():
83
+ """Tests the PruningThreadPoolExecutor by running and submitting the work function synchronously."""
84
+ executor = PruningThreadPoolExecutor(0)
85
+ coro = executor.run(time.sleep, 0.1)
86
+ assert asyncio.iscoroutine(coro)
87
+ await coro
88
+
89
+
90
+ @pytest.mark.asyncio
91
+ async def test_process_pool_executor_sync_submit():
92
+ """Tests the ProcessPoolExecutor by submitting the work function synchronously."""
93
+ executor = ProcessPoolExecutor(0)
94
+ fut = executor.submit(time.sleep, 0.1)
95
+ assert isinstance(fut, asyncio.Future)
96
+ await fut
97
+
98
+
99
+ @pytest.mark.asyncio
100
+ async def test_thread_pool_executor_sync_submit():
101
+ """Tests the ThreadPoolExecutor by submitting the work function synchronously."""
102
+ executor = ThreadPoolExecutor(0)
103
+ fut = executor.submit(time.sleep, 0.1)
104
+ assert isinstance(fut, asyncio.Future)
105
+ await fut
106
+
107
+
108
+ @pytest.mark.asyncio
109
+ async def test_pruning_thread_pool_executor_sync_submit():
110
+ """Tests the PruningThreadPoolExecutor by submitting the work function synchronously."""
111
+ executor = PruningThreadPoolExecutor(0)
112
+ fut = executor.submit(time.sleep, 0.1)
113
+ assert isinstance(fut, asyncio.Future)
114
+ await fut