dycw-utilities 0.123.0__tar.gz → 0.124.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 (223) hide show
  1. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/PKG-INFO +3 -3
  2. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/pyproject.toml +5 -5
  3. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_asyncio.py +119 -61
  4. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_more_itertools.py +29 -0
  5. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_redis.py +2 -2
  6. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sqlalchemy.py +1 -1
  7. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/__init__.py +1 -1
  8. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/asyncio.py +179 -41
  9. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/more_itertools.py +62 -6
  10. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/redis.py +2 -2
  11. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/slack_sdk.py +6 -10
  12. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sqlalchemy.py +2 -1
  13. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/.gitignore +0 -0
  14. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/LICENSE +0 -0
  15. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/README.md +0 -0
  16. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/__init__.py +0 -0
  17. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/conftest.py +0 -0
  18. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/__init__.py +0 -0
  19. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_missing/__init__.py +0 -0
  20. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_missing/module.py +0 -0
  21. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/__init__.py +0 -0
  22. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/outer_1.py +0 -0
  23. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/outer_2.py +0 -0
  24. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  25. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  26. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  27. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  28. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/__init__.py +0 -0
  29. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/module_1.py +0 -0
  30. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/module_2.py +0 -0
  31. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/standalone.py +0 -0
  32. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/with_imports.py +0 -0
  33. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  34. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  35. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  36. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  37. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  38. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  39. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  40. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  41. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_altair.py +0 -0
  42. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_astor.py +0 -0
  43. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_atomicwrites.py +0 -0
  44. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_atools.py +0 -0
  45. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cachetools.py +0 -0
  46. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_click.py +0 -0
  47. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_concurrent.py +0 -0
  48. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_contextlib.py +0 -0
  49. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_contextvars.py +0 -0
  50. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cryptography.py +0 -0
  51. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cvxpy.py +0 -0
  52. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_dataclasses.py +0 -0
  53. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_datetime.py +0 -0
  54. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_enum.py +0 -0
  55. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_errors.py +0 -0
  56. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_eventkit.py +0 -0
  57. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_fastapi.py +0 -0
  58. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_fpdf2.py +0 -0
  59. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_functions.py +0 -0
  60. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_functools.py +0 -0
  61. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_getpass.py +0 -0
  62. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_git.py +0 -0
  63. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_hashlib.py +0 -0
  64. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_http.py +0 -0
  65. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_hypothesis.py +0 -0
  66. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_importlib.py +0 -0
  67. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_ipython.py +0 -0
  68. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_iterables.py +0 -0
  69. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_jupyter.py +0 -0
  70. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_lightweight_charts.py +0 -0
  71. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_logging.py +0 -0
  72. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_loguru.py +0 -0
  73. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_luigi.py +0 -0
  74. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_math.py +0 -0
  75. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_memory_profiler.py +0 -0
  76. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_modules.py +0 -0
  77. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_numpy.py +0 -0
  78. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_period.py +0 -0
  85. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pickle.py +0 -0
  86. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_platform.py +0 -0
  87. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_polars.py +0 -0
  88. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_polars_ols.py +0 -0
  89. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pqdm.py +0 -0
  90. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pydantic.py +0 -0
  91. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pyrsistent.py +0 -0
  93. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_python_dotenv.py +0 -0
  96. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_reprlib.py +0 -0
  99. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_rich.py +0 -0
  100. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_scipy.py +0 -0
  101. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sentinel.py +0 -0
  102. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_shelve.py +0 -0
  103. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_slack_sdk.py +0 -0
  104. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_socket.py +0 -0
  105. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sqlalchemy_polars.py +0 -0
  106. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_statsmodel.py +0 -0
  107. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_streamlit.py +0 -0
  108. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sys.py +0 -0
  109. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tempfile.py +0 -0
  110. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tenacity.py +0 -0
  111. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_text.py +0 -0
  112. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_threading.py +0 -0
  113. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_timer.py +0 -0
  114. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback.py +0 -0
  115. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/__init__.py +0 -0
  116. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/chain.py +0 -0
  117. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  118. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  119. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  120. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/many.py +0 -0
  121. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/one.py +0 -0
  122. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/recursive.py +0 -0
  123. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  124. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  125. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/two.py +0 -0
  126. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/untraced.py +0 -0
  127. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_types.py +0 -0
  128. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing.py +0 -0
  129. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/__init__.py +0 -0
  130. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/no_future.py +0 -0
  131. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/with_future.py +0 -0
  132. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tzdata.py +0 -0
  133. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tzlocal.py +0 -0
  134. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_uuid.py +0 -0
  135. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_version.py +0 -0
  136. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_warnings.py +0 -0
  137. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_whenever.py +0 -0
  138. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_zipfile.py +0 -0
  139. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_zoneinfo.py +0 -0
  140. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/altair.py +0 -0
  141. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/astor.py +0 -0
  142. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/atomicwrites.py +0 -0
  143. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/atools.py +0 -0
  144. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cachetools.py +0 -0
  145. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/click.py +0 -0
  146. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/concurrent.py +0 -0
  147. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/contextlib.py +0 -0
  148. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/contextvars.py +0 -0
  149. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cryptography.py +0 -0
  150. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cvxpy.py +0 -0
  151. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/dataclasses.py +0 -0
  152. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/datetime.py +0 -0
  153. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/enum.py +0 -0
  154. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/errors.py +0 -0
  155. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/eventkit.py +0 -0
  156. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/fastapi.py +0 -0
  157. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/fpdf2.py +0 -0
  158. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/functions.py +0 -0
  159. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/functools.py +0 -0
  160. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/getpass.py +0 -0
  161. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/git.py +0 -0
  162. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/hashlib.py +0 -0
  163. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/http.py +0 -0
  164. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/hypothesis.py +0 -0
  165. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/importlib.py +0 -0
  166. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/ipython.py +0 -0
  167. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/iterables.py +0 -0
  168. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/jupyter.py +0 -0
  169. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/lightweight_charts.py +0 -0
  170. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/logging.py +0 -0
  171. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/loguru.py +0 -0
  172. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/luigi.py +0 -0
  173. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/math.py +0 -0
  174. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/memory_profiler.py +0 -0
  175. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/modules.py +0 -0
  176. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/numpy.py +0 -0
  177. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/operator.py +0 -0
  178. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/optuna.py +0 -0
  179. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/orjson.py +0 -0
  180. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/os.py +0 -0
  181. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/parse.py +0 -0
  182. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pathlib.py +0 -0
  183. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/period.py +0 -0
  184. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pickle.py +0 -0
  185. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/platform.py +0 -0
  186. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/polars.py +0 -0
  187. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/polars_ols.py +0 -0
  188. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pqdm.py +0 -0
  189. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/py.typed +0 -0
  190. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pydantic.py +0 -0
  191. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pyinstrument.py +0 -0
  192. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pyrsistent.py +0 -0
  193. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pytest.py +0 -0
  194. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pytest_regressions.py +0 -0
  195. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/python_dotenv.py +0 -0
  196. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/random.py +0 -0
  197. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/re.py +0 -0
  198. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/reprlib.py +0 -0
  199. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/rich.py +0 -0
  200. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/scipy.py +0 -0
  201. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sentinel.py +0 -0
  202. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/shelve.py +0 -0
  203. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/socket.py +0 -0
  204. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sqlalchemy_polars.py +0 -0
  205. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/statsmodels.py +0 -0
  206. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/streamlit.py +0 -0
  207. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sys.py +0 -0
  208. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tempfile.py +0 -0
  209. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tenacity.py +0 -0
  210. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/text.py +0 -0
  211. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/threading.py +0 -0
  212. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/timer.py +0 -0
  213. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/traceback.py +0 -0
  214. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/types.py +0 -0
  215. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/typing.py +0 -0
  216. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tzdata.py +0 -0
  217. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tzlocal.py +0 -0
  218. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/uuid.py +0 -0
  219. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/version.py +0 -0
  220. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/warnings.py +0 -0
  221. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/whenever.py +0 -0
  222. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/zipfile.py +0 -0
  223. {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/zoneinfo.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.123.0
3
+ Version: 0.124.1
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
7
  Requires-Dist: typing-extensions<4.14,>=4.13.1
8
8
  Provides-Extra: test
9
- Requires-Dist: hypothesis<6.132,>=6.131.21; extra == 'test'
9
+ Requires-Dist: hypothesis<6.132,>=6.131.24; extra == 'test'
10
10
  Requires-Dist: pytest-asyncio<0.27,>=0.26.0; extra == 'test'
11
11
  Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
12
12
  Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
@@ -80,7 +80,7 @@ Provides-Extra: zzz-test-hypothesis
80
80
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
81
81
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
82
82
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
83
- Requires-Dist: hypothesis<6.132,>=6.131.21; extra == 'zzz-test-hypothesis'
83
+ Requires-Dist: hypothesis<6.132,>=6.131.24; extra == 'zzz-test-hypothesis'
84
84
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
85
85
  Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
86
86
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
@@ -26,7 +26,7 @@ dev = [
26
26
  "fpdf2 >= 2.8.3, < 2.9",
27
27
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
28
28
  "httpx >= 0.28.1, < 0.29", # for fastapi
29
- "hypothesis >= 6.131.21, < 6.132",
29
+ "hypothesis >= 6.131.24, < 6.132",
30
30
  "img2pdf >= 0.6.0, < 0.7",
31
31
  "lightweight-charts >= 2.1, < 2.2",
32
32
  "loguru >= 0.7.3, < 0.8",
@@ -92,11 +92,11 @@ dependencies = [
92
92
  name = "dycw-utilities"
93
93
  readme = "README.md"
94
94
  requires-python = ">= 3.12"
95
- version = "0.123.0"
95
+ version = "0.124.1"
96
96
 
97
97
  [project.optional-dependencies]
98
98
  test = [
99
- "hypothesis >= 6.131.21, < 6.132",
99
+ "hypothesis >= 6.131.24, < 6.132",
100
100
  "pytest >= 8.3.5, < 8.4",
101
101
  "pytest-asyncio >= 0.26.0, < 0.27",
102
102
  "pytest-cov >= 6.1.1, < 6.2",
@@ -174,7 +174,7 @@ zzz-test-hypothesis = [
174
174
  "aiosqlite >= 0.21.0, < 0.22",
175
175
  "asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
176
176
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
177
- "hypothesis >= 6.131.21, < 6.132",
177
+ "hypothesis >= 6.131.24, < 6.132",
178
178
  "luigi >= 3.6.0, < 3.7",
179
179
  "numpy >= 2.2.6, < 2.3",
180
180
  "pathvalidate >= 3.2.3, < 3.3",
@@ -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.123.0"
337
+ current_version = "0.124.1"
338
338
 
339
339
  [[tool.bumpversion.files]]
340
340
  filename = "src/utilities/__init__.py"
@@ -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,6 +68,77 @@ 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
143
  async def test_create_task_context_coroutine(self) -> None:
70
144
  flag: bool = False
@@ -175,6 +249,24 @@ class TestGetEvent:
175
249
  assert get_event(event=lambda: event) is event
176
250
 
177
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
+
178
270
  class TestInfiniteLooper:
179
271
  sleep_restart_cases: ClassVar[list[Any]] = [
180
272
  param(60.0, "for 0:01:00"),
@@ -386,9 +478,9 @@ class TestInfiniteLooper:
386
478
  Example(sleep_core=0.05, sleep_restart=0.05) as looper,
387
479
  ):
388
480
  ...
389
- assert 4 <= looper.initializations <= 6
390
- assert 0 <= looper.counter <= 7
391
- assert 14 <= external <= 21
481
+ assert 3 <= looper.initializations <= 7
482
+ assert 0 <= looper.counter <= 8
483
+ assert 13 <= external <= 22
392
484
 
393
485
  async def test_with_coroutine_self_error(self) -> None:
394
486
  class CustomError(Exception): ...
@@ -661,13 +753,13 @@ class TestInfiniteQueueLooper:
661
753
  counter: int = 0
662
754
 
663
755
  @override
664
- async def _process_items(self, *items: int) -> None:
665
- self.counter += len(items)
756
+ async def _process_queue(self) -> None:
757
+ self.counter += len(self._queue.get_all_nowait())
666
758
 
667
759
  async with timeout_dur(duration=1.0), Example(sleep_core=0.05) as looper:
668
760
  await sleep(0.1)
669
761
  for i in range(10):
670
- looper.put_items_nowait(i)
762
+ looper.put_right_nowait(i)
671
763
  await sleep(0.05)
672
764
 
673
765
  assert looper.counter == 10
@@ -678,13 +770,13 @@ class TestInfiniteQueueLooper:
678
770
  output: set[int] = field(default_factory=set)
679
771
 
680
772
  @override
681
- async def _process_items(self, *items: int) -> None:
682
- self.output.update(items)
773
+ async def _process_queue(self) -> None:
774
+ self.output.update(self._queue.get_all_nowait())
683
775
 
684
776
  looper = Example(sleep_core=0.05)
685
777
  assert len(looper) == 0
686
778
  assert looper.empty()
687
- looper.put_items_nowait(*range(n))
779
+ looper.put_right_nowait(*range(n))
688
780
  assert len(looper) == n
689
781
  assert not looper.empty()
690
782
 
@@ -694,11 +786,11 @@ class TestInfiniteQueueLooper:
694
786
  output: set[int] = field(default_factory=set)
695
787
 
696
788
  @override
697
- async def _process_items(self, *items: int) -> None:
698
- self.output.update(items)
789
+ async def _process_queue(self) -> None:
790
+ self.output.update(self._queue.get_all_nowait())
699
791
 
700
792
  looper = Example(sleep_core=0.05)
701
- looper.put_items_nowait(*range(10))
793
+ looper.put_right_nowait(*range(10))
702
794
  async with looper:
703
795
  await looper.run_until_empty()
704
796
  assert looper.empty()
@@ -715,66 +807,32 @@ class TestInfiniteQueueLooper:
715
807
  output: set[int] = field(default_factory=set)
716
808
 
717
809
  @override
718
- async def _process_items(self, *items: int) -> None:
719
- raise CustomError(*items)
810
+ async def _process_queue(self) -> None:
811
+ raise CustomError
720
812
 
721
813
  async with (
722
814
  timeout_dur(duration=1.0),
723
815
  Example(sleep_core=0.05, logger=logger) as looper,
724
816
  ):
725
- looper.put_items_nowait(1)
817
+ looper.put_left_nowait(1)
726
818
  if logger is not None:
727
819
  message = caplog.messages[0]
728
- 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..."
729
821
  assert message == expected
730
822
 
731
823
 
732
- class TestPutAndGetItems:
733
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
734
- 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:
735
827
  queue: Queue[int] = Queue()
736
- await put_items(xs, queue)
737
- result = await get_items(queue, max_size=max_size)
738
- if max_size is None:
739
- assert result == xs
828
+ if wait:
829
+ put_items_nowait(xs, queue)
740
830
  else:
741
- assert result == xs[:max_size]
742
-
743
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
744
- async def test_get_then_put(self, *, xs: list[int], max_size: int | None) -> None:
745
- queue: Queue[int] = Queue()
746
-
747
- async def put() -> None:
748
- await sleep(0.01)
749
831
  await put_items(xs, queue)
750
-
751
- async with TaskGroup() as tg:
752
- task = tg.create_task(get_items(queue, max_size=max_size))
753
- _ = tg.create_task(put())
754
- result = task.result()
755
- if max_size is None:
756
- assert result == xs
757
- else:
758
- assert result == xs[:max_size]
759
-
760
- async def test_empty(self) -> None:
761
- queue: Queue[int] = Queue()
762
- with raises(TimeoutError): # noqa: PT012
763
- async with timeout(0.01), TaskGroup() as tg:
764
- _ = tg.create_task(get_items(queue))
765
- _ = tg.create_task(sleep(0.02))
766
-
767
-
768
- class TestPutAndGetItemsNoWait:
769
- @given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
770
- def test_main(self, *, xs: list[int], max_size: int | None) -> None:
771
- queue: Queue[int] = Queue()
772
- put_items_nowait(xs, queue)
773
- result = get_items_nowait(queue, max_size=max_size)
774
- if max_size is None:
775
- assert result == xs
776
- else:
777
- assert result == xs[:max_size]
832
+ result: list[int] = []
833
+ while not queue.empty():
834
+ result.append(await queue.get())
835
+ assert result == xs
778
836
 
779
837
 
780
838
  class TestUniquePriorityQueue:
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Iterator
3
4
  from typing import TYPE_CHECKING, Any, ClassVar, TypeGuard
4
5
 
5
6
  from pytest import mark, param, raises
@@ -24,17 +25,45 @@ class TestBucketMapping:
24
25
  def test_main(self) -> None:
25
26
  mapping = bucket_mapping(self.iterable, lambda x: x[0])
26
27
  assert set(mapping) == {"a", "b", "c"}
28
+ for value in mapping.values():
29
+ assert isinstance(value, Iterator)
30
+ assert not isinstance(value, list)
27
31
  assert list(mapping["a"]) == ["a1", "a2"]
28
32
  assert list(mapping["b"]) == ["b1", "b2", "b3"]
29
33
  assert list(mapping["c"]) == ["c1", "c2"]
30
34
 
35
+ def test_transform(self) -> None:
36
+ mapping = bucket_mapping(
37
+ self.iterable, lambda x: x[0], transform=lambda x: int(x[-1])
38
+ )
39
+ assert set(mapping) == {"a", "b", "c"}
40
+ for value in mapping.values():
41
+ assert isinstance(value, Iterator)
42
+ assert not isinstance(value, list)
43
+ assert list(mapping["a"]) == [1, 2]
44
+ assert list(mapping["b"]) == [1, 2, 3]
45
+ assert list(mapping["c"]) == [1, 2]
46
+
31
47
  def test_list(self) -> None:
32
48
  mapping = bucket_mapping(self.iterable, lambda x: x[0], list=True)
33
49
  assert set(mapping) == {"a", "b", "c"}
50
+ for value in mapping.values():
51
+ assert isinstance(value, list)
34
52
  assert mapping["a"] == ["a1", "a2"]
35
53
  assert mapping["b"] == ["b1", "b2", "b3"]
36
54
  assert mapping["c"] == ["c1", "c2"]
37
55
 
56
+ def test_transform_and_list(self) -> None:
57
+ mapping = bucket_mapping(
58
+ self.iterable, lambda x: x[0], transform=lambda x: int(x[-1]), list=True
59
+ )
60
+ assert set(mapping) == {"a", "b", "c"}
61
+ for value in mapping.values():
62
+ assert isinstance(value, list)
63
+ assert mapping["a"] == [1, 2]
64
+ assert mapping["b"] == [1, 2, 3]
65
+ assert mapping["c"] == [1, 2]
66
+
38
67
 
39
68
  class TestPartitionList:
40
69
  def test_main(self) -> None:
@@ -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.123.0"
3
+ __version__ = "0.124.1"