dycw-utilities 0.117.0__tar.gz → 0.117.1__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 (230) hide show
  1. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/PKG-INFO +1 -1
  2. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/pyproject.toml +2 -2
  3. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_asyncio.py +58 -10
  4. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/__init__.py +1 -1
  5. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/asyncio.py +40 -12
  6. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/.gitignore +0 -0
  7. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/LICENSE +0 -0
  8. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/README.md +0 -0
  9. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/__init__.py +0 -0
  10. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/conftest.py +0 -0
  11. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/__init__.py +0 -0
  35. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_async_service/__init__.py +0 -0
  36. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_async_service/__main__.py +0 -0
  37. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_async_service/run.sh +0 -0
  38. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  39. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  40. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  41. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_altair.py +0 -0
  42. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_astor.py +0 -0
  43. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_atomicwrites.py +0 -0
  44. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_atools.py +0 -0
  45. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_cachetools.py +0 -0
  46. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_click.py +0 -0
  47. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_concurrent.py +0 -0
  48. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_contextlib.py +0 -0
  49. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_contextvars.py +0 -0
  50. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_cryptography.py +0 -0
  51. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_cvxpy.py +0 -0
  52. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_dataclasses.py +0 -0
  53. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_datetime.py +0 -0
  54. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_enum.py +0 -0
  55. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_errors.py +0 -0
  56. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_eventkit.py +0 -0
  57. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_fastapi.py +0 -0
  58. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_fpdf2.py +0 -0
  59. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_functions.py +0 -0
  60. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_functools.py +0 -0
  61. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_getpass.py +0 -0
  62. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_git.py +0 -0
  63. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_hashlib.py +0 -0
  64. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_http.py +0 -0
  65. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_hypothesis.py +0 -0
  66. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_importlib.py +0 -0
  67. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_ipython.py +0 -0
  68. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_iterables.py +0 -0
  69. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_jupyter.py +0 -0
  70. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_lightweight_charts.py +0 -0
  71. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_logging.py +0 -0
  72. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_loguru.py +0 -0
  73. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_luigi.py +0 -0
  74. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_math.py +0 -0
  75. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_memory_profiler.py +0 -0
  76. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_modules.py +0 -0
  77. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_more_itertools.py +0 -0
  78. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_numpy.py +0 -0
  79. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_operator.py +0 -0
  80. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_optuna.py +0 -0
  81. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_orjson.py +0 -0
  82. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_os.py +0 -0
  83. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_parse.py +0 -0
  84. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pathlib.py +0 -0
  85. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_period.py +0 -0
  86. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pickle.py +0 -0
  87. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_platform.py +0 -0
  88. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_polars.py +0 -0
  89. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_polars_ols.py +0 -0
  90. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pqdm.py +0 -0
  91. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pydantic.py +0 -0
  92. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pyinstrument.py +0 -0
  93. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pyrsistent.py +0 -0
  94. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pytest.py +0 -0
  95. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_pytest_regressions.py +0 -0
  96. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_python_dotenv.py +0 -0
  97. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_random.py +0 -0
  98. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_re.py +0 -0
  99. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_redis.py +0 -0
  100. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_reprlib.py +0 -0
  101. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_rich.py +0 -0
  102. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_scipy.py +0 -0
  103. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_sentinel.py +0 -0
  104. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_shelve.py +0 -0
  105. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_slack_sdk.py +0 -0
  106. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_socket.py +0 -0
  107. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_sqlalchemy.py +0 -0
  108. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_sqlalchemy_polars.py +0 -0
  109. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_statsmodel.py +0 -0
  110. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_streamlit.py +0 -0
  111. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_sys.py +0 -0
  112. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_tempfile.py +0 -0
  113. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_tenacity.py +0 -0
  114. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_text.py +0 -0
  115. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_threading.py +0 -0
  116. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_timer.py +0 -0
  117. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback.py +0 -0
  118. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/__init__.py +0 -0
  119. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/chain.py +0 -0
  120. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  121. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  122. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  123. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/many.py +0 -0
  124. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/one.py +0 -0
  125. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/recursive.py +0 -0
  126. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  127. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  128. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/two.py +0 -0
  129. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_traceback_funcs/untraced.py +0 -0
  130. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_types.py +0 -0
  131. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_typing.py +0 -0
  132. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_typing_funcs/__init__.py +0 -0
  133. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_typing_funcs/no_future.py +0 -0
  134. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_typing_funcs/with_future.py +0 -0
  135. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_tzdata.py +0 -0
  136. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_tzlocal.py +0 -0
  137. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_uuid.py +0 -0
  138. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_version.py +0 -0
  139. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_warnings.py +0 -0
  140. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_whenever.py +0 -0
  141. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_zipfile.py +0 -0
  142. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/tests/test_zoneinfo.py +0 -0
  143. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/altair.py +0 -0
  144. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/astor.py +0 -0
  145. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/atomicwrites.py +0 -0
  146. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/atools.py +0 -0
  147. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/cachetools.py +0 -0
  148. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/click.py +0 -0
  149. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/concurrent.py +0 -0
  150. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/contextlib.py +0 -0
  151. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/contextvars.py +0 -0
  152. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/cryptography.py +0 -0
  153. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/cvxpy.py +0 -0
  154. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/dataclasses.py +0 -0
  155. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/datetime.py +0 -0
  156. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/enum.py +0 -0
  157. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/errors.py +0 -0
  158. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/eventkit.py +0 -0
  159. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/fastapi.py +0 -0
  160. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/fpdf2.py +0 -0
  161. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/functions.py +0 -0
  162. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/functools.py +0 -0
  163. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/getpass.py +0 -0
  164. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/git.py +0 -0
  165. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/hashlib.py +0 -0
  166. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/http.py +0 -0
  167. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/hypothesis.py +0 -0
  168. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/importlib.py +0 -0
  169. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/ipython.py +0 -0
  170. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/iterables.py +0 -0
  171. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/jupyter.py +0 -0
  172. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/lightweight_charts.py +0 -0
  173. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/logging.py +0 -0
  174. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/loguru.py +0 -0
  175. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/luigi.py +0 -0
  176. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/math.py +0 -0
  177. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/memory_profiler.py +0 -0
  178. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/modules.py +0 -0
  179. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/more_itertools.py +0 -0
  180. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/numpy.py +0 -0
  181. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/operator.py +0 -0
  182. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/optuna.py +0 -0
  183. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/orjson.py +0 -0
  184. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/os.py +0 -0
  185. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/parse.py +0 -0
  186. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pathlib.py +0 -0
  187. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/period.py +0 -0
  188. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pickle.py +0 -0
  189. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/platform.py +0 -0
  190. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/polars.py +0 -0
  191. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/polars_ols.py +0 -0
  192. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pqdm.py +0 -0
  193. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/py.typed +0 -0
  194. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pydantic.py +0 -0
  195. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pyinstrument.py +0 -0
  196. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pyrsistent.py +0 -0
  197. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pytest.py +0 -0
  198. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/pytest_regressions.py +0 -0
  199. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/python_dotenv.py +0 -0
  200. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/random.py +0 -0
  201. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/re.py +0 -0
  202. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/redis.py +0 -0
  203. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/reprlib.py +0 -0
  204. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/rich.py +0 -0
  205. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/scipy.py +0 -0
  206. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/sentinel.py +0 -0
  207. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/shelve.py +0 -0
  208. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/slack_sdk.py +0 -0
  209. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/socket.py +0 -0
  210. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/sqlalchemy.py +0 -0
  211. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/sqlalchemy_polars.py +0 -0
  212. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/sys.py +0 -0
  215. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/text.py +0 -0
  218. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/threading.py +0 -0
  219. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/timer.py +0 -0
  220. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/traceback.py +0 -0
  221. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/types.py +0 -0
  222. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/typing.py +0 -0
  223. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/tzdata.py +0 -0
  224. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/tzlocal.py +0 -0
  225. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/uuid.py +0 -0
  226. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/version.py +0 -0
  227. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/warnings.py +0 -0
  228. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/whenever.py +0 -0
  229. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/zipfile.py +0 -0
  230. {dycw_utilities-0.117.0 → dycw_utilities-0.117.1}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.117.0
3
+ Version: 0.117.1
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.117.0"
95
+ version = "0.117.1"
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.117.0"
337
+ current_version = "0.117.1"
338
338
 
339
339
  [[tool.bumpversion.files]]
340
340
  filename = "src/utilities/__init__.py"
@@ -17,7 +17,7 @@ from itertools import chain, count
17
17
  from re import search
18
18
  from typing import TYPE_CHECKING, Self, override
19
19
 
20
- from hypothesis import Phase, given, settings
20
+ from hypothesis import HealthCheck, Phase, given, settings
21
21
  from hypothesis.strategies import (
22
22
  DataObject,
23
23
  data,
@@ -28,7 +28,7 @@ from hypothesis.strategies import (
28
28
  permutations,
29
29
  sampled_from,
30
30
  )
31
- from pytest import approx, mark, param, raises
31
+ from pytest import LogCaptureFixture, approx, mark, param, raises
32
32
 
33
33
  from utilities.asyncio import (
34
34
  AsyncLoopingService,
@@ -42,6 +42,7 @@ from utilities.asyncio import (
42
42
  QueueProcessor,
43
43
  UniquePriorityQueue,
44
44
  UniqueQueue,
45
+ _DurationOrEvery,
45
46
  get_event,
46
47
  get_items,
47
48
  get_items_nowait,
@@ -54,7 +55,12 @@ from utilities.asyncio import (
54
55
  timeout_dur,
55
56
  )
56
57
  from utilities.dataclasses import replace_non_sentinel
57
- from utilities.datetime import MILLISECOND, datetime_duration_to_timedelta, get_now
58
+ from utilities.datetime import (
59
+ MILLISECOND,
60
+ MINUTE,
61
+ datetime_duration_to_timedelta,
62
+ get_now,
63
+ )
58
64
  from utilities.hypothesis import sentinels, text_ascii
59
65
  from utilities.iterables import one, unique_everseen
60
66
  from utilities.pytest import skipif_windows
@@ -343,8 +349,8 @@ class TestGetEvent:
343
349
 
344
350
 
345
351
  class TestInfiniteLooper:
346
- @given(n=integers(10, 11))
347
- async def test_main(self, *, n: int) -> None:
352
+ @given(n=integers(10, 11), sleep_core=sampled_from([0.1, ("every", 0.1)]))
353
+ async def test_main(self, *, n: int, sleep_core: _DurationOrEvery) -> None:
348
354
  class TrueError(BaseException): ...
349
355
 
350
356
  class FalseError(BaseException): ...
@@ -370,7 +376,7 @@ class TestInfiniteLooper:
370
376
  yield (True, TrueError)
371
377
  yield (False, FalseError)
372
378
 
373
- looper = Example(sleep_core=0.1)
379
+ looper = Example(sleep_core=sleep_core)
374
380
  match n % 2 == 0:
375
381
  case True:
376
382
  with raises(TrueError):
@@ -522,7 +528,24 @@ class TestInfiniteLooper:
522
528
  assert 1 <= looper.counter <= 6
523
529
 
524
530
  @given(logger=just("logger") | none())
525
- async def test_error_upon_initialize(self, *, logger: str | None) -> None:
531
+ @mark.parametrize(
532
+ ("sleep_restart", "desc"),
533
+ [
534
+ (60.0, "for 0:01:00"),
535
+ (MINUTE, "for 0:01:00"),
536
+ (("every", 60), "until next 0:01:00"),
537
+ (("every", MINUTE), "until next 0:01:00"),
538
+ ],
539
+ )
540
+ @settings(suppress_health_check={HealthCheck.function_scoped_fixture})
541
+ async def test_error_upon_initialize(
542
+ self,
543
+ *,
544
+ sleep_restart: _DurationOrEvery,
545
+ desc: str,
546
+ logger: str | None,
547
+ caplog: LogCaptureFixture,
548
+ ) -> None:
526
549
  class CustomError(Exception): ...
527
550
 
528
551
  @dataclass(kw_only=True)
@@ -535,13 +558,34 @@ class TestInfiniteLooper:
535
558
  async def _core(self) -> None:
536
559
  raise NotImplementedError
537
560
 
538
- looper = Example(sleep_core=0.1, logger=logger)
561
+ looper = Example(sleep_core=0.1, sleep_restart=sleep_restart, logger=logger)
539
562
  with raises(TimeoutError):
540
563
  async with timeout_dur(duration=0.5):
541
564
  _ = await looper()
565
+ if logger is not None:
566
+ message = caplog.messages[0]
567
+ expected = f"'Example' encountered 'CustomError()' whilst initializing; sleeping {desc}..."
568
+ assert message == expected
542
569
 
543
570
  @given(logger=just("logger") | none())
544
- async def test_error_group_upon_coroutines(self, *, logger: str | None) -> None:
571
+ @mark.parametrize(
572
+ ("sleep_restart", "desc"),
573
+ [
574
+ (60.0, "for 0:01:00"),
575
+ (MINUTE, "for 0:01:00"),
576
+ (("every", 60), "until next 0:01:00"),
577
+ (("every", MINUTE), "until next 0:01:00"),
578
+ ],
579
+ )
580
+ @settings(suppress_health_check={HealthCheck.function_scoped_fixture})
581
+ async def test_error_group_upon_coroutines(
582
+ self,
583
+ *,
584
+ sleep_restart: _DurationOrEvery,
585
+ desc: str,
586
+ logger: str | None,
587
+ caplog: LogCaptureFixture,
588
+ ) -> None:
545
589
  class CustomError(Exception): ...
546
590
 
547
591
  @dataclass(kw_only=True)
@@ -556,10 +600,14 @@ class TestInfiniteLooper:
556
600
  ) -> Iterator[tuple[None, MaybeType[BaseException]]]:
557
601
  yield (None, CustomError)
558
602
 
559
- looper = Example(sleep_core=0.1, logger=logger)
603
+ looper = Example(sleep_core=0.1, sleep_restart=sleep_restart, logger=logger)
560
604
  with raises(TimeoutError):
561
605
  async with timeout_dur(duration=0.5):
562
606
  _ = await looper()
607
+ if logger is not None:
608
+ message = caplog.messages[0]
609
+ expected = f"'Example' encountered 'CustomError()'; sleeping {desc}..."
610
+ assert message == expected
563
611
 
564
612
  async def test_error_no_event_found(self) -> None:
565
613
  @dataclass(kw_only=True)
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.117.0"
3
+ __version__ = "0.117.1"
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import datetime as dt
3
4
  from abc import ABC, abstractmethod
4
5
  from asyncio import (
5
6
  CancelledError,
@@ -32,6 +33,7 @@ from typing import (
32
33
  TYPE_CHECKING,
33
34
  Any,
34
35
  Generic,
36
+ Literal,
35
37
  NoReturn,
36
38
  Self,
37
39
  TextIO,
@@ -46,6 +48,7 @@ from utilities.datetime import (
46
48
  MINUTE,
47
49
  SECOND,
48
50
  datetime_duration_to_float,
51
+ datetime_duration_to_timedelta,
49
52
  get_now,
50
53
  round_datetime,
51
54
  )
@@ -62,7 +65,6 @@ from utilities.types import (
62
65
  )
63
66
 
64
67
  if TYPE_CHECKING:
65
- import datetime as dt
66
68
  from asyncio import _CoroutineLike
67
69
  from asyncio.subprocess import Process
68
70
  from collections.abc import AsyncIterator, Sequence
@@ -337,12 +339,15 @@ class ExceptionProcessor(QueueProcessor[Exception | type[Exception]]):
337
339
  ##
338
340
 
339
341
 
342
+ type _DurationOrEvery = Duration | tuple[Literal["every"], Duration]
343
+
344
+
340
345
  @dataclass(kw_only=True, unsafe_hash=True)
341
346
  class InfiniteLooper(ABC, Generic[THashable]):
342
347
  """An infinite loop which can throw exceptions by setting events."""
343
348
 
344
- sleep_core: Duration = SECOND
345
- sleep_restart: Duration = MINUTE
349
+ sleep_core: _DurationOrEvery = SECOND
350
+ sleep_restart: _DurationOrEvery = MINUTE
346
351
  logger: str | None = None
347
352
  _events: Mapping[THashable, Event] = field(
348
353
  default_factory=dict, init=False, repr=False, hash=False
@@ -369,7 +374,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
369
374
  await self._initialize()
370
375
  except Exception as error: # noqa: BLE001
371
376
  self._error_upon_initialize(error)
372
- await sleep_dur(duration=self.sleep_restart)
377
+ await self._run_sleep(self.sleep_restart)
373
378
  else:
374
379
  while True:
375
380
  try:
@@ -380,14 +385,14 @@ class InfiniteLooper(ABC, Generic[THashable]):
380
385
  )
381
386
  except StopIteration:
382
387
  await self._core()
383
- await sleep_dur(duration=self.sleep_core)
388
+ await self._run_sleep(self.sleep_core)
384
389
  else:
385
390
  self._raise_error(event)
386
391
  except InfiniteLooperError:
387
392
  raise
388
393
  except Exception as error: # noqa: BLE001
389
394
  self._error_upon_core(error)
390
- await sleep_dur(duration=self.sleep_restart)
395
+ await self._run_sleep(self.sleep_restart)
391
396
 
392
397
  async def _run_looper_with_coroutines(
393
398
  self, *coroutines: Callable[[], Coroutine1[None]]
@@ -401,7 +406,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
401
406
  _ = [tg.create_task(c()) for c in coroutines]
402
407
  except ExceptionGroup as error:
403
408
  self._error_group_upon_coroutines(error)
404
- await sleep_dur(duration=self.sleep_restart)
409
+ await self._run_sleep(self.sleep_restart)
405
410
 
406
411
  async def _initialize(self) -> None:
407
412
  """Initialize the loop."""
@@ -413,20 +418,20 @@ class InfiniteLooper(ABC, Generic[THashable]):
413
418
  """Handle any errors upon initializing the looper."""
414
419
  if self.logger is not None:
415
420
  getLogger(name=self.logger).error(
416
- "%r encountered %r whilst initializing; sleeping for %s...",
421
+ "%r encountered %r whilst initializing; sleeping %s...",
417
422
  get_class_name(self),
418
423
  repr_error(error),
419
- self.sleep_restart,
424
+ self._sleep_restart_desc,
420
425
  )
421
426
 
422
427
  def _error_upon_core(self, error: Exception, /) -> None:
423
428
  """Handle any errors upon running the core function."""
424
429
  if self.logger is not None:
425
430
  getLogger(name=self.logger).error(
426
- "%r encountered %r; sleeping for %s...",
431
+ "%r encountered %r; sleeping %s...",
427
432
  get_class_name(self),
428
433
  repr_error(error),
429
- self.sleep_restart,
434
+ self._sleep_restart_desc,
430
435
  )
431
436
 
432
437
  def _error_group_upon_coroutines(self, group: ExceptionGroup, /) -> None:
@@ -439,7 +444,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
439
444
  f"- Error #{i}/{n}: {repr_error(e)}"
440
445
  for i, e in enumerate(errors, start=1)
441
446
  )
442
- msgs.append(f"Sleeping for {self.sleep_restart}...")
447
+ msgs.append(f"Sleeping {self._sleep_restart_desc}...")
443
448
  getLogger(name=self.logger).error("\n".join(msgs))
444
449
 
445
450
  def _raise_error(self, event: THashable, /) -> NoReturn:
@@ -454,6 +459,29 @@ class InfiniteLooper(ABC, Generic[THashable]):
454
459
  event: Event() for event, _ in self._yield_events_and_exceptions()
455
460
  }
456
461
 
462
+ async def _run_sleep(self, sleep: _DurationOrEvery, /) -> None:
463
+ """Sleep until the next part of the loop."""
464
+ match sleep:
465
+ case int() | float() | dt.timedelta() as duration:
466
+ await sleep_dur(duration=duration)
467
+ case "every", (int() | float() | dt.timedelta()) as duration:
468
+ await sleep_until_rounded(duration)
469
+ case _ as never:
470
+ assert_never(never)
471
+
472
+ @property
473
+ def _sleep_restart_desc(self) -> str:
474
+ """Get a description of the sleep until restart."""
475
+ match self.sleep_restart:
476
+ case int() | float() | dt.timedelta() as duration:
477
+ timedelta = datetime_duration_to_timedelta(duration)
478
+ return f"for {timedelta}"
479
+ case "every", (int() | float() | dt.timedelta()) as duration:
480
+ timedelta = datetime_duration_to_timedelta(duration)
481
+ return f"until next {timedelta}"
482
+ case _ as never:
483
+ assert_never(never)
484
+
457
485
  def _set_event(self, event: THashable, /) -> None:
458
486
  """Set the given event."""
459
487
  try: