ez-a-sync 0.24.3__tar.gz → 0.24.4__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 (163) hide show
  1. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/PKG-INFO +1 -1
  2. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_helpers.pyi +1 -0
  3. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/abstract.pyi +1 -0
  4. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/method.pyi +1 -0
  5. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_debug.c +4 -4
  6. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_debug.pyi +1 -0
  7. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_debug.pyx +1 -1
  8. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_loggable.pyi +1 -0
  9. ez_a_sync-0.24.4/a_sync/primitives/locks/counter.pyi +142 -0
  10. ez_a_sync-0.24.4/a_sync/primitives/locks/event.pyi +36 -0
  11. ez_a_sync-0.24.4/a_sync/primitives/locks/prio_semaphore.c +24744 -0
  12. ez_a_sync-0.24.4/a_sync/primitives/locks/prio_semaphore.pyi +208 -0
  13. ez_a_sync-0.24.3/a_sync/primitives/locks/prio_semaphore.py → ez_a_sync-0.24.4/a_sync/primitives/locks/prio_semaphore.pyx +191 -98
  14. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/semaphore.c +5630 -6583
  15. ez_a_sync-0.24.4/a_sync/primitives/locks/semaphore.pxd +17 -0
  16. ez_a_sync-0.24.4/a_sync/primitives/locks/semaphore.pyi +180 -0
  17. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/semaphore.pyx +59 -30
  18. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/task.pyi +1 -0
  19. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/PKG-INFO +1 -1
  20. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/SOURCES.txt +8 -1
  21. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/setup.py +2 -2
  22. ez_a_sync-0.24.4/tests/test_prio_semaphore.py +32 -0
  23. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_semaphore.py +2 -2
  24. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.coverage +0 -0
  25. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/black.yaml +0 -0
  26. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/codeql.yaml +0 -0
  27. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/docs.yaml +0 -0
  28. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/mypy.yaml +0 -0
  29. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/pytest.yaml +0 -0
  30. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.github/workflows/release.yaml +0 -0
  31. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.gitignore +0 -0
  32. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/.sourcery.yaml +0 -0
  33. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/LICENSE.txt +0 -0
  34. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/Makefile +0 -0
  35. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/README.md +0 -0
  36. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/TODO +0 -0
  37. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/ENVIRONMENT_VARIABLES.py +0 -0
  38. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/__init__.pxd +0 -0
  39. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/__init__.py +0 -0
  40. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/_smart.py +0 -0
  41. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/_typing.py +0 -0
  42. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/__init__.py +0 -0
  43. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_descriptor.py +0 -0
  44. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_flags.c +0 -0
  45. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_flags.pxd +0 -0
  46. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_flags.pyx +0 -0
  47. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_helpers.c +0 -0
  48. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_helpers.pxd +0 -0
  49. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_helpers.pyx +0 -0
  50. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_kwargs.c +0 -0
  51. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_kwargs.pxd +0 -0
  52. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_kwargs.pyx +0 -0
  53. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/_meta.py +0 -0
  54. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/abstract.c +0 -0
  55. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/abstract.pyx +0 -0
  56. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/base.c +0 -0
  57. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/base.pyi +0 -0
  58. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/base.pyx +0 -0
  59. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/config.py +0 -0
  60. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/decorator.py +0 -0
  61. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/flags.py +0 -0
  62. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/function.c +0 -0
  63. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/function.pyi +0 -0
  64. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/function.pyx +0 -0
  65. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/method.c +0 -0
  66. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/method.pxd +0 -0
  67. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/method.pyx +0 -0
  68. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/__init__.py +0 -0
  69. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/cache/__init__.py +0 -0
  70. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/cache/memory.py +0 -0
  71. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/limiter.py +0 -0
  72. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/manager.c +0 -0
  73. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/manager.pyi +0 -0
  74. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/manager.pyx +0 -0
  75. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/modifiers/semaphores.py +0 -0
  76. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/property.c +0 -0
  77. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/property.pyi +0 -0
  78. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/property.pyx +0 -0
  79. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/a_sync/singleton.py +0 -0
  80. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/aliases.py +0 -0
  81. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/__init__.py +0 -0
  82. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/as_completed.c +0 -0
  83. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/as_completed.pxd +0 -0
  84. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/as_completed.pyi +0 -0
  85. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/as_completed.pyx +0 -0
  86. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/create_task.c +0 -0
  87. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/create_task.pxd +0 -0
  88. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/create_task.pyi +0 -0
  89. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/create_task.pyx +0 -0
  90. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/gather.c +0 -0
  91. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/gather.pyi +0 -0
  92. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/asyncio/gather.pyx +0 -0
  93. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/exceptions.py +0 -0
  94. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/executor.py +0 -0
  95. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/future.py +0 -0
  96. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/iter.c +0 -0
  97. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/iter.pyi +0 -0
  98. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/iter.pyx +0 -0
  99. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/__init__.pxd +0 -0
  100. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/__init__.py +0 -0
  101. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_debug.pxd +0 -0
  102. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_loggable.c +0 -0
  103. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_loggable.pxd +0 -0
  104. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/_loggable.pyx +0 -0
  105. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/__init__.pxd +0 -0
  106. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/__init__.py +0 -0
  107. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/counter.c +0 -0
  108. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/counter.pxd +0 -0
  109. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/counter.pyx +0 -0
  110. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/event.c +0 -0
  111. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/event.pxd +0 -0
  112. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/locks/event.pyx +0 -0
  113. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/primitives/queue.py +0 -0
  114. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/py.typed +0 -0
  115. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/sphinx/__init__.py +0 -0
  116. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/sphinx/ext.py +0 -0
  117. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/task.c +0 -0
  118. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/task.pyx +0 -0
  119. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/utils/__init__.py +0 -0
  120. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/a_sync/utils/iterators.py +0 -0
  121. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/Makefile +0 -0
  122. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/alabaster.css +0 -0
  123. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/basic.css +0 -0
  124. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/custom.css +0 -0
  125. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/doctools.js +0 -0
  126. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/documentation_options.js +0 -0
  127. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/file.png +0 -0
  128. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/language_data.js +0 -0
  129. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/minus.png +0 -0
  130. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/plus.png +0 -0
  131. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/pygments.css +0 -0
  132. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/searchtools.js +0 -0
  133. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/_build/html/_static/sphinx_highlight.js +0 -0
  134. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/conf.py +0 -0
  135. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/index.rst +0 -0
  136. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/docs/make.bat +0 -0
  137. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/dependency_links.txt +0 -0
  138. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/not-zip-safe +0 -0
  139. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/requires.txt +0 -0
  140. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/ez_a_sync.egg-info/top_level.txt +0 -0
  141. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/pyproject.yaml +0 -0
  142. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/requirements-dev.txt +0 -0
  143. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/requirements.txt +0 -0
  144. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/setup.cfg +0 -0
  145. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/__init__.py +0 -0
  146. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/conftest.py +0 -0
  147. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/executor.py +0 -0
  148. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/fixtures.py +0 -0
  149. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_abstract.py +0 -0
  150. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_as_completed.py +0 -0
  151. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_base.py +0 -0
  152. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_cache.py +0 -0
  153. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_decorator.py +0 -0
  154. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_executor.py +0 -0
  155. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_future.py +0 -0
  156. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_gather.py +0 -0
  157. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_helpers.py +0 -0
  158. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_iter.py +0 -0
  159. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_limiter.py +0 -0
  160. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_meta.py +0 -0
  161. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_modified.py +0 -0
  162. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_singleton.py +0 -0
  163. {ez_a_sync-0.24.3 → ez_a_sync-0.24.4}/tests/test_task.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ez-a-sync
3
- Version: 0.24.3
3
+ Version: 0.24.4
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
@@ -2,6 +2,7 @@
2
2
  This module provides utility functions for handling asynchronous operations
3
3
  and converting synchronous functions to asynchronous ones.
4
4
  """
5
+
5
6
  from a_sync._typing import *
6
7
  from a_sync import exceptions as exceptions
7
8
 
@@ -8,6 +8,7 @@ the execution mode based on flags and keyword arguments.
8
8
  Note: It is recommended to use :class:`ASyncGenericBase` for most use cases. This class
9
9
  is intended for more custom implementations if necessary.
10
10
  """
11
+
11
12
  from a_sync._typing import *
12
13
  import abc
13
14
  import functools
@@ -5,6 +5,7 @@ It includes descriptors and bound methods that can be used to create flexible
5
5
  asynchronous interfaces, allowing methods to be called both synchronously and
6
6
  asynchronously based on various conditions and configurations.
7
7
  """
8
+
8
9
  from a_sync._typing import *
9
10
  import functools
10
11
  import weakref
@@ -5442,7 +5442,7 @@ static PyObject *__pyx_pf_6a_sync_10primitives_6_debug_17_DebugDaemonMixin_5_ens
5442
5442
  * self._daemon = self._start_debug_daemon(*args, **kwargs)
5443
5443
  * self._daemon.add_done_callback(self._stop_debug_daemon) # <<<<<<<<<<<<<<
5444
5444
  * else:
5445
- * self._daemon = get_event_loop().create_future()
5445
+ * self._daemon = self._c_get_loop().create_future()
5446
5446
  */
5447
5447
  __Pyx_TraceLine(160,0,__PYX_ERR(0, 160, __pyx_L1_error))
5448
5448
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_daemon, __pyx_n_s_add_done_callback); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 160, __pyx_L1_error)
@@ -5487,13 +5487,13 @@ static PyObject *__pyx_pf_6a_sync_10primitives_6_debug_17_DebugDaemonMixin_5_ens
5487
5487
  /* "a_sync/primitives/_debug.pyx":162
5488
5488
  * self._daemon.add_done_callback(self._stop_debug_daemon)
5489
5489
  * else:
5490
- * self._daemon = get_event_loop().create_future() # <<<<<<<<<<<<<<
5490
+ * self._daemon = self._c_get_loop().create_future() # <<<<<<<<<<<<<<
5491
5491
  * return self._daemon
5492
5492
  *
5493
5493
  */
5494
5494
  __Pyx_TraceLine(162,0,__PYX_ERR(0, 162, __pyx_L1_error))
5495
5495
  /*else*/ {
5496
- __pyx_t_3 = __pyx_f_6a_sync_6a_sync_8_helpers_get_event_loop(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 162, __pyx_L1_error)
5496
+ __pyx_t_3 = ((struct __pyx_vtabstruct_6a_sync_10primitives_6_debug__DebugDaemonMixin *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base._c_get_loop(((struct __pyx_obj_6a_sync_10primitives_6_debug__LoopBoundMixin *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 162, __pyx_L1_error)
5497
5497
  __Pyx_GOTREF(__pyx_t_3);
5498
5498
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_create_future); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 162, __pyx_L1_error)
5499
5499
  __Pyx_GOTREF(__pyx_t_1);
@@ -5539,7 +5539,7 @@ static PyObject *__pyx_pf_6a_sync_10primitives_6_debug_17_DebugDaemonMixin_5_ens
5539
5539
 
5540
5540
  /* "a_sync/primitives/_debug.pyx":163
5541
5541
  * else:
5542
- * self._daemon = get_event_loop().create_future()
5542
+ * self._daemon = self._c_get_loop().create_future()
5543
5543
  * return self._daemon # <<<<<<<<<<<<<<
5544
5544
  *
5545
5545
  * def _stop_debug_daemon(self, t: Optional[asyncio.Task] = None) -> None:
@@ -3,6 +3,7 @@ This module provides a mixin class used to facilitate the creation of debugging
3
3
 
4
4
  The mixin provides a framework for managing a debug daemon task, which can be used to emit rich debug logs from subclass instances whenever debug logging is enabled. Subclasses must implement the specific logging behavior.
5
5
  """
6
+
6
7
  import abc
7
8
  from a_sync.primitives._loggable import _LoggerMixin
8
9
 
@@ -159,7 +159,7 @@ cdef class _DebugDaemonMixin(_LoopBoundMixin):
159
159
  self._daemon = self._start_debug_daemon(*args, **kwargs)
160
160
  self._daemon.add_done_callback(self._stop_debug_daemon)
161
161
  else:
162
- self._daemon = get_event_loop().create_future()
162
+ self._daemon = self._c_get_loop().create_future()
163
163
  return self._daemon
164
164
 
165
165
  def _stop_debug_daemon(self, t: Optional[asyncio.Task] = None) -> None:
@@ -1,6 +1,7 @@
1
1
  """
2
2
  This module provides a mixin class to add debug logging capabilities to other classes.
3
3
  """
4
+
4
5
  from functools import cached_property as cached_property
5
6
  from logging import Logger
6
7
 
@@ -0,0 +1,142 @@
1
+ from _typeshed import Incomplete
2
+ from a_sync.primitives._debug import _DebugDaemonMixin
3
+ from a_sync.primitives.locks.event import Event as Event
4
+ from typing import Iterable, Optional
5
+
6
+ class CounterLock(_DebugDaemonMixin):
7
+ """
8
+ An async primitive that uses an internal counter to manage task synchronization.
9
+
10
+ A coroutine can `await counter.wait_for(3)` and it will wait until the internal counter >= 3.
11
+ If some other task executes `counter.value = 5` or `counter.set(5)`, the first coroutine will proceed as 5 >= 3.
12
+
13
+ The internal counter can only be set to a value greater than the current value.
14
+
15
+ See Also:
16
+ :class:`CounterLockCluster` for managing multiple :class:`CounterLock` instances.
17
+ """
18
+
19
+ is_ready: Incomplete
20
+ def __init__(self, start_value: int = 0, name: Optional[str] = None) -> None:
21
+ """
22
+ Initializes the :class:`CounterLock` with a starting value and an optional name.
23
+
24
+ Args:
25
+ start_value: The initial value of the counter.
26
+ name: An optional name for the counter, used in debug logs.
27
+
28
+ Examples:
29
+ >>> counter = CounterLock(start_value=0, name="example_counter")
30
+ >>> counter.value
31
+ 0
32
+ """
33
+
34
+ async def wait_for(self, value: int) -> bool:
35
+ """
36
+ Waits until the counter reaches or exceeds the specified value.
37
+
38
+ This method will ensure the debug daemon is running if the counter is not ready.
39
+
40
+ Args:
41
+ value: The value to wait for.
42
+
43
+ Examples:
44
+ >>> counter = CounterLock(start_value=0)
45
+ >>> await counter.wait_for(5) # This will block until counter.value >= 5
46
+
47
+ See Also:
48
+ :meth:`CounterLock.set` to set the counter value.
49
+ """
50
+
51
+ def set(self, value: int) -> None:
52
+ """
53
+ Sets the counter to the specified value.
54
+
55
+ This method internally uses the `value` property to enforce that the new value must be strictly greater than the current value.
56
+
57
+ Args:
58
+ value: The value to set the counter to. Must be strictly greater than the current value.
59
+
60
+ Raises:
61
+ ValueError: If the new value is less than or equal to the current value.
62
+
63
+ Examples:
64
+ >>> counter = CounterLock(start_value=0)
65
+ >>> counter.set(5)
66
+ >>> counter.value
67
+ 5
68
+
69
+ See Also:
70
+ :meth:`CounterLock.value` for direct value assignment.
71
+ """
72
+
73
+ @property
74
+ def value(self) -> int:
75
+ """
76
+ Gets the current value of the counter.
77
+
78
+ Examples:
79
+ >>> counter = CounterLock(start_value=0)
80
+ >>> counter.value
81
+ 0
82
+ """
83
+
84
+ @value.setter
85
+ def value(self, value: int) -> None:
86
+ """
87
+ Sets the counter to a new value, waking up any waiters if the value increases beyond the value they are awaiting.
88
+
89
+ Args:
90
+ value: The new value of the counter.
91
+
92
+ Raises:
93
+ ValueError: If the new value is less than the current value.
94
+
95
+ Examples:
96
+ >>> counter = CounterLock(start_value=0)
97
+ >>> counter.value = 5
98
+ >>> counter.value
99
+ 5
100
+ >>> counter.value = 3
101
+ Traceback (most recent call last):
102
+ ...
103
+ ValueError: You cannot decrease the value.
104
+ """
105
+
106
+ class CounterLockCluster:
107
+ """
108
+ An asyncio primitive that represents a collection of :class:`CounterLock` objects.
109
+
110
+ `wait_for(i)` will wait until the value of all :class:`CounterLock` objects is >= i.
111
+
112
+ See Also:
113
+ :class:`CounterLock` for managing individual counters.
114
+ """
115
+
116
+ locks: Incomplete
117
+ def __init__(self, counter_locks: Iterable[CounterLock]) -> None:
118
+ """
119
+ Initializes the :class:`CounterLockCluster` with a collection of :class:`CounterLock` objects.
120
+
121
+ Args:
122
+ counter_locks: The :class:`CounterLock` objects to manage.
123
+
124
+ Examples:
125
+ >>> lock1 = CounterLock(start_value=0)
126
+ >>> lock2 = CounterLock(start_value=0)
127
+ >>> cluster = CounterLockCluster([lock1, lock2])
128
+ """
129
+
130
+ async def wait_for(self, value: int) -> bool:
131
+ """
132
+ Waits until the value of all :class:`CounterLock` objects in the cluster reaches or exceeds the specified value.
133
+
134
+ Args:
135
+ value: The value to wait for.
136
+
137
+ Examples:
138
+ >>> lock1 = CounterLock(start_value=0)
139
+ >>> lock2 = CounterLock(start_value=0)
140
+ >>> cluster = CounterLockCluster([lock1, lock2])
141
+ >>> await cluster.wait_for(5) # This will block until all locks have value >= 5
142
+ """
@@ -0,0 +1,36 @@
1
+ from a_sync._typing import *
2
+ import asyncio
3
+ from a_sync.primitives._debug import _DebugDaemonMixin
4
+
5
+ class Event(asyncio.Event, _DebugDaemonMixin):
6
+ """
7
+ An asyncio.Event with additional debug logging to help detect deadlocks.
8
+
9
+ This event class extends asyncio.Event by adding debug logging capabilities. It logs
10
+ detailed information about the event state and waiters, which can be useful for
11
+ diagnosing and debugging potential deadlocks.
12
+ """
13
+
14
+ def __init__(
15
+ self,
16
+ name: str = "",
17
+ debug_daemon_interval: int = 300,
18
+ *,
19
+ loop: Optional[asyncio.AbstractEventLoop] = None
20
+ ) -> None:
21
+ """
22
+ Initializes the Event.
23
+
24
+ Args:
25
+ name (str): An optional name for the event, used in debug logs.
26
+ debug_daemon_interval (int): The interval in seconds for the debug daemon to log information.
27
+ loop (Optional[asyncio.AbstractEventLoop]): The event loop to use.
28
+ """
29
+
30
+ async def wait(self) -> Literal[True]:
31
+ """
32
+ Wait until the event is set.
33
+
34
+ Returns:
35
+ True when the event is set.
36
+ """