ez-a-sync 0.27.5__tar.gz → 0.27.6__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 (196) hide show
  1. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/PKG-INFO +1 -1
  2. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/queue.py +128 -73
  3. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/PKG-INFO +1 -1
  4. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/primitives/test_queue.py +84 -1
  5. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.coverage +0 -0
  6. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/black.yaml +0 -0
  7. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/codeql.yaml +0 -0
  8. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/docs.yaml +0 -0
  9. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/mypy.yaml +0 -0
  10. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/pytest.yaml +0 -0
  11. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.github/workflows/release.yaml +0 -0
  12. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.gitignore +0 -0
  13. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/.sourcery.yaml +0 -0
  14. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/LICENSE.txt +0 -0
  15. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/MANIFEST.in +0 -0
  16. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/Makefile +0 -0
  17. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/README.md +0 -0
  18. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/TODO +0 -0
  19. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/ENVIRONMENT_VARIABLES.py +0 -0
  20. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/__init__.pxd +0 -0
  21. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/__init__.py +0 -0
  22. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/_smart.c +0 -0
  23. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/_smart.pxd +0 -0
  24. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/_smart.pyi +0 -0
  25. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/_smart.pyx +0 -0
  26. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/_typing.py +0 -0
  27. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/__init__.py +0 -0
  28. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_descriptor.c +0 -0
  29. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_descriptor.pyi +0 -0
  30. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_descriptor.pyx +0 -0
  31. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_flags.c +0 -0
  32. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_flags.pxd +0 -0
  33. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_flags.pyx +0 -0
  34. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_helpers.c +0 -0
  35. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_helpers.pxd +0 -0
  36. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_helpers.pyi +0 -0
  37. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_helpers.pyx +0 -0
  38. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_kwargs.c +0 -0
  39. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_kwargs.pxd +0 -0
  40. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_kwargs.pyx +0 -0
  41. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/_meta.py +0 -0
  42. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/abstract.c +0 -0
  43. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/abstract.pyi +0 -0
  44. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/abstract.pyx +0 -0
  45. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/base.c +0 -0
  46. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/base.pyi +0 -0
  47. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/base.pyx +0 -0
  48. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/config.py +0 -0
  49. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/decorator.py +0 -0
  50. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/flags.py +0 -0
  51. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/function.c +0 -0
  52. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/function.pxd +0 -0
  53. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/function.pyi +0 -0
  54. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/function.pyx +0 -0
  55. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/method.c +0 -0
  56. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/method.pxd +0 -0
  57. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/method.pyi +0 -0
  58. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/method.pyx +0 -0
  59. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/__init__.pxd +0 -0
  60. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/__init__.py +0 -0
  61. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/cache/__init__.py +0 -0
  62. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/cache/memory.py +0 -0
  63. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/limiter.py +0 -0
  64. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/manager.c +0 -0
  65. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/manager.pxd +0 -0
  66. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/manager.pyi +0 -0
  67. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/manager.pyx +0 -0
  68. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/modifiers/semaphores.py +0 -0
  69. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/property.c +0 -0
  70. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/property.pyi +0 -0
  71. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/property.pyx +0 -0
  72. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/a_sync/singleton.py +0 -0
  73. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/aliases.py +0 -0
  74. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/__init__.pxd +0 -0
  75. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/__init__.py +0 -0
  76. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/cached.c +0 -0
  77. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/cached.pxd +0 -0
  78. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/cached.pyi +0 -0
  79. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/cached.pyx +0 -0
  80. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/proxy.c +0 -0
  81. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/proxy.pxd +0 -0
  82. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/proxy.pyi +0 -0
  83. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/async_property/proxy.pyx +0 -0
  84. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/__init__.pxd +0 -0
  85. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/__init__.py +0 -0
  86. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/as_completed.c +0 -0
  87. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/as_completed.pxd +0 -0
  88. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/as_completed.pyi +0 -0
  89. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/as_completed.pyx +0 -0
  90. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/create_task.c +0 -0
  91. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/create_task.pxd +0 -0
  92. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/create_task.pyi +0 -0
  93. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/create_task.pyx +0 -0
  94. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/gather.c +0 -0
  95. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/gather.pyi +0 -0
  96. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/gather.pyx +0 -0
  97. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/igather.c +0 -0
  98. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/igather.pxd +0 -0
  99. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/asyncio/igather.pyx +0 -0
  100. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/exceptions.py +0 -0
  101. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/executor.py +0 -0
  102. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/functools.c +0 -0
  103. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/functools.pxd +0 -0
  104. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/functools.pyi +0 -0
  105. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/functools.pyx +0 -0
  106. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/future.py +0 -0
  107. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/iter.c +0 -0
  108. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/iter.pyi +0 -0
  109. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/iter.pyx +0 -0
  110. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/__init__.pxd +0 -0
  111. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/__init__.py +0 -0
  112. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_debug.c +0 -0
  113. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_debug.pxd +0 -0
  114. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_debug.pyi +0 -0
  115. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_debug.pyx +0 -0
  116. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_loggable.c +0 -0
  117. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_loggable.pxd +0 -0
  118. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_loggable.pyi +0 -0
  119. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/_loggable.pyx +0 -0
  120. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/__init__.pxd +0 -0
  121. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/__init__.py +0 -0
  122. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/counter.c +0 -0
  123. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/counter.pxd +0 -0
  124. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/counter.pyi +0 -0
  125. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/counter.pyx +0 -0
  126. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/event.c +0 -0
  127. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/event.pxd +0 -0
  128. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/event.pyi +0 -0
  129. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/event.pyx +0 -0
  130. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/prio_semaphore.c +0 -0
  131. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/prio_semaphore.pxd +0 -0
  132. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/prio_semaphore.pyi +0 -0
  133. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/prio_semaphore.pyx +0 -0
  134. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/semaphore.c +0 -0
  135. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/semaphore.pxd +0 -0
  136. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/semaphore.pyi +0 -0
  137. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/primitives/locks/semaphore.pyx +0 -0
  138. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/py.typed +0 -0
  139. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/sphinx/__init__.py +0 -0
  140. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/sphinx/ext.py +0 -0
  141. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/task.py +0 -0
  142. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/utils/__init__.py +0 -0
  143. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/a_sync/utils/iterators.py +0 -0
  144. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/Makefile +0 -0
  145. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/alabaster.css +0 -0
  146. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/basic.css +0 -0
  147. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/custom.css +0 -0
  148. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/doctools.js +0 -0
  149. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/documentation_options.js +0 -0
  150. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/file.png +0 -0
  151. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/language_data.js +0 -0
  152. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/minus.png +0 -0
  153. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/plus.png +0 -0
  154. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/pygments.css +0 -0
  155. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/searchtools.js +0 -0
  156. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/_build/html/_static/sphinx_highlight.js +0 -0
  157. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/conf.py +0 -0
  158. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/index.rst +0 -0
  159. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/docs/make.bat +0 -0
  160. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/SOURCES.txt +0 -0
  161. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/dependency_links.txt +0 -0
  162. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/not-zip-safe +0 -0
  163. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/requires.txt +0 -0
  164. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/ez_a_sync.egg-info/top_level.txt +0 -0
  165. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/pyproject.toml +0 -0
  166. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/requirements-dev.txt +0 -0
  167. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/requirements.txt +0 -0
  168. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/setup.cfg +0 -0
  169. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/setup.py +0 -0
  170. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/__init__.py +0 -0
  171. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/modifiers/test_apply_semaphore.py +0 -0
  172. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_abstract.py +0 -0
  173. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_base.py +0 -0
  174. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_cache.py +0 -0
  175. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_decorator.py +0 -0
  176. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_limiter.py +0 -0
  177. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_meta.py +0 -0
  178. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_modified.py +0 -0
  179. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/a_sync/test_singleton.py +0 -0
  180. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/asyncio/test_as_completed.py +0 -0
  181. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/asyncio/test_create_task.py +0 -0
  182. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/asyncio/test_gather.py +0 -0
  183. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/conftest.py +0 -0
  184. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/executor.py +0 -0
  185. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/fixtures.py +0 -0
  186. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/primitives/test_counter.py +0 -0
  187. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/primitives/test_event.py +0 -0
  188. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/primitives/test_prio_semaphore.py +0 -0
  189. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/primitives/test_semaphore.py +0 -0
  190. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/task/test_task.py +0 -0
  191. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/task/test_task_mapping_views.py +0 -0
  192. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/test_executor.py +0 -0
  193. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/test_future.py +0 -0
  194. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/test_helpers.py +0 -0
  195. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/test_iter.py +0 -0
  196. {ez_a_sync-0.27.5 → ez_a_sync-0.27.6}/tests/test_smart.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ez-a-sync
3
- Version: 0.27.5
3
+ Version: 0.27.6
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
@@ -15,7 +15,7 @@ See Also:
15
15
 
16
16
  import asyncio
17
17
  import sys
18
- from asyncio import InvalidStateError, QueueEmpty
18
+ from asyncio import AbstractEventLoop, Future, InvalidStateError, QueueEmpty, Task, get_event_loop
19
19
  from asyncio.events import _get_running_loop
20
20
  from functools import wraps
21
21
  from heapq import heappop, heappush, heappushpop
@@ -271,7 +271,7 @@ _put_nowait = asyncio.Queue.put_nowait
271
271
  _loop_kwarg_deprecated = sys.version_info >= (3, 10)
272
272
 
273
273
 
274
- class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
274
+ class ProcessingQueue(_Queue[Tuple[P, "Future[V]"]], Generic[P, V]):
275
275
  """
276
276
  A queue designed for processing tasks asynchronously with multiple workers.
277
277
 
@@ -299,7 +299,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
299
299
  *,
300
300
  return_data: bool = True,
301
301
  name: str = "",
302
- loop: Optional[asyncio.AbstractEventLoop] = None,
302
+ loop: Optional[AbstractEventLoop] = None,
303
303
  ) -> None:
304
304
  """
305
305
  Initializes a processing queue with the given worker function and worker count.
@@ -367,7 +367,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
367
367
  repr_string += f" pending={self._unfinished_tasks}"
368
368
  return f"{repr_string}>"
369
369
 
370
- def __call__(self, *args: P.args, **kwargs: P.kwargs) -> "asyncio.Future[V]":
370
+ def __call__(self, *args: P.args, **kwargs: P.kwargs) -> "Future[V]":
371
371
  """
372
372
  Submits a task to the queue.
373
373
 
@@ -409,7 +409,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
409
409
  """
410
410
  self._closed = True
411
411
 
412
- async def put(self, *args: P.args, **kwargs: P.kwargs) -> "asyncio.Future[V]":
412
+ async def put(self, *args: P.args, **kwargs: P.kwargs) -> "Future[V]":
413
413
  # sourcery skip: use-contextlib-suppress
414
414
  """
415
415
  Asynchronously submits a task to the queue.
@@ -446,7 +446,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
446
446
  raise
447
447
  return self.put_nowait(*args, **kwargs)
448
448
 
449
- def put_nowait(self, *args: P.args, **kwargs: P.kwargs) -> "asyncio.Future[V]":
449
+ def put_nowait(self, *args: P.args, **kwargs: P.kwargs) -> "Future[V]":
450
450
  """
451
451
  Immediately submits a task to the queue without waiting.
452
452
 
@@ -468,7 +468,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
468
468
  _put_nowait(self, (args, kwargs, proxy(fut)))
469
469
  return fut
470
470
 
471
- def _create_future(self) -> "asyncio.Future[V]":
471
+ def _create_future(self) -> "Future[V]":
472
472
  """Creates a future for the task."""
473
473
  return _get_running_loop().create_future()
474
474
 
@@ -477,7 +477,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
477
477
  if self._closed:
478
478
  raise RuntimeError(f"{type(self).__name__} is closed: ", self) from None
479
479
  if self._workers.done():
480
- worker_subtasks: List["asyncio.Task[NoReturn]"] = self._workers._workers
480
+ worker_subtasks: List["Task[NoReturn]"] = self._workers._workers
481
481
  for worker in worker_subtasks:
482
482
  if worker.done(): # its only done if its broken
483
483
  exc = worker.exception()
@@ -489,10 +489,10 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
489
489
  raise exc.with_traceback(exc.__traceback__) from exc.__cause__
490
490
 
491
491
  @cached_property_unsafe
492
- def _workers(self) -> "asyncio.Task[NoReturn]":
492
+ def _workers(self) -> "Task[NoReturn]":
493
493
  """Creates and manages the worker tasks for the queue."""
494
494
  log_debug("starting worker task for %s", self)
495
- name = self.name
495
+ name = str(self.name)
496
496
  workers = tuple(
497
497
  create_task(
498
498
  coro=self._worker_coro(),
@@ -530,33 +530,32 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
530
530
  logger.exception(e)
531
531
  task_done()
532
532
  else:
533
- fut: asyncio.Future[V]
533
+ fut: Future[V]
534
534
  while True:
535
- args, kwargs, fut = await get_next_job()
536
535
  try:
537
- if fut is None:
538
- # the weakref was already cleaned up, we don't need to process this item
539
- task_done()
540
- continue
536
+ args, kwargs, fut = await get_next_job()
537
+ except RuntimeError as e:
538
+ if _check_loop_is_closed(self, e):
539
+ return
540
+ raise
541
+
542
+ if fut is None:
543
+ # the weakref was already cleaned up, we don't need to process this item
544
+ task_done()
545
+ continue
546
+
547
+ try:
541
548
  result = await func(*args, **kwargs)
542
- fut.set_result(result)
543
- except InvalidStateError:
544
- logger.error(
545
- "cannot set result for %s %s: %s",
546
- func.__name__,
547
- fut,
548
- result,
549
- )
550
549
  except Exception as e:
551
550
  try:
552
551
  fut.set_exception(e)
553
552
  except InvalidStateError:
554
- logger.error(
555
- "cannot set exception for %s %s: %s",
556
- func.__name__,
557
- fut,
558
- e,
559
- )
553
+ _log_invalid_state_err("exception", func, fut, e)
554
+ else:
555
+ try:
556
+ fut.set_result(result)
557
+ except InvalidStateError:
558
+ _log_invalid_state_err("result", func, fut, result)
560
559
  task_done()
561
560
 
562
561
 
@@ -674,7 +673,8 @@ class PriorityProcessingQueue(_PriorityQueueMixin[T], ProcessingQueue[T, V]):
674
673
  :class:`~ProcessingQueue`
675
674
  """
676
675
 
677
- async def put(self, priority: Any, *args: P.args, **kwargs: P.kwargs) -> "asyncio.Future[V]":
676
+ async def put(self, priority: Any, *args: P.args, **kwargs: P.kwargs) -> "Future[V]":
677
+ # sourcery skip: use-contextlib-suppress
678
678
  """
679
679
  Asynchronously adds a task with priority to the queue.
680
680
 
@@ -690,12 +690,29 @@ class PriorityProcessingQueue(_PriorityQueueMixin[T], ProcessingQueue[T, V]):
690
690
  >>> fut = await queue.put(priority=1, item='task')
691
691
  >>> print(await fut)
692
692
  """
693
- self._ensure_workers()
694
- fut = asyncio.get_event_loop().create_future()
695
- await ProcessingQueue.put(self, (priority, args, kwargs, fut))
696
- return fut
693
+ while self.full():
694
+ putter = self._get_loop().create_future()
695
+ self._putters.append(putter)
696
+ try:
697
+ await putter
698
+ except:
699
+ putter.cancel() # Just in case putter is not done yet.
700
+ try:
701
+ # Clean self._putters from canceled putters.
702
+ self._putters.remove(putter)
703
+ except ValueError:
704
+ # The putter could be removed from self._putters by a
705
+ # previous get_nowait call.
706
+ pass
707
+ if not self.full() and not putter.cancelled():
708
+ # We were woken up by get_nowait(), but can't take
709
+ # the call. Wake up the next in line.
710
+ self._wakeup_next(self._putters)
711
+ raise
712
+
713
+ return self.put_nowait(priority, *args, **kwargs)
697
714
 
698
- def put_nowait(self, priority: Any, *args: P.args, **kwargs: P.kwargs) -> "asyncio.Future[V]":
715
+ def put_nowait(self, priority: Any, *args: P.args, **kwargs: P.kwargs) -> "Future[V]":
699
716
  """
700
717
  Immediately adds a task with priority to the queue without waiting.
701
718
 
@@ -713,7 +730,7 @@ class PriorityProcessingQueue(_PriorityQueueMixin[T], ProcessingQueue[T, V]):
713
730
  """
714
731
  self._ensure_workers()
715
732
  fut = self._create_future()
716
- ProcessingQueue.put_nowait(self, (priority, args, kwargs, fut))
733
+ _Queue.put_nowait(self, (priority, args, kwargs, fut))
717
734
  return fut
718
735
 
719
736
  def _get(self, heappop=heappop):
@@ -727,8 +744,10 @@ class PriorityProcessingQueue(_PriorityQueueMixin[T], ProcessingQueue[T, V]):
727
744
  >>> task = queue._get()
728
745
  >>> print(task)
729
746
  """
730
- priority, args, kwargs, fut = heappop(self._queue)
731
- return args, kwargs, fut
747
+ # For readability, what we're really doing is this:
748
+ # priority, args, kwargs, fut = heappop(self._queue)
749
+ # return args, kwargs, fut
750
+ return heappop(self._queue)[1:]
732
751
 
733
752
 
734
753
  class _VariablePriorityQueueMixin(_PriorityQueueMixin[T]):
@@ -756,8 +775,7 @@ class _VariablePriorityQueueMixin(_PriorityQueueMixin[T]):
756
775
  # NOTE: Since waiter priorities can change, heappop might not return the job with the
757
776
  # most waiters if `self._queue` is not currently in order, but we can use `heappushpop`,
758
777
  # to ensure we get the job with the most waiters.
759
- queue = self._queue
760
- return heappushpop(queue, heappop(queue))
778
+ return heappushpop(queue := self._queue, heappop(queue))
761
779
 
762
780
  def _get_key(self, *args, **kwargs) -> _SmartKey:
763
781
  """
@@ -774,7 +792,7 @@ class _VariablePriorityQueueMixin(_PriorityQueueMixin[T]):
774
792
  >>> key = queue._get_key(*args, **kwargs)
775
793
  >>> print(key)
776
794
  """
777
- return (args, tuple((kwarg, kwargs[kwarg]) for kwarg in sorted(kwargs)))
795
+ return args, tuple(sorted(kwargs.items()))
778
796
 
779
797
 
780
798
  class VariablePriorityQueue(_VariablePriorityQueueMixin[T], asyncio.PriorityQueue):
@@ -830,7 +848,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
830
848
  num_workers: int,
831
849
  *,
832
850
  name: str = "",
833
- loop: Optional[asyncio.AbstractEventLoop] = None,
851
+ loop: Optional[AbstractEventLoop] = None,
834
852
  ) -> None:
835
853
  """
836
854
  Initializes a smart processing queue with the given worker function.
@@ -849,6 +867,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
849
867
  self._futs = WeakValueDictionary()
850
868
 
851
869
  async def put(self, *args: P.args, **kwargs: P.kwargs) -> SmartFuture[V]:
870
+ # sourcery skip: use-contextlib-suppress
852
871
  """
853
872
  Asynchronously adds a task with smart future handling to the queue.
854
873
 
@@ -863,14 +882,26 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
863
882
  >>> fut = await queue.put(item='task')
864
883
  >>> print(await fut)
865
884
  """
866
- self._ensure_workers()
867
- key = self._get_key(*args, **kwargs)
868
- if fut := self._futs.get(key, None):
869
- return fut
870
- fut = self._create_future(key)
871
- self._futs[key] = fut
872
- await Queue.put(self, (_SmartFutureRef(fut), args, kwargs))
873
- return fut
885
+ while self.full():
886
+ putter = self._loop.create_future()
887
+ self._putters.append(putter)
888
+ try:
889
+ await putter
890
+ except:
891
+ putter.cancel() # Just in case putter is not done yet.
892
+ try:
893
+ # Clean self._putters from canceled putters.
894
+ self._putters.remove(putter)
895
+ except ValueError:
896
+ # The putter could be removed from self._putters by a
897
+ # previous get_nowait call.
898
+ pass
899
+ if not self.full() and not putter.cancelled():
900
+ # We were woken up by get_nowait(), but can't take
901
+ # the call. Wake up the next in line.
902
+ self._wakeup_next(self._putters)
903
+ raise
904
+ return self.put_nowait(*args, **kwargs)
874
905
 
875
906
  def put_nowait(self, *args: P.args, **kwargs: P.kwargs) -> SmartFuture[V]:
876
907
  """
@@ -896,7 +927,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
896
927
  Queue.put_nowait(self, (_SmartFutureRef(fut), args, kwargs))
897
928
  return fut
898
929
 
899
- def _create_future(self, key: _SmartKey) -> "asyncio.Future[V]":
930
+ def _create_future(self, key: _SmartKey) -> "Future[V]":
900
931
  """Creates a smart future for the task."""
901
932
  return create_future(queue=self, key=key, loop=self._loop)
902
933
 
@@ -929,7 +960,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
929
960
  get_next_job = self.get
930
961
  func = self.func
931
962
  task_done = self.task_done
932
- log_debug = log_debug
963
+ log = log_debug
933
964
 
934
965
  args: P.args
935
966
  kwargs: P.kwargs
@@ -938,34 +969,58 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
938
969
  while True:
939
970
  try:
940
971
  args, kwargs, fut = await get_next_job()
941
- if fut is None:
942
- # the weakref was already cleaned up, we don't need to process this item
943
- task_done()
944
- continue
945
- log_debug("processing %s", fut)
972
+ except RuntimeError as e:
973
+ if _check_loop_is_closed(self, e):
974
+ return
975
+ raise
976
+
977
+ if fut is None:
978
+ # the weakref was already cleaned up, we don't need to process this item
979
+ task_done()
980
+ continue
981
+
982
+ log("processing %s", fut)
983
+
984
+ try:
946
985
  result = await func(*args, **kwargs)
947
- fut.set_result(result)
948
- except InvalidStateError:
949
- logger.error(
950
- "cannot set result for %s %s: %s",
951
- func.__name__,
952
- fut,
953
- result,
954
- )
955
986
  except Exception as e:
956
- log_debug("%s: %s", type(e).__name__, e)
987
+ log("%s: %s", type(e).__name__, e)
957
988
  try:
958
989
  fut.set_exception(e)
959
990
  except InvalidStateError:
960
- logger.error(
961
- "cannot set exception for %s %s: %s",
962
- func.__name__,
963
- fut,
964
- e,
965
- )
991
+ _log_invalid_state_err("exception", func, fut, e)
992
+ else:
993
+ try:
994
+ fut.set_result(result)
995
+ except InvalidStateError:
996
+ _log_invalid_state_err("result", func, fut, result)
966
997
  task_done()
967
998
 
968
999
  except Exception as e:
969
1000
  logger.error("%s is broken!!!", self)
970
1001
  logger.exception(e)
971
1002
  raise
1003
+
1004
+
1005
+ def _log_invalid_state_err(
1006
+ typ: Literal["result", "exception"], func: Callable, fut: Future, value: Any
1007
+ ) -> None:
1008
+ logger.error(
1009
+ "cannot set %s for %s %s: %s",
1010
+ typ,
1011
+ func.__name__,
1012
+ fut,
1013
+ value,
1014
+ )
1015
+
1016
+
1017
+ def _check_loop_is_closed(queue: Queue, e: Exception) -> bool:
1018
+ if "Event loop is closed" not in str(e):
1019
+ return False
1020
+ if queue._unfinished_tasks:
1021
+ logger.error(
1022
+ "Event loop is closed. Closing %s with %s unfinished tasks",
1023
+ queue,
1024
+ queue._unfinished_tasks,
1025
+ )
1026
+ return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ez-a-sync
3
- Version: 0.27.5
3
+ Version: 0.27.6
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
@@ -1,6 +1,11 @@
1
1
  import pytest
2
2
  import asyncio
3
- from a_sync.primitives.queue import ProcessingQueue, Queue
3
+ from a_sync.primitives.queue import (
4
+ PriorityProcessingQueue,
5
+ ProcessingQueue,
6
+ Queue,
7
+ SmartProcessingQueue,
8
+ )
4
9
 
5
10
 
6
11
  @pytest.mark.asyncio_cooperative
@@ -366,3 +371,81 @@ async def test_processing_call():
366
371
  results = await asyncio.gather(*big_work)
367
372
  assert results == list(range(100))
368
373
  assert queue.empty()
374
+
375
+
376
+ @pytest.mark.asyncio_cooperative
377
+ async def test_smart_processing_queue_initialization():
378
+ queue = SmartProcessingQueue(coro_fn, 2)
379
+ assert isinstance(queue, ProcessingQueue)
380
+ assert queue.func == coro_fn
381
+ assert queue.num_workers == 2
382
+ assert queue.empty()
383
+
384
+
385
+ @pytest.mark.asyncio_cooperative
386
+ async def test_priority_processing_queue_initialization():
387
+ queue = PriorityProcessingQueue(coro_fn, 2)
388
+ assert isinstance(queue, PriorityProcessingQueue)
389
+ assert queue.func == coro_fn
390
+ assert queue.num_workers == 2
391
+ assert queue.empty()
392
+
393
+
394
+ @pytest.mark.asyncio_cooperative
395
+ async def test_smart_processing_put_and_await():
396
+ queue = SmartProcessingQueue(coro_fn, 2)
397
+ fut = await queue.put("1")
398
+ assert isinstance(fut, asyncio.Future)
399
+ assert not queue.empty()
400
+ assert await fut == 1
401
+ assert queue.empty()
402
+
403
+
404
+ @pytest.mark.asyncio_cooperative
405
+ async def test_priority_processing_put_and_await():
406
+ queue = PriorityProcessingQueue(coro_fn, 2)
407
+ fut = await queue.put(5, "1")
408
+ assert isinstance(fut, asyncio.Future)
409
+ assert not queue.empty()
410
+ assert await fut == 1
411
+ assert queue.empty()
412
+
413
+
414
+ @pytest.mark.asyncio_cooperative
415
+ async def test_smart_processing_put_nowait_and_await():
416
+ queue = SmartProcessingQueue(coro_fn, 2)
417
+ fut = queue.put_nowait("2")
418
+ assert isinstance(fut, asyncio.Future)
419
+ assert not queue.empty()
420
+ assert await fut == 2
421
+ with pytest.raises(asyncio.QueueEmpty):
422
+ queue.get_nowait()
423
+
424
+
425
+ @pytest.mark.asyncio_cooperative
426
+ async def test_priority_processing_put_nowait_and_await():
427
+ queue = PriorityProcessingQueue(coro_fn, 2)
428
+ fut = queue.put_nowait(5, "2")
429
+ assert isinstance(fut, asyncio.Future)
430
+ assert not queue.empty()
431
+ assert await fut == 2
432
+ with pytest.raises(asyncio.QueueEmpty):
433
+ queue.get_nowait()
434
+
435
+
436
+ @pytest.mark.asyncio_cooperative
437
+ async def test_smart_processing_call():
438
+ queue = SmartProcessingQueue(coro_fn, 10)
439
+ big_work = map(queue, map(str, range(100)))
440
+ results = await asyncio.gather(*big_work)
441
+ assert results == list(range(100))
442
+ assert queue.empty()
443
+
444
+
445
+ @pytest.mark.asyncio_cooperative
446
+ async def test_priority_processing_call():
447
+ queue = PriorityProcessingQueue(coro_fn, 10)
448
+ big_work = (queue(i, str(i)) for i in range(100))
449
+ results = await asyncio.gather(*big_work)
450
+ assert results == list(range(100))
451
+ assert queue.empty()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes