ez-a-sync 0.22.15__tar.gz → 0.22.16__tar.gz

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 (119) hide show
  1. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/PKG-INFO +1 -1
  2. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/README.md +132 -0
  3. ez_a_sync-0.22.16/a_sync/ENVIRONMENT_VARIABLES.py +44 -0
  4. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/__init__.py +32 -9
  5. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/_smart.py +105 -6
  6. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/_typing.py +56 -3
  7. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/_descriptor.py +174 -12
  8. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/_flags.py +64 -3
  9. ez_a_sync-0.22.16/a_sync/a_sync/_helpers.py +91 -0
  10. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/_kwargs.py +30 -6
  11. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/_meta.py +35 -6
  12. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/abstract.py +57 -9
  13. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/config.py +44 -7
  14. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/decorator.py +217 -37
  15. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/function.py +339 -47
  16. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/method.py +241 -52
  17. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/modifiers/__init__.py +39 -1
  18. ez_a_sync-0.22.16/a_sync/a_sync/modifiers/cache/__init__.py +159 -0
  19. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/modifiers/cache/memory.py +50 -6
  20. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/modifiers/limiter.py +55 -6
  21. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/modifiers/manager.py +46 -2
  22. ez_a_sync-0.22.16/a_sync/a_sync/modifiers/semaphores.py +175 -0
  23. ez_a_sync-0.22.16/a_sync/a_sync/singleton.py +61 -0
  24. ez_a_sync-0.22.16/a_sync/asyncio/__init__.py +149 -0
  25. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/asyncio/as_completed.py +44 -38
  26. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/asyncio/create_task.py +46 -10
  27. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/asyncio/gather.py +72 -25
  28. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/exceptions.py +178 -11
  29. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/executor.py +51 -3
  30. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/future.py +671 -29
  31. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/iter.py +64 -7
  32. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/_debug.py +59 -5
  33. ez_a_sync-0.22.16/a_sync/primitives/_loggable.py +69 -0
  34. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/locks/counter.py +74 -7
  35. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/locks/prio_semaphore.py +87 -8
  36. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/locks/semaphore.py +68 -20
  37. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/queue.py +65 -26
  38. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/task.py +51 -15
  39. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/utils/iterators.py +52 -16
  40. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/ez_a_sync.egg-info/PKG-INFO +1 -1
  41. ez_a_sync-0.22.16/tests/executor.py +252 -0
  42. ez_a_sync-0.22.16/tests/test_abstract.py +35 -0
  43. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_base.py +198 -2
  44. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_executor.py +23 -0
  45. ez_a_sync-0.22.16/tests/test_singleton.py +37 -0
  46. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_task.py +45 -17
  47. ez_a_sync-0.22.15/a_sync/ENVIRONMENT_VARIABLES.py +0 -13
  48. ez_a_sync-0.22.15/a_sync/a_sync/_helpers.py +0 -59
  49. ez_a_sync-0.22.15/a_sync/a_sync/modifiers/cache/__init__.py +0 -89
  50. ez_a_sync-0.22.15/a_sync/a_sync/modifiers/semaphores.py +0 -102
  51. ez_a_sync-0.22.15/a_sync/a_sync/singleton.py +0 -37
  52. ez_a_sync-0.22.15/a_sync/asyncio/__init__.py +0 -13
  53. ez_a_sync-0.22.15/a_sync/primitives/_loggable.py +0 -39
  54. ez_a_sync-0.22.15/tests/executor.py +0 -114
  55. ez_a_sync-0.22.15/tests/test_abstract.py +0 -20
  56. ez_a_sync-0.22.15/tests/test_singleton.py +0 -25
  57. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.coverage +0 -0
  58. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/black.yaml +0 -0
  59. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/codeql.yaml +0 -0
  60. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/docs.yaml +0 -0
  61. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/mypy.yaml +0 -0
  62. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/pytest.yaml +0 -0
  63. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.github/workflows/release.yaml +0 -0
  64. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.gitignore +0 -0
  65. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/.sourcery.yaml +0 -0
  66. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/LICENSE.txt +0 -0
  67. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/Makefile +0 -0
  68. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/TODO +0 -0
  69. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/__init__.py +0 -0
  70. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/base.py +0 -0
  71. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/a_sync/property.py +0 -0
  72. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/aliases.py +0 -0
  73. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/asyncio/utils.py +0 -0
  74. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/__init__.py +0 -0
  75. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/locks/__init__.py +0 -0
  76. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/primitives/locks/event.py +0 -0
  77. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/py.typed +0 -0
  78. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/sphinx/__init__.py +0 -0
  79. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/sphinx/ext.py +0 -0
  80. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/a_sync/utils/__init__.py +0 -0
  81. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/Makefile +0 -0
  82. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/alabaster.css +0 -0
  83. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/basic.css +0 -0
  84. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/custom.css +0 -0
  85. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/doctools.js +0 -0
  86. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/documentation_options.js +0 -0
  87. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/file.png +0 -0
  88. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/language_data.js +0 -0
  89. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/minus.png +0 -0
  90. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/plus.png +0 -0
  91. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/pygments.css +0 -0
  92. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/searchtools.js +0 -0
  93. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/_build/html/_static/sphinx_highlight.js +0 -0
  94. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/conf.py +0 -0
  95. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/index.rst +0 -0
  96. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/docs/make.bat +0 -0
  97. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/ez_a_sync.egg-info/SOURCES.txt +0 -0
  98. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/ez_a_sync.egg-info/dependency_links.txt +0 -0
  99. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/ez_a_sync.egg-info/requires.txt +0 -0
  100. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/ez_a_sync.egg-info/top_level.txt +0 -0
  101. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/pyproject.yaml +0 -0
  102. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/requirements-dev.txt +0 -0
  103. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/requirements.txt +0 -0
  104. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/setup.cfg +0 -0
  105. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/setup.py +0 -0
  106. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/__init__.py +0 -0
  107. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/conftest.py +0 -0
  108. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/fixtures.py +0 -0
  109. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_as_completed.py +0 -0
  110. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_cache.py +0 -0
  111. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_decorator.py +0 -0
  112. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_future.py +0 -0
  113. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_gather.py +0 -0
  114. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_helpers.py +0 -0
  115. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_iter.py +0 -0
  116. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_limiter.py +0 -0
  117. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_meta.py +0 -0
  118. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_modified.py +0 -0
  119. {ez_a_sync-0.22.15 → ez_a_sync-0.22.16}/tests/test_semaphore.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ez-a-sync
3
- Version: 0.22.15
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
@@ -13,6 +13,16 @@
13
13
  - [async modifiers](#async-modifiers)
14
14
  - [sync modifiers](#sync-modifiers)
15
15
  - [Default Modifiers](#default-modifiers)
16
+ - [Other Helpful Classes](#other-helpful-modules)
17
+ - [ASyncIterable](#asynciterable)
18
+ - [ASyncIterator](#asynciterator)
19
+ - [ASyncFilter](#asyncfilter)
20
+ - [ASyncSorter](#asyncsorter)
21
+ - [Other Helpful Modules](#other-helpful-modules)
22
+ - [future](#future)
23
+ - [ASyncFuture](#asyncfuture)
24
+ - [future decorator](#future-decorator)
25
+ - [asyncio](#asyncio)
16
26
 
17
27
  <!-- /TOC -->
18
28
  ## Introduction
@@ -195,3 +205,125 @@ Instead of setting modifiers one by one in functions, you can set a default valu
195
205
  - `RAM_CACHE_TTL`
196
206
  - `RUNS_PER_MINUTE`
197
207
  - `SEMAPHORE`
208
+
209
+ ### Other Helpful Classes
210
+ #### ASyncIterable
211
+ The [ASyncIterable](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncIterable) class allows objects to be iterated over using either a standard `for` loop or an `async for` loop. This is particularly useful in scenarios where the mode of iteration needs to be flexible or is determined at runtime.
212
+
213
+ ```python
214
+ from a_sync import ASyncIterable
215
+
216
+ async_iterable = ASyncIterable(some_async_iterable)
217
+
218
+ # Asynchronous iteration
219
+ async for item in async_iterable:
220
+ ...
221
+
222
+ # Synchronous iteration
223
+ for item in async_iterable:
224
+ ...
225
+ ```
226
+
227
+ See the [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncIterable) for more information.
228
+
229
+ #### ASyncIterator
230
+
231
+ The [ASyncIterator](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncIterator) class provides a unified interface for iteration that can operate in both synchronous and asynchronous contexts. It allows the wrapping of asynchronous iterable objects or async generator functions.
232
+
233
+ ```python
234
+ from a_sync import ASyncIterator
235
+
236
+ async_iterator = ASyncIterator(some_async_iterator)
237
+
238
+ # Asynchronous iteration
239
+ async for item in async_iterator:
240
+ ...
241
+
242
+ # Synchronous iteration
243
+ for item in async_iterator:
244
+ ...
245
+ ```
246
+
247
+ See the [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncIterator) for more information.
248
+
249
+ #### ASyncFilter
250
+
251
+ The [ASyncFilter](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncFilter) class filters items of an async iterable based on a provided function. It can handle both synchronous and asynchronous filter functions.
252
+
253
+ ```python
254
+ from a_sync import ASyncFilter
255
+
256
+ async def is_even(x):
257
+ return x % 2 == 0
258
+
259
+ filtered_iterable = ASyncFilter(is_even, some_async_iterable)
260
+
261
+ # or use the alias
262
+ import a_sync
263
+
264
+ filtered_iterable = a_sync.filter(is_even, some_async_iterable)
265
+
266
+ # Asynchronous iteration
267
+ async for item in filtered_iterable:
268
+ ...
269
+
270
+ # Synchronous iteration
271
+ for item in filtered_iterable:
272
+ ...
273
+ ```
274
+
275
+ See the [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncFilter) for more information.
276
+
277
+ #### ASyncSorter
278
+
279
+ The [ASyncSorter](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncSorter) class sorts items of an async iterable based on a provided key function. It supports both synchronous and asynchronous key functions.
280
+
281
+ ```python
282
+ from a_sync import ASyncSorter
283
+
284
+ sorted_iterable = ASyncSorter(some_async_iterable, key=lambda x: x.value)
285
+
286
+ # or use the alias
287
+ import a_sync
288
+
289
+ sorted_iterable = a_sync.sort(some_async_iterable, key=lambda x: x.value)
290
+
291
+ # Asynchronous iteration
292
+ async for item in sorted_iterable:
293
+ ...
294
+
295
+ # Synchronous iteration
296
+ for item in sorted_iterable:
297
+ ...
298
+ ```
299
+
300
+ See the [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.ASyncSorter) for more information.
301
+
302
+ ## Other Helpful Modules
303
+ The stuff here is unrelated to the main purpose of ez-a-sync, but cool and useful nonetheless
304
+
305
+ ### asyncio
306
+
307
+ The `ez-a-sync` library extends the functionality of Python's `asyncio` module with additional utilities to simplify asynchronous programming.
308
+
309
+ - **as_completed**: This function allows you to iterate over awaitables as they complete, similar to `asyncio.as_completed`. It supports both synchronous and asynchronous iteration. [Learn more about `as_completed`](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.asyncio.as_completed).
310
+
311
+ - **gather**: A utility to run multiple asynchronous operations concurrently and wait for all of them to complete. It is similar to `asyncio.gather` but integrates seamlessly with the `ez-a-sync` library. [Learn more about `gather`](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.asyncio.gather).
312
+
313
+ - **create_task**: A function to create a new task from a coroutine, similar to `asyncio.create_task`, but with additional features provided by `ez-a-sync`. [Learn more about `create_task`](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.asyncio.create_task).
314
+
315
+ - **as_completed**: This function allows you to iterate over awaitables as they complete, similar to `asyncio.as_completed`. It supports both synchronous and asynchronous iteration. [Learn more about `as_completed`](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.asyncio.as_completed).
316
+
317
+ These utilities enhance the standard `asyncio` module, providing more flexibility and control over asynchronous operations. For detailed documentation and examples, please refer to the [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.asyncio)
318
+
319
+ ### future
320
+ The future module is something totally different.
321
+ TODO: short explainer of module value prop and use case
322
+
323
+ #### ASyncFuture
324
+ [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.future.ASyncFuture)
325
+ TODO: short explainers on ASyncFuture class
326
+
327
+ #### future decorator
328
+ [documentation](#https://bobthebuidler.github.io/ez-a-sync/source/a_sync.html#a_sync.future.future)
329
+ TODO: short explainers on future fn
@@ -0,0 +1,44 @@
1
+ from typed_envs import EnvVarFactory
2
+
3
+ envs = EnvVarFactory("EZASYNC")
4
+
5
+ # We have some envs here to help you debug your custom class implementations
6
+
7
+ DEBUG_CLASS_NAME = envs.create_env("DEBUG_CLASS_NAME", str, default="", verbose=False)
8
+ """str: The name of the class to debug.
9
+
10
+ If you're only interested in debugging a specific class, set this to the class name.
11
+
12
+ Examples:
13
+ To debug a class named `MyClass`, set the environment variable:
14
+
15
+ .. code-block:: bash
16
+
17
+ export EZASYNC_DEBUG_CLASS_NAME=MyClass
18
+
19
+ See Also:
20
+ :func:`DEBUG_MODE` for enabling debug mode on all classes.
21
+ """
22
+
23
+ DEBUG_MODE = envs.create_env(
24
+ "DEBUG_MODE", bool, default=bool(DEBUG_CLASS_NAME), verbose=False
25
+ )
26
+ """bool: Enables debug mode on all classes.
27
+
28
+ Set this environment variable to `True` to enable debug mode on all classes.
29
+ If `DEBUG_CLASS_NAME` is set to a truthy value other than an empty string,
30
+ `DEBUG_MODE` will default to `True`.
31
+
32
+ Examples:
33
+ To enable debug mode globally, set the environment variable:
34
+
35
+ .. code-block:: bash
36
+
37
+ export EZASYNC_DEBUG_MODE=True
38
+
39
+ If you have set `DEBUG_CLASS_NAME` to a specific class, `DEBUG_MODE` will
40
+ automatically be `True` unless `DEBUG_CLASS_NAME` is an empty string.
41
+
42
+ See Also:
43
+ :func:`DEBUG_CLASS_NAME` for debugging a specific class.
44
+ """
@@ -8,17 +8,40 @@ that can operate in both synchronous and asynchronous contexts. Additionally, it
8
8
  such as queues and locks, with extra functionality.
9
9
 
10
10
  Modules and components included:
11
- - `aliases`, `exceptions`, `iter`, `task`: Core modules of the library.
12
- - `ASyncGenericBase`, `ASyncGenericSingleton`, `a_sync`: Base classes and decorators for dual-context execution.
13
- - `apply_semaphore`: Function to apply semaphores to coroutines.
14
- - `ASyncCachedPropertyDescriptor`, `ASyncPropertyDescriptor`, `cached_property`, `property`: Property descriptors for async properties.
15
- - `as_completed`, `create_task`, `gather`: Enhanced asyncio functions.
16
- - Executors: `AsyncThreadPoolExecutor`, `AsyncProcessPoolExecutor`, `PruningThreadPoolExecutor` for async execution.
17
- - Iterators: `ASyncFilter`, `ASyncSorter`, `ASyncIterable`, `ASyncIterator` for async iteration.
18
- - Utilities: `all`, `any`, `as_yielded` for async utilities.
11
+ - :mod:`~aliases`, :mod:`~exceptions`, :mod:`~iter`, :mod:`~task`: Core modules of the library.
12
+ - :class:`~ASyncGenericBase`, :class:`~ASyncGenericSingleton`, :func:`~a_sync`: Base classes and decorators for dual-context execution.
13
+ - :class:`~ASyncCachedPropertyDescriptor`, :class:`~ASyncPropertyDescriptor`, `cached_property`, `property`: Property descriptors for async properties.
14
+ - :func:`~as_completed`, :func:`~create_task`, :func:`~gather`: Enhanced asyncio functions.
15
+ - Executors: :class:`~AsyncThreadPoolExecutor`, :class:`~AsyncProcessPoolExecutor`, :class:`~PruningThreadPoolExecutor` for async execution.
16
+ - Iterators: :class:`~ASyncFilter`, :class:`~ASyncSorter`, :class:`~ASyncIterable`, :class:`~ASyncIterator` for async iteration.
17
+ - Utilities: :func:`~all`, :func:`~any`, :func:`~as_yielded`, :func:`~exhaust_iterator`, :func:`~exhaust_iterators` for async utilities.
18
+ - :func:`~apply_semaphore`: Function to apply semaphores to coroutines.
19
19
 
20
20
  Alias for backward compatibility:
21
- - `ASyncBase` is an alias for `ASyncGenericBase`, which will be removed eventually, probably in version 0.1.0.
21
+ - :class:`~ASyncBase` is an alias for :class:`~ASyncGenericBase`, which will be removed eventually, probably in version 0.1.0.
22
+
23
+ Examples:
24
+ Using the `@a_sync` decorator:
25
+ >>> from a_sync import a_sync
26
+ >>> @a_sync
27
+ ... async def my_function():
28
+ ... return "Hello, World!"
29
+ >>> result = await my_function()
30
+ >>> print(result)
31
+
32
+ Using `ASyncGenericBase` for dual-context classes:
33
+ >>> from a_sync import ASyncGenericBase
34
+ >>> class MyClass(ASyncGenericBase):
35
+ ... async def my_method(self):
36
+ ... return "Hello from MyClass"
37
+ >>> obj = MyClass()
38
+ >>> result = await obj.my_method()
39
+ >>> print(result)
40
+
41
+ See Also:
42
+ - :mod:`a_sync.a_sync`: Contains the core classes and decorators.
43
+ - :mod:`a_sync.asyncio`: Provides enhanced asyncio functions.
44
+ - :mod:`a_sync.primitives`: Includes modified versions of standard asyncio primitives.
22
45
  """
23
46
 
24
47
  from a_sync import aliases, exceptions, iter, task
@@ -1,7 +1,8 @@
1
1
  """
2
2
  This module defines smart future and task utilities for the a_sync library.
3
3
  These utilities provide enhanced functionality for managing asynchronous tasks and futures,
4
- including task shielding and a custom task factory for creating SmartTask instances.
4
+ including a custom task factory for creating :class:`~SmartTask` instances and a shielding mechanism
5
+ to protect tasks from cancellation.
5
6
  """
6
7
 
7
8
  import asyncio
@@ -37,6 +38,27 @@ class _SmartFutureMixin(Generic[T]):
37
38
  def __await__(self: Union["SmartFuture", "SmartTask"]) -> Generator[Any, None, T]:
38
39
  """
39
40
  Await the smart future or task, handling waiters and logging.
41
+
42
+ Yields:
43
+ The result of the future or task.
44
+
45
+ Raises:
46
+ RuntimeError: If await wasn't used with future.
47
+
48
+ Example:
49
+ Awaiting a SmartFuture:
50
+
51
+ ```python
52
+ future = SmartFuture()
53
+ result = await future
54
+ ```
55
+
56
+ Awaiting a SmartTask:
57
+
58
+ ```python
59
+ task = SmartTask(coro=my_coroutine())
60
+ result = await task
61
+ ```
40
62
  """
41
63
  if self.done():
42
64
  return self.result() # May raise too.
@@ -54,6 +76,12 @@ class _SmartFutureMixin(Generic[T]):
54
76
  # NOTE: we check .done() because the callback may not have ran yet and its very lightweight
55
77
  """
56
78
  Get the number of waiters currently awaiting the future or task.
79
+
80
+ Example:
81
+ ```python
82
+ future = SmartFuture()
83
+ print(future.num_waiters)
84
+ ```
57
85
  """
58
86
  if self.done():
59
87
  # if there are any waiters left, there won't be once the event loop runs once
@@ -67,6 +95,9 @@ class _SmartFutureMixin(Generic[T]):
67
95
  Callback to clean up waiters when a waiter task is done.
68
96
 
69
97
  Removes the waiter from _waiters, and _queue._futs if applicable
98
+
99
+ Args:
100
+ waiter: The waiter task to clean up.
70
101
  """
71
102
  if not self.done():
72
103
  self._waiters.remove(waiter)
@@ -84,8 +115,16 @@ class SmartFuture(_SmartFutureMixin[T], asyncio.Future):
84
115
  """
85
116
  A smart future that tracks waiters and integrates with a smart processing queue.
86
117
 
87
- Inherits from both _SmartFutureMixin and asyncio.Future, providing additional functionality
118
+ Inherits from both :class:`_SmartFutureMixin` and :class:`asyncio.Future`, providing additional functionality
88
119
  for tracking waiters and integrating with a smart processing queue.
120
+
121
+ Example:
122
+ Creating and awaiting a SmartFuture:
123
+
124
+ ```python
125
+ future = SmartFuture()
126
+ await future
127
+ ```
89
128
  """
90
129
 
91
130
  _queue = None
@@ -105,6 +144,11 @@ class SmartFuture(_SmartFutureMixin[T], asyncio.Future):
105
144
  queue: Optional; a smart processing queue.
106
145
  key: Optional; a key identifying the future.
107
146
  loop: Optional; the event loop.
147
+
148
+ Example:
149
+ ```python
150
+ future = SmartFuture(queue=my_queue, key=my_key)
151
+ ```
108
152
  """
109
153
  super().__init__(loop=loop)
110
154
  if queue:
@@ -125,8 +169,12 @@ class SmartFuture(_SmartFutureMixin[T], asyncio.Future):
125
169
  Args:
126
170
  other: Another SmartFuture to compare with.
127
171
 
128
- Returns:
129
- True if self has more waiters than other.
172
+ Example:
173
+ ```python
174
+ future1 = SmartFuture()
175
+ future2 = SmartFuture()
176
+ print(future1 < future2)
177
+ ```
130
178
  """
131
179
  return self.num_waiters > other.num_waiters
132
180
 
@@ -138,7 +186,7 @@ def create_future(
138
186
  loop: Optional[asyncio.AbstractEventLoop] = None,
139
187
  ) -> SmartFuture[V]:
140
188
  """
141
- Create a SmartFuture instance.
189
+ Create a :class:`~SmartFuture` instance.
142
190
 
143
191
  Args:
144
192
  queue: Optional; a smart processing queue.
@@ -147,6 +195,13 @@ def create_future(
147
195
 
148
196
  Returns:
149
197
  A SmartFuture instance.
198
+
199
+ Example:
200
+ Creating a SmartFuture using the factory function:
201
+
202
+ ```python
203
+ future = create_future(queue=my_queue, key=my_key)
204
+ ```
150
205
  """
151
206
  return SmartFuture(queue=queue, key=key, loop=loop or asyncio.get_event_loop())
152
207
 
@@ -155,8 +210,16 @@ class SmartTask(_SmartFutureMixin[T], asyncio.Task):
155
210
  """
156
211
  A smart task that tracks waiters and integrates with a smart processing queue.
157
212
 
158
- Inherits from both _SmartFutureMixin and asyncio.Task, providing additional functionality
213
+ Inherits from both :class:`_SmartFutureMixin` and :class:`asyncio.Task`, providing additional functionality
159
214
  for tracking waiters and integrating with a smart processing queue.
215
+
216
+ Example:
217
+ Creating and awaiting a SmartTask:
218
+
219
+ ```python
220
+ task = SmartTask(coro=my_coroutine())
221
+ await task
222
+ ```
160
223
  """
161
224
 
162
225
  def __init__(
@@ -173,6 +236,11 @@ class SmartTask(_SmartFutureMixin[T], asyncio.Task):
173
236
  coro: The coroutine to run in the task.
174
237
  loop: Optional; the event loop.
175
238
  name: Optional; the name of the task.
239
+
240
+ Example:
241
+ ```python
242
+ task = SmartTask(coro=my_coroutine(), name="my_task")
243
+ ```
176
244
  """
177
245
  super().__init__(coro, loop=loop, name=name)
178
246
  self._waiters: Set["asyncio.Task[T]"] = set()
@@ -193,6 +261,17 @@ def smart_task_factory(
193
261
 
194
262
  Returns:
195
263
  A SmartTask instance running the provided coroutine.
264
+
265
+ Example:
266
+ Using the smart task factory to create a SmartTask:
267
+
268
+ ```python
269
+ loop = asyncio.get_event_loop()
270
+ task = smart_task_factory(loop, my_coroutine())
271
+ ```
272
+
273
+ See Also:
274
+ - :func:`set_smart_task_factory`
196
275
  """
197
276
  return SmartTask(coro, loop=loop)
198
277
 
@@ -203,6 +282,16 @@ def set_smart_task_factory(loop: asyncio.AbstractEventLoop = None) -> None:
203
282
 
204
283
  Args:
205
284
  loop: Optional; the event loop. If None, the current event loop is used.
285
+
286
+ Example:
287
+ Setting the smart task factory for the current event loop:
288
+
289
+ ```python
290
+ set_smart_task_factory()
291
+ ```
292
+
293
+ See Also:
294
+ - :func:`smart_task_factory`
206
295
  """
207
296
  if loop is None:
208
297
  loop = a_sync.asyncio.get_event_loop()
@@ -241,6 +330,16 @@ def shield(
241
330
  Args:
242
331
  arg: The awaitable to shield from cancellation.
243
332
  loop: Optional; the event loop. Deprecated since Python 3.8.
333
+
334
+ Example:
335
+ Using shield to protect a coroutine from cancellation:
336
+
337
+ ```python
338
+ result = await shield(my_coroutine())
339
+ ```
340
+
341
+ See Also:
342
+ - :func:`asyncio.shield`
244
343
  """
245
344
  if loop is not None:
246
345
  warnings.warn(
@@ -1,7 +1,60 @@
1
1
  """
2
- This module provides type definitions and type-related utilities for the a_sync library.
3
- It includes various type aliases, protocols, and TypedDicts used throughout the library
4
- to enhance type checking and provide better IDE support.
2
+ This module provides type definitions and type-related utilities for the `a_sync` library.
3
+
4
+ It includes various type aliases and protocols used throughout the library to enhance type checking and provide better IDE support.
5
+
6
+ Examples:
7
+ The following examples demonstrate how to use some of the type aliases and protocols defined in this module.
8
+
9
+ Example of a function that can return either an awaitable or a direct value:
10
+
11
+ ```python
12
+ from a_sync._typing import MaybeAwaitable
13
+ from typing import Awaitable
14
+
15
+ async def process_data(data: MaybeAwaitable[int]) -> int:
16
+ if isinstance(data, Awaitable):
17
+ return await data
18
+ return data
19
+
20
+ # Usage
21
+ import asyncio
22
+
23
+ async def main():
24
+ result = await process_data(asyncio.sleep(1, result=42))
25
+ print(result) # Output: 42
26
+
27
+ result = await process_data(42)
28
+ print(result) # Output: 42
29
+
30
+ asyncio.run(main())
31
+ ```
32
+
33
+ Example of defining a coroutine function type:
34
+
35
+ ```python
36
+ from a_sync._typing import CoroFn
37
+
38
+ async def async_function(x: int) -> str:
39
+ return str(x)
40
+
41
+ coro_fn: CoroFn[[int], str] = async_function
42
+ ```
43
+
44
+ Example of defining a synchronous function type:
45
+
46
+ ```python
47
+ from a_sync._typing import SyncFn
48
+
49
+ def sync_function(x: int) -> str:
50
+ return str(x)
51
+
52
+ sync_fn: SyncFn[[int], str] = sync_function
53
+ ```
54
+
55
+ See Also:
56
+ - :mod:`typing`
57
+ - :mod:`asyncio`
5
58
  """
6
59
 
7
60
  import asyncio