dycw-utilities 0.122.1__tar.gz → 0.124.0__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 (223) hide show
  1. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/PKG-INFO +1 -1
  2. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/pyproject.toml +3 -2
  3. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_asyncio.py +153 -89
  4. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_redis.py +2 -2
  5. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sqlalchemy.py +1 -1
  6. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/__init__.py +1 -1
  7. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/asyncio.py +191 -61
  8. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/redis.py +2 -2
  9. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/slack_sdk.py +6 -10
  10. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sqlalchemy.py +2 -1
  11. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/.gitignore +0 -0
  12. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/LICENSE +0 -0
  13. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/README.md +0 -0
  14. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/__init__.py +0 -0
  15. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/conftest.py +0 -0
  16. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/__init__.py +0 -0
  17. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_missing/__init__.py +0 -0
  18. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_missing/module.py +0 -0
  19. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/__init__.py +0 -0
  20. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/outer_1.py +0 -0
  21. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/outer_2.py +0 -0
  22. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  23. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  24. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  25. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  26. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/__init__.py +0 -0
  27. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/module_1.py +0 -0
  28. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/package_without/module_2.py +0 -0
  29. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/standalone.py +0 -0
  30. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/modules/with_imports.py +0 -0
  31. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  32. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  33. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  34. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  35. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  36. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  37. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  38. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  39. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_altair.py +0 -0
  40. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_astor.py +0 -0
  41. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_atomicwrites.py +0 -0
  42. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_atools.py +0 -0
  43. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cachetools.py +0 -0
  44. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_click.py +0 -0
  45. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_concurrent.py +0 -0
  46. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_contextlib.py +0 -0
  47. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_contextvars.py +0 -0
  48. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cryptography.py +0 -0
  49. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_cvxpy.py +0 -0
  50. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_dataclasses.py +0 -0
  51. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_datetime.py +0 -0
  52. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_enum.py +0 -0
  53. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_errors.py +0 -0
  54. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_eventkit.py +0 -0
  55. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_fastapi.py +0 -0
  56. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_fpdf2.py +0 -0
  57. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_functions.py +0 -0
  58. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_functools.py +0 -0
  59. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_getpass.py +0 -0
  60. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_git.py +0 -0
  61. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_hashlib.py +0 -0
  62. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_http.py +0 -0
  63. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_hypothesis.py +0 -0
  64. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_importlib.py +0 -0
  65. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_ipython.py +0 -0
  66. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_iterables.py +0 -0
  67. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_jupyter.py +0 -0
  68. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_lightweight_charts.py +0 -0
  69. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_logging.py +0 -0
  70. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_loguru.py +0 -0
  71. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_luigi.py +0 -0
  72. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_math.py +0 -0
  73. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_memory_profiler.py +0 -0
  74. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_modules.py +0 -0
  75. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_more_itertools.py +0 -0
  76. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_numpy.py +0 -0
  77. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_operator.py +0 -0
  78. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_optuna.py +0 -0
  79. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_orjson.py +0 -0
  80. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_os.py +0 -0
  81. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_parse.py +0 -0
  82. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pathlib.py +0 -0
  83. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_period.py +0 -0
  84. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pickle.py +0 -0
  85. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_platform.py +0 -0
  86. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_polars.py +0 -0
  87. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_polars_ols.py +0 -0
  88. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pqdm.py +0 -0
  89. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pydantic.py +0 -0
  90. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pyinstrument.py +0 -0
  91. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pyrsistent.py +0 -0
  92. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pytest.py +0 -0
  93. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_pytest_regressions.py +0 -0
  94. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_python_dotenv.py +0 -0
  95. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_random.py +0 -0
  96. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_re.py +0 -0
  97. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_reprlib.py +0 -0
  98. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_rich.py +0 -0
  99. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_scipy.py +0 -0
  100. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sentinel.py +0 -0
  101. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_shelve.py +0 -0
  102. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sqlalchemy_polars.py +0 -0
  105. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_statsmodel.py +0 -0
  106. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_streamlit.py +0 -0
  107. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_sys.py +0 -0
  108. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tempfile.py +0 -0
  109. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tenacity.py +0 -0
  110. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_text.py +0 -0
  111. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_threading.py +0 -0
  112. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_timer.py +0 -0
  113. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback.py +0 -0
  114. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/__init__.py +0 -0
  115. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/chain.py +0 -0
  116. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  117. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  118. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  119. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/many.py +0 -0
  120. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/one.py +0 -0
  121. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/recursive.py +0 -0
  122. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  123. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  124. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/two.py +0 -0
  125. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_traceback_funcs/untraced.py +0 -0
  126. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_types.py +0 -0
  127. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing.py +0 -0
  128. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/__init__.py +0 -0
  129. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/no_future.py +0 -0
  130. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_typing_funcs/with_future.py +0 -0
  131. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tzdata.py +0 -0
  132. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_tzlocal.py +0 -0
  133. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_uuid.py +0 -0
  134. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_version.py +0 -0
  135. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_warnings.py +0 -0
  136. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_whenever.py +0 -0
  137. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_zipfile.py +0 -0
  138. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/tests/test_zoneinfo.py +0 -0
  139. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/altair.py +0 -0
  140. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/astor.py +0 -0
  141. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/atomicwrites.py +0 -0
  142. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/atools.py +0 -0
  143. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cachetools.py +0 -0
  144. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/click.py +0 -0
  145. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/concurrent.py +0 -0
  146. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/contextlib.py +0 -0
  147. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/contextvars.py +0 -0
  148. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cryptography.py +0 -0
  149. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/cvxpy.py +0 -0
  150. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/dataclasses.py +0 -0
  151. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/datetime.py +0 -0
  152. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/enum.py +0 -0
  153. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/errors.py +0 -0
  154. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/eventkit.py +0 -0
  155. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/fastapi.py +0 -0
  156. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/fpdf2.py +0 -0
  157. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/functions.py +0 -0
  158. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/functools.py +0 -0
  159. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/getpass.py +0 -0
  160. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/git.py +0 -0
  161. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/hashlib.py +0 -0
  162. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/http.py +0 -0
  163. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/hypothesis.py +0 -0
  164. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/importlib.py +0 -0
  165. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/ipython.py +0 -0
  166. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/iterables.py +0 -0
  167. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/jupyter.py +0 -0
  168. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/lightweight_charts.py +0 -0
  169. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/logging.py +0 -0
  170. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/loguru.py +0 -0
  171. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/luigi.py +0 -0
  172. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/math.py +0 -0
  173. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/memory_profiler.py +0 -0
  174. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/modules.py +0 -0
  175. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/more_itertools.py +0 -0
  176. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/numpy.py +0 -0
  177. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/operator.py +0 -0
  178. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/optuna.py +0 -0
  179. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/orjson.py +0 -0
  180. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/os.py +0 -0
  181. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/parse.py +0 -0
  182. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pathlib.py +0 -0
  183. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/period.py +0 -0
  184. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pickle.py +0 -0
  185. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/platform.py +0 -0
  186. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/polars.py +0 -0
  187. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/polars_ols.py +0 -0
  188. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pqdm.py +0 -0
  189. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/py.typed +0 -0
  190. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pydantic.py +0 -0
  191. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pyinstrument.py +0 -0
  192. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pyrsistent.py +0 -0
  193. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pytest.py +0 -0
  194. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/pytest_regressions.py +0 -0
  195. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/python_dotenv.py +0 -0
  196. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/random.py +0 -0
  197. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/re.py +0 -0
  198. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/reprlib.py +0 -0
  199. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/rich.py +0 -0
  200. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/scipy.py +0 -0
  201. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sentinel.py +0 -0
  202. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/shelve.py +0 -0
  203. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/socket.py +0 -0
  204. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sqlalchemy_polars.py +0 -0
  205. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/statsmodels.py +0 -0
  206. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/streamlit.py +0 -0
  207. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/sys.py +0 -0
  208. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tempfile.py +0 -0
  209. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tenacity.py +0 -0
  210. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/text.py +0 -0
  211. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/threading.py +0 -0
  212. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/timer.py +0 -0
  213. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/traceback.py +0 -0
  214. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/types.py +0 -0
  215. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/typing.py +0 -0
  216. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tzdata.py +0 -0
  217. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/tzlocal.py +0 -0
  218. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/uuid.py +0 -0
  219. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/version.py +0 -0
  220. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/warnings.py +0 -0
  221. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/whenever.py +0 -0
  222. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/zipfile.py +0 -0
  223. {dycw_utilities-0.122.1 → dycw_utilities-0.124.0}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.122.1
3
+ Version: 0.124.0
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -92,7 +92,7 @@ dependencies = [
92
92
  name = "dycw-utilities"
93
93
  readme = "README.md"
94
94
  requires-python = ">= 3.12"
95
- version = "0.122.1"
95
+ version = "0.124.0"
96
96
 
97
97
  [project.optional-dependencies]
98
98
  test = [
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
334
334
  # bump-my-version
335
335
  [tool.bumpversion]
336
336
  allow_dirty = true
337
- current_version = "0.122.1"
337
+ current_version = "0.124.0"
338
338
 
339
339
  [[tool.bumpversion.files]]
340
340
  filename = "src/utilities/__init__.py"
@@ -433,6 +433,7 @@ addopts = [
433
433
  "--durations=10",
434
434
  "--durations-min=10",
435
435
  "--strict-markers",
436
+ "--timeout=300",
436
437
  ]
437
438
  asyncio_default_fixture_loop_scope = "function"
438
439
  asyncio_mode = "auto"
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from asyncio import CancelledError, Event, Queue, TaskGroup, run, sleep, timeout
3
+ from asyncio import CancelledError, Event, Queue, run, sleep
4
+ from collections import deque
4
5
  from contextlib import asynccontextmanager
5
6
  from dataclasses import dataclass, field
6
7
  from functools import partial
@@ -8,9 +9,10 @@ from itertools import chain, count
8
9
  from re import search
9
10
  from typing import TYPE_CHECKING, Any, ClassVar, Self, cast, override
10
11
 
11
- from hypothesis import HealthCheck, Phase, given, settings
12
+ from hypothesis import HealthCheck, Phase, assume, given, settings
12
13
  from hypothesis.strategies import (
13
14
  DataObject,
15
+ booleans,
14
16
  data,
15
17
  integers,
16
18
  just,
@@ -22,6 +24,7 @@ from hypothesis.strategies import (
22
24
  from pytest import LogCaptureFixture, mark, param, raises
23
25
 
24
26
  from utilities.asyncio import (
27
+ EnhancedQueue,
25
28
  EnhancedTaskGroup,
26
29
  InfiniteLooper,
27
30
  InfiniteQueueLooper,
@@ -65,41 +68,118 @@ if TYPE_CHECKING:
65
68
  )
66
69
 
67
70
 
71
+ class TestEnhancedQueue:
72
+ @given(
73
+ xs=lists(integers()),
74
+ wait=booleans(),
75
+ put_all=booleans(),
76
+ get_reverse=booleans(),
77
+ )
78
+ async def test_left(
79
+ self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
80
+ ) -> None:
81
+ _ = assume(not ((len(xs) == 0) and wait))
82
+ deq: deque[int] = deque()
83
+ for x in xs:
84
+ deq.appendleft(x)
85
+ queue: EnhancedQueue[int] = EnhancedQueue()
86
+ if put_all:
87
+ if wait:
88
+ await queue.put_left(*xs)
89
+ else:
90
+ queue.put_left_nowait(*xs)
91
+ else:
92
+ for i, x in enumerate(xs, start=1):
93
+ if wait:
94
+ await queue.put_left(x)
95
+ else:
96
+ queue.put_left_nowait(x)
97
+ assert queue.qsize() == i
98
+ assert list(deq) == xs[::-1]
99
+ if wait:
100
+ res = await queue.get_all(reverse=get_reverse)
101
+ else:
102
+ res = queue.get_all_nowait(reverse=get_reverse)
103
+ expected = xs if get_reverse else xs[::-1]
104
+ assert res == expected
105
+
106
+ @given(
107
+ xs=lists(integers()),
108
+ wait=booleans(),
109
+ put_all=booleans(),
110
+ get_reverse=booleans(),
111
+ )
112
+ async def test_right(
113
+ self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
114
+ ) -> None:
115
+ _ = assume(not ((len(xs) == 0) and wait))
116
+ deq: deque[int] = deque()
117
+ for x in xs:
118
+ deq.append(x)
119
+ queue: EnhancedQueue[int] = EnhancedQueue()
120
+ if put_all:
121
+ if wait:
122
+ await queue.put_right(*xs)
123
+ else:
124
+ queue.put_right_nowait(*xs)
125
+ assert queue.qsize() == len(xs)
126
+ else:
127
+ for i, x in enumerate(xs, start=1):
128
+ if wait:
129
+ await queue.put_right(x)
130
+ else:
131
+ queue.put_right_nowait(x)
132
+ assert queue.qsize() == i
133
+ assert list(deq) == xs
134
+ if wait:
135
+ res = await queue.get_all(reverse=get_reverse)
136
+ else:
137
+ res = queue.get_all_nowait(reverse=get_reverse)
138
+ expected = xs[::-1] if get_reverse else xs
139
+ assert res == expected
140
+
141
+
68
142
  class TestEnhancedTaskGroup:
69
- async def test_context_managers(self) -> None:
70
- first: bool = False
143
+ async def test_create_task_context_coroutine(self) -> None:
144
+ flag: bool = False
71
145
 
72
146
  @asynccontextmanager
73
- async def yield_first() -> AsyncIterator[None]:
74
- nonlocal first
147
+ async def yield_true() -> AsyncIterator[None]:
148
+ nonlocal flag
75
149
  try:
76
- first = True
150
+ flag = True
77
151
  yield
78
152
  finally:
79
- first = False
153
+ flag = False
80
154
 
81
- second: bool = False
155
+ assert not flag
156
+ async with EnhancedTaskGroup(timeout=0.1) as tg:
157
+ _ = tg.create_task_context(yield_true())
158
+ await sleep(0.05)
159
+ assert flag
160
+ assert not flag
82
161
 
83
- @asynccontextmanager
84
- async def yield_second() -> AsyncIterator[None]:
85
- nonlocal second
86
- try:
87
- second = True
88
- yield
89
- finally:
90
- second = False
91
-
92
- async with EnhancedTaskGroup() as tg:
93
- assert not first
94
- assert not second
95
- _ = await tg.enter_async_context(yield_first())
96
- assert first
97
- assert not second
98
- _ = await tg.enter_async_context(yield_second())
99
- assert first
100
- assert second
101
- assert not first
102
- assert not second
162
+ async def test_create_task_context_looper(self) -> None:
163
+ @dataclass(kw_only=True)
164
+ class Example(InfiniteLooper[None]):
165
+ running: bool = False
166
+
167
+ @override
168
+ async def _initialize(self) -> None:
169
+ self.running = True
170
+
171
+ @override
172
+ async def _teardown(self) -> None:
173
+ self.running = False
174
+
175
+ looper = Example(duration=0.1)
176
+ assert not looper.running
177
+ async with EnhancedTaskGroup(timeout=0.1) as tg:
178
+ assert not looper.running
179
+ _ = tg.create_task_context(looper)
180
+ await sleep(0.05)
181
+ assert looper.running
182
+ assert not looper.running
103
183
 
104
184
  async def test_max_tasks_disabled(self) -> None:
105
185
  with Timer() as timer:
@@ -169,6 +249,24 @@ class TestGetEvent:
169
249
  assert get_event(event=lambda: event) is event
170
250
 
171
251
 
252
+ class TestGetItems:
253
+ @given(
254
+ xs=lists(integers(), min_size=1),
255
+ max_size=integers(1, 10) | none(),
256
+ wait=booleans(),
257
+ )
258
+ async def test_main(
259
+ self, *, xs: list[int], max_size: int | None, wait: bool
260
+ ) -> None:
261
+ queue: Queue[int] = Queue()
262
+ put_items_nowait(xs, queue)
263
+ if wait:
264
+ result = await get_items(queue, max_size=max_size)
265
+ else:
266
+ result = get_items_nowait(queue, max_size=max_size)
267
+ assert result == xs[:max_size]
268
+
269
+
172
270
  class TestInfiniteLooper:
173
271
  sleep_restart_cases: ClassVar[list[Any]] = [
174
272
  param(60.0, "for 0:01:00"),
@@ -350,7 +448,7 @@ class TestInfiniteLooper:
350
448
 
351
449
  async def inc_external(obj: Example, /) -> None:
352
450
  nonlocal external
353
- while True:
451
+ for _ in range(100): # infinite doesn't work on CI
354
452
  external += 1
355
453
  obj.counter += 1
356
454
  await sleep(0.05)
@@ -380,9 +478,9 @@ class TestInfiniteLooper:
380
478
  Example(sleep_core=0.05, sleep_restart=0.05) as looper,
381
479
  ):
382
480
  ...
383
- assert 4 <= looper.initializations <= 6
384
- assert 0 <= looper.counter <= 7
385
- assert 14 <= external <= 21
481
+ assert 3 <= looper.initializations <= 7
482
+ assert 0 <= looper.counter <= 8
483
+ assert 13 <= external <= 22
386
484
 
387
485
  async def test_with_coroutine_self_error(self) -> None:
388
486
  class CustomError(Exception): ...
@@ -655,13 +753,13 @@ class TestInfiniteQueueLooper:
655
753
  counter: int = 0
656
754
 
657
755
  @override
658
- async def _process_items(self, *items: int) -> None:
659
- self.counter += len(items)
756
+ async def _process_queue(self) -> None:
757
+ self.counter += len(self._queue.get_all_nowait())
660
758
 
661
759
  async with timeout_dur(duration=1.0), Example(sleep_core=0.05) as looper:
662
760
  await sleep(0.1)
663
761
  for i in range(10):
664
- looper.put_items_nowait(i)
762
+ looper.put_right_nowait(i)
665
763
  await sleep(0.05)
666
764
 
667
765
  assert looper.counter == 10
@@ -672,13 +770,13 @@ class TestInfiniteQueueLooper:
672
770
  output: set[int] = field(default_factory=set)
673
771
 
674
772
  @override
675
- async def _process_items(self, *items: int) -> None:
676
- self.output.update(items)
773
+ async def _process_queue(self) -> None:
774
+ self.output.update(self._queue.get_all_nowait())
677
775
 
678
776
  looper = Example(sleep_core=0.05)
679
777
  assert len(looper) == 0
680
778
  assert looper.empty()
681
- looper.put_items_nowait(*range(n))
779
+ looper.put_right_nowait(*range(n))
682
780
  assert len(looper) == n
683
781
  assert not looper.empty()
684
782
 
@@ -688,11 +786,11 @@ class TestInfiniteQueueLooper:
688
786
  output: set[int] = field(default_factory=set)
689
787
 
690
788
  @override
691
- async def _process_items(self, *items: int) -> None:
692
- self.output.update(items)
789
+ async def _process_queue(self) -> None:
790
+ self.output.update(self._queue.get_all_nowait())
693
791
 
694
792
  looper = Example(sleep_core=0.05)
695
- looper.put_items_nowait(*range(10))
793
+ looper.put_right_nowait(*range(10))
696
794
  async with looper:
697
795
  await looper.run_until_empty()
698
796
  assert looper.empty()
@@ -709,66 +807,32 @@ class TestInfiniteQueueLooper:
709
807
  output: set[int] = field(default_factory=set)
710
808
 
711
809
  @override
712
- async def _process_items(self, *items: int) -> None:
713
- raise CustomError(*items)
810
+ async def _process_queue(self) -> None:
811
+ raise CustomError
714
812
 
715
813
  async with (
716
814
  timeout_dur(duration=1.0),
717
815
  Example(sleep_core=0.05, logger=logger) as looper,
718
816
  ):
719
- looper.put_items_nowait(1)
817
+ looper.put_left_nowait(1)
720
818
  if logger is not None:
721
819
  message = caplog.messages[0]
722
- expected = "'Example' encountered CustomError(1) whilst processing 1 item(s) [1]; sleeping for 0:01:00..."
820
+ expected = "'Example' encountered 'CustomError()'; sleeping for 0:01:00..."
723
821
  assert message == expected
724
822
 
725
823
 
726
- class TestPutAndGetItems:
727
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
728
- async def test_put_then_get(self, *, xs: list[int], max_size: int | None) -> None:
824
+ class TestPutItems:
825
+ @given(xs=lists(integers(), min_size=1), wait=booleans())
826
+ async def test_main(self, *, xs: list[int], wait: bool) -> None:
729
827
  queue: Queue[int] = Queue()
730
- await put_items(xs, queue)
731
- result = await get_items(queue, max_size=max_size)
732
- if max_size is None:
733
- assert result == xs
828
+ if wait:
829
+ put_items_nowait(xs, queue)
734
830
  else:
735
- assert result == xs[:max_size]
736
-
737
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
738
- async def test_get_then_put(self, *, xs: list[int], max_size: int | None) -> None:
739
- queue: Queue[int] = Queue()
740
-
741
- async def put() -> None:
742
- await sleep(0.01)
743
831
  await put_items(xs, queue)
744
-
745
- async with TaskGroup() as tg:
746
- task = tg.create_task(get_items(queue, max_size=max_size))
747
- _ = tg.create_task(put())
748
- result = task.result()
749
- if max_size is None:
750
- assert result == xs
751
- else:
752
- assert result == xs[:max_size]
753
-
754
- async def test_empty(self) -> None:
755
- queue: Queue[int] = Queue()
756
- with raises(TimeoutError): # noqa: PT012
757
- async with timeout(0.01), TaskGroup() as tg:
758
- _ = tg.create_task(get_items(queue))
759
- _ = tg.create_task(sleep(0.02))
760
-
761
-
762
- class TestPutAndGetItemsNoWait:
763
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
764
- def test_main(self, *, xs: list[int], max_size: int | None) -> None:
765
- queue: Queue[int] = Queue()
766
- put_items_nowait(xs, queue)
767
- result = get_items_nowait(queue, max_size=max_size)
768
- if max_size is None:
769
- assert result == xs
770
- else:
771
- assert result == xs[:max_size]
832
+ result: list[int] = []
833
+ while not queue.empty():
834
+ result.append(await queue.get())
835
+ assert result == xs
772
836
 
773
837
 
774
838
  class TestUniquePriorityQueue:
@@ -150,7 +150,7 @@ class TestPublisher:
150
150
 
151
151
  async def sleep_then_put() -> None:
152
152
  await sleep(0.1)
153
- publisher.put_items_nowait((channel, obj))
153
+ publisher.put_right_nowait((channel, obj))
154
154
 
155
155
  with raises(ExceptionGroup): # noqa: PT012
156
156
  async with EnhancedTaskGroup(timeout=1.0) as tg:
@@ -187,7 +187,7 @@ class TestPublisher:
187
187
 
188
188
  async def sleep_then_put() -> None:
189
189
  await sleep(0.1)
190
- publisher.put_items_nowait((channel, text))
190
+ publisher.put_right_nowait((channel, text))
191
191
 
192
192
  with raises(ExceptionGroup): # noqa: PT012
193
193
  async with EnhancedTaskGroup(timeout=1.0) as tg:
@@ -1169,7 +1169,7 @@ class TestUpserter:
1169
1169
  engine = await sqlalchemy_engines(data, table)
1170
1170
  pairs = [(id_, init) for id_, init, _ in triples]
1171
1171
  async with Upserter(duration=1.0, sleep_core=0.1, engine=engine) as upserter:
1172
- upserter.put_items_nowait((pairs, table))
1172
+ upserter.put_right_nowait((pairs, table))
1173
1173
 
1174
1174
  sel = select(table)
1175
1175
  async with engine.begin() as conn:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.122.1"
3
+ __version__ = "0.124.0"