ez-a-sync 0.22.15__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 (49) hide show
  1. a_sync/ENVIRONMENT_VARIABLES.py +34 -3
  2. a_sync/__init__.py +32 -9
  3. a_sync/_smart.py +105 -6
  4. a_sync/_typing.py +56 -3
  5. a_sync/a_sync/_descriptor.py +174 -12
  6. a_sync/a_sync/_flags.py +64 -3
  7. a_sync/a_sync/_helpers.py +40 -8
  8. a_sync/a_sync/_kwargs.py +30 -6
  9. a_sync/a_sync/_meta.py +35 -6
  10. a_sync/a_sync/abstract.py +57 -9
  11. a_sync/a_sync/config.py +44 -7
  12. a_sync/a_sync/decorator.py +217 -37
  13. a_sync/a_sync/function.py +339 -47
  14. a_sync/a_sync/method.py +241 -52
  15. a_sync/a_sync/modifiers/__init__.py +39 -1
  16. a_sync/a_sync/modifiers/cache/__init__.py +75 -5
  17. a_sync/a_sync/modifiers/cache/memory.py +50 -6
  18. a_sync/a_sync/modifiers/limiter.py +55 -6
  19. a_sync/a_sync/modifiers/manager.py +46 -2
  20. a_sync/a_sync/modifiers/semaphores.py +84 -11
  21. a_sync/a_sync/singleton.py +43 -19
  22. a_sync/asyncio/__init__.py +137 -1
  23. a_sync/asyncio/as_completed.py +44 -38
  24. a_sync/asyncio/create_task.py +46 -10
  25. a_sync/asyncio/gather.py +72 -25
  26. a_sync/exceptions.py +178 -11
  27. a_sync/executor.py +51 -3
  28. a_sync/future.py +671 -29
  29. a_sync/iter.py +64 -7
  30. a_sync/primitives/_debug.py +59 -5
  31. a_sync/primitives/_loggable.py +36 -6
  32. a_sync/primitives/locks/counter.py +74 -7
  33. a_sync/primitives/locks/prio_semaphore.py +87 -8
  34. a_sync/primitives/locks/semaphore.py +68 -20
  35. a_sync/primitives/queue.py +65 -26
  36. a_sync/task.py +51 -15
  37. a_sync/utils/iterators.py +52 -16
  38. {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/METADATA +1 -1
  39. ez_a_sync-0.22.16.dist-info/RECORD +74 -0
  40. {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/WHEEL +1 -1
  41. tests/executor.py +150 -12
  42. tests/test_abstract.py +15 -0
  43. tests/test_base.py +198 -2
  44. tests/test_executor.py +23 -0
  45. tests/test_singleton.py +13 -1
  46. tests/test_task.py +45 -17
  47. ez_a_sync-0.22.15.dist-info/RECORD +0 -74
  48. {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/LICENSE.txt +0 -0
  49. {ez_a_sync-0.22.15.dist-info → ez_a_sync-0.22.16.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,17 @@
1
1
  """
2
- This package provides custom utilities and extensions to the builtin `asyncio` package.
2
+ This package provides custom utilities and extensions to the built-in `asyncio` package.
3
3
 
4
4
  These utilities include enhanced versions of common asyncio functions, offering additional
5
5
  features and improved functionality for asynchronous programming.
6
+
7
+ Modules:
8
+ - :func:`create_task`: Extends `asyncio.create_task` to support any `Awaitable`, manage task lifecycle, and enhance error handling.
9
+ - :func:`gather`: Provides an enhanced version of `asyncio.gather` with additional features like progress reporting and exclusion of results based on a condition.
10
+ - :func:`as_completed`: Extends `asyncio.as_completed` with additional functionality such as progress reporting using `tqdm`.
11
+ - :func:`get_event_loop`: Utility to get the current event loop, handling cases where no current event loop exists by raising a `RuntimeError`.
12
+
13
+ See Also:
14
+ - `asyncio <https://docs.python.org/3/library/asyncio.html>`_: The standard asyncio library documentation for more details on the original functions.
6
15
  """
7
16
 
8
17
  from a_sync.asyncio.as_completed import as_completed
@@ -11,3 +20,130 @@ from a_sync.asyncio.gather import gather
11
20
  from a_sync.asyncio.utils import get_event_loop
12
21
 
13
22
  __all__ = ["create_task", "gather", "as_completed", "get_event_loop"]
23
+
24
+
25
+ # Function: create_task
26
+ """
27
+ Extends `asyncio.create_task` to support any `Awaitable`, manage task lifecycle, and enhance error handling.
28
+
29
+ This function accepts any `Awaitable`, ensuring broader compatibility. If the `Awaitable` is not a coroutine,
30
+ it attempts to convert it to one. It optionally prevents the task from being garbage-collected until completion
31
+ and provides enhanced error management by wrapping exceptions in a custom exception when `skip_gc_until_done` is True.
32
+
33
+ Args:
34
+ coro: An `Awaitable` object from which to create the task. If not a coroutine, it will be converted.
35
+ name: Optional name for the task, aiding in debugging.
36
+ skip_gc_until_done: If True, the task is kept alive until it completes, preventing garbage collection.
37
+ Exceptions are wrapped in `PersistedTaskException` for special handling.
38
+ log_destroy_pending: If False, asyncio's default error log when a pending task is destroyed is suppressed.
39
+
40
+ Examples:
41
+ Basic usage:
42
+ ```
43
+ task = create_task(some_coroutine())
44
+ ```
45
+
46
+ With options:
47
+ ```
48
+ task = create_task(some_coroutine(), name="MyTask", skip_gc_until_done=True)
49
+ ```
50
+
51
+ See Also:
52
+ - :func:`asyncio.create_task`: The original asyncio function.
53
+ """
54
+
55
+
56
+ # Function: gather
57
+ """
58
+ Provides an enhanced version of :func:`asyncio.gather`.
59
+
60
+ This function extends Python's `asyncio.gather`, providing additional features for handling either individual awaitable objects or a mapping of awaitables.
61
+
62
+ Differences from `asyncio.gather`:
63
+ - Uses type hints for use with static type checkers.
64
+ - Supports gathering either individual awaitables or a k:v mapping of awaitables.
65
+ - Provides progress reporting using `tqdm` if 'tqdm' is set to True.
66
+ - Allows exclusion of results based on a condition using the 'exclude_if' parameter.
67
+
68
+ Args:
69
+ *awaitables: The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables.
70
+ return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
71
+ exclude_if: A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None.
72
+ tqdm: If True, enables progress reporting using `tqdm`. Defaults to False.
73
+ **tqdm_kwargs: Additional keyword arguments for `tqdm` if progress reporting is enabled.
74
+
75
+ Examples:
76
+ Awaiting individual awaitables:
77
+ ```
78
+ results = await gather(thing1(), thing2())
79
+ ```
80
+
81
+ Awaiting a mapping of awaitables:
82
+ ```
83
+ mapping = {'key1': thing1(), 'key2': thing2()}
84
+ results = await gather(mapping)
85
+ ```
86
+
87
+ See Also:
88
+ - :func:`asyncio.gather`: The original asyncio function.
89
+ """
90
+
91
+
92
+ # Function: as_completed
93
+ """
94
+ Extends Python's :func:`asyncio.as_completed` with additional functionality.
95
+
96
+ This function extends Python's `asyncio.as_completed`, providing additional features for mixed use cases of individual awaitable objects and mappings of awaitables.
97
+
98
+ Differences from `asyncio.as_completed`:
99
+ - Uses type hints for use with static type checkers.
100
+ - Supports either individual awaitables or a k:v mapping of awaitables.
101
+ - Can be used as an async iterator which yields the result values.
102
+ - Provides progress reporting using `tqdm` if 'tqdm' is set to True.
103
+
104
+ Args:
105
+ fs: The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables.
106
+ timeout: The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout).
107
+ return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
108
+ aiter: If True, returns an async iterator of results. Defaults to False.
109
+ tqdm: If True, enables progress reporting using `tqdm`. Defaults to False.
110
+ **tqdm_kwargs: Additional keyword arguments for `tqdm` if progress reporting is enabled.
111
+
112
+ Examples:
113
+ Awaiting individual awaitables:
114
+ ```
115
+ awaitables = [async_function1(), async_function2()]
116
+ for coro in as_completed(awaitables):
117
+ val = await coro
118
+ ```
119
+
120
+ Awaiting mappings of awaitables:
121
+ ```
122
+ mapping = {'key1': async_function1(), 'key2': async_function2()}
123
+ for coro in as_completed(mapping):
124
+ k, v = await coro
125
+ ```
126
+
127
+ See Also:
128
+ - :func:`asyncio.as_completed`: The original asyncio function.
129
+ """
130
+
131
+
132
+ # Function: get_event_loop
133
+ """
134
+ Utility to get the current event loop, handling cases where no current event loop exists by raising a `RuntimeError`.
135
+
136
+ This function attempts to get the current event loop. If no event loop is found (which can occur in multi-threaded applications), it raises a `RuntimeError`.
137
+
138
+ Examples:
139
+ Basic usage:
140
+ ```
141
+ try:
142
+ loop = get_event_loop()
143
+ except RuntimeError:
144
+ print("No current event loop found.")
145
+ ```
146
+
147
+ See Also:
148
+ - :func:`asyncio.get_event_loop`: The original asyncio function.
149
+ """
@@ -9,6 +9,7 @@ try:
9
9
  except ImportError as e:
10
10
 
11
11
  class tqdm_asyncio: # type: ignore [no-redef]
12
+ @staticmethod
12
13
  def as_completed(*args, **kwargs):
13
14
  raise ImportError("You must have tqdm installed to use this feature")
14
15
 
@@ -69,45 +70,49 @@ def as_completed(
69
70
  """
70
71
  Concurrently awaits a list of awaitable objects or mappings of awaitables and returns an iterator of results.
71
72
 
72
- This function extends Python's asyncio.as_completed, providing additional features for mixed use cases of individual awaitable objects and mappings of awaitables.
73
+ This function extends Python's :func:`asyncio.as_completed`, providing additional features for mixed use cases of individual awaitable objects and mappings of awaitables.
73
74
 
74
- Differences from asyncio.as_completed:
75
+ Differences from :func:`asyncio.as_completed`:
75
76
  - Uses type hints for use with static type checkers.
76
77
  - Supports either individual awaitables or a k:v mapping of awaitables.
77
- - Can be used as an async iterator which yields the result values. Example below.
78
- - Provides progress reporting using tqdm if 'tqdm' is set to True.
78
+ - Can be used as an async iterator which yields the result values.
79
+ - Provides progress reporting using :mod:`tqdm` if 'tqdm' is set to True.
80
+
81
+ Note:
82
+ The `return_exceptions` parameter is partially implemented. While exceptions can be wrapped and returned instead of being raised, this behavior may not be fully consistent across all scenarios. Users should test their specific use cases to ensure the desired behavior.
79
83
 
80
84
  Args:
81
85
  fs: The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables.
82
86
  timeout: The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout).
83
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False. Note: This parameter is not currently implemented in the function logic.
87
+ return_exceptions: If True, exceptions are wrapped and returned as results instead of raising them. Defaults to False.
84
88
  aiter: If True, returns an async iterator of results. Defaults to False.
85
- tqdm: If True, enables progress reporting using tqdm. Defaults to False.
86
- **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
89
+ tqdm: If True, enables progress reporting using :mod:`tqdm`. Defaults to False.
90
+ **tqdm_kwargs: Additional keyword arguments for :mod:`tqdm` if progress reporting is enabled.
87
91
 
88
92
  Examples:
89
93
  Awaiting individual awaitables:
90
- ```
91
- awaitables = [async_function1(), async_function2()]
92
- for coro in as_completed(awaitables):
93
- val = await coro
94
- ...
95
94
 
96
- async for val in as_completed(awaitables, aiter=True):
97
- ...
98
- ```
95
+ >>> awaitables = [async_function1(), async_function2()]
96
+ >>> for coro in as_completed(awaitables):
97
+ ... val = await coro
98
+ ... ...
99
+
100
+ >>> async for val in as_completed(awaitables, aiter=True):
101
+ ... ...
99
102
 
100
103
  Awaiting mappings of awaitables:
101
- ```
102
- mapping = {'key1': async_function1(), 'key2': async_function2()}
103
104
 
104
- for coro in as_completed(mapping):
105
- k, v = await coro
106
- ...
105
+ >>> mapping = {'key1': async_function1(), 'key2': async_function2()}
106
+ >>> for coro in as_completed(mapping):
107
+ ... k, v = await coro
108
+ ... ...
109
+
110
+ >>> async for k, v in as_completed(mapping, aiter=True):
111
+ ... ...
107
112
 
108
- async for k, v in as_completed(mapping, aiter=True):
109
- ...
110
- ```
113
+ See Also:
114
+ - :func:`asyncio.as_completed`
115
+ - :class:`ASyncIterator`
111
116
  """
112
117
  if isinstance(fs, Mapping):
113
118
  return as_completed_mapping(
@@ -170,22 +175,23 @@ def as_completed_mapping(
170
175
  Args:
171
176
  mapping: A dictionary-like object where keys are of type K and values are awaitable objects of type V.
172
177
  timeout: The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout).
173
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
178
+ return_exceptions: If True, exceptions are wrapped and returned as results instead of raising them. Defaults to False.
174
179
  aiter: If True, returns an async iterator of results. Defaults to False.
175
- tqdm: If True, enables progress reporting using tqdm. Defaults to False.
176
- **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
180
+ tqdm: If True, enables progress reporting using :mod:`tqdm`. Defaults to False.
181
+ **tqdm_kwargs: Additional keyword arguments for :mod:`tqdm` if progress reporting is enabled.
177
182
 
178
183
  Example:
179
- ```
180
- mapping = {'key1': async_function1(), 'key2': async_function2()}
184
+ >>> mapping = {'key1': async_function1(), 'key2': async_function2()}
185
+ >>> for coro in as_completed_mapping(mapping):
186
+ ... k, v = await coro
187
+ ... ...
181
188
 
182
- for coro in as_completed_mapping(mapping):
183
- k, v = await coro
184
- ...
189
+ >>> async for k, v in as_completed_mapping(mapping, aiter=True):
190
+ ... ...
185
191
 
186
- async for k, v in as_completed_mapping(mapping, aiter=True):
187
- ...
188
- ```
192
+ See Also:
193
+ - :func:`as_completed`
194
+ - :class:`ASyncIterator`
189
195
  """
190
196
  return as_completed(
191
197
  [
@@ -227,9 +233,9 @@ async def __yield_as_completed(
227
233
  Args:
228
234
  futs: The awaitables to await.
229
235
  timeout: The maximum time, in seconds, to wait for the completion of awaitables. Defaults to None (no timeout).
230
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
231
- tqdm: If True, enables progress reporting using tqdm. Defaults to False.
232
- **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
236
+ return_exceptions: If True, exceptions are wrapped and returned as results instead of raising them. Defaults to False.
237
+ tqdm: If True, enables progress reporting using :mod:`tqdm`. Defaults to False.
238
+ **tqdm_kwargs: Additional keyword arguments for :mod:`tqdm` if progress reporting is enabled.
233
239
  """
234
240
  for fut in as_completed(
235
241
  futs,
@@ -257,7 +263,7 @@ async def __mapping_wrap(
257
263
  Args:
258
264
  k: The key associated with the awaitable.
259
265
  v: The awaitable to wrap.
260
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
266
+ return_exceptions: If True, exceptions are wrapped and returned as results instead of raising them. Defaults to False.
261
267
 
262
268
  Returns:
263
269
  A tuple of the key and the result of the awaitable or the exception if one is raised.
@@ -21,21 +21,41 @@ def create_task(
21
21
  log_destroy_pending: bool = True,
22
22
  ) -> "asyncio.Task[T]":
23
23
  """
24
- Extends asyncio.create_task to support any Awaitable, manage task lifecycle, and enhance error handling.
24
+ Extends :func:`asyncio.create_task` to support any :class:`Awaitable`, manage task lifecycle, and enhance error handling.
25
25
 
26
- This function accepts any Awaitable, ensuring broader compatibility. If the Awaitable is not a coroutine,
27
- it attempts to convert it to one. It optionally prevents the task from being garbage-collected until completion
28
- and provides enhanced error management by wrapping exceptions in a custom exception when skip_gc_until_done is True.
26
+ This function accepts any :class:`Awaitable`, ensuring broader compatibility. If the Awaitable is not a coroutine,
27
+ it is awaited directly using a private helper function `__await`, which can handle any Awaitable object.
28
+
29
+ Note:
30
+ The `__await` function is designed to handle any Awaitable, implicitly managing non-coroutine Awaitables by awaiting them.
29
31
 
30
32
  Args:
31
- coro: An Awaitable object from which to create the task. If not a coroutine, it will be converted.
33
+ coro: An :class:`Awaitable` object from which to create the task.
32
34
  name: Optional name for the task, aiding in debugging.
33
35
  skip_gc_until_done: If True, the task is kept alive until it completes, preventing garbage collection.
34
- Exceptions are wrapped in PersistedTaskException for special handling.
36
+ Exceptions are wrapped in :class:`PersistedTaskException` for special handling within the
37
+ `__persisted_task_exc_wrap` function.
35
38
  log_destroy_pending: If False, asyncio's default error log when a pending task is destroyed is suppressed.
36
39
 
37
40
  Returns:
38
- An asyncio.Task object created from the provided Awaitable.
41
+ An :class:`asyncio.Task` object created from the provided Awaitable.
42
+
43
+ Examples:
44
+ Create a simple task with a coroutine:
45
+
46
+ >>> async def my_coroutine():
47
+ ... return "Hello, World!"
48
+ >>> task = create_task(my_coroutine())
49
+
50
+ Create a task with a non-coroutine Awaitable:
51
+
52
+ >>> from concurrent.futures import Future
53
+ >>> future = Future()
54
+ >>> task = create_task(future)
55
+
56
+ See Also:
57
+ - :func:`asyncio.create_task`
58
+ - :class:`asyncio.Task`
39
59
  """
40
60
 
41
61
  if not asyncio.iscoroutine(coro):
@@ -57,10 +77,20 @@ async def __await(awaitable: Awaitable[T]) -> T:
57
77
  """Wait for the completion of an Awaitable.
58
78
 
59
79
  Args:
60
- awaitable: The Awaitable object to wait for.
80
+ awaitable: The :class:`Awaitable` object to wait for.
61
81
 
62
82
  Raises:
63
83
  RuntimeError: If a RuntimeError occurs during the await, it is raised with additional context.
84
+
85
+ Examples:
86
+ Await a simple coroutine:
87
+
88
+ >>> async def my_coroutine():
89
+ ... return "Hello, World!"
90
+ >>> result = await __await(my_coroutine())
91
+
92
+ See Also:
93
+ - :class:`Awaitable`
64
94
  """
65
95
  try:
66
96
  return await awaitable
@@ -75,8 +105,11 @@ def __prune_persisted_tasks():
75
105
  """Remove completed tasks from the set of persisted tasks.
76
106
 
77
107
  This function checks each task in the persisted tasks set. If a task is done and has an exception,
78
- it logs the exception and raises it if it's not a PersistedTaskException. It also logs the traceback
108
+ it logs the exception and raises it if it's not a :class:`PersistedTaskException`. It also logs the traceback
79
109
  manually since the usual handler will not run after retrieving the exception.
110
+
111
+ See Also:
112
+ - :class:`PersistedTaskException`
80
113
  """
81
114
  for task in tuple(__persisted_tasks):
82
115
  if task.done() and (e := task.exception()):
@@ -102,10 +135,13 @@ async def __persisted_task_exc_wrap(task: "asyncio.Task[T]") -> T:
102
135
  Wrap a task to handle its exception in a specialized manner.
103
136
 
104
137
  Args:
105
- task: The asyncio Task to wrap.
138
+ task: The :class:`asyncio.Task` to wrap.
106
139
 
107
140
  Raises:
108
141
  PersistedTaskException: Wraps any exception raised by the task for special handling.
142
+
143
+ See Also:
144
+ - :class:`PersistedTaskException`
109
145
  """
110
146
  try:
111
147
  return await task
a_sync/asyncio/gather.py CHANGED
@@ -2,35 +2,57 @@
2
2
  This module provides an enhanced version of :func:`asyncio.gather`.
3
3
  """
4
4
 
5
- import asyncio
6
- from typing import Any, Awaitable, Dict, List, Mapping, TypeVar, Union, overload
5
+ from typing import Any, Awaitable, Dict, List, Mapping, Union, overload
6
+
7
+ from a_sync._typing import *
8
+ from a_sync.asyncio.as_completed import as_completed_mapping, _exc_wrap
7
9
 
8
10
  try:
9
11
  from tqdm.asyncio import tqdm_asyncio
10
12
  except ImportError as e:
11
13
 
12
14
  class tqdm_asyncio: # type: ignore [no-redef]
15
+ @staticmethod
13
16
  async def gather(*args, **kwargs):
14
17
  raise ImportError(
15
18
  "You must have tqdm installed in order to use this feature"
16
19
  )
17
20
 
18
21
 
19
- from a_sync._typing import *
20
- from a_sync.asyncio.as_completed import as_completed_mapping, _exc_wrap
21
-
22
-
23
22
  Excluder = Callable[[T], bool]
24
23
 
25
24
 
26
25
  @overload
27
26
  async def gather(
28
- *awaitables: Mapping[K, Awaitable[V]],
27
+ awaitables: Mapping[K, Awaitable[V]],
29
28
  return_exceptions: bool = False,
30
29
  exclude_if: Optional[Excluder[V]] = None,
31
30
  tqdm: bool = False,
32
31
  **tqdm_kwargs: Any,
33
- ) -> Dict[K, V]: ...
32
+ ) -> Dict[K, V]:
33
+ """
34
+ Concurrently awaits a k:v mapping of awaitables and returns the results.
35
+
36
+ Args:
37
+ awaitables (Mapping[K, Awaitable[V]]): A mapping of keys to awaitable objects.
38
+ return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False.
39
+ exclude_if (Optional[Excluder[V]], optional): A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None. Note: This is only applied when the input is not a mapping.
40
+ tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False.
41
+ **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
42
+
43
+ Examples:
44
+ Awaiting a mapping of awaitables:
45
+
46
+ >>> mapping = {'key1': thing1(), 'key2': thing2()}
47
+ >>> results = await gather(mapping)
48
+ >>> results
49
+ {'key1': 'result', 'key2': 123}
50
+
51
+ See Also:
52
+ :func:`asyncio.gather`
53
+ """
54
+
55
+
34
56
  @overload
35
57
  async def gather(
36
58
  *awaitables: Awaitable[T],
@@ -38,7 +60,29 @@ async def gather(
38
60
  exclude_if: Optional[Excluder[T]] = None,
39
61
  tqdm: bool = False,
40
62
  **tqdm_kwargs: Any,
41
- ) -> List[T]: ...
63
+ ) -> List[T]:
64
+ """
65
+ Concurrently awaits a series of awaitable objects and returns the results.
66
+
67
+ Args:
68
+ *awaitables (Awaitable[T]): The awaitables to await concurrently.
69
+ return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False.
70
+ exclude_if (Optional[Excluder[T]], optional): A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None.
71
+ tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False.
72
+ **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
73
+
74
+ Examples:
75
+ Awaiting individual awaitables:
76
+
77
+ >>> results = await gather(thing1(), thing2())
78
+ >>> results
79
+ ['result', 123]
80
+
81
+ See Also:
82
+ :func:`asyncio.gather`
83
+ """
84
+
85
+
42
86
  async def gather(
43
87
  *awaitables: Union[Awaitable[T], Mapping[K, Awaitable[V]]],
44
88
  return_exceptions: bool = False,
@@ -47,40 +91,40 @@ async def gather(
47
91
  **tqdm_kwargs: Any,
48
92
  ) -> Union[List[T], Dict[K, V]]:
49
93
  """
50
- Concurrently awaits a list of awaitable objects or a mapping of awaitables and returns the results.
94
+ Concurrently awaits a list of awaitable objects or a k:v mapping of awaitables, and returns the results.
51
95
 
52
- This function extends Python's asyncio.gather, providing additional features for handling either individual awaitable objects or a mapping of awaitables.
96
+ This function extends Python's :func:`asyncio.gather`, providing additional features for handling either individual
97
+ awaitable objects or a single mapping of awaitables.
53
98
 
54
- Differences from asyncio.gather:
99
+ Differences from :func:`asyncio.gather`:
55
100
  - Uses type hints for use with static type checkers.
56
101
  - Supports gathering either individual awaitables or a k:v mapping of awaitables.
57
102
  - Provides progress reporting using tqdm if 'tqdm' is set to True.
58
- - Allows exclusion of results based on a condition using the 'exclude_if' parameter.
103
+ - Allows exclusion of results based on a condition using the 'exclude_if' parameter. Note: This is only applied when the input is not a mapping.
59
104
 
60
105
  Args:
61
- *awaitables: The awaitables to await concurrently. It can be a list of individual awaitables or a mapping of awaitables.
62
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
63
- exclude_if: A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None.
64
- tqdm: If True, enables progress reporting using tqdm. Defaults to False.
106
+ *awaitables (Union[Awaitable[T], Mapping[K, Awaitable[V]]]): The awaitables to await concurrently. It can be a list of individual awaitables or a single mapping of awaitables.
107
+ return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False.
108
+ exclude_if (Optional[Excluder[T]], optional): A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None. Note: This is only applied when the input is not a mapping.
109
+ tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False.
65
110
  **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
66
111
 
67
112
  Examples:
68
113
  Awaiting individual awaitables:
69
114
 
70
- - Results will be a list containing the result of each awaitable in sequential order.
71
-
72
115
  >>> results = await gather(thing1(), thing2())
73
116
  >>> results
74
117
  ['result', 123]
75
118
 
76
119
  Awaiting a mapping of awaitables:
77
120
 
78
- - Results will be a dictionary with 'key1' mapped to the result of thing1() and 'key2' mapped to the result of thing2.
79
-
80
121
  >>> mapping = {'key1': thing1(), 'key2': thing2()}
81
122
  >>> results = await gather(mapping)
82
123
  >>> results
83
124
  {'key1': 'result', 'key2': 123}
125
+
126
+ See Also:
127
+ :func:`asyncio.gather`
84
128
  """
85
129
  is_mapping = _is_mapping(awaitables)
86
130
  results = await (
@@ -123,10 +167,10 @@ async def gather_mapping(
123
167
  This function is designed to await a mapping of awaitable objects, where each key-value pair represents a unique awaitable. It enables concurrent execution and gathers results into a dictionary.
124
168
 
125
169
  Args:
126
- mapping: A dictionary-like object where keys are of type K and values are awaitable objects of type V.
127
- return_exceptions: If True, exceptions are returned as results instead of raising them. Defaults to False.
128
- exclude_if: A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None.
129
- tqdm: If True, enables progress reporting using tqdm. Defaults to False.
170
+ mapping (Mapping[K, Awaitable[V]]): A dictionary-like object where keys are of type K and values are awaitable objects of type V.
171
+ return_exceptions (bool, optional): If True, exceptions are returned as results instead of raising them. Defaults to False.
172
+ exclude_if (Optional[Excluder[V]], optional): A callable that takes a result and returns True if the result should be excluded from the final output. Defaults to None. Note: This is not applied when the input is a mapping.
173
+ tqdm (bool, optional): If True, enables progress reporting using tqdm. Defaults to False.
130
174
  **tqdm_kwargs: Additional keyword arguments for tqdm if progress reporting is enabled.
131
175
 
132
176
  Example:
@@ -136,6 +180,9 @@ async def gather_mapping(
136
180
  >>> results = await gather_mapping(mapping)
137
181
  >>> results
138
182
  {'task1': "result", 'task2': 123, 'task3': None}
183
+
184
+ See Also:
185
+ :func:`asyncio.gather`
139
186
  """
140
187
  results = {
141
188
  k: v