dycw-utilities 0.125.3__tar.gz → 0.125.4__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.125.3 → dycw_utilities-0.125.4}/PKG-INFO +3 -3
  2. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/pyproject.toml +7 -6
  3. dycw_utilities-0.125.4/src/tests/test_libcst.py +160 -0
  4. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/__init__.py +1 -1
  5. dycw_utilities-0.125.4/src/utilities/libcst.py +184 -0
  6. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/.gitignore +0 -0
  7. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/LICENSE +0 -0
  8. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/README.md +0 -0
  9. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/__init__.py +0 -0
  10. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/conftest.py +0 -0
  11. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_altair.py +0 -0
  35. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_asyncio.py +0 -0
  36. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_atomicwrites.py +0 -0
  37. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_atools.py +0 -0
  38. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_cachetools.py +0 -0
  39. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_click.py +0 -0
  40. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_concurrent.py +0 -0
  41. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_contextlib.py +0 -0
  42. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_contextvars.py +0 -0
  43. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_cryptography.py +0 -0
  44. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_cvxpy.py +0 -0
  45. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_dataclasses.py +0 -0
  46. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_datetime.py +0 -0
  47. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_enum.py +0 -0
  48. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_errors.py +0 -0
  49. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_eventkit.py +0 -0
  50. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_fastapi.py +0 -0
  51. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_fpdf2.py +0 -0
  52. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_functions.py +0 -0
  53. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_functools.py +0 -0
  54. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_getpass.py +0 -0
  55. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_git.py +0 -0
  56. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_hashlib.py +0 -0
  57. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_http.py +0 -0
  58. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_hypothesis.py +0 -0
  59. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_importlib.py +0 -0
  60. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_ipython.py +0 -0
  61. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_iterables.py +0 -0
  62. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_jupyter.py +0 -0
  63. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_lightweight_charts.py +0 -0
  64. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_logging.py +0 -0
  65. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_loguru.py +0 -0
  66. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_luigi.py +0 -0
  67. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_math.py +0 -0
  68. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_memory_profiler.py +0 -0
  69. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_modules.py +0 -0
  70. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_more_itertools.py +0 -0
  71. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_numpy.py +0 -0
  72. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_operator.py +0 -0
  73. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_optuna.py +0 -0
  74. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_orjson.py +0 -0
  75. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_os.py +0 -0
  76. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_parse.py +0 -0
  77. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pathlib.py +0 -0
  78. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_period.py +0 -0
  79. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pickle.py +0 -0
  80. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_platform.py +0 -0
  81. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_polars.py +0 -0
  82. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_polars_ols.py +0 -0
  83. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pqdm.py +0 -0
  84. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pydantic.py +0 -0
  85. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pyinstrument.py +0 -0
  86. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pyrsistent.py +0 -0
  87. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pytest.py +0 -0
  88. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_pytest_regressions.py +0 -0
  89. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_python_dotenv.py +0 -0
  90. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_random.py +0 -0
  91. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_re.py +0 -0
  92. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_redis.py +0 -0
  93. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_reprlib.py +0 -0
  94. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_rich.py +0 -0
  95. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_scipy.py +0 -0
  96. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_sentinel.py +0 -0
  97. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_shelve.py +0 -0
  98. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_slack_sdk.py +0 -0
  99. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_socket.py +0 -0
  100. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_sqlalchemy.py +0 -0
  101. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_sqlalchemy_polars.py +0 -0
  102. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_statsmodel.py +0 -0
  103. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_streamlit.py +0 -0
  104. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_sys.py +0 -0
  105. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_tempfile.py +0 -0
  106. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_tenacity.py +0 -0
  107. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_text.py +0 -0
  108. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_threading.py +0 -0
  109. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_timer.py +0 -0
  110. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback.py +0 -0
  111. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/__init__.py +0 -0
  112. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/chain.py +0 -0
  113. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  114. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  115. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  116. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/many.py +0 -0
  117. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/one.py +0 -0
  118. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/recursive.py +0 -0
  119. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  120. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  121. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/two.py +0 -0
  122. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_traceback_funcs/untraced.py +0 -0
  123. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_types.py +0 -0
  124. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_typing.py +0 -0
  125. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_typing_funcs/__init__.py +0 -0
  126. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_typing_funcs/no_future.py +0 -0
  127. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_typing_funcs/with_future.py +0 -0
  128. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_tzdata.py +0 -0
  129. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_tzlocal.py +0 -0
  130. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_uuid.py +0 -0
  131. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_version.py +0 -0
  132. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_warnings.py +0 -0
  133. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_whenever.py +0 -0
  134. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_zipfile.py +0 -0
  135. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/tests/test_zoneinfo.py +0 -0
  136. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/altair.py +0 -0
  137. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/asyncio.py +0 -0
  138. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/atomicwrites.py +0 -0
  139. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/atools.py +0 -0
  140. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/cachetools.py +0 -0
  141. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/click.py +0 -0
  142. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/concurrent.py +0 -0
  143. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/contextlib.py +0 -0
  144. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/contextvars.py +0 -0
  145. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/cryptography.py +0 -0
  146. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/cvxpy.py +0 -0
  147. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/dataclasses.py +0 -0
  148. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/datetime.py +0 -0
  149. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/enum.py +0 -0
  150. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/errors.py +0 -0
  151. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/eventkit.py +0 -0
  152. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/fastapi.py +0 -0
  153. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/fpdf2.py +0 -0
  154. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/functions.py +0 -0
  155. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/functools.py +0 -0
  156. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/getpass.py +0 -0
  157. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/git.py +0 -0
  158. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/hashlib.py +0 -0
  159. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/http.py +0 -0
  160. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/hypothesis.py +0 -0
  161. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/importlib.py +0 -0
  162. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/ipython.py +0 -0
  163. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/iterables.py +0 -0
  164. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/jupyter.py +0 -0
  165. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/lightweight_charts.py +0 -0
  166. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/logging.py +0 -0
  167. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/loguru.py +0 -0
  168. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/luigi.py +0 -0
  169. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/math.py +0 -0
  170. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/memory_profiler.py +0 -0
  171. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/modules.py +0 -0
  172. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/more_itertools.py +0 -0
  173. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/numpy.py +0 -0
  174. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/operator.py +0 -0
  175. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/optuna.py +0 -0
  176. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/orjson.py +0 -0
  177. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/os.py +0 -0
  178. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/parse.py +0 -0
  179. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pathlib.py +0 -0
  180. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/period.py +0 -0
  181. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pickle.py +0 -0
  182. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/platform.py +0 -0
  183. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/polars.py +0 -0
  184. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/polars_ols.py +0 -0
  185. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pqdm.py +0 -0
  186. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/py.typed +0 -0
  187. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pydantic.py +0 -0
  188. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pyinstrument.py +0 -0
  189. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pyrsistent.py +0 -0
  190. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pytest.py +0 -0
  191. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/pytest_regressions.py +0 -0
  192. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/python_dotenv.py +0 -0
  193. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/random.py +0 -0
  194. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/re.py +0 -0
  195. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/redis.py +0 -0
  196. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/reprlib.py +0 -0
  197. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/rich.py +0 -0
  198. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/scipy.py +0 -0
  199. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/sentinel.py +0 -0
  200. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/shelve.py +0 -0
  201. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/slack_sdk.py +0 -0
  202. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/socket.py +0 -0
  203. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/sqlalchemy.py +0 -0
  204. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/sqlalchemy_polars.py +0 -0
  205. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/statsmodels.py +0 -0
  206. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/streamlit.py +0 -0
  207. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/sys.py +0 -0
  208. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/tempfile.py +0 -0
  209. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/tenacity.py +0 -0
  210. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/text.py +0 -0
  211. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/threading.py +0 -0
  212. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/timer.py +0 -0
  213. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/traceback.py +0 -0
  214. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/types.py +0 -0
  215. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/typing.py +0 -0
  216. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/tzdata.py +0 -0
  217. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/tzlocal.py +0 -0
  218. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/uuid.py +0 -0
  219. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/version.py +0 -0
  220. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/warnings.py +0 -0
  221. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/whenever.py +0 -0
  222. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/zipfile.py +0 -0
  223. {dycw_utilities-0.125.3 → dycw_utilities-0.125.4}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.125.3
3
+ Version: 0.125.4
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -10,7 +10,7 @@ Requires-Dist: hypothesis<6.132,>=6.131.27; 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'
13
- Requires-Dist: pytest-lazy-fixtures<1.2,>=1.1.2; extra == 'test'
13
+ Requires-Dist: pytest-lazy-fixtures<1.2,>=1.1.3; extra == 'test'
14
14
  Requires-Dist: pytest-only<2.2,>=2.1.2; extra == 'test'
15
15
  Requires-Dist: pytest-randomly<3.17,>=3.16.0; extra == 'test'
16
16
  Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'test'
@@ -174,7 +174,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
174
174
  Provides-Extra: zzz-test-sentinel
175
175
  Provides-Extra: zzz-test-shelve
176
176
  Provides-Extra: zzz-test-slack-sdk
177
- Requires-Dist: aiohttp<3.12,>=3.11.16; extra == 'zzz-test-slack-sdk'
177
+ Requires-Dist: aiohttp<3.13,>=3.12.0; extra == 'zzz-test-slack-sdk'
178
178
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
179
179
  Provides-Extra: zzz-test-socket
180
180
  Provides-Extra: zzz-test-sqlalchemy
@@ -8,7 +8,7 @@ requires = ["hatchling"]
8
8
  # dependency groups
9
9
  [dependency-groups]
10
10
  dev = [
11
- "aiohttp >= 3.11.16, < 3.12", # for slack
11
+ "aiohttp >= 3.12.0, < 3.13", # for slack
12
12
  "aiosqlite >= 0.21.0, < 0.22",
13
13
  "altair >= 5.5.0, < 5.6",
14
14
  "asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
@@ -35,6 +35,7 @@ dev = [
35
35
  "nest-asyncio >= 1.6.0, < 1.7", # for sqlalchemy async
36
36
  "nox >= 2025.2.9, < 2025.3",
37
37
  "numpy >= 2.2.6, < 2.3",
38
+ "libcst >= 1.7.0, < 1.8",
38
39
  "optuna >= 4.3.0, < 4.4",
39
40
  "orjson >= 3.10.18, < 3.11",
40
41
  "pathvalidate >= 3.2.3, < 3.3",
@@ -70,7 +71,7 @@ dev = [
70
71
  "pytest-asyncio >= 0.26.0, < 0.27",
71
72
  "pytest-cov >= 6.1.1, < 6.2",
72
73
  "pytest-instafail >= 0.5.0, < 0.6",
73
- "pytest-lazy-fixtures >= 1.1.2, < 1.2",
74
+ "pytest-lazy-fixtures >= 1.1.3, < 1.2",
74
75
  "pytest-only >= 2.1.2, < 2.2",
75
76
  "pytest-randomly >= 3.16.0, < 3.17",
76
77
  "pytest-rerunfailures >= 15.1, < 16",
@@ -91,7 +92,7 @@ dependencies = [
91
92
  name = "dycw-utilities"
92
93
  readme = "README.md"
93
94
  requires-python = ">= 3.12"
94
- version = "0.125.3"
95
+ version = "0.125.4"
95
96
 
96
97
  [project.optional-dependencies]
97
98
  test = [
@@ -100,7 +101,7 @@ test = [
100
101
  "pytest-asyncio >= 0.26.0, < 0.27",
101
102
  "pytest-cov >= 6.1.1, < 6.2",
102
103
  "pytest-instafail >= 0.5.0, < 0.6",
103
- "pytest-lazy-fixtures >= 1.1.2, < 1.2",
104
+ "pytest-lazy-fixtures >= 1.1.3, < 1.2",
104
105
  "pytest-only >= 2.1.2, < 2.2",
105
106
  "pytest-randomly >= 3.16.0, < 3.17",
106
107
  "pytest-regressions >= 2.7.0, < 2.8",
@@ -268,7 +269,7 @@ zzz-test-scipy = ["scipy >= 1.15.3, < 1.16"]
268
269
  zzz-test-sentinel = []
269
270
  zzz-test-shelve = []
270
271
  zzz-test-slack-sdk = [
271
- "aiohttp >= 3.11.16, < 3.12", # for slack
272
+ "aiohttp >= 3.12.0, < 3.13", # for slack
272
273
  "slack-sdk >= 3.35.0, < 3.36",
273
274
  ]
274
275
  zzz-test-socket = []
@@ -332,7 +333,7 @@ zzz-test-zoneinfo = [
332
333
  # bump-my-version
333
334
  [tool.bumpversion]
334
335
  allow_dirty = true
335
- current_version = "0.125.3"
336
+ current_version = "0.125.4"
336
337
 
337
338
  [[tool.bumpversion.files]]
338
339
  filename = "src/utilities/__init__.py"
@@ -0,0 +1,160 @@
1
+ from __future__ import annotations
2
+
3
+ from hypothesis import given
4
+ from hypothesis.strategies import sampled_from
5
+ from libcst import (
6
+ Attribute,
7
+ Dot,
8
+ Expr,
9
+ Import,
10
+ ImportAlias,
11
+ ImportFrom,
12
+ ImportStar,
13
+ Integer,
14
+ Module,
15
+ Name,
16
+ SimpleStatementLine,
17
+ )
18
+ from pytest import raises
19
+
20
+ from tests.conftest import SKIPIF_CI
21
+ from utilities.iterables import one
22
+ from utilities.libcst import (
23
+ JoinDottedStrError,
24
+ _ParseImportAliasError,
25
+ _ParseImportEmptyModuleError,
26
+ generate_f_string,
27
+ generate_from_import,
28
+ generate_import,
29
+ join_dotted_str,
30
+ parse_import,
31
+ render_module,
32
+ split_dotted_str,
33
+ )
34
+
35
+
36
+ class TestGenerateFString:
37
+ def test_main(self) -> None:
38
+ string = generate_f_string("foo", "bar")
39
+ result = Module([SimpleStatementLine([Expr(string)])]).code.strip("\n")
40
+ expected = 'f"{foo}bar"'
41
+ assert result == expected
42
+
43
+
44
+ class TestGenerateFromImport:
45
+ @given(
46
+ case=sampled_from([
47
+ ("foo", "bar", None, "from foo import bar"),
48
+ ("foo", "bar", "bar2", "from foo import bar as bar2"),
49
+ ("foo.bar", "baz", None, "from foo.bar import baz"),
50
+ ("foo.bar", "baz", "baz2", "from foo.bar import baz as baz2"),
51
+ ])
52
+ )
53
+ def test_main(self, *, case: tuple[str, str, str | None, str]) -> None:
54
+ module, name, asname, expected = case
55
+ imp = generate_from_import(module, name, asname=asname)
56
+ result = Module([SimpleStatementLine([imp])]).code.strip("\n")
57
+ assert result == expected
58
+
59
+
60
+ class TestGenerateImport:
61
+ @given(
62
+ case=sampled_from([
63
+ ("foo", None, "import foo"),
64
+ ("foo", "foo2", "import foo as foo2"),
65
+ ("foo.bar", None, "import foo.bar"),
66
+ ("foo.bar", "bar2", "import foo.bar as bar2"),
67
+ ])
68
+ )
69
+ def test_main(self, *, case: tuple[str, str | None, str]) -> None:
70
+ module, asname, expected = case
71
+ imp = generate_import(module, asname=asname)
72
+ result = Module([SimpleStatementLine([imp])]).code.strip("\n")
73
+ assert result == expected
74
+
75
+
76
+ class TestParseImport:
77
+ def test_import_one_name(self) -> None:
78
+ imp = Import(names=[ImportAlias(Name("foo"))])
79
+ parsed = one(parse_import(imp))
80
+ assert parsed.module == "foo"
81
+ assert parsed.name is None
82
+
83
+ def test_import_one_attr(self) -> None:
84
+ imp = Import(names=[ImportAlias(Attribute(Name("foo"), Name("bar")))])
85
+ parsed = one(parse_import(imp))
86
+ assert parsed.module == "foo.bar"
87
+ assert parsed.name is None
88
+
89
+ def test_import_many(self) -> None:
90
+ imp = Import(names=[ImportAlias(Name("foo")), ImportAlias(Name("bar"))])
91
+ result = parse_import(imp)
92
+ assert len(result) == 2
93
+ first, second = result
94
+ assert first.module == "foo"
95
+ assert first.name is None
96
+ assert second.module == "bar"
97
+ assert second.name is None
98
+
99
+ def test_from_import_one(self) -> None:
100
+ imp = ImportFrom(module=Name("foo"), names=[ImportAlias(Name("bar"))])
101
+ result = one(parse_import(imp))
102
+ assert result.module == "foo"
103
+ assert result.name == "bar"
104
+
105
+ def test_from_import_many(self) -> None:
106
+ imp = ImportFrom(
107
+ module=Name("foo"),
108
+ names=[ImportAlias(Name("bar")), ImportAlias(Name("baz"))],
109
+ )
110
+ result = parse_import(imp)
111
+ first, second = result
112
+ assert first.module == "foo"
113
+ assert first.name == "bar"
114
+ assert second.module == "foo"
115
+ assert second.name == "baz"
116
+
117
+ def test_from_import_star(self) -> None:
118
+ imp = ImportFrom(module=Name("foo"), names=ImportStar())
119
+ result = one(parse_import(imp))
120
+ assert result.module == "foo"
121
+ assert result.name == "*"
122
+
123
+ def test_error_empty_module(self) -> None:
124
+ alias = ImportAlias(name=Name("foo"))
125
+ imp = ImportFrom(module=None, names=[alias], relative=[Dot()])
126
+ with raises(
127
+ _ParseImportEmptyModuleError, match="Module must not be None; got .*"
128
+ ):
129
+ _ = parse_import(imp)
130
+
131
+ def test_error_alias(self) -> None:
132
+ alias = ImportAlias(name=Attribute(Name("foo"), Name("bar")))
133
+ imp = ImportFrom(module=Name("baz"), names=[alias])
134
+ with raises(
135
+ _ParseImportAliasError,
136
+ match=r"Invalid alias name; got module 'baz' and attribute 'foo\.bar'",
137
+ ):
138
+ _ = parse_import(imp)
139
+
140
+
141
+ class TestRenderModule:
142
+ @SKIPIF_CI
143
+ def test_main(self) -> None:
144
+ module = Module([SimpleStatementLine([generate_import("foo")])])
145
+ result = render_module(module)
146
+ expected = "import foo\n"
147
+ assert result == expected
148
+
149
+
150
+ class TestSplitAndJoinDottedStr:
151
+ @given(text=sampled_from(["foo", "foo.bar", "foo.bar.baz"]))
152
+ def test_main(self, *, text: str) -> None:
153
+ result = join_dotted_str(split_dotted_str(text))
154
+ assert result == text
155
+
156
+ def test_join_dotted_fallback_expression(self) -> None:
157
+ with raises(
158
+ JoinDottedStrError, match="Only names & attributes allowed; got .*"
159
+ ):
160
+ _ = join_dotted_str(Integer("0"))
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.125.3"
3
+ __version__ = "0.125.4"
@@ -0,0 +1,184 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Sequence
4
+ from dataclasses import dataclass
5
+ from subprocess import check_output
6
+ from typing import assert_never, override
7
+
8
+ from libcst import (
9
+ AsName,
10
+ Attribute,
11
+ BaseExpression,
12
+ FormattedString,
13
+ FormattedStringExpression,
14
+ FormattedStringText,
15
+ Import,
16
+ ImportAlias,
17
+ ImportFrom,
18
+ ImportStar,
19
+ Module,
20
+ Name,
21
+ )
22
+
23
+
24
+ def generate_from_import(
25
+ module: str, name: str, /, *, asname: str | None = None
26
+ ) -> ImportFrom:
27
+ """Generate an `ImportFrom` object."""
28
+ alias = ImportAlias(
29
+ name=Name(name), asname=AsName(Name(asname)) if asname else None
30
+ )
31
+ return ImportFrom(module=split_dotted_str(module), names=[alias])
32
+
33
+
34
+ def generate_f_string(var: str, suffix: str, /) -> FormattedString:
35
+ """Generate an f-string."""
36
+ return FormattedString([
37
+ FormattedStringExpression(expression=Name(var)),
38
+ FormattedStringText(suffix),
39
+ ])
40
+
41
+
42
+ def generate_import(module: str, /, *, asname: str | None = None) -> Import:
43
+ """Generate an `Import` object."""
44
+ alias = ImportAlias(
45
+ name=split_dotted_str(module), asname=AsName(Name(asname)) if asname else None
46
+ )
47
+ return Import(names=[alias])
48
+
49
+
50
+ ##
51
+
52
+
53
+ @dataclass(kw_only=True, slots=True)
54
+ class _ParseImportOutput:
55
+ module: str
56
+ name: str | None = None
57
+
58
+
59
+ def parse_import(import_: Import | ImportFrom, /) -> Sequence[_ParseImportOutput]:
60
+ """Parse an import."""
61
+ match import_:
62
+ case Import():
63
+ return [_parse_import_one(n) for n in import_.names]
64
+ case ImportFrom():
65
+ if (attr_or_name := import_.module) is None:
66
+ raise _ParseImportEmptyModuleError(import_=import_)
67
+ module = join_dotted_str(attr_or_name)
68
+ match import_.names:
69
+ case Sequence() as names:
70
+ return [_parse_import_from_one(module, n) for n in names]
71
+ case ImportStar():
72
+ return [_ParseImportOutput(module=module, name="*")]
73
+ case _ as never:
74
+ assert_never(never)
75
+ case _ as never:
76
+ assert_never(never)
77
+
78
+
79
+ def _parse_import_one(alias: ImportAlias, /) -> _ParseImportOutput:
80
+ return _ParseImportOutput(module=join_dotted_str(alias.name))
81
+
82
+
83
+ def _parse_import_from_one(module: str, alias: ImportAlias, /) -> _ParseImportOutput:
84
+ match alias.name:
85
+ case Name(name):
86
+ return _ParseImportOutput(module=module, name=name)
87
+ case Attribute() as attr:
88
+ raise _ParseImportAliasError(module=module, attr=attr)
89
+ case _ as never:
90
+ assert_never(never)
91
+
92
+
93
+ @dataclass(kw_only=True, slots=True)
94
+ class ParseImportError(Exception): ...
95
+
96
+
97
+ @dataclass(kw_only=True, slots=True)
98
+ class _ParseImportEmptyModuleError(ParseImportError):
99
+ import_: ImportFrom
100
+
101
+ @override
102
+ def __str__(self) -> str:
103
+ return f"Module must not be None; got {self.import_}"
104
+
105
+
106
+ @dataclass(kw_only=True, slots=True)
107
+ class _ParseImportAliasError(ParseImportError):
108
+ module: str
109
+ attr: Attribute
110
+
111
+ @override
112
+ def __str__(self) -> str:
113
+ attr = self.attr
114
+ return f"Invalid alias name; got module {self.module!r} and attribute '{attr.value.value}.{attr.attr.value}'"
115
+
116
+
117
+ ##
118
+
119
+
120
+ def split_dotted_str(dotted: str, /) -> Name | Attribute:
121
+ """Split a dotted string into a name/attribute."""
122
+ parts = dotted.split(".")
123
+ node = Name(parts[0])
124
+ for part in parts[1:]:
125
+ node = Attribute(value=node, attr=Name(part))
126
+ return node
127
+
128
+
129
+ def join_dotted_str(name_or_attr: Name | Attribute, /) -> str:
130
+ """Join a dotted from from a name/attribute."""
131
+ parts: Sequence[str] = []
132
+ curr: BaseExpression | Name | Attribute = name_or_attr
133
+ while True:
134
+ match curr:
135
+ case Name(value=value):
136
+ parts.append(value)
137
+ break
138
+ case Attribute(value=value, attr=Name(value=attr_value)):
139
+ parts.append(attr_value)
140
+ curr = value
141
+ case BaseExpression() as expr:
142
+ raise JoinDottedStrError(name_or_attr=name_or_attr, expr=expr)
143
+ case _ as never:
144
+ assert_never(never)
145
+ return ".".join(reversed(parts))
146
+
147
+
148
+ @dataclass(kw_only=True, slots=True)
149
+ class JoinDottedStrError(Exception):
150
+ name_or_attr: Name | Attribute
151
+ expr: BaseExpression
152
+
153
+ @override
154
+ def __str__(self) -> str:
155
+ return f"Only names & attributes allowed; got {self.expr}"
156
+
157
+
158
+ ##
159
+
160
+
161
+ def render_module(source: str | Module, /) -> str:
162
+ """Render a module."""
163
+ match source: # skipif-ci
164
+ case str() as text:
165
+ return check_output(["ruff", "format", "-"], input=text, text=True)
166
+ case Module() as module:
167
+ return render_module(module.code)
168
+ case _ as never:
169
+ assert_never(never)
170
+
171
+
172
+ ##
173
+
174
+
175
+ __all__ = [
176
+ "ParseImportError",
177
+ "generate_f_string",
178
+ "generate_from_import",
179
+ "generate_import",
180
+ "join_dotted_str",
181
+ "parse_import",
182
+ "render_module",
183
+ "split_dotted_str",
184
+ ]