dycw-utilities 0.166.25__tar.gz → 0.166.27__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 (217) hide show
  1. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/PKG-INFO +3 -3
  2. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/pyproject.toml +7 -7
  3. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_asyncio.py +64 -5
  4. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_iterables.py +15 -12
  5. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/asyncio.py +63 -0
  7. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/iterables.py +1 -1
  8. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/.gitignore +0 -0
  9. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/LICENSE +0 -0
  10. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/README.md +0 -0
  11. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/__init__.py +0 -0
  12. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/conftest.py +0 -0
  13. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/__init__.py +0 -0
  14. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_missing/__init__.py +0 -0
  15. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_missing/module.py +0 -0
  16. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/__init__.py +0 -0
  17. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/outer_1.py +0 -0
  18. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/outer_2.py +0 -0
  19. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  20. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  21. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  22. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  23. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_without/__init__.py +0 -0
  24. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_without/module_1.py +0 -0
  25. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/package_without/module_2.py +0 -0
  26. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/standalone.py +0 -0
  27. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/modules/with_imports.py +0 -0
  28. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  29. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  30. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  31. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  32. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  33. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  34. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  35. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  36. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_aeventkit.py +0 -0
  37. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_altair.py +0 -0
  38. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_atomicwrites.py +0 -0
  39. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_atools.py +0 -0
  40. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_cachetools.py +0 -0
  41. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_click.py +0 -0
  42. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_concurrent.py +0 -0
  43. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_contextlib.py +0 -0
  44. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_contextvars.py +0 -0
  45. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_cryptography.py +0 -0
  46. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_cvxpy.py +0 -0
  47. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_dataclasses.py +0 -0
  48. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_enum.py +0 -0
  49. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_errors.py +0 -0
  50. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_fastapi.py +0 -0
  51. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_fpdf2.py +0 -0
  52. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_functions.py +0 -0
  53. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_functools.py +0 -0
  54. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_getpass.py +0 -0
  55. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_git.py +0 -0
  56. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_gzip.py +0 -0
  57. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_hashlib.py +0 -0
  58. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_http.py +0 -0
  59. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_hypothesis.py +0 -0
  60. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_importlib.py +0 -0
  61. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_inflect.py +0 -0
  62. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_ipython.py +0 -0
  63. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_json.py +0 -0
  64. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_jupyter.py +0 -0
  65. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_libcst.py +0 -0
  66. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_lightweight_charts.py +0 -0
  67. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_logging.py +0 -0
  68. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_math.py +0 -0
  69. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_memory_profiler.py +0 -0
  70. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_modules.py +0 -0
  71. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_more_itertools.py +0 -0
  72. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_numpy.py +0 -0
  73. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_objects/__init__.py +0 -0
  74. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_objects/objects.py +0 -0
  75. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_operator.py +0 -0
  76. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_optuna.py +0 -0
  77. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_orjson.py +0 -0
  78. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_os.py +0 -0
  79. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_parse.py +0 -0
  80. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pathlib.py +0 -0
  81. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pickle.py +0 -0
  82. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_platform.py +0 -0
  83. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_polars.py +0 -0
  84. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_polars_ols.py +0 -0
  85. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_postgres.py +0 -0
  86. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pottery.py +0 -0
  87. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pqdm.py +0 -0
  88. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_psutil.py +0 -0
  89. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pydantic_settings.py +0 -0
  90. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pydantic_settings_sops.py +0 -0
  91. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pytest.py +0 -0
  93. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pytest_randomly.py +0 -0
  94. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_random.py +0 -0
  96. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_re.py +0 -0
  97. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_redis.py +0 -0
  98. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_reprlib.py +0 -0
  99. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_scipy.py +0 -0
  100. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_sentinel.py +0 -0
  101. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_shelve.py +0 -0
  102. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_sqlalchemy.py +0 -0
  105. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_sqlalchemy_polars.py +0 -0
  106. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_statsmodels.py +0 -0
  107. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_string.py +0 -0
  108. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_tempfile.py +0 -0
  109. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_testbook.py +0 -0
  110. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_text.py +0 -0
  111. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_threading.py +0 -0
  112. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_timer.py +0 -0
  113. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_traceback.py +0 -0
  114. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_typed_settings.py +0 -0
  115. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_types.py +0 -0
  116. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_typing.py +0 -0
  117. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_typing_funcs/__init__.py +0 -0
  118. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_typing_funcs/no_future.py +0 -0
  119. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_typing_funcs/with_future.py +0 -0
  120. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_tzdata.py +0 -0
  121. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_tzlocal.py +0 -0
  122. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_uuid.py +0 -0
  123. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_version.py +0 -0
  124. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_warnings.py +0 -0
  125. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_whenever.py +0 -0
  126. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_zipfile.py +0 -0
  127. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/tests/test_zoneinfo.py +0 -0
  128. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/aeventkit.py +0 -0
  129. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/altair.py +0 -0
  130. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/atomicwrites.py +0 -0
  131. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/atools.py +0 -0
  132. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/cachetools.py +0 -0
  133. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/click.py +0 -0
  134. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/concurrent.py +0 -0
  135. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/contextlib.py +0 -0
  136. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/contextvars.py +0 -0
  137. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/cryptography.py +0 -0
  138. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/cvxpy.py +0 -0
  139. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/dataclasses.py +0 -0
  140. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/enum.py +0 -0
  141. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/errors.py +0 -0
  142. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/fastapi.py +0 -0
  143. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/fpdf2.py +0 -0
  144. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/functions.py +0 -0
  145. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/functools.py +0 -0
  146. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/getpass.py +0 -0
  147. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/git.py +0 -0
  148. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/gzip.py +0 -0
  149. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/hashlib.py +0 -0
  150. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/http.py +0 -0
  151. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/hypothesis.py +0 -0
  152. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/importlib.py +0 -0
  153. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/inflect.py +0 -0
  154. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/ipython.py +0 -0
  155. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/json.py +0 -0
  156. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/jupyter.py +0 -0
  157. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/libcst.py +0 -0
  158. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/lightweight_charts.py +0 -0
  159. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/logging.py +0 -0
  160. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/math.py +0 -0
  161. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/memory_profiler.py +0 -0
  162. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/modules.py +0 -0
  163. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/more_itertools.py +0 -0
  164. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/numpy.py +0 -0
  165. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/operator.py +0 -0
  166. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/optuna.py +0 -0
  167. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/orjson.py +0 -0
  168. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/os.py +0 -0
  169. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/parse.py +0 -0
  170. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pathlib.py +0 -0
  171. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pickle.py +0 -0
  172. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/platform.py +0 -0
  173. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/polars.py +0 -0
  174. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/polars_ols.py +0 -0
  175. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/postgres.py +0 -0
  176. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pottery.py +0 -0
  177. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pqdm.py +0 -0
  178. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/psutil.py +0 -0
  179. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/py.typed +0 -0
  180. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pydantic_settings.py +0 -0
  181. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pydantic_settings_sops.py +0 -0
  182. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pyinstrument.py +0 -0
  183. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pytest.py +0 -0
  184. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pytest_plugins/__init__.py +0 -0
  185. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  186. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  187. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/pytest_regressions.py +0 -0
  188. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/random.py +0 -0
  189. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/re.py +0 -0
  190. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/redis.py +0 -0
  191. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/reprlib.py +0 -0
  192. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/scipy.py +0 -0
  193. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/sentinel.py +0 -0
  194. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/shelve.py +0 -0
  195. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/slack_sdk.py +0 -0
  196. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/socket.py +0 -0
  197. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/sqlalchemy.py +0 -0
  198. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/sqlalchemy_polars.py +0 -0
  199. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/statsmodels.py +0 -0
  200. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/string.py +0 -0
  201. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/tempfile.py +0 -0
  202. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/testbook.py +0 -0
  203. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/text.py +0 -0
  204. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/threading.py +0 -0
  205. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/timer.py +0 -0
  206. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/traceback.py +0 -0
  207. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/typed_settings.py +0 -0
  208. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/types.py +0 -0
  209. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/typing.py +0 -0
  210. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/tzdata.py +0 -0
  211. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/tzlocal.py +0 -0
  212. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/uuid.py +0 -0
  213. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/version.py +0 -0
  214. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/warnings.py +0 -0
  215. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/whenever.py +0 -0
  216. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/zipfile.py +0 -0
  217. {dycw_utilities-0.166.25 → dycw_utilities-0.166.27}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.166.25
3
+ Version: 0.166.27
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -13,11 +13,11 @@ Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
13
13
  Provides-Extra: test
14
14
  Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
15
15
  Requires-Dist: hypothesis<6.139,>=6.138.15; extra == 'test'
16
- Requires-Dist: pytest-asyncio<1.2,>=1.1.0; extra == 'test'
16
+ Requires-Dist: pytest-asyncio<1.2,>=1.1.1; extra == 'test'
17
17
  Requires-Dist: pytest-cov<7.1,>=7.0.0; extra == 'test'
18
18
  Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
19
19
  Requires-Dist: pytest-lazy-fixtures<1.4,>=1.3.4; extra == 'test'
20
- Requires-Dist: pytest-randomly<4.1,>=4.0.0; extra == 'test'
20
+ Requires-Dist: pytest-randomly<4.1,>=4.0.1; extra == 'test'
21
21
  Requires-Dist: pytest-regressions<2.9,>=2.8.3; extra == 'test'
22
22
  Requires-Dist: pytest-repeat<0.10,>=0.9.4; extra == 'test'
23
23
  Requires-Dist: pytest-rerunfailures<16.1,>=16.0.1; extra == 'test'
@@ -161,8 +161,8 @@ pyinstrument = [
161
161
  ]
162
162
  pytest = [
163
163
  "pytest >=8.4.2, <8.5",
164
- "pytest-asyncio >=1.1.0, <1.2",
165
- "pytest-randomly >=4.0.0, <4.1",
164
+ "pytest-asyncio >=1.1.1, <1.2",
165
+ "pytest-randomly >=4.0.1, <4.1",
166
166
  "pytest-timeout >=2.4.0, <2.5",
167
167
  "pytest-xdist >=3.8.0, <3.9",
168
168
  ]
@@ -189,7 +189,7 @@ reprlib-test = [
189
189
  "rich",
190
190
  ]
191
191
  scipy = [
192
- "scipy >=1.16.0, <1.17",
192
+ "scipy >=1.16.2, <1.17",
193
193
  ]
194
194
  sklearn = [
195
195
  "scikit-learn >=1.7.2, <1.8",
@@ -246,7 +246,7 @@ dependencies = [
246
246
  name = "dycw-utilities"
247
247
  readme = "README.md"
248
248
  requires-python = ">= 3.12"
249
- version = "0.166.25"
249
+ version = "0.166.27"
250
250
 
251
251
  [project.entry-points.pytest11]
252
252
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -260,11 +260,11 @@ test = [
260
260
  "dycw-pytest-only >=2.1.1, <2.2",
261
261
  "hypothesis >=6.138.15, <6.139",
262
262
  "pytest >=8.4.2, <8.5",
263
- "pytest-asyncio >=1.1.0, <1.2",
263
+ "pytest-asyncio >=1.1.1, <1.2",
264
264
  "pytest-cov >=7.0.0, <7.1",
265
265
  "pytest-instafail >=0.5.0, <0.6",
266
266
  "pytest-lazy-fixtures >=1.3.4, <1.4",
267
- "pytest-randomly >=4.0.0, <4.1",
267
+ "pytest-randomly >=4.0.1, <4.1",
268
268
  "pytest-regressions >=2.8.3, <2.9",
269
269
  "pytest-repeat >=0.9.4, <0.10",
270
270
  "pytest-rerunfailures >=16.0.1, <16.1",
@@ -279,7 +279,7 @@ test = [
279
279
  # bump-my-version
280
280
  [tool.bumpversion]
281
281
  allow_dirty = true
282
- current_version = "0.166.25"
282
+ current_version = "0.166.27"
283
283
 
284
284
  [[tool.bumpversion.files]]
285
285
  filename = "src/utilities/__init__.py"
@@ -1,21 +1,26 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
3
4
  from asyncio import Queue, run
4
- from collections.abc import ItemsView, KeysView, ValuesView
5
+ from collections.abc import AsyncIterable, ItemsView, Iterable, KeysView, ValuesView
5
6
  from contextlib import asynccontextmanager
6
- from re import search
7
- from typing import TYPE_CHECKING, ClassVar
7
+ from re import DOTALL, search
8
+ from typing import TYPE_CHECKING, Any, ClassVar
8
9
 
9
10
  from hypothesis import HealthCheck, given, settings
10
- from hypothesis.strategies import booleans, dictionaries, integers, lists, none
11
- from pytest import RaisesGroup, raises
11
+ from hypothesis.strategies import booleans, dictionaries, integers, lists, none, sets
12
+ from pytest import RaisesGroup, mark, param, raises
12
13
 
13
14
  from utilities.asyncio import (
14
15
  AsyncDict,
15
16
  EnhancedTaskGroup,
17
+ OneAsyncEmptyError,
18
+ OneAsyncNonUniqueError,
19
+ chain_async,
16
20
  get_coroutine_name,
17
21
  get_items,
18
22
  get_items_nowait,
23
+ one_async,
19
24
  put_items,
20
25
  put_items_nowait,
21
26
  sleep_max,
@@ -188,6 +193,26 @@ class TestAsyncDict:
188
193
  assert isinstance(value, int)
189
194
 
190
195
 
196
+ class TestChainAsync:
197
+ @given(n=integers(0, 10))
198
+ async def test_sync(self, *, n: int) -> None:
199
+ it = chain_async(range(n))
200
+ result = [x async for x in it]
201
+ expected = list(range(n))
202
+ assert result == expected
203
+
204
+ @given(n=integers(0, 10))
205
+ async def test_async(self, *, n: int) -> None:
206
+ async def range_async(n: int, /) -> AsyncIterator[int]:
207
+ for i in range(n):
208
+ yield i
209
+
210
+ it = chain_async(range_async(n))
211
+ result = [x async for x in it]
212
+ expected = list(range(n))
213
+ assert result == expected
214
+
215
+
191
216
  class TestEnhancedTaskGroup:
192
217
  delta: ClassVar[TimeDelta] = 0.05 * SECOND
193
218
 
@@ -317,6 +342,40 @@ class TestGetItems:
317
342
  assert result == xs[:max_size]
318
343
 
319
344
 
345
+ class TestOneAsync:
346
+ @mark.parametrize(
347
+ "args", [param(([None],)), param(([None], [])), param(([None], [], []))]
348
+ )
349
+ async def test_main(self, *, args: tuple[Iterable[Any], ...]) -> None:
350
+ assert await one_async(*map(self._lift, args)) is None
351
+
352
+ @mark.parametrize("args", [param([]), param(([], [])), param(([], [], []))])
353
+ async def test_error_empty(self, *, args: tuple[Iterable[Any], ...]) -> None:
354
+ with raises(
355
+ OneAsyncEmptyError,
356
+ match=re.compile(r"Iterable\(s\) .* must not be empty", flags=DOTALL),
357
+ ):
358
+ _ = await one_async(*map(self._lift, args))
359
+
360
+ @given(iterable=sets(integers(), min_size=2))
361
+ async def test_error_non_unique(self, *, iterable: set[int]) -> None:
362
+ with raises(
363
+ OneAsyncNonUniqueError,
364
+ match=re.compile(
365
+ r"Iterable\(s\) .* must contain exactly one item; got .*, .* and perhaps more",
366
+ flags=DOTALL,
367
+ ),
368
+ ):
369
+ _ = await one_async(iterable)
370
+
371
+ def _lift[T](self, iterable: Iterable[T], /) -> AsyncIterable[T]:
372
+ async def lifted() -> AsyncIterator[Any]:
373
+ for i in iterable:
374
+ yield i
375
+
376
+ return lifted()
377
+
378
+
320
379
  class TestPutItems:
321
380
  @given(xs=lists(integers(), min_size=1), wait=booleans())
322
381
  async def test_main(self, *, xs: list[int], wait: bool) -> None:
@@ -885,11 +885,13 @@ class TestMergeStrMappings:
885
885
 
886
886
 
887
887
  class TestOne:
888
- @given(args=sampled_from([([None],), ([None], []), ([None], [], [])]))
888
+ @mark.parametrize(
889
+ "args", [param(([None],)), param(([None], [])), param(([None], [], []))]
890
+ )
889
891
  def test_main(self, *, args: tuple[Iterable[Any], ...]) -> None:
890
892
  assert one(*args) is None
891
893
 
892
- @given(args=sampled_from([([],), ([], []), ([], [], [])]))
894
+ @mark.parametrize("args", [param([]), param(([], [])), param(([], [], []))])
893
895
  def test_error_empty(self, *, args: tuple[Iterable[Any], ...]) -> None:
894
896
  with raises(OneEmptyError, match=r"Iterable\(s\) .* must not be empty"):
895
897
  _ = one(*args)
@@ -907,20 +909,21 @@ class TestOne:
907
909
 
908
910
 
909
911
  class TestOneMaybe:
910
- @given(
911
- args=sampled_from([
912
- (None,),
913
- ([None],),
914
- (None, []),
915
- ([None], []),
916
- (None, []),
917
- ([None], [], []),
918
- ])
912
+ @mark.parametrize(
913
+ "args",
914
+ [
915
+ param((None,)),
916
+ param(([None],)),
917
+ param((None, [])),
918
+ param(([None], [])),
919
+ param((None, [], [])),
920
+ param(([None], [], [])),
921
+ ],
919
922
  )
920
923
  def test_main(self, *, args: tuple[MaybeIterable[Any], ...]) -> None:
921
924
  assert one_maybe(*args) is None
922
925
 
923
- @given(args=sampled_from([([],), ([], []), ([], [], [])]))
926
+ @mark.parametrize("args", [param([]), param(([], [])), param(([], [], []))])
924
927
  def test_error_empty(self, *, args: tuple[MaybeIterable[Any], ...]) -> None:
925
928
  with raises(OneMaybeEmptyError, match=r"Object\(s\) must not be empty"):
926
929
  _ = one_maybe(*args)
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.166.25"
3
+ __version__ = "0.166.27"
@@ -31,6 +31,7 @@ from typing import (
31
31
  Self,
32
32
  TextIO,
33
33
  assert_never,
34
+ cast,
34
35
  overload,
35
36
  override,
36
37
  )
@@ -38,6 +39,7 @@ from typing import (
38
39
  from utilities.functions import ensure_int, ensure_not_none
39
40
  from utilities.os import is_pytest
40
41
  from utilities.random import SYSTEM_RANDOM
42
+ from utilities.reprlib import get_repr
41
43
  from utilities.sentinel import Sentinel, sentinel
42
44
  from utilities.shelve import yield_shelf
43
45
  from utilities.text import to_bool
@@ -48,6 +50,7 @@ if TYPE_CHECKING:
48
50
  from asyncio import _CoroutineLike
49
51
  from asyncio.subprocess import Process
50
52
  from collections.abc import (
53
+ AsyncIterable,
51
54
  AsyncIterator,
52
55
  Callable,
53
56
  ItemsView,
@@ -346,6 +349,24 @@ class EnhancedTaskGroup(TaskGroup):
346
349
  ##
347
350
 
348
351
 
352
+ def chain_async[T](*iterables: Iterable[T] | AsyncIterable[T]) -> AsyncIterator[T]:
353
+ """Asynchronous version of `chain`."""
354
+
355
+ async def iterator() -> AsyncIterator[T]:
356
+ for it in iterables:
357
+ try:
358
+ async for item in cast("AsyncIterable[T]", it):
359
+ yield item
360
+ except TypeError:
361
+ for item in cast("Iterable[T]", it):
362
+ yield item
363
+
364
+ return iterator()
365
+
366
+
367
+ ##
368
+
369
+
349
370
  def get_coroutine_name(func: Callable[[], Coro[Any]], /) -> str:
350
371
  """Get the name of a coroutine, and then dispose of it gracefully."""
351
372
  coro = func()
@@ -394,6 +415,43 @@ def get_items_nowait[T](queue: Queue[T], /, *, max_size: int | None = None) -> l
394
415
  ##
395
416
 
396
417
 
418
+ async def one_async[T](*iterables: Iterable[T] | AsyncIterable[T]) -> T:
419
+ """Asynchronous version of `one`."""
420
+ result: T | Sentinel = sentinel
421
+ async for item in chain_async(*iterables):
422
+ if not isinstance(result, Sentinel):
423
+ raise OneAsyncNonUniqueError(iterables=iterables, first=result, second=item)
424
+ result = item
425
+ if isinstance(result, Sentinel):
426
+ raise OneAsyncEmptyError(iterables=iterables)
427
+ return result
428
+
429
+
430
+ @dataclass(kw_only=True, slots=True)
431
+ class OneAsyncError[T](Exception):
432
+ iterables: tuple[Iterable[T] | AsyncIterable[T], ...]
433
+
434
+
435
+ @dataclass(kw_only=True, slots=True)
436
+ class OneAsyncEmptyError[T](OneAsyncError[T]):
437
+ @override
438
+ def __str__(self) -> str:
439
+ return f"Iterable(s) {get_repr(self.iterables)} must not be empty"
440
+
441
+
442
+ @dataclass(kw_only=True, slots=True)
443
+ class OneAsyncNonUniqueError[T](OneAsyncError):
444
+ first: T
445
+ second: T
446
+
447
+ @override
448
+ def __str__(self) -> str:
449
+ return f"Iterable(s) {get_repr(self.iterables)} must contain exactly one item; got {self.first}, {self.second} and perhaps more"
450
+
451
+
452
+ ##
453
+
454
+
397
455
  async def put_items[T](items: Iterable[T], queue: Queue[T], /) -> None:
398
456
  """Put items into a queue; if full then wait."""
399
457
  for item in items:
@@ -542,10 +600,15 @@ async def yield_locked_shelf(
542
600
  __all__ = [
543
601
  "AsyncDict",
544
602
  "EnhancedTaskGroup",
603
+ "OneAsyncEmptyError",
604
+ "OneAsyncError",
605
+ "OneAsyncNonUniqueError",
545
606
  "StreamCommandOutput",
607
+ "chain_async",
546
608
  "get_coroutine_name",
547
609
  "get_items",
548
610
  "get_items_nowait",
611
+ "one_async",
549
612
  "put_items",
550
613
  "put_items_nowait",
551
614
  "sleep_max",
@@ -933,7 +933,7 @@ class MergeStrMappingsError(Exception):
933
933
 
934
934
  def one[T](*iterables: Iterable[T]) -> T:
935
935
  """Return the unique value in a set of iterables."""
936
- it = iter(chain(*iterables))
936
+ it = chain(*iterables)
937
937
  try:
938
938
  first = next(it)
939
939
  except StopIteration: