dycw-utilities 0.129.1__tar.gz → 0.129.2__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 (228) hide show
  1. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/PKG-INFO +1 -1
  2. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/pyproject.toml +2 -2
  3. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_asyncio.py +55 -38
  4. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_sqlalchemy.py +1 -0
  5. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/asyncio.py +30 -52
  7. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/.gitignore +0 -0
  8. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/LICENSE +0 -0
  9. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/README.md +0 -0
  10. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/__init__.py +0 -0
  11. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/conftest.py +0 -0
  12. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/__init__.py +0 -0
  13. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_missing/__init__.py +0 -0
  14. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_missing/module.py +0 -0
  15. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/__init__.py +0 -0
  16. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/outer_1.py +0 -0
  17. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/outer_2.py +0 -0
  18. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  19. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  20. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  21. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  22. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_without/__init__.py +0 -0
  23. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_without/module_1.py +0 -0
  24. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/package_without/module_2.py +0 -0
  25. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/standalone.py +0 -0
  26. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/modules/with_imports.py +0 -0
  27. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  28. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  29. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  30. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  31. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  32. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  33. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  34. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  35. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_altair.py +0 -0
  36. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_asyncio_classes/__init__.py +0 -0
  37. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_asyncio_classes/loopers.py +0 -0
  38. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_asyncio_classes/redis.py +0 -0
  39. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_atomicwrites.py +0 -0
  40. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_atools.py +0 -0
  41. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_cachetools.py +0 -0
  42. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_click.py +0 -0
  43. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_concurrent.py +0 -0
  44. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_contextlib.py +0 -0
  45. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_contextvars.py +0 -0
  46. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_cryptography.py +0 -0
  47. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_cvxpy.py +0 -0
  48. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_dataclasses.py +0 -0
  49. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_datetime.py +0 -0
  50. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_enum.py +0 -0
  51. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_errors.py +0 -0
  52. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_eventkit.py +0 -0
  53. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_fastapi.py +0 -0
  54. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_fpdf2.py +0 -0
  55. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_functions.py +0 -0
  56. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_functools.py +0 -0
  57. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_getpass.py +0 -0
  58. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_hashlib.py +0 -0
  59. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_http.py +0 -0
  60. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_hypothesis.py +0 -0
  61. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_importlib.py +0 -0
  62. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_ipython.py +0 -0
  63. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_iterables.py +0 -0
  64. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_jupyter.py +0 -0
  65. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_libcst.py +0 -0
  66. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_lightweight_charts.py +0 -0
  67. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_logging.py +0 -0
  68. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_loguru.py +0 -0
  69. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_luigi.py +0 -0
  70. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_math.py +0 -0
  71. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_memory_profiler.py +0 -0
  72. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_modules.py +0 -0
  73. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_more_itertools.py +0 -0
  74. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_numpy.py +0 -0
  75. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_operator.py +0 -0
  76. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_optuna.py +0 -0
  77. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_orjson.py +0 -0
  78. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_os.py +0 -0
  79. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_parse.py +0 -0
  80. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pathlib.py +0 -0
  81. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_period.py +0 -0
  82. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pickle.py +0 -0
  83. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_platform.py +0 -0
  84. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_polars.py +0 -0
  85. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_polars_ols.py +0 -0
  86. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pottery.py +0 -0
  87. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pqdm.py +0 -0
  88. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_psutil.py +0 -0
  89. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pydantic.py +0 -0
  90. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pyinstrument.py +0 -0
  91. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pyrsistent.py +0 -0
  92. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pytest.py +0 -0
  93. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_pytest_regressions.py +0 -0
  94. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_python_dotenv.py +0 -0
  95. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_random.py +0 -0
  96. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_re.py +0 -0
  97. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_redis.py +0 -0
  98. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_reprlib.py +0 -0
  99. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_scipy.py +0 -0
  100. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_sentinel.py +0 -0
  101. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_shelve.py +0 -0
  102. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_sqlalchemy_polars.py +0 -0
  105. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_statsmodel.py +0 -0
  106. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_streamlit.py +0 -0
  107. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_string.py +0 -0
  108. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_sys.py +0 -0
  109. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_tempfile.py +0 -0
  110. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_tenacity.py +0 -0
  111. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_text.py +0 -0
  112. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_threading.py +0 -0
  113. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_timer.py +0 -0
  114. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback.py +0 -0
  115. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/__init__.py +0 -0
  116. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/chain.py +0 -0
  117. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  118. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  119. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  120. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/many.py +0 -0
  121. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/one.py +0 -0
  122. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/recursive.py +0 -0
  123. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  124. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  125. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/two.py +0 -0
  126. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_traceback_funcs/untraced.py +0 -0
  127. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_types.py +0 -0
  128. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_typing.py +0 -0
  129. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_typing_funcs/__init__.py +0 -0
  130. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_typing_funcs/no_future.py +0 -0
  131. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_typing_funcs/with_future.py +0 -0
  132. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_tzdata.py +0 -0
  133. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_tzlocal.py +0 -0
  134. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_uuid.py +0 -0
  135. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_version.py +0 -0
  136. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_warnings.py +0 -0
  137. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_whenever.py +0 -0
  138. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_zipfile.py +0 -0
  139. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/tests/test_zoneinfo.py +0 -0
  140. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/altair.py +0 -0
  141. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/atomicwrites.py +0 -0
  142. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/atools.py +0 -0
  143. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/cachetools.py +0 -0
  144. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/click.py +0 -0
  145. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/concurrent.py +0 -0
  146. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/contextlib.py +0 -0
  147. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/contextvars.py +0 -0
  148. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/cryptography.py +0 -0
  149. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/cvxpy.py +0 -0
  150. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/dataclasses.py +0 -0
  151. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/datetime.py +0 -0
  152. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/enum.py +0 -0
  153. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/errors.py +0 -0
  154. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/eventkit.py +0 -0
  155. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/fastapi.py +0 -0
  156. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/fpdf2.py +0 -0
  157. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/functions.py +0 -0
  158. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/functools.py +0 -0
  159. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/getpass.py +0 -0
  160. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/hashlib.py +0 -0
  161. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/http.py +0 -0
  162. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/hypothesis.py +0 -0
  163. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/importlib.py +0 -0
  164. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/ipython.py +0 -0
  165. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/iterables.py +0 -0
  166. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/jupyter.py +0 -0
  167. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/libcst.py +0 -0
  168. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/lightweight_charts.py +0 -0
  169. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/logging.py +0 -0
  170. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/loguru.py +0 -0
  171. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/luigi.py +0 -0
  172. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/math.py +0 -0
  173. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/memory_profiler.py +0 -0
  174. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/modules.py +0 -0
  175. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/more_itertools.py +0 -0
  176. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/numpy.py +0 -0
  177. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/operator.py +0 -0
  178. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/optuna.py +0 -0
  179. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/orjson.py +0 -0
  180. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/os.py +0 -0
  181. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/parse.py +0 -0
  182. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pathlib.py +0 -0
  183. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/period.py +0 -0
  184. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pickle.py +0 -0
  185. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/platform.py +0 -0
  186. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/polars.py +0 -0
  187. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/polars_ols.py +0 -0
  188. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pottery.py +0 -0
  189. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pqdm.py +0 -0
  190. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/psutil.py +0 -0
  191. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/py.typed +0 -0
  192. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pydantic.py +0 -0
  193. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pyinstrument.py +0 -0
  194. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pyrsistent.py +0 -0
  195. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pytest.py +0 -0
  196. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/pytest_regressions.py +0 -0
  197. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/python_dotenv.py +0 -0
  198. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/random.py +0 -0
  199. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/re.py +0 -0
  200. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/redis.py +0 -0
  201. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/reprlib.py +0 -0
  202. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/scipy.py +0 -0
  203. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/sentinel.py +0 -0
  204. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/shelve.py +0 -0
  205. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/slack_sdk.py +0 -0
  206. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/socket.py +0 -0
  207. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/sqlalchemy.py +0 -0
  208. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/sqlalchemy_polars.py +0 -0
  209. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/statsmodels.py +0 -0
  210. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/streamlit.py +0 -0
  211. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/string.py +0 -0
  212. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/sys.py +0 -0
  213. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/tempfile.py +0 -0
  214. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/tenacity.py +0 -0
  215. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/text.py +0 -0
  216. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/threading.py +0 -0
  217. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/timer.py +0 -0
  218. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/traceback.py +0 -0
  219. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/types.py +0 -0
  220. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/typing.py +0 -0
  221. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/tzdata.py +0 -0
  222. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/tzlocal.py +0 -0
  223. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/uuid.py +0 -0
  224. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/version.py +0 -0
  225. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/warnings.py +0 -0
  226. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/whenever.py +0 -0
  227. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/zipfile.py +0 -0
  228. {dycw_utilities-0.129.1 → dycw_utilities-0.129.2}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.129.1
3
+ Version: 0.129.2
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -94,7 +94,7 @@ dependencies = [
94
94
  name = "dycw-utilities"
95
95
  readme = "README.md"
96
96
  requires-python = ">= 3.12"
97
- version = "0.129.1"
97
+ version = "0.129.2"
98
98
 
99
99
  [project.optional-dependencies]
100
100
  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.129.1"
337
+ current_version = "0.129.2"
338
338
 
339
339
  [[tool.bumpversion.files]]
340
340
  filename = "src/utilities/__init__.py"
@@ -21,7 +21,9 @@ from hypothesis.strategies import (
21
21
  )
22
22
  from pytest import LogCaptureFixture, approx, mark, param, raises
23
23
 
24
+ from tests.conftest import IS_CI
24
25
  from tests.test_asyncio_classes.loopers import (
26
+ _BACKOFF,
25
27
  _REL,
26
28
  CountingLooper,
27
29
  CountingLooperError,
@@ -63,6 +65,7 @@ from utilities.sentinel import Sentinel, sentinel
63
65
  from utilities.timer import Timer
64
66
 
65
67
  if TYPE_CHECKING:
68
+ import datetime as dt
66
69
  from collections.abc import AsyncIterator
67
70
 
68
71
  from utilities.types import Duration, MaybeCallableEvent
@@ -255,9 +258,12 @@ class TestGetItems:
255
258
 
256
259
 
257
260
  class TestLooper:
258
- sleep_if_failure_cases: ClassVar[list[Any]] = [
259
- param(True, "; sleeping for .*"),
260
- param(False, ""),
261
+ _restart_min_elapsed: ClassVar[dt.timedelta] = datetime_duration_to_timedelta(
262
+ (0.9 if IS_CI else 1.0) * _BACKOFF
263
+ )
264
+ skip_sleep_if_failure_cases: ClassVar[list[Any]] = [
265
+ param(True, ""),
266
+ param(False, "; sleeping for .*"),
261
267
  ]
262
268
 
263
269
  async def test_main_with_nothing(self) -> None:
@@ -330,16 +336,16 @@ class TestLooper:
330
336
  @override
331
337
  async def _initialize_core(self) -> None:
332
338
  if self._initialization_attempts == 1:
333
- _ = await super().initialize(sleep_if_failure=False)
339
+ _ = await super().initialize()
334
340
  await super()._initialize_core()
335
341
 
336
342
  looper = Example()
337
- _ = await looper.initialize(sleep_if_failure=False)
343
+ _ = await looper.initialize()
338
344
  _ = one(m for m in caplog.messages if search(": already initializing$", m))
339
345
 
340
- @mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
346
+ @mark.parametrize(("skip_sleep_if_failure", "extra"), skip_sleep_if_failure_cases)
341
347
  async def test_initialize_failure(
342
- self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
348
+ self, *, skip_sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
343
349
  ) -> None:
344
350
  class Example(CountingLooper):
345
351
  @override
@@ -349,7 +355,7 @@ class TestLooper:
349
355
  await super()._initialize_core()
350
356
 
351
357
  looper = Example()
352
- _ = await looper.initialize(sleep_if_failure=sleep_if_failure)
358
+ _ = await looper.initialize(skip_sleep_if_failure=skip_sleep_if_failure)
353
359
  pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst initializing{extra}$"
354
360
  _ = one(m for m in caplog.messages if search(pattern, m))
355
361
 
@@ -459,11 +465,11 @@ class TestLooper:
459
465
  assert_looper_stats(
460
466
  looper,
461
467
  entries=1,
462
- core_successes=79,
468
+ core_successes=35,
463
469
  core_failures=1,
464
- initialization_successes=16,
465
- tear_down_successes=15,
466
- restart_successes=15,
470
+ initialization_successes=7,
471
+ tear_down_successes=6,
472
+ restart_successes=6,
467
473
  stops=1,
468
474
  )
469
475
 
@@ -553,9 +559,8 @@ class TestLooper:
553
559
  if search(r": already requested stop when empty$", m)
554
560
  )
555
561
 
556
- @mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
557
562
  async def test_restart_failure_during_initialization(
558
- self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
563
+ self, *, caplog: LogCaptureFixture
559
564
  ) -> None:
560
565
  class Example(CountingLooper):
561
566
  @override
@@ -565,13 +570,14 @@ class TestLooper:
565
570
  await super()._initialize_core()
566
571
 
567
572
  looper = Example()
568
- await looper.restart(sleep_if_failure=sleep_if_failure)
569
- pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(initialize\){extra}$"
573
+ with Timer() as timer:
574
+ await looper.restart()
575
+ assert timer.timedelta >= self._restart_min_elapsed
576
+ pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(initialize\); sleeping for .*\.\.\.$"
570
577
  _ = one(m for m in caplog.messages if search(pattern, m))
571
578
 
572
- @mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
573
579
  async def test_restart_failure_during_tear_down(
574
- self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
580
+ self, *, caplog: LogCaptureFixture
575
581
  ) -> None:
576
582
  class Example(CountingLooper):
577
583
  @override
@@ -581,13 +587,14 @@ class TestLooper:
581
587
  await super()._tear_down_core()
582
588
 
583
589
  looper = Example()
584
- await looper.restart(sleep_if_failure=sleep_if_failure)
585
- pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(tear down\){extra}$"
590
+ with Timer() as timer:
591
+ await looper.restart()
592
+ assert timer.timedelta >= self._restart_min_elapsed
593
+ pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst restarting \(tear down\); sleeping for .*\.\.\.$"
586
594
  _ = one(m for m in caplog.messages if search(pattern, m))
587
595
 
588
- @mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
589
596
  async def test_restart_failure_during_tear_down_and_initialization(
590
- self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
597
+ self, *, caplog: LogCaptureFixture
591
598
  ) -> None:
592
599
  class Example(CountingLooper):
593
600
  @override
@@ -603,8 +610,18 @@ class TestLooper:
603
610
  await super()._tear_down_core()
604
611
 
605
612
  looper = Example()
606
- await looper.restart(sleep_if_failure=sleep_if_failure)
607
- pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) \(tear down\) and then {get_class_name(CountingLooperError)}\(\) \(initialization\) whilst restarting{extra}$"
613
+ with Timer() as timer:
614
+ await looper.restart()
615
+ assert timer.timedelta >= self._restart_min_elapsed
616
+ pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) \(tear down\) and then {get_class_name(CountingLooperError)}\(\) \(initialization\) whilst restarting; sleeping for .*\.\.\.$"
617
+ _ = one(m for m in caplog.messages if search(pattern, m))
618
+
619
+ async def test_restart_success(self, *, caplog: LogCaptureFixture) -> None:
620
+ looper = CountingLooper()
621
+ with Timer() as timer:
622
+ await looper.restart()
623
+ assert timer.timedelta >= self._restart_min_elapsed
624
+ pattern = r": finished restarting; sleeping for .*\.\.\.$"
608
625
  _ = one(m for m in caplog.messages if search(pattern, m))
609
626
 
610
627
  @mark.parametrize("n", [param(0), param(1), param(2)])
@@ -698,16 +715,16 @@ class TestLooper:
698
715
  @override
699
716
  async def _tear_down_core(self) -> None:
700
717
  if self._tear_down_attempts == 1:
701
- _ = await super().tear_down(sleep_if_failure=False)
718
+ _ = await super().tear_down()
702
719
  await super()._tear_down_core()
703
720
 
704
721
  looper = Example()
705
- _ = await looper.tear_down(sleep_if_failure=False)
722
+ _ = await looper.tear_down()
706
723
  _ = one(m for m in caplog.messages if search(": already tearing down$", m))
707
724
 
708
- @mark.parametrize(("sleep_if_failure", "extra"), sleep_if_failure_cases)
725
+ @mark.parametrize(("skip_sleep_if_failure", "extra"), skip_sleep_if_failure_cases)
709
726
  async def test_tear_down_failure(
710
- self, *, sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
727
+ self, *, skip_sleep_if_failure: bool, extra: str, caplog: LogCaptureFixture
711
728
  ) -> None:
712
729
  class Example(CountingLooper):
713
730
  @override
@@ -717,7 +734,7 @@ class TestLooper:
717
734
  await super()._tear_down_core()
718
735
 
719
736
  looper = Example()
720
- _ = await looper.tear_down(sleep_if_failure=sleep_if_failure)
737
+ _ = await looper.tear_down(skip_sleep_if_failure=skip_sleep_if_failure)
721
738
  pattern = rf": encountered {get_class_name(CountingLooperError)}\(\) whilst tearing down{extra}$"
722
739
  _ = one(m for m in caplog.messages if search(pattern, m))
723
740
 
@@ -751,7 +768,7 @@ class TestLooper:
751
768
  assert_looper_stats(
752
769
  looper,
753
770
  entries=1,
754
- core_successes=45,
771
+ core_successes=47,
755
772
  core_failures=5,
756
773
  initialization_successes=6,
757
774
  tear_down_successes=5,
@@ -767,10 +784,10 @@ class TestLooper:
767
784
  looper,
768
785
  entries=1,
769
786
  core_successes=56,
770
- core_failures=13,
771
- initialization_successes=14,
772
- tear_down_successes=13,
773
- restart_successes=13,
787
+ core_failures=14,
788
+ initialization_successes=15,
789
+ tear_down_successes=14,
790
+ restart_successes=14,
774
791
  stops=stops,
775
792
  rel=rel,
776
793
  )
@@ -781,7 +798,7 @@ class TestLooper:
781
798
  assert_looper_stats(
782
799
  looper,
783
800
  entries=1,
784
- core_successes=49,
801
+ core_successes=48,
785
802
  core_failures=24,
786
803
  initialization_successes=25,
787
804
  tear_down_successes=24,
@@ -798,9 +815,9 @@ class TestLooper:
798
815
  entries=1,
799
816
  core_successes=35,
800
817
  core_failures=35,
801
- initialization_successes=35,
802
- tear_down_successes=34,
803
- restart_successes=34,
818
+ initialization_successes=36,
819
+ tear_down_successes=35,
820
+ restart_successes=35,
804
821
  stops=stops,
805
822
  rel=rel,
806
823
  )
@@ -1332,6 +1332,7 @@ class TestUpsertItems:
1332
1332
  await upsert_items(engine, item)
1333
1333
 
1334
1334
  @given(data=data(), triples=_upsert_lists(nullable=True, min_size=1))
1335
+ @mark.flaky
1335
1336
  @settings_with_reduced_examples(phases={Phase.generate})
1336
1337
  async def test_multiple_elements_with_the_same_primary_key(
1337
1338
  self, *, data: DataObject, triples: list[tuple[int, bool, bool | None]]
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.129.1"
3
+ __version__ = "0.129.2"
@@ -458,7 +458,9 @@ class Looper(Generic[_T]):
458
458
  """Remove and return an item from the end of the queue without blocking."""
459
459
  return self._queue.get_right_nowait()
460
460
 
461
- async def initialize(self, *, sleep_if_failure: bool) -> Exception | None:
461
+ async def initialize(
462
+ self, *, skip_sleep_if_failure: bool = False
463
+ ) -> Exception | None:
462
464
  """Initialize the looper."""
463
465
  match self._is_initializing.is_set():
464
466
  case True:
@@ -476,21 +478,21 @@ class Looper(Generic[_T]):
476
478
  async with self._lock:
477
479
  self._initialization_failures += 1
478
480
  ret = error
479
- match sleep_if_failure:
481
+ match skip_sleep_if_failure:
480
482
  case True:
481
483
  _ = self._logger.warning(
482
- "%s: encountered %s whilst initializing; sleeping for %s...",
484
+ "%s: encountered %s whilst initializing",
483
485
  self,
484
486
  repr_error(error),
485
- self.backoff,
486
487
  )
487
- await sleep(self._backoff)
488
488
  case False:
489
489
  _ = self._logger.warning(
490
- "%s: encountered %s whilst initializing",
490
+ "%s: encountered %s whilst initializing; sleeping for %s...",
491
491
  self,
492
492
  repr_error(error),
493
+ self.backoff,
493
494
  )
495
+ await sleep(self._backoff)
494
496
  case _ as never:
495
497
  assert_never(never)
496
498
  else:
@@ -590,20 +592,22 @@ class Looper(Generic[_T]):
590
592
  case _ as never:
591
593
  assert_never(never)
592
594
 
593
- async def restart(self, *, sleep_if_failure: bool) -> None:
595
+ async def restart(self) -> None:
594
596
  """Restart the looper."""
595
597
  _ = self._debug and self._logger.debug("%s: restarting...", self)
596
598
  self._is_pending_restart.clear()
597
599
  async with self._lock:
598
600
  self._restart_attempts += 1
599
- tear_down = await self.tear_down(sleep_if_failure=False)
600
- initialization = await self.initialize(sleep_if_failure=False)
601
- match tear_down, initialization, sleep_if_failure:
602
- case None, None, bool():
603
- _ = self._debug and self._logger.debug("%s: finished restarting", self)
601
+ tear_down = await self.tear_down(skip_sleep_if_failure=True)
602
+ initialization = await self.initialize(skip_sleep_if_failure=True)
603
+ match tear_down, initialization:
604
+ case None, None:
605
+ _ = self._debug and self._logger.debug(
606
+ "%s: finished restarting; sleeping for %s...", self, self.backoff
607
+ )
604
608
  async with self._lock:
605
609
  self._restart_successes += 1
606
- case Exception(), None, True:
610
+ case Exception(), None:
607
611
  async with self._lock:
608
612
  self._restart_failures += 1
609
613
  _ = self._logger.warning(
@@ -612,16 +616,7 @@ class Looper(Generic[_T]):
612
616
  repr_error(tear_down),
613
617
  self.backoff,
614
618
  )
615
- await sleep(self._backoff)
616
- case Exception(), None, False:
617
- async with self._lock:
618
- self._restart_failures += 1
619
- _ = self._logger.warning(
620
- "%s: encountered %s whilst restarting (tear down)",
621
- self,
622
- repr_error(tear_down),
623
- )
624
- case None, Exception(), True:
619
+ case None, Exception():
625
620
  async with self._lock:
626
621
  self._restart_failures += 1
627
622
  _ = self._logger.warning(
@@ -630,16 +625,7 @@ class Looper(Generic[_T]):
630
625
  repr_error(initialization),
631
626
  self.backoff,
632
627
  )
633
- await sleep(self._backoff)
634
- case None, Exception(), False:
635
- async with self._lock:
636
- self._restart_failures += 1
637
- _ = self._logger.warning(
638
- "%s: encountered %s whilst restarting (initialize)",
639
- self,
640
- repr_error(initialization),
641
- )
642
- case Exception(), Exception(), True:
628
+ case Exception(), Exception():
643
629
  async with self._lock:
644
630
  self._restart_failures += 1
645
631
  _ = self._logger.warning(
@@ -649,18 +635,9 @@ class Looper(Generic[_T]):
649
635
  repr_error(initialization),
650
636
  self.backoff,
651
637
  )
652
- await sleep(self._backoff)
653
- case Exception(), Exception(), False:
654
- async with self._lock:
655
- self._restart_failures += 1
656
- _ = self._logger.warning(
657
- "%s: encountered %s (tear down) and then %s (initialization) whilst restarting",
658
- self,
659
- repr_error(tear_down),
660
- repr_error(initialization),
661
- )
662
638
  case _ as never:
663
639
  assert_never(never)
640
+ await sleep(self._backoff)
664
641
 
665
642
  async def run_looper(self) -> None:
666
643
  """Run the looper."""
@@ -675,9 +652,9 @@ class Looper(Generic[_T]):
675
652
  ):
676
653
  await self.stop()
677
654
  elif self._is_pending_restart.is_set():
678
- await self.restart(sleep_if_failure=True)
655
+ await self.restart()
679
656
  elif not self._is_initialized.is_set():
680
- _ = await self.initialize(sleep_if_failure=True)
657
+ _ = await self.initialize()
681
658
  else:
682
659
  _ = self._debug and self._logger.debug(
683
660
  "%s: running core...", self
@@ -695,7 +672,6 @@ class Looper(Generic[_T]):
695
672
  async with self._lock:
696
673
  self._core_failures += 1
697
674
  self.request_restart()
698
- await sleep(self._backoff)
699
675
  else:
700
676
  async with self._lock:
701
677
  self._core_successes += 1
@@ -749,7 +725,9 @@ class Looper(Generic[_T]):
749
725
  case _ as never:
750
726
  assert_never(never)
751
727
 
752
- async def tear_down(self, *, sleep_if_failure: bool) -> Exception | None:
728
+ async def tear_down(
729
+ self, *, skip_sleep_if_failure: bool = False
730
+ ) -> Exception | None:
753
731
  """Tear down the looper."""
754
732
  match self._is_tearing_down.is_set():
755
733
  case True:
@@ -766,21 +744,21 @@ class Looper(Generic[_T]):
766
744
  async with self._lock:
767
745
  self._tear_down_failures += 1
768
746
  ret = error
769
- match sleep_if_failure:
747
+ match skip_sleep_if_failure:
770
748
  case True:
771
749
  _ = self._logger.warning(
772
- "%s: encountered %s whilst tearing down; sleeping for %s...",
750
+ "%s: encountered %s whilst tearing down",
773
751
  self,
774
752
  repr_error(error),
775
- self.backoff,
776
753
  )
777
- await sleep(self._backoff)
778
754
  case False:
779
755
  _ = self._logger.warning(
780
- "%s: encountered %s whilst tearing down",
756
+ "%s: encountered %s whilst tearing down; sleeping for %s...",
781
757
  self,
782
758
  repr_error(error),
759
+ self.backoff,
783
760
  )
761
+ await sleep(self._backoff)
784
762
  case _ as never:
785
763
  assert_never(never)
786
764
  else: