dycw-utilities 0.138.7__tar.gz → 0.138.9__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 (215) hide show
  1. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/PKG-INFO +1 -1
  2. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/pyproject.toml +2 -2
  3. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pathlib.py +82 -29
  4. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pytest.py +21 -14
  5. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/hypothesis.py +3 -3
  7. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pathlib.py +90 -24
  8. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pytest.py +8 -8
  9. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pytest_regressions_plugin.py +6 -5
  10. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/traceback.py +2 -2
  11. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/.gitignore +0 -0
  12. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/LICENSE +0 -0
  13. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/README.md +0 -0
  14. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/__init__.py +0 -0
  15. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/conftest.py +0 -0
  16. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/__init__.py +0 -0
  17. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_missing/__init__.py +0 -0
  18. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_missing/module.py +0 -0
  19. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/__init__.py +0 -0
  20. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/outer_1.py +0 -0
  21. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/outer_2.py +0 -0
  22. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  23. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  24. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  25. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  26. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_without/__init__.py +0 -0
  27. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_without/module_1.py +0 -0
  28. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/package_without/module_2.py +0 -0
  29. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/standalone.py +0 -0
  30. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/modules/with_imports.py +0 -0
  31. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  32. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  33. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  34. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  35. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  36. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  37. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  38. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  39. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_aiolimiter.py +0 -0
  40. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_altair.py +0 -0
  41. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_asyncio.py +0 -0
  42. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_asyncio_classes/__init__.py +0 -0
  43. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_asyncio_classes/loopers.py +0 -0
  44. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_asyncio_classes/redis.py +0 -0
  45. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_atomicwrites.py +0 -0
  46. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_atools.py +0 -0
  47. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_cachetools.py +0 -0
  48. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_click.py +0 -0
  49. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_concurrent.py +0 -0
  50. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_contextlib.py +0 -0
  51. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_contextvars.py +0 -0
  52. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_cryptography.py +0 -0
  53. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_cvxpy.py +0 -0
  54. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_dataclasses.py +0 -0
  55. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_enum.py +0 -0
  56. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_errors.py +0 -0
  57. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_eventkit.py +0 -0
  58. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_fastapi.py +0 -0
  59. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_fpdf2.py +0 -0
  60. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_functions.py +0 -0
  61. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_functools.py +0 -0
  62. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_getpass.py +0 -0
  63. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_hashlib.py +0 -0
  64. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_http.py +0 -0
  65. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_hypothesis.py +0 -0
  66. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_importlib.py +0 -0
  67. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_inflect.py +0 -0
  68. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_ipython.py +0 -0
  69. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_iterables.py +0 -0
  70. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_jupyter.py +0 -0
  71. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_libcst.py +0 -0
  72. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_lightweight_charts.py +0 -0
  73. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_logging.py +0 -0
  74. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_luigi.py +0 -0
  75. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_math.py +0 -0
  76. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_memory_profiler.py +0 -0
  77. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_modules.py +0 -0
  78. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_more_itertools.py +0 -0
  79. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_numpy.py +0 -0
  80. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_objects/__init__.py +0 -0
  81. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_objects/objects.py +0 -0
  82. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_operator.py +0 -0
  83. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_optuna.py +0 -0
  84. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_orjson.py +0 -0
  85. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_os.py +0 -0
  86. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_parse.py +0 -0
  87. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_period.py +0 -0
  88. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pickle.py +0 -0
  89. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_platform.py +0 -0
  90. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_polars.py +0 -0
  91. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_polars_ols.py +0 -0
  92. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pottery.py +0 -0
  93. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pqdm.py +0 -0
  94. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_psutil.py +0 -0
  95. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pydantic.py +0 -0
  96. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pyinstrument.py +0 -0
  97. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_pytest_regressions.py +0 -0
  98. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_python_dotenv.py +0 -0
  99. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_random.py +0 -0
  100. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_re.py +0 -0
  101. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_redis.py +0 -0
  102. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_reprlib.py +0 -0
  103. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_scipy.py +0 -0
  104. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_sentinel.py +0 -0
  105. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_shelve.py +0 -0
  106. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_slack_sdk.py +0 -0
  107. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_socket.py +0 -0
  108. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_sqlalchemy.py +0 -0
  109. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_sqlalchemy_polars.py +0 -0
  110. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_statsmodels.py +0 -0
  111. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_streamlit.py +0 -0
  112. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_string.py +0 -0
  113. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_tempfile.py +0 -0
  114. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_text.py +0 -0
  115. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_threading.py +0 -0
  116. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_timer.py +0 -0
  117. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_traceback.py +0 -0
  118. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_typed_settings.py +0 -0
  119. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_types.py +0 -0
  120. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_typing.py +0 -0
  121. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_typing_funcs/__init__.py +0 -0
  122. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_typing_funcs/no_future.py +0 -0
  123. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_typing_funcs/with_future.py +0 -0
  124. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_tzdata.py +0 -0
  125. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_tzlocal.py +0 -0
  126. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_uuid.py +0 -0
  127. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_version.py +0 -0
  128. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_warnings.py +0 -0
  129. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_whenever.py +0 -0
  130. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_zipfile.py +0 -0
  131. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/tests/test_zoneinfo.py +0 -0
  132. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/aiolimiter.py +0 -0
  133. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/altair.py +0 -0
  134. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/asyncio.py +0 -0
  135. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/atomicwrites.py +0 -0
  136. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/atools.py +0 -0
  137. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/cachetools.py +0 -0
  138. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/click.py +0 -0
  139. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/concurrent.py +0 -0
  140. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/contextlib.py +0 -0
  141. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/contextvars.py +0 -0
  142. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/cryptography.py +0 -0
  143. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/cvxpy.py +0 -0
  144. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/dataclasses.py +0 -0
  145. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/enum.py +0 -0
  146. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/errors.py +0 -0
  147. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/eventkit.py +0 -0
  148. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/fastapi.py +0 -0
  149. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/fpdf2.py +0 -0
  150. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/functions.py +0 -0
  151. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/functools.py +0 -0
  152. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/getpass.py +0 -0
  153. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/hashlib.py +0 -0
  154. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/http.py +0 -0
  155. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/importlib.py +0 -0
  156. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/inflect.py +0 -0
  157. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/ipython.py +0 -0
  158. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/iterables.py +0 -0
  159. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/jupyter.py +0 -0
  160. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/libcst.py +0 -0
  161. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/lightweight_charts.py +0 -0
  162. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/logging.py +0 -0
  163. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/luigi.py +0 -0
  164. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/math.py +0 -0
  165. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/memory_profiler.py +0 -0
  166. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/modules.py +0 -0
  167. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/more_itertools.py +0 -0
  168. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/numpy.py +0 -0
  169. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/operator.py +0 -0
  170. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/optuna.py +0 -0
  171. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/orjson.py +0 -0
  172. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/os.py +0 -0
  173. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/parse.py +0 -0
  174. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/period.py +0 -0
  175. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pickle.py +0 -0
  176. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/platform.py +0 -0
  177. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/polars.py +0 -0
  178. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/polars_ols.py +0 -0
  179. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pottery.py +0 -0
  180. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pqdm.py +0 -0
  181. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/psutil.py +0 -0
  182. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/py.typed +0 -0
  183. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pydantic.py +0 -0
  184. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pyinstrument.py +0 -0
  185. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/pytest_regressions.py +0 -0
  186. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/python_dotenv.py +0 -0
  187. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/random.py +0 -0
  188. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/re.py +0 -0
  189. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/redis.py +0 -0
  190. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/reprlib.py +0 -0
  191. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/scipy.py +0 -0
  192. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/sentinel.py +0 -0
  193. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/shelve.py +0 -0
  194. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/slack_sdk.py +0 -0
  195. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/socket.py +0 -0
  196. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/sqlalchemy.py +0 -0
  197. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/sqlalchemy_polars.py +0 -0
  198. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/statsmodels.py +0 -0
  199. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/streamlit.py +0 -0
  200. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/string.py +0 -0
  201. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/tempfile.py +0 -0
  202. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/text.py +0 -0
  203. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/threading.py +0 -0
  204. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/timer.py +0 -0
  205. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/typed_settings.py +0 -0
  206. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/types.py +0 -0
  207. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/typing.py +0 -0
  208. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/tzdata.py +0 -0
  209. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/tzlocal.py +0 -0
  210. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/uuid.py +0 -0
  211. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/version.py +0 -0
  212. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/warnings.py +0 -0
  213. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/whenever.py +0 -0
  214. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/zipfile.py +0 -0
  215. {dycw_utilities-0.138.7 → dycw_utilities-0.138.9}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.138.7
3
+ Version: 0.138.9
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -106,7 +106,7 @@ dependencies = [
106
106
  name = "dycw-utilities"
107
107
  readme = "README.md"
108
108
  requires-python = ">= 3.12"
109
- version = "0.138.7"
109
+ version = "0.138.9"
110
110
 
111
111
  [project.entry-points.pytest11]
112
112
  pytest-regressions = "utilities.pytest_regressions_plugin"
@@ -137,7 +137,7 @@ test = [
137
137
  # bump-my-version
138
138
  [tool.bumpversion]
139
139
  allow_dirty = true
140
- current_version = "0.138.7"
140
+ current_version = "0.138.9"
141
141
 
142
142
  [[tool.bumpversion.files]]
143
143
  filename = "src/utilities/__init__.py"
@@ -6,13 +6,15 @@ from shutil import copytree
6
6
  from typing import TYPE_CHECKING, Self
7
7
 
8
8
  from hypothesis import HealthCheck, given, settings
9
- from hypothesis.strategies import DataObject, data, integers, sets
9
+ from hypothesis.strategies import integers, sets
10
10
  from pytest import mark, param, raises
11
11
 
12
12
  from tests.conftest import SKIPIF_CI_AND_WINDOWS
13
13
  from utilities.dataclasses import replace_non_sentinel
14
14
  from utilities.hypothesis import git_repos, paths, temp_paths
15
15
  from utilities.pathlib import (
16
+ GetPackageRootError,
17
+ GetRepoRootError,
16
18
  GetRootError,
17
19
  _GetTailDisambiguate,
18
20
  _GetTailEmptyError,
@@ -20,11 +22,14 @@ from utilities.pathlib import (
20
22
  _GetTailNonUniqueError,
21
23
  ensure_suffix,
22
24
  expand_path,
25
+ get_package_root,
23
26
  get_path,
27
+ get_repo_root,
24
28
  get_root,
25
29
  get_tail,
26
30
  is_sub_path,
27
31
  list_dir,
32
+ module_path,
28
33
  temp_cwd,
29
34
  )
30
35
  from utilities.sentinel import Sentinel, sentinel
@@ -105,71 +110,109 @@ class TestGetPath:
105
110
  assert get_path(path=lambda: path) == path
106
111
 
107
112
 
108
- class TestGetRoot:
109
- @given(data=data(), repo=git_repos())
113
+ class TestGetPackageRoot:
114
+ @given(tail=paths())
110
115
  @settings(
111
116
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
112
117
  )
113
- def test_git_dir(self, *, data: DataObject, repo: Path) -> None:
114
- path = repo.joinpath(data.draw(paths()))
115
- path.mkdir(parents=True, exist_ok=True)
116
- root = get_root(path=path)
117
- expected = repo.resolve()
118
- assert root == expected
118
+ def test_dir(self, *, tmp_path: Path, tail: Path) -> None:
119
+ tmp_path.joinpath("pyproject.toml").touch()
120
+ path = tmp_path.joinpath(tail)
121
+ result = get_package_root(path=path)
122
+ expected = tmp_path.resolve()
123
+ assert result == expected
119
124
 
120
- @given(data=data(), repo=git_repos())
125
+ @given(tail=paths(min_depth=1))
121
126
  @settings(
122
127
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
123
128
  )
124
- def test_git_file(self, *, data: DataObject, repo: Path) -> None:
125
- path = repo.joinpath(data.draw(paths(min_depth=1)))
129
+ def test_file(self, *, tmp_path: Path, tail: Path) -> None:
130
+ tmp_path.joinpath("pyproject.toml").touch()
131
+ path = tmp_path.joinpath(tail)
126
132
  path.touch()
127
- root = get_root(path=path)
133
+ root = get_package_root(path=path)
134
+ expected = tmp_path.resolve()
135
+ assert root == expected
136
+
137
+ def test_error(self, *, tmp_path: Path) -> None:
138
+ with raises(GetPackageRootError, match="Path is not part of a package: .*"):
139
+ _ = get_package_root(path=tmp_path)
140
+
141
+
142
+ class TestGetRepoRoot:
143
+ @given(repo=git_repos(), tail=paths())
144
+ @settings(max_examples=1)
145
+ def test_dir(self, *, repo: Path, tail: Path) -> None:
146
+ root = get_repo_root(path=repo.joinpath(tail))
147
+ expected = repo.resolve()
148
+ assert root == expected
149
+
150
+ @given(repo=git_repos(), tail=paths(min_depth=1))
151
+ @settings(max_examples=1)
152
+ def test_file(self, *, repo: Path, tail: Path) -> None:
153
+ path = repo.joinpath(tail)
154
+ path.touch()
155
+ root = get_repo_root(path=path)
128
156
  expected = repo.resolve()
129
157
  assert root == expected
130
158
 
131
- @given(data=data())
159
+ def test_error(self, *, tmp_path: Path) -> None:
160
+ with raises(
161
+ GetRepoRootError, match="Path is not part of a `git` repository: .*"
162
+ ):
163
+ _ = get_repo_root(path=tmp_path)
164
+
165
+
166
+ class TestGetRoot:
167
+ @given(repo=git_repos(), tail=paths())
168
+ @settings(max_examples=1)
169
+ def test_repo_only(self, *, repo: Path, tail: Path) -> None:
170
+ root = get_root(path=repo.joinpath(tail))
171
+ expected = repo.resolve()
172
+ assert root == expected
173
+
174
+ @given(tail=paths())
132
175
  @settings(
133
176
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
134
177
  )
135
- def test_envrc(self, *, data: DataObject, tmp_path: Path) -> None:
136
- tmp_path.joinpath(".envrc").touch()
137
- path = tmp_path.joinpath(data.draw(paths()))
178
+ def test_package_only(self, *, tmp_path: Path, tail: Path) -> None:
179
+ tmp_path.joinpath("pyproject.toml").touch()
180
+ path = tmp_path.joinpath(tail)
138
181
  result = get_root(path=path)
139
182
  expected = tmp_path.resolve()
140
183
  assert result == expected
141
184
 
142
- @given(data=data(), repo=git_repos())
185
+ @given(repo=git_repos(), tail=paths())
143
186
  @settings(
144
187
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
145
188
  )
146
- def test_git_and_envrc(self, *, data: DataObject, repo: Path) -> None:
147
- repo.joinpath(".envrc").touch()
148
- path = repo.joinpath(data.draw(paths()))
189
+ def test_repo_and_package(self, *, repo: Path, tail: Path) -> None:
190
+ repo.joinpath("pyproject.toml").touch()
191
+ path = repo.joinpath(tail)
149
192
  root = get_root(path=path)
150
193
  expected = repo.resolve()
151
194
  assert root == expected
152
195
 
153
- @given(data=data(), repo=git_repos())
196
+ @given(repo=git_repos(), tail=paths(min_depth=1))
154
197
  @settings(
155
198
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
156
199
  )
157
- def test_git_with_envrc_inside(self, *, data: DataObject, repo: Path) -> None:
158
- path = repo.joinpath(data.draw(paths(min_depth=1)))
200
+ def test_repo_with_package_inside(self, *, repo: Path, tail: Path) -> None:
201
+ path = repo.joinpath(tail)
159
202
  path.mkdir(parents=True)
160
- path.joinpath(".envrc").touch()
203
+ path.joinpath("pyproject.toml").touch()
161
204
  root = get_root(path=path)
162
205
  expected = path.resolve()
163
206
  assert root == expected
164
207
 
165
- @given(data=data(), repo=git_repos())
208
+ @given(repo=git_repos(), tail=paths(min_depth=1))
166
209
  @settings(
167
210
  max_examples=1, suppress_health_check={HealthCheck.function_scoped_fixture}
168
211
  )
169
- def test_envrc_with_git_inside(self, *, data: DataObject, repo: Path) -> None:
212
+ def test_package_with_repo_inside(self, *, repo: Path, tail: Path) -> None:
170
213
  with TemporaryDirectory() as temp:
171
- temp.joinpath(".envrc").touch()
172
- path = temp.joinpath(data.draw(paths(min_depth=1)))
214
+ temp.joinpath("pyproject.toml").touch()
215
+ path = temp.joinpath(tail)
173
216
  _ = copytree(repo, path)
174
217
  root = get_root(path=path)
175
218
  expected = path.resolve()
@@ -255,6 +298,16 @@ class TestListDir:
255
298
  assert result == expected
256
299
 
257
300
 
301
+ class TestModulePath:
302
+ @mark.parametrize(
303
+ ("root", "expected"),
304
+ [param(None, "foo.bar.baz"), param("foo", "bar.baz"), param("foo/bar", "baz")],
305
+ )
306
+ def test_main(self, *, root: PathLike | None, expected: Path) -> None:
307
+ module = module_path("foo/bar/baz.py", root=root)
308
+ assert module == expected
309
+
310
+
258
311
  class TestTempCWD:
259
312
  def test_main(self, *, tmp_path: Path) -> None:
260
313
  assert Path.cwd() != tmp_path
@@ -12,7 +12,7 @@ from utilities.iterables import one
12
12
  from utilities.pytest import (
13
13
  NodeIdToPathError,
14
14
  is_pytest,
15
- node_id_to_path,
15
+ node_id_path,
16
16
  random_state,
17
17
  throttle,
18
18
  )
@@ -31,46 +31,53 @@ class TestIsPytest:
31
31
  assert is_pytest()
32
32
 
33
33
 
34
- class TestNodeIdToPath:
34
+ class TestNodeIdPath:
35
35
  @mark.parametrize(
36
36
  ("node_id", "expected"),
37
37
  [
38
38
  param(
39
39
  "src/tests/module/test_funcs.py::TestClass::test_main",
40
- Path("src.tests.module.test_funcs", "TestClass__test_main"),
40
+ Path("src.tests.module.test_funcs/TestClass__test_main"),
41
41
  ),
42
42
  param(
43
43
  "src/tests/module/test_funcs.py::TestClass::test_main[param1, param2]",
44
44
  Path(
45
- "src.tests.module.test_funcs",
46
- "TestClass__test_main[param1, param2]",
45
+ "src.tests.module.test_funcs/TestClass__test_main[param1, param2]"
47
46
  ),
48
47
  ),
49
48
  param(
50
49
  "src/tests/module/test_funcs.py::TestClass::test_main[EUR.USD]",
51
- Path("src.tests.module.test_funcs", "TestClass__test_main[EUR.USD]"),
50
+ Path("src.tests.module.test_funcs/TestClass__test_main[EUR.USD]"),
52
51
  ),
53
52
  ],
54
53
  )
55
54
  def test_main(self, *, node_id: str, expected: Path) -> None:
56
- result = node_id_to_path(node_id)
55
+ result = node_id_path(node_id)
57
56
  assert result == expected
58
57
 
59
- def test_head(self) -> None:
60
- node_id = "src/tests/module/test_funcs.py::TestClass::test_main"
61
- result = node_id_to_path(node_id, head="src/tests")
62
- expected = Path("module.test_funcs", "TestClass__test_main")
58
+ @mark.parametrize(
59
+ "node_id",
60
+ [
61
+ param("src/tests/module/test_funcs.py::TestClass::test_main"),
62
+ param(
63
+ "python/package/src/tests/module/test_funcs.py::TestClass::test_main"
64
+ ),
65
+ ],
66
+ )
67
+ def test_root(self, *, node_id: str) -> None:
68
+ result = node_id_path(node_id, root="src/tests")
69
+ expected = Path("module.test_funcs/TestClass__test_main")
63
70
  assert result == expected
64
71
 
65
72
  def test_suffix(self) -> None:
66
73
  node_id = "src/tests/module/test_funcs.py::TestClass::test_main"
67
- result = node_id_to_path(node_id, head="src/tests", suffix=".sv")
68
- expected = Path("module.test_funcs", "TestClass__test_main.sv")
74
+ result = node_id_path(node_id, root="src/tests", suffix=".csv")
75
+ expected = Path("module.test_funcs/TestClass__test_main.csv")
69
76
  assert result == expected
70
77
 
71
78
  def test_error_file_suffix(self) -> None:
72
79
  with raises(NodeIdToPathError, match="Node ID must be a Python file; got .*"):
73
- _ = node_id_to_path("src/tests/module/test_funcs.csv::TestClass::test_main")
80
+ _ = node_id_path("src/tests/module/test_funcs.csv::TestClass::test_main")
74
81
 
75
82
 
76
83
  class TestPytestOptions:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.138.7"
3
+ __version__ = "0.138.9"
@@ -66,7 +66,7 @@ from utilities.math import (
66
66
  is_zero,
67
67
  )
68
68
  from utilities.os import get_env_var
69
- from utilities.pathlib import temp_cwd
69
+ from utilities.pathlib import module_path, temp_cwd
70
70
  from utilities.platform import IS_WINDOWS
71
71
  from utilities.sentinel import Sentinel, sentinel
72
72
  from utilities.tempfile import TEMP_DIR, TemporaryDirectory
@@ -567,7 +567,7 @@ def import_froms(
567
567
  max_depth=max_depth_,
568
568
  )
569
569
  )
570
- module = ".".join(path.parts)
570
+ module = module_path(path)
571
571
  name = draw(text_ascii(min_size=1))
572
572
  asname = draw(text_ascii(min_size=1) | none())
573
573
  return generate_import_from(module, name, asname=asname)
@@ -594,7 +594,7 @@ def imports(
594
594
  max_depth=max_depth_,
595
595
  )
596
596
  )
597
- module = ".".join(path.parts)
597
+ module = module_path(path)
598
598
  asname = draw(text_ascii(min_size=1) | none())
599
599
  return generate_import(module, asname=asname)
600
600
 
@@ -71,8 +71,35 @@ def get_path(
71
71
  ##
72
72
 
73
73
 
74
- def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
75
- """Get the root of a path."""
74
+ def get_package_root(*, path: MaybeCallablePathLike | None = None) -> Path:
75
+ """Get the package root."""
76
+ path = get_path(path=path)
77
+ path_dir = path.parent if path.is_file() else path
78
+ all_paths = list(chain([path_dir], path_dir.parents))
79
+ try:
80
+ return next(
81
+ p.resolve()
82
+ for p in all_paths
83
+ if any(p_i.name == "pyproject.toml" for p_i in p.iterdir())
84
+ )
85
+ except StopIteration:
86
+ raise GetPackageRootError(path=path) from None
87
+
88
+
89
+ @dataclass(kw_only=True, slots=True)
90
+ class GetPackageRootError(Exception):
91
+ path: PathLike
92
+
93
+ @override
94
+ def __str__(self) -> str:
95
+ return f"Path is not part of a package: {self.path}"
96
+
97
+
98
+ ##
99
+
100
+
101
+ def get_repo_root(*, path: MaybeCallablePathLike | None = None) -> Path:
102
+ """Get the repo root."""
76
103
  path = get_path(path=path)
77
104
  path_dir = path.parent if path.is_file() else path
78
105
  try:
@@ -85,36 +112,52 @@ def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
85
112
  except CalledProcessError as error:
86
113
  # newer versions of git report "Not a git repository", whilst older
87
114
  # versions report "not a git repository"
88
- if not search("fatal: not a git repository", error.stderr, flags=IGNORECASE):
89
- raise # pragma: no cover
90
- root_git = None
115
+ if search("fatal: not a git repository", error.stderr, flags=IGNORECASE):
116
+ raise GetRepoRootError(path=path) from None
117
+ raise # pragma: no cover
91
118
  else:
92
- root_git = Path(output.strip("\n")).resolve()
93
- all_paths = list(chain([path_dir], path_dir.parents))
119
+ return Path(output.strip("\n"))
120
+
121
+
122
+ @dataclass(kw_only=True, slots=True)
123
+ class GetRepoRootError(Exception):
124
+ path: PathLike
125
+
126
+ @override
127
+ def __str__(self) -> str:
128
+ return f"Path is not part of a `git` repository: {self.path}"
129
+
130
+
131
+ ##
132
+
133
+
134
+ def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
135
+ """Get the root of a path."""
136
+ path = get_path(path=path)
94
137
  try:
95
- root_envrc = next(
96
- p.resolve()
97
- for p in all_paths
98
- if any(p_i.name == ".envrc" for p_i in p.iterdir())
99
- )
100
- except StopIteration:
101
- root_envrc = None
102
- match root_git, root_envrc:
138
+ repo = get_repo_root(path=path)
139
+ except GetRepoRootError:
140
+ repo = None
141
+ try:
142
+ package = get_package_root(path=path)
143
+ except GetPackageRootError:
144
+ package = None
145
+ match repo, package:
103
146
  case None, None:
104
147
  raise GetRootError(path=path)
105
148
  case Path(), None:
106
- return root_git
149
+ return repo
107
150
  case None, Path():
108
- return root_envrc
151
+ return package
109
152
  case Path(), Path():
110
- if root_git == root_envrc:
111
- return root_git
112
- if is_sub_path(root_git, root_envrc, strict=True):
113
- return root_git
114
- if is_sub_path(root_envrc, root_git, strict=True):
115
- return root_envrc
153
+ if repo == package:
154
+ return repo
155
+ if is_sub_path(repo, package, strict=True):
156
+ return repo
157
+ if is_sub_path(package, repo, strict=True):
158
+ return package
116
159
  raise ImpossibleCaseError( # pragma: no cover
117
- case=[f"{root_git=}", f"{root_envrc=}"]
160
+ case=[f"{repo=}", f"{package=}"]
118
161
  )
119
162
  case _ as never:
120
163
  assert_never(never)
@@ -211,6 +254,24 @@ class _GetTailNonUniqueError(GetTailError):
211
254
  ##
212
255
 
213
256
 
257
+ def module_path(
258
+ path: PathLike,
259
+ /,
260
+ *,
261
+ root: PathLike | None = None,
262
+ disambiguate: _GetTailDisambiguate = "raise",
263
+ ) -> str:
264
+ """Return a module path."""
265
+ path = Path(path)
266
+ if root is not None:
267
+ path = get_tail(path, root, disambiguate=disambiguate)
268
+ parts = path.with_suffix("").parts
269
+ return ".".join(parts)
270
+
271
+
272
+ ##
273
+
274
+
214
275
  def is_sub_path(x: PathLike, y: PathLike, /, *, strict: bool = False) -> bool:
215
276
  """Check if a path is a sub path of another."""
216
277
  x, y = [Path(i).resolve() for i in [x, y]]
@@ -241,12 +302,17 @@ def temp_cwd(path: PathLike, /) -> Iterator[None]:
241
302
 
242
303
  __all__ = [
243
304
  "PWD",
305
+ "GetPackageRootError",
306
+ "GetRepoRootError",
244
307
  "GetTailError",
245
308
  "ensure_suffix",
246
309
  "expand_path",
310
+ "get_package_root",
247
311
  "get_path",
312
+ "get_repo_root",
248
313
  "get_tail",
249
314
  "is_sub_path",
250
315
  "list_dir",
316
+ "module_path",
251
317
  "temp_cwd",
252
318
  ]
@@ -13,7 +13,7 @@ from whenever import ZonedDateTime
13
13
  from utilities.atomicwrites import writer
14
14
  from utilities.functools import cache
15
15
  from utilities.hashlib import md5_hash
16
- from utilities.pathlib import ensure_suffix, get_root
16
+ from utilities.pathlib import ensure_suffix, get_root, get_tail, module_path
17
17
  from utilities.platform import (
18
18
  IS_LINUX,
19
19
  IS_MAC,
@@ -123,18 +123,18 @@ def is_pytest() -> bool:
123
123
  ##
124
124
 
125
125
 
126
- def node_id_to_path(
127
- node_id: str, /, *, head: PathLike | None = None, suffix: str | None = None
126
+ def node_id_path(
127
+ node_id: str, /, *, root: PathLike | None = None, suffix: str | None = None
128
128
  ) -> Path:
129
- """Map a node ID to a path."""
129
+ """Get the path of a node ID."""
130
130
  path_file, *parts = node_id.split("::")
131
131
  path_file = Path(path_file)
132
132
  if path_file.suffix != ".py":
133
133
  raise NodeIdToPathError(node_id=node_id)
134
134
  path = path_file.with_suffix("")
135
- if head is not None:
136
- path = path.relative_to(head)
137
- path = Path(".".join(path.parts), "__".join(parts))
135
+ if root is not None:
136
+ path = get_tail(path, root)
137
+ path = Path(module_path(path), "__".join(parts))
138
138
  if suffix is not None:
139
139
  path = ensure_suffix(path, suffix)
140
140
  return path
@@ -267,7 +267,7 @@ __all__ = [
267
267
  "add_pytest_collection_modifyitems",
268
268
  "add_pytest_configure",
269
269
  "is_pytest",
270
- "node_id_to_path",
270
+ "node_id_path",
271
271
  "random_state",
272
272
  "skipif_linux",
273
273
  "skipif_mac",
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
- from typing import TYPE_CHECKING
4
+ from typing import TYPE_CHECKING, Any, cast
5
5
 
6
6
  if TYPE_CHECKING:
7
7
  from pytest import FixtureRequest
@@ -41,11 +41,12 @@ else:
41
41
 
42
42
  def _get_path(request: FixtureRequest, /) -> Path:
43
43
  from utilities.pathlib import get_root
44
- from utilities.pytest import node_id_to_path
44
+ from utilities.pytest import node_id_path
45
45
 
46
- head = Path("src", "tests")
47
- tail = node_id_to_path(request.node.nodeid, head=head)
48
- return get_root().joinpath(head, "regressions", tail)
46
+ path = Path(cast("Any", request).fspath)
47
+ root = Path("src", "tests")
48
+ tail = node_id_path(request.node.nodeid, root=root)
49
+ return get_root(path=path).joinpath(root, "regressions", tail)
49
50
 
50
51
 
51
52
  __all__ = ["orjson_regression", "polars_regression"]
@@ -16,7 +16,7 @@ from utilities.atomicwrites import writer
16
16
  from utilities.errors import repr_error
17
17
  from utilities.functions import to_bool
18
18
  from utilities.iterables import OneEmptyError, one
19
- from utilities.pathlib import get_path
19
+ from utilities.pathlib import get_path, module_path
20
20
  from utilities.reprlib import (
21
21
  RICH_EXPAND_ALL,
22
22
  RICH_INDENT_SIZE,
@@ -181,7 +181,7 @@ def _path_to_dots(path: PathLike, /) -> str:
181
181
  if (new_path := _trim_path(path, pattern)) is not None:
182
182
  break
183
183
  path_use = Path(path) if new_path is None else new_path
184
- return ".".join(path_use.with_suffix("").parts)
184
+ return module_path(path_use)
185
185
 
186
186
 
187
187
  def _trim_path(path: PathLike, pattern: str, /) -> Path | None: