dycw-utilities 0.149.9__tar.gz → 0.149.11__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.
Files changed (216) hide show
  1. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/PKG-INFO +1 -1
  2. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/pyproject.toml +2 -2
  3. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_asyncio.py +17 -1
  4. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pottery.py +19 -5
  5. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_shelve.py +8 -5
  6. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/__init__.py +1 -1
  7. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/asyncio.py +35 -0
  8. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pottery.py +9 -1
  9. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/shelve.py +4 -1
  10. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/.gitignore +0 -0
  11. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/LICENSE +0 -0
  12. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/README.md +0 -0
  13. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_altair.py +0 -0
  39. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_atomicwrites.py +0 -0
  40. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_atools.py +0 -0
  41. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_cachetools.py +0 -0
  42. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_click.py +0 -0
  43. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_concurrent.py +0 -0
  44. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_contextlib.py +0 -0
  45. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_contextvars.py +0 -0
  46. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_cryptography.py +0 -0
  47. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_cvxpy.py +0 -0
  48. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_dataclasses.py +0 -0
  49. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_dnspython.py +0 -0
  50. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_enum.py +0 -0
  51. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_errors.py +0 -0
  52. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_eventkit.py +0 -0
  53. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_fastapi.py +0 -0
  54. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_fpdf2.py +0 -0
  55. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_functions.py +0 -0
  56. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_functools.py +0 -0
  57. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_getpass.py +0 -0
  58. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_gzip.py +0 -0
  59. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_hashlib.py +0 -0
  60. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_http.py +0 -0
  61. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_hypothesis.py +0 -0
  62. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_importlib.py +0 -0
  63. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_inflect.py +0 -0
  64. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_ipython.py +0 -0
  65. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_iterables.py +0 -0
  66. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_json.py +0 -0
  67. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_jupyter.py +0 -0
  68. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_libcst.py +0 -0
  69. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_lightweight_charts.py +0 -0
  70. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_logging.py +0 -0
  71. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_math.py +0 -0
  72. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_memory_profiler.py +0 -0
  73. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_modules.py +0 -0
  74. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_more_itertools.py +0 -0
  75. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_numpy.py +0 -0
  76. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_objects/__init__.py +0 -0
  77. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_objects/objects.py +0 -0
  78. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_period.py +0 -0
  85. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pickle.py +0 -0
  86. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_platform.py +0 -0
  87. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_polars.py +0 -0
  88. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_polars_ols.py +0 -0
  89. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_postgres.py +0 -0
  90. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pqdm.py +0 -0
  91. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_psutil.py +0 -0
  92. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pyinstrument.py +0 -0
  93. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pytest_randomly.py +0 -0
  95. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_pytest_regressions.py +0 -0
  96. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_redis.py +0 -0
  99. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_reprlib.py +0 -0
  100. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_scipy.py +0 -0
  101. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_sentinel.py +0 -0
  102. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_sqlalchemy.py +0 -0
  105. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_sqlalchemy_polars.py +0 -0
  106. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_statsmodels.py +0 -0
  107. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_string.py +0 -0
  108. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_tempfile.py +0 -0
  109. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_text.py +0 -0
  110. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_threading.py +0 -0
  111. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_timer.py +0 -0
  112. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_traceback.py +0 -0
  113. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_typed_settings.py +0 -0
  114. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_types.py +0 -0
  115. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_typing.py +0 -0
  116. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_typing_funcs/__init__.py +0 -0
  117. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_typing_funcs/no_future.py +0 -0
  118. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_typing_funcs/with_future.py +0 -0
  119. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_tzdata.py +0 -0
  120. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_tzlocal.py +0 -0
  121. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_uuid.py +0 -0
  122. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_version.py +0 -0
  123. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_warnings.py +0 -0
  124. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_whenever.py +0 -0
  125. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_yield_access/__init__.py +0 -0
  126. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_yield_access/script.py +0 -0
  127. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_yield_access/script.sh +0 -0
  128. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_zipfile.py +0 -0
  129. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/tests/test_zoneinfo.py +0 -0
  130. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/altair.py +0 -0
  131. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/atomicwrites.py +0 -0
  132. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/atools.py +0 -0
  133. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/cachetools.py +0 -0
  134. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/click.py +0 -0
  135. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/concurrent.py +0 -0
  136. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/contextlib.py +0 -0
  137. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/contextvars.py +0 -0
  138. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/cryptography.py +0 -0
  139. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/cvxpy.py +0 -0
  140. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/dataclasses.py +0 -0
  141. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/dnspython.py +0 -0
  142. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/enum.py +0 -0
  143. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/errors.py +0 -0
  144. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/eventkit.py +0 -0
  145. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/fastapi.py +0 -0
  146. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/fpdf2.py +0 -0
  147. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/functions.py +0 -0
  148. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/functools.py +0 -0
  149. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/getpass.py +0 -0
  150. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/gzip.py +0 -0
  151. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/hashlib.py +0 -0
  152. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/http.py +0 -0
  153. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/hypothesis.py +0 -0
  154. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/importlib.py +0 -0
  155. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/inflect.py +0 -0
  156. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/ipython.py +0 -0
  157. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/iterables.py +0 -0
  158. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/json.py +0 -0
  159. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/jupyter.py +0 -0
  160. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/libcst.py +0 -0
  161. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/lightweight_charts.py +0 -0
  162. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/logging.py +0 -0
  163. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/math.py +0 -0
  164. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/memory_profiler.py +0 -0
  165. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/modules.py +0 -0
  166. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/more_itertools.py +0 -0
  167. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/numpy.py +0 -0
  168. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/operator.py +0 -0
  169. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/optuna.py +0 -0
  170. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/orjson.py +0 -0
  171. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/os.py +0 -0
  172. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/parse.py +0 -0
  173. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pathlib.py +0 -0
  174. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/period.py +0 -0
  175. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pickle.py +0 -0
  176. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/platform.py +0 -0
  177. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/polars.py +0 -0
  178. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/polars_ols.py +0 -0
  179. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/postgres.py +0 -0
  180. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pqdm.py +0 -0
  181. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/psutil.py +0 -0
  182. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/py.typed +0 -0
  183. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pyinstrument.py +0 -0
  184. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pytest.py +0 -0
  185. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pytest_plugins/__init__.py +0 -0
  186. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  187. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  188. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/pytest_regressions.py +0 -0
  189. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/random.py +0 -0
  190. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/re.py +0 -0
  191. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/redis.py +0 -0
  192. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/reprlib.py +0 -0
  193. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/scipy.py +0 -0
  194. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/sentinel.py +0 -0
  195. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/slack_sdk.py +0 -0
  196. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/socket.py +0 -0
  197. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/sqlalchemy.py +0 -0
  198. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/sqlalchemy_polars.py +0 -0
  199. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/statsmodels.py +0 -0
  200. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/string.py +0 -0
  201. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/tempfile.py +0 -0
  202. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/text.py +0 -0
  203. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/threading.py +0 -0
  204. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/timer.py +0 -0
  205. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/traceback.py +0 -0
  206. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/typed_settings.py +0 -0
  207. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/types.py +0 -0
  208. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/typing.py +0 -0
  209. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/tzdata.py +0 -0
  210. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/tzlocal.py +0 -0
  211. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/uuid.py +0 -0
  212. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/version.py +0 -0
  213. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/warnings.py +0 -0
  214. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/whenever.py +0 -0
  215. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/zipfile.py +0 -0
  216. {dycw_utilities-0.149.9 → dycw_utilities-0.149.11}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.149.9
3
+ Version: 0.149.11
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -103,7 +103,7 @@ dependencies = [
103
103
  name = "dycw-utilities"
104
104
  readme = "README.md"
105
105
  requires-python = ">= 3.12"
106
- version = "0.149.9"
106
+ version = "0.149.11"
107
107
 
108
108
  [project.entry-points.pytest11]
109
109
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -136,7 +136,7 @@ test = [
136
136
  # bump-my-version
137
137
  [tool.bumpversion]
138
138
  allow_dirty = true
139
- current_version = "0.149.9"
139
+ current_version = "0.149.11"
140
140
 
141
141
  [[tool.bumpversion.files]]
142
142
  filename = "src/utilities/__init__.py"
@@ -6,7 +6,7 @@ from contextlib import asynccontextmanager
6
6
  from re import search
7
7
  from typing import TYPE_CHECKING, ClassVar
8
8
 
9
- from hypothesis import given
9
+ from hypothesis import HealthCheck, given, settings
10
10
  from hypothesis.strategies import booleans, dictionaries, integers, lists, none
11
11
  from pytest import LogCaptureFixture, RaisesGroup, mark, param, raises
12
12
 
@@ -25,6 +25,7 @@ from utilities.asyncio import (
25
25
  sleep_until,
26
26
  stream_command,
27
27
  timeout_td,
28
+ yield_locked_shelf,
28
29
  )
29
30
  from utilities.hypothesis import pairs, text_ascii
30
31
  from utilities.pytest import skipif_windows
@@ -34,6 +35,7 @@ from utilities.whenever import MILLISECOND, SECOND, get_now
34
35
 
35
36
  if TYPE_CHECKING:
36
37
  from collections.abc import AsyncIterator
38
+ from pathlib import Path
37
39
 
38
40
  from whenever import TimeDelta
39
41
 
@@ -477,6 +479,20 @@ class TestTimeoutTD:
477
479
  await sleep_td(2 * self.delta)
478
480
 
479
481
 
482
+ class TestYieldLockedShelf:
483
+ @given(key=text_ascii(), value=integers())
484
+ @settings(
485
+ max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
486
+ )
487
+ async def test_main(self, *, key: str, value: int, tmp_path: Path) -> None:
488
+ path = tmp_path.joinpath("shelf")
489
+ async with yield_locked_shelf(path) as shelf:
490
+ shelf[key] = value
491
+ async with yield_locked_shelf(path) as shelf:
492
+ result = shelf[key]
493
+ assert result == value
494
+
495
+
480
496
  if __name__ == "__main__":
481
497
  _ = run(
482
498
  stream_command('echo "stdout message" && sleep 2 && echo "stderr message" >&2')
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from asyncio import TaskGroup
4
+ from contextvars import ContextVar
4
5
  from typing import TYPE_CHECKING, ClassVar
5
6
 
6
7
  from pottery import AIORedlock
@@ -39,16 +40,27 @@ class TestTryYieldCoroutineLooper:
39
40
  delta: ClassVar[TimeDelta] = 0.1 * SECOND
40
41
 
41
42
  @mark.parametrize("use_logger", [param(True), param(False)])
43
+ @mark.parametrize("use_context", [param(True), param(False)])
42
44
  async def test_main(
43
- self, *, caplog: LogCaptureFixture, use_logger: bool, test_redis: Redis
45
+ self,
46
+ *,
47
+ caplog: LogCaptureFixture,
48
+ use_logger: bool,
49
+ use_context: bool,
50
+ test_redis: Redis,
44
51
  ) -> None:
45
52
  caplog.set_level("DEBUG", logger=(name := unique_str()))
46
53
  lst: list[None] = []
47
54
  logger = name if use_logger else None
55
+ context = ContextVar(unique_str(), default=False) if use_context else None
48
56
 
49
57
  async with TaskGroup() as tg:
50
- _ = tg.create_task(self.now(test_redis, name, lst, logger=logger))
51
- _ = tg.create_task(self.delayed(test_redis, name, lst, logger=logger))
58
+ _ = tg.create_task(
59
+ self.now(test_redis, name, lst, logger=logger, context=context)
60
+ )
61
+ _ = tg.create_task(
62
+ self.delayed(test_redis, name, lst, logger=logger, context=context)
63
+ )
52
64
 
53
65
  assert len(lst) == 1
54
66
  if use_logger:
@@ -68,9 +80,10 @@ class TestTryYieldCoroutineLooper:
68
80
  /,
69
81
  *,
70
82
  logger: LoggerOrName | None = None,
83
+ context: ContextVar[bool] | None = None,
71
84
  ) -> None:
72
85
  async with try_yield_coroutine_looper(
73
- redis, key, timeout_acquire=self.delta, logger=logger
86
+ redis, key, timeout_acquire=self.delta, logger=logger, context=context
74
87
  ) as looper:
75
88
  if looper is not None:
76
89
  assert await looper(self.func_main, lst)
@@ -83,9 +96,10 @@ class TestTryYieldCoroutineLooper:
83
96
  /,
84
97
  *,
85
98
  logger: LoggerOrName | None = None,
99
+ context: ContextVar[bool] | None = None,
86
100
  ) -> None:
87
101
  await sleep_td(self.delta)
88
- await self.now(redis, key, lst, logger=logger)
102
+ await self.now(redis, key, lst, logger=logger, context=context)
89
103
 
90
104
  @mark.parametrize("use_logger", [param(True), param(False)])
91
105
  async def test_error(
@@ -2,10 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- from hypothesis import given
5
+ from hypothesis import HealthCheck, given, settings
6
6
  from hypothesis.strategies import integers
7
7
 
8
- from utilities.hypothesis import temp_paths, text_ascii
8
+ from utilities.hypothesis import text_ascii
9
9
  from utilities.shelve import yield_shelf
10
10
 
11
11
  if TYPE_CHECKING:
@@ -13,9 +13,12 @@ if TYPE_CHECKING:
13
13
 
14
14
 
15
15
  class TestYieldShelf:
16
- @given(root=temp_paths(), key=text_ascii(), value=integers())
17
- def test_main(self, *, root: Path, key: str, value: int) -> None:
18
- path = root.joinpath("shelf")
16
+ @given(key=text_ascii(), value=integers())
17
+ @settings(
18
+ max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
19
+ )
20
+ def test_main(self, *, key: str, value: int, tmp_path: Path) -> None:
21
+ path = tmp_path.joinpath("shelf")
19
22
  with yield_shelf(path) as shelf:
20
23
  shelf[key] = value
21
24
  with yield_shelf(path) as shelf:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.149.9"
3
+ __version__ = "0.149.11"
@@ -22,6 +22,7 @@ from contextlib import (
22
22
  )
23
23
  from dataclasses import dataclass
24
24
  from io import StringIO
25
+ from pathlib import Path
25
26
  from subprocess import PIPE
26
27
  from sys import stderr, stdout
27
28
  from typing import (
@@ -40,6 +41,7 @@ from utilities.functions import ensure_int, ensure_not_none, to_bool
40
41
  from utilities.logging import get_logger
41
42
  from utilities.random import SYSTEM_RANDOM
42
43
  from utilities.sentinel import Sentinel, sentinel
44
+ from utilities.shelve import yield_shelf
43
45
  from utilities.warnings import suppress_warnings
44
46
  from utilities.whenever import get_now, round_date_or_date_time, to_nanoseconds
45
47
 
@@ -58,10 +60,12 @@ if TYPE_CHECKING:
58
60
  )
59
61
  from contextvars import Context
60
62
  from random import Random
63
+ from shelve import Shelf
61
64
  from types import TracebackType
62
65
 
63
66
  from whenever import ZonedDateTime
64
67
 
68
+ from utilities.shelve import _Flag
65
69
  from utilities.types import (
66
70
  Coro,
67
71
  Delta,
@@ -69,6 +73,7 @@ if TYPE_CHECKING:
69
73
  LoggerOrName,
70
74
  MaybeCallableBool,
71
75
  MaybeType,
76
+ PathLike,
72
77
  SupportsKeysAndGetItem,
73
78
  )
74
79
 
@@ -547,6 +552,35 @@ async def timeout_td(
547
552
  raise error from None
548
553
 
549
554
 
555
+ ##
556
+
557
+
558
+ _LOCKS: AsyncDict[Path, Lock] = AsyncDict()
559
+
560
+
561
+ @asynccontextmanager
562
+ async def yield_locked_shelf(
563
+ path: PathLike,
564
+ /,
565
+ *,
566
+ flag: _Flag = "c",
567
+ protocol: int | None = None,
568
+ writeback: bool = False,
569
+ ) -> AsyncIterator[Shelf[Any]]:
570
+ """Yield a shelf, behind a lock."""
571
+ path = Path(path)
572
+ try:
573
+ lock = _LOCKS[path]
574
+ except KeyError:
575
+ lock = Lock()
576
+ await _LOCKS.set(path, lock)
577
+ async with lock:
578
+ with yield_shelf(
579
+ path, flag=flag, protocol=protocol, writeback=writeback
580
+ ) as shelf:
581
+ yield shelf
582
+
583
+
550
584
  __all__ = [
551
585
  "AsyncDict",
552
586
  "EnhancedTaskGroup",
@@ -563,4 +597,5 @@ __all__ = [
563
597
  "sleep_until",
564
598
  "stream_command",
565
599
  "timeout_td",
600
+ "yield_locked_shelf",
566
601
  ]
@@ -12,12 +12,14 @@ from redis.asyncio import Redis
12
12
 
13
13
  from utilities.asyncio import loop_until_succeed, sleep_td, timeout_td
14
14
  from utilities.contextlib import enhanced_async_context_manager
15
+ from utilities.contextvars import yield_set_context
15
16
  from utilities.iterables import always_iterable
16
17
  from utilities.logging import get_logger
17
18
  from utilities.whenever import MILLISECOND, SECOND, to_seconds
18
19
 
19
20
  if TYPE_CHECKING:
20
21
  from collections.abc import AsyncIterator, Callable, Iterable
22
+ from contextvars import ContextVar
21
23
 
22
24
  from whenever import Delta
23
25
 
@@ -57,6 +59,7 @@ async def try_yield_coroutine_looper(
57
59
  throttle: Delta | None = None,
58
60
  logger: LoggerOrName | None = None,
59
61
  sleep_error: Delta | None = None,
62
+ context: ContextVar[bool] | None = None,
60
63
  ) -> AsyncIterator[CoroutineLooper | None]:
61
64
  """Try acquire access to a coroutine looper."""
62
65
  try: # skipif-ci-and-not-linux
@@ -70,7 +73,12 @@ async def try_yield_coroutine_looper(
70
73
  sleep=sleep_acquire,
71
74
  throttle=throttle,
72
75
  ) as lock:
73
- yield CoroutineLooper(lock=lock, logger=logger, sleep=sleep_error)
76
+ looper = CoroutineLooper(lock=lock, logger=logger, sleep=sleep_error)
77
+ if context is None:
78
+ yield looper
79
+ else:
80
+ with yield_set_context(context):
81
+ yield looper
74
82
  except _YieldAccessUnableToAcquireLockError as error: # skipif-ci-and-not-linux
75
83
  if logger is not None:
76
84
  get_logger(logger=logger).info("%s", error)
@@ -12,12 +12,15 @@ if TYPE_CHECKING:
12
12
  from utilities.types import PathLike
13
13
 
14
14
 
15
+ type _Flag = Literal["r", "w", "c", "n"]
16
+
17
+
15
18
  @contextmanager
16
19
  def yield_shelf(
17
20
  path: PathLike,
18
21
  /,
19
22
  *,
20
- flag: Literal["r", "w", "c", "n"] = "c",
23
+ flag: _Flag = "c",
21
24
  protocol: int | None = None,
22
25
  writeback: bool = False,
23
26
  ) -> Iterator[Shelf[Any]]: