dycw-utilities 0.125.3__tar.gz → 0.125.5__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.5}/PKG-INFO +6 -6
  2. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/pyproject.toml +14 -11
  3. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_iterables.py +2 -165
  4. dycw_utilities-0.125.5/src/tests/test_libcst.py +158 -0
  5. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_loguru.py +1 -6
  6. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_polars.py +2 -9
  7. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pytest.py +1 -1
  8. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sqlalchemy_polars.py +1 -3
  9. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/__init__.py +1 -1
  10. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/iterables.py +1 -53
  11. dycw_utilities-0.125.5/src/utilities/libcst.py +176 -0
  12. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/lightweight_charts.py +1 -1
  13. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/polars.py +8 -8
  14. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/polars_ols.py +1 -3
  15. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pyrsistent.py +5 -5
  16. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pytest.py +3 -5
  17. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sqlalchemy_polars.py +1 -4
  18. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/.gitignore +0 -0
  19. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/LICENSE +0 -0
  20. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/README.md +0 -0
  21. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/__init__.py +0 -0
  22. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/conftest.py +0 -0
  23. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/__init__.py +0 -0
  24. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_missing/__init__.py +0 -0
  25. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_missing/module.py +0 -0
  26. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/__init__.py +0 -0
  27. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/outer_1.py +0 -0
  28. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/outer_2.py +0 -0
  29. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  30. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  31. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  32. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  33. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/__init__.py +0 -0
  34. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/module_1.py +0 -0
  35. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/package_without/module_2.py +0 -0
  36. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/standalone.py +0 -0
  37. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/modules/with_imports.py +0 -0
  38. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  39. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  40. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  41. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  42. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  43. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  44. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  45. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  46. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_altair.py +0 -0
  47. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_asyncio.py +0 -0
  48. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_atomicwrites.py +0 -0
  49. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_atools.py +0 -0
  50. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cachetools.py +0 -0
  51. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_click.py +0 -0
  52. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_concurrent.py +0 -0
  53. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_contextlib.py +0 -0
  54. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_contextvars.py +0 -0
  55. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cryptography.py +0 -0
  56. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_cvxpy.py +0 -0
  57. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_dataclasses.py +0 -0
  58. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_datetime.py +0 -0
  59. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_enum.py +0 -0
  60. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_errors.py +0 -0
  61. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_eventkit.py +0 -0
  62. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_fastapi.py +0 -0
  63. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_fpdf2.py +0 -0
  64. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_functions.py +0 -0
  65. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_functools.py +0 -0
  66. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_getpass.py +0 -0
  67. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_git.py +0 -0
  68. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_hashlib.py +0 -0
  69. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_http.py +0 -0
  70. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_hypothesis.py +0 -0
  71. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_importlib.py +0 -0
  72. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_ipython.py +0 -0
  73. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_jupyter.py +0 -0
  74. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_lightweight_charts.py +0 -0
  75. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_logging.py +0 -0
  76. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_luigi.py +0 -0
  77. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_math.py +0 -0
  78. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_memory_profiler.py +0 -0
  79. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_modules.py +0 -0
  80. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_more_itertools.py +0 -0
  81. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_numpy.py +0 -0
  82. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_operator.py +0 -0
  83. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_optuna.py +0 -0
  84. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_orjson.py +0 -0
  85. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_os.py +0 -0
  86. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_parse.py +0 -0
  87. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pathlib.py +0 -0
  88. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_period.py +0 -0
  89. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pickle.py +0 -0
  90. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_platform.py +0 -0
  91. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_polars_ols.py +0 -0
  92. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pqdm.py +0 -0
  93. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pydantic.py +0 -0
  94. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pyinstrument.py +0 -0
  95. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pyrsistent.py +0 -0
  96. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_pytest_regressions.py +0 -0
  97. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_python_dotenv.py +0 -0
  98. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_random.py +0 -0
  99. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_re.py +0 -0
  100. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_redis.py +0 -0
  101. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_reprlib.py +0 -0
  102. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_rich.py +0 -0
  103. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_scipy.py +0 -0
  104. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sentinel.py +0 -0
  105. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_shelve.py +0 -0
  106. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_slack_sdk.py +0 -0
  107. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_socket.py +0 -0
  108. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sqlalchemy.py +0 -0
  109. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_statsmodel.py +0 -0
  110. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_streamlit.py +0 -0
  111. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_sys.py +0 -0
  112. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tempfile.py +0 -0
  113. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tenacity.py +0 -0
  114. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_text.py +0 -0
  115. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_threading.py +0 -0
  116. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_timer.py +0 -0
  117. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback.py +0 -0
  118. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/__init__.py +0 -0
  119. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/chain.py +0 -0
  120. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  121. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  122. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  123. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/many.py +0 -0
  124. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/one.py +0 -0
  125. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/recursive.py +0 -0
  126. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  127. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  128. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/two.py +0 -0
  129. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_traceback_funcs/untraced.py +0 -0
  130. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_types.py +0 -0
  131. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing.py +0 -0
  132. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/__init__.py +0 -0
  133. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/no_future.py +0 -0
  134. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_typing_funcs/with_future.py +0 -0
  135. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tzdata.py +0 -0
  136. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_tzlocal.py +0 -0
  137. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_uuid.py +0 -0
  138. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_version.py +0 -0
  139. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_warnings.py +0 -0
  140. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_whenever.py +0 -0
  141. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_zipfile.py +0 -0
  142. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/tests/test_zoneinfo.py +0 -0
  143. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/altair.py +0 -0
  144. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/asyncio.py +0 -0
  145. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/atomicwrites.py +0 -0
  146. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/atools.py +0 -0
  147. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cachetools.py +0 -0
  148. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/click.py +0 -0
  149. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/concurrent.py +0 -0
  150. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/contextlib.py +0 -0
  151. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/contextvars.py +0 -0
  152. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cryptography.py +0 -0
  153. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/cvxpy.py +0 -0
  154. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/dataclasses.py +0 -0
  155. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/datetime.py +0 -0
  156. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/enum.py +0 -0
  157. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/errors.py +0 -0
  158. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/eventkit.py +0 -0
  159. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/fastapi.py +0 -0
  160. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/fpdf2.py +0 -0
  161. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/functions.py +0 -0
  162. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/functools.py +0 -0
  163. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/getpass.py +0 -0
  164. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/git.py +0 -0
  165. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/hashlib.py +0 -0
  166. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/http.py +0 -0
  167. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/hypothesis.py +0 -0
  168. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/importlib.py +0 -0
  169. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/ipython.py +0 -0
  170. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/jupyter.py +0 -0
  171. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/logging.py +0 -0
  172. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/loguru.py +0 -0
  173. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/luigi.py +0 -0
  174. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/math.py +0 -0
  175. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/memory_profiler.py +0 -0
  176. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/modules.py +0 -0
  177. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/more_itertools.py +0 -0
  178. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/numpy.py +0 -0
  179. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/operator.py +0 -0
  180. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/optuna.py +0 -0
  181. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/orjson.py +0 -0
  182. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/os.py +0 -0
  183. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/parse.py +0 -0
  184. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pathlib.py +0 -0
  185. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/period.py +0 -0
  186. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pickle.py +0 -0
  187. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/platform.py +0 -0
  188. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pqdm.py +0 -0
  189. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/py.typed +0 -0
  190. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pydantic.py +0 -0
  191. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pyinstrument.py +0 -0
  192. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/pytest_regressions.py +0 -0
  193. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/python_dotenv.py +0 -0
  194. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/random.py +0 -0
  195. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/re.py +0 -0
  196. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/redis.py +0 -0
  197. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/reprlib.py +0 -0
  198. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/rich.py +0 -0
  199. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/scipy.py +0 -0
  200. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sentinel.py +0 -0
  201. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/shelve.py +0 -0
  202. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/slack_sdk.py +0 -0
  203. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/socket.py +0 -0
  204. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sqlalchemy.py +0 -0
  205. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/statsmodels.py +0 -0
  206. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/streamlit.py +0 -0
  207. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/sys.py +0 -0
  208. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tempfile.py +0 -0
  209. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tenacity.py +0 -0
  210. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/text.py +0 -0
  211. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/threading.py +0 -0
  212. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/timer.py +0 -0
  213. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/traceback.py +0 -0
  214. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/types.py +0 -0
  215. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/typing.py +0 -0
  216. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tzdata.py +0 -0
  217. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/tzlocal.py +0 -0
  218. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/uuid.py +0 -0
  219. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/version.py +0 -0
  220. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/warnings.py +0 -0
  221. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/whenever.py +0 -0
  222. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/zipfile.py +0 -0
  223. {dycw_utilities-0.125.3 → dycw_utilities-0.125.5}/src/utilities/zoneinfo.py +0 -0
@@ -1,16 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.125.3
3
+ Version: 0.125.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
7
  Requires-Dist: typing-extensions<4.14,>=4.13.1
8
8
  Provides-Extra: test
9
- Requires-Dist: hypothesis<6.132,>=6.131.27; extra == 'test'
9
+ Requires-Dist: hypothesis<6.132,>=6.131.28; 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'
@@ -41,7 +41,7 @@ Requires-Dist: whenever<0.9,>=0.8.2; extra == 'zzz-test-click'
41
41
  Provides-Extra: zzz-test-contextlib
42
42
  Provides-Extra: zzz-test-contextvars
43
43
  Provides-Extra: zzz-test-cryptography
44
- Requires-Dist: cryptography<45.1,>=45.0.2; extra == 'zzz-test-cryptography'
44
+ Requires-Dist: cryptography<45.1,>=45.0.3; extra == 'zzz-test-cryptography'
45
45
  Provides-Extra: zzz-test-cvxpy
46
46
  Requires-Dist: cvxpy<1.7,>=1.6.5; extra == 'zzz-test-cvxpy'
47
47
  Provides-Extra: zzz-test-dataclasses
@@ -78,7 +78,7 @@ Provides-Extra: zzz-test-hypothesis
78
78
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
79
79
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
80
80
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
81
- Requires-Dist: hypothesis<6.132,>=6.131.27; extra == 'zzz-test-hypothesis'
81
+ Requires-Dist: hypothesis<6.132,>=6.131.28; extra == 'zzz-test-hypothesis'
82
82
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
83
83
  Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
84
84
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
@@ -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
@@ -18,14 +18,14 @@ dev = [
18
18
  "click >= 8.2.1, < 8.3",
19
19
  "coloredlogs >= 15.0.1, < 15.1",
20
20
  "concurrent-log-handler >= 0.9.26, < 0.10",
21
- "cryptography >= 45.0.2, < 45.1",
21
+ "cryptography >= 45.0.3, < 45.1",
22
22
  "cvxpy >= 1.6.5, < 1.7",
23
23
  "eventkit >= 1.0.3, < 1.1",
24
24
  "fastapi >= 0.115.11, < 0.116",
25
25
  "fpdf2 >= 2.8.3, < 2.9",
26
26
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
27
27
  "httpx >= 0.28.1, < 0.29", # for fastapi
28
- "hypothesis >= 6.131.27, < 6.132",
28
+ "hypothesis >= 6.131.28, < 6.132",
29
29
  "img2pdf >= 0.6.0, < 0.7",
30
30
  "lightweight-charts >= 2.1, < 2.2",
31
31
  "loguru >= 0.7.3, < 0.8",
@@ -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",
@@ -44,6 +45,7 @@ dev = [
44
45
  "psycopg2-binary >= 2.9.10, < 2.10", # for sqlalchemy
45
46
  "pydantic >= 2.11.4, < 2.12",
46
47
  "pyinstrument >= 5.0.2, < 5.1",
48
+ "pyright[nodejs] >= 1.1.401, < 1.2",
47
49
  "pyrsistent >= 0.20.0, < 0.21",
48
50
  "pytest >= 8.3.5, < 8.4",
49
51
  "pytest-regressions >= 2.7.0, < 2.8",
@@ -70,7 +72,7 @@ dev = [
70
72
  "pytest-asyncio >= 0.26.0, < 0.27",
71
73
  "pytest-cov >= 6.1.1, < 6.2",
72
74
  "pytest-instafail >= 0.5.0, < 0.6",
73
- "pytest-lazy-fixtures >= 1.1.2, < 1.2",
75
+ "pytest-lazy-fixtures >= 1.1.3, < 1.2",
74
76
  "pytest-only >= 2.1.2, < 2.2",
75
77
  "pytest-randomly >= 3.16.0, < 3.17",
76
78
  "pytest-rerunfailures >= 15.1, < 16",
@@ -91,16 +93,16 @@ dependencies = [
91
93
  name = "dycw-utilities"
92
94
  readme = "README.md"
93
95
  requires-python = ">= 3.12"
94
- version = "0.125.3"
96
+ version = "0.125.5"
95
97
 
96
98
  [project.optional-dependencies]
97
99
  test = [
98
- "hypothesis >= 6.131.27, < 6.132",
100
+ "hypothesis >= 6.131.28, < 6.132",
99
101
  "pytest >= 8.3.5, < 8.4",
100
102
  "pytest-asyncio >= 0.26.0, < 0.27",
101
103
  "pytest-cov >= 6.1.1, < 6.2",
102
104
  "pytest-instafail >= 0.5.0, < 0.6",
103
- "pytest-lazy-fixtures >= 1.1.2, < 1.2",
105
+ "pytest-lazy-fixtures >= 1.1.3, < 1.2",
104
106
  "pytest-only >= 2.1.2, < 2.2",
105
107
  "pytest-randomly >= 3.16.0, < 3.17",
106
108
  "pytest-regressions >= 2.7.0, < 2.8",
@@ -131,7 +133,7 @@ zzz-test-click = [
131
133
  ]
132
134
  zzz-test-contextlib = []
133
135
  zzz-test-contextvars = []
134
- zzz-test-cryptography = ["cryptography >= 45.0.2, < 45.1"]
136
+ zzz-test-cryptography = ["cryptography >= 45.0.3, < 45.1"]
135
137
  zzz-test-cvxpy = ["cvxpy >= 1.6.5, < 1.7"]
136
138
  zzz-test-dataclasses = [
137
139
  "orjson >= 3.10.15, < 3.11",
@@ -172,7 +174,7 @@ zzz-test-hypothesis = [
172
174
  "aiosqlite >= 0.21.0, < 0.22",
173
175
  "asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
174
176
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
175
- "hypothesis >= 6.131.27, < 6.132",
177
+ "hypothesis >= 6.131.28, < 6.132",
176
178
  "luigi >= 3.6.0, < 3.7",
177
179
  "numpy >= 2.2.6, < 2.3",
178
180
  "pathvalidate >= 3.2.3, < 3.3",
@@ -268,7 +270,7 @@ zzz-test-scipy = ["scipy >= 1.15.3, < 1.16"]
268
270
  zzz-test-sentinel = []
269
271
  zzz-test-shelve = []
270
272
  zzz-test-slack-sdk = [
271
- "aiohttp >= 3.11.16, < 3.12", # for slack
273
+ "aiohttp >= 3.12.0, < 3.13", # for slack
272
274
  "slack-sdk >= 3.35.0, < 3.36",
273
275
  ]
274
276
  zzz-test-socket = []
@@ -332,7 +334,7 @@ zzz-test-zoneinfo = [
332
334
  # bump-my-version
333
335
  [tool.bumpversion]
334
336
  allow_dirty = true
335
- current_version = "0.125.3"
337
+ current_version = "0.125.5"
336
338
 
337
339
  [[tool.bumpversion.files]]
338
340
  filename = "src/utilities/__init__.py"
@@ -394,6 +396,7 @@ style = [
394
396
  [tool.pyright]
395
397
  deprecateTypingAliases = true
396
398
  enableReachabilityAnalysis = false
399
+ ignore = ["**/_typeshed/**"]
397
400
  pythonVersion = "3.12"
398
401
  reportAny = false
399
402
  reportCallInDefaultInitializer = true
@@ -1,14 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
- from dataclasses import dataclass, replace
4
+ from dataclasses import dataclass
5
5
  from enum import Enum, auto
6
6
  from functools import cmp_to_key
7
7
  from itertools import chain, repeat
8
8
  from math import isfinite, isinf, isnan, nan
9
9
  from operator import add, neg, sub
10
10
  from re import DOTALL
11
- from typing import TYPE_CHECKING, Any, ClassVar, override
11
+ from typing import TYPE_CHECKING, Any, ClassVar
12
12
 
13
13
  from hypothesis import given
14
14
  from hypothesis.strategies import (
@@ -52,7 +52,6 @@ from utilities.iterables import (
52
52
  CheckSubSetError,
53
53
  CheckSuperMappingError,
54
54
  CheckSuperSetError,
55
- Collection,
56
55
  EnsureIterableError,
57
56
  EnsureIterableNotStrError,
58
57
  MergeStrMappingsError,
@@ -637,168 +636,6 @@ class TestCmpNullable:
637
636
  assert result == expected
638
637
 
639
638
 
640
- @dataclass(unsafe_hash=True, slots=True)
641
- class _Item:
642
- n: int
643
-
644
-
645
- class TestCollection:
646
- def test_and_singleton(self) -> None:
647
- collection = Collection(map(_Item, range(3)))
648
- result = collection & _Item(1)
649
- assert isinstance(result, Collection)
650
- expected = Collection(_Item(1))
651
- assert result == expected
652
-
653
- def test_and_collection(self) -> None:
654
- collection = Collection(map(_Item, range(3)))
655
- result = collection & Collection(_Item(1))
656
- assert isinstance(result, Collection)
657
- expected = Collection(_Item(1))
658
- assert result == expected
659
-
660
- def test_and_iterable(self) -> None:
661
- collection = Collection(map(_Item, range(3)))
662
- result = collection & [_Item(1)]
663
- assert isinstance(result, Collection)
664
- expected = Collection(_Item(1))
665
- assert result == expected
666
-
667
- def test_filter(self) -> None:
668
- collection = Collection(map(_Item, range(4)))
669
- result = collection.filter(lambda item: item.n % 2 == 0)
670
- assert isinstance(result, Collection)
671
- expected = Collection(_Item(0), _Item(2))
672
- assert result == expected
673
-
674
- def test_hash(self) -> None:
675
- collection = Collection(map(_Item, range(3)))
676
- _ = hash(collection)
677
-
678
- def test_init(self) -> None:
679
- class SubCollection(Collection[_Item]):
680
- @override
681
- def __init__(self, *item_or_items: MaybeIterable[_Item]) -> None:
682
- super().__init__(*item_or_items)
683
- if any(item.n >= 1 for item in self):
684
- msg = "n >= 1 is not permitted"
685
- raise ValueError(msg)
686
-
687
- with raises(ValueError, match="n >= 1 is not permitted"):
688
- _ = SubCollection(map(_Item, range(3)))
689
-
690
- def test_map_return_same_type(self) -> None:
691
- collection = Collection(map(_Item, range(3)))
692
- result = collection.map(lambda item: replace(item, n=item.n + 1))
693
- assert isinstance(result, Collection)
694
- expected = Collection(map(_Item, range(1, 4)))
695
- assert result == expected
696
-
697
- def test_map_return_different_type(self) -> None:
698
- collection = Collection(map(_Item, range(3)))
699
- result = collection.map(lambda item: item.n)
700
- assert isinstance(result, Collection)
701
- expected = Collection(range(3))
702
- assert result == expected
703
-
704
- def test_new_one_singleton(self) -> None:
705
- collection = Collection(_Item(1))
706
- assert isinstance(collection, Collection)
707
- assert len(collection) == 1
708
- assert one(collection) == _Item(1)
709
-
710
- def test_new_one_iterable(self) -> None:
711
- collection = Collection(map(_Item, range(3)))
712
- assert isinstance(collection, Collection)
713
- assert len(collection) == 3
714
-
715
- def test_new_many_singletons(self) -> None:
716
- collection = Collection(_Item(1), _Item(2), _Item(3))
717
- assert isinstance(collection, Collection)
718
- assert len(collection) == 3
719
-
720
- def test_new_many_iterables(self) -> None:
721
- collection = Collection(map(_Item, range(3)), map(_Item, range(3)))
722
- assert isinstance(collection, Collection)
723
- assert len(collection) == 3
724
-
725
- def test_new_check_items(self) -> None:
726
- class SubCollection(Collection[_Item]):
727
- @classmethod
728
- @override
729
- def check_items(cls, items: Iterable[_Item]) -> None:
730
- if any(item.n >= 1 for item in items):
731
- msg = "n >= 1 is not permitted"
732
- raise ValueError(msg)
733
-
734
- with raises(ValueError, match="n >= 1 is not permitted"):
735
- _ = SubCollection(map(_Item, range(3)))
736
-
737
- def test_or_singleton(self) -> None:
738
- collection = Collection(map(_Item, range(3)))
739
- result = collection | _Item(3)
740
- assert isinstance(result, Collection)
741
- expected = Collection(map(_Item, range(4)))
742
- assert result == expected
743
-
744
- def test_or_collection(self) -> None:
745
- collection = Collection(map(_Item, range(3)))
746
- result = collection | Collection(map(_Item, range(1, 4)))
747
- assert isinstance(result, Collection)
748
- expected = Collection(map(_Item, range(4)))
749
- assert result == expected
750
-
751
- def test_or_iterable(self) -> None:
752
- collection = Collection(map(_Item, range(3)))
753
- result = collection | map(_Item, range(1, 4))
754
- assert isinstance(result, Collection)
755
- expected = Collection(map(_Item, range(4)))
756
- assert result == expected
757
-
758
- def test_partition(self) -> None:
759
- collection = Collection(map(_Item, range(4)))
760
- result_false, result_true = collection.partition(lambda item: item.n % 2 == 0)
761
- assert isinstance(result_false, Collection)
762
- expected_false = Collection(_Item(1), _Item(3))
763
- assert result_false == expected_false
764
- assert isinstance(result_true, Collection)
765
- expected_true = Collection(_Item(0), _Item(2))
766
- assert result_true == expected_true
767
-
768
- def test_repr(self) -> None:
769
- collection = Collection(map(_Item, range(3)))
770
- result = repr(collection)
771
- expected = "Collection({_Item(n=0), _Item(n=1), _Item(n=2)})"
772
- assert result == expected
773
-
774
- def test_str(self) -> None:
775
- collection = Collection(map(_Item, range(3)))
776
- result = str(collection)
777
- expected = "Collection({_Item(n=0), _Item(n=1), _Item(n=2)})"
778
- assert result == expected
779
-
780
- def test_sub_single_item(self) -> None:
781
- collection = Collection(map(_Item, range(3)))
782
- result = collection - _Item(1)
783
- assert isinstance(result, Collection)
784
- expected = Collection(_Item(0), _Item(2))
785
- assert result == expected
786
-
787
- def test_sub_collection(self) -> None:
788
- collection = Collection(map(_Item, range(3)))
789
- result = collection - Collection(_Item(1))
790
- assert isinstance(result, Collection)
791
- expected = Collection(_Item(0), _Item(2))
792
- assert result == expected
793
-
794
- def test_sub_iterable(self) -> None:
795
- collection = Collection(map(_Item, range(3)))
796
- result = collection - [_Item(1)]
797
- assert isinstance(result, Collection)
798
- expected = Collection(_Item(0), _Item(2))
799
- assert result == expected
800
-
801
-
802
639
  class TestEnsureHashables:
803
640
  def test_main(self) -> None:
804
641
  assert ensure_hashables(1, 2, a=3, b=4) == ([1, 2], {"a": 3, "b": 4})
@@ -0,0 +1,158 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from re import DOTALL
5
+
6
+ from hypothesis import given
7
+ from hypothesis.strategies import sampled_from
8
+ from libcst import (
9
+ Attribute,
10
+ Dot,
11
+ Expr,
12
+ Import,
13
+ ImportAlias,
14
+ ImportFrom,
15
+ ImportStar,
16
+ Module,
17
+ Name,
18
+ SimpleStatementLine,
19
+ )
20
+ from pytest import raises
21
+
22
+ from tests.conftest import SKIPIF_CI
23
+ from utilities.iterables import one
24
+ from utilities.libcst import (
25
+ _ParseImportAliasError,
26
+ _ParseImportEmptyModuleError,
27
+ generate_f_string,
28
+ generate_from_import,
29
+ generate_import,
30
+ join_dotted_str,
31
+ parse_import,
32
+ render_module,
33
+ split_dotted_str,
34
+ )
35
+
36
+
37
+ class TestGenerateFString:
38
+ def test_main(self) -> None:
39
+ string = generate_f_string("foo", "bar")
40
+ result = Module([SimpleStatementLine([Expr(string)])]).code.strip("\n")
41
+ expected = 'f"{foo}bar"'
42
+ assert result == expected
43
+
44
+
45
+ class TestGenerateFromImport:
46
+ @given(
47
+ case=sampled_from([
48
+ ("foo", "bar", None, "from foo import bar"),
49
+ ("foo", "bar", "bar2", "from foo import bar as bar2"),
50
+ ("foo.bar", "baz", None, "from foo.bar import baz"),
51
+ ("foo.bar", "baz", "baz2", "from foo.bar import baz as baz2"),
52
+ ])
53
+ )
54
+ def test_main(self, *, case: tuple[str, str, str | None, str]) -> None:
55
+ module, name, asname, expected = case
56
+ imp = generate_from_import(module, name, asname=asname)
57
+ result = Module([SimpleStatementLine([imp])]).code.strip("\n")
58
+ assert result == expected
59
+
60
+
61
+ class TestGenerateImport:
62
+ @given(
63
+ case=sampled_from([
64
+ ("foo", None, "import foo"),
65
+ ("foo", "foo2", "import foo as foo2"),
66
+ ("foo.bar", None, "import foo.bar"),
67
+ ("foo.bar", "bar2", "import foo.bar as bar2"),
68
+ ])
69
+ )
70
+ def test_main(self, *, case: tuple[str, str | None, str]) -> None:
71
+ module, asname, expected = case
72
+ imp = generate_import(module, asname=asname)
73
+ result = Module([SimpleStatementLine([imp])]).code.strip("\n")
74
+ assert result == expected
75
+
76
+
77
+ class TestParseImport:
78
+ def test_import_one_name(self) -> None:
79
+ imp = Import(names=[ImportAlias(Name("foo"))])
80
+ parsed = one(parse_import(imp))
81
+ assert parsed.module == "foo"
82
+ assert parsed.name is None
83
+
84
+ def test_import_one_attr(self) -> None:
85
+ imp = Import(names=[ImportAlias(Attribute(Name("foo"), Name("bar")))])
86
+ parsed = one(parse_import(imp))
87
+ assert parsed.module == "foo.bar"
88
+ assert parsed.name is None
89
+
90
+ def test_import_many(self) -> None:
91
+ imp = Import(names=[ImportAlias(Name("foo")), ImportAlias(Name("bar"))])
92
+ result = parse_import(imp)
93
+ assert len(result) == 2
94
+ first, second = result
95
+ assert first.module == "foo"
96
+ assert first.name is None
97
+ assert second.module == "bar"
98
+ assert second.name is None
99
+
100
+ def test_from_import_one(self) -> None:
101
+ imp = ImportFrom(module=Name("foo"), names=[ImportAlias(Name("bar"))])
102
+ result = one(parse_import(imp))
103
+ assert result.module == "foo"
104
+ assert result.name == "bar"
105
+
106
+ def test_from_import_many(self) -> None:
107
+ imp = ImportFrom(
108
+ module=Name("foo"),
109
+ names=[ImportAlias(Name("bar")), ImportAlias(Name("baz"))],
110
+ )
111
+ result = parse_import(imp)
112
+ first, second = result
113
+ assert first.module == "foo"
114
+ assert first.name == "bar"
115
+ assert second.module == "foo"
116
+ assert second.name == "baz"
117
+
118
+ def test_from_import_star(self) -> None:
119
+ imp = ImportFrom(module=Name("foo"), names=ImportStar())
120
+ result = one(parse_import(imp))
121
+ assert result.module == "foo"
122
+ assert result.name == "*"
123
+
124
+ def test_error_empty_module(self) -> None:
125
+ alias = ImportAlias(name=Name("foo"))
126
+ imp = ImportFrom(module=None, names=[alias], relative=[Dot()])
127
+ with raises(
128
+ _ParseImportEmptyModuleError, match="Module must not be None; got .*"
129
+ ):
130
+ _ = parse_import(imp)
131
+
132
+ def test_error_alias(self) -> None:
133
+ alias = ImportAlias(name=Attribute(Name("foo"), Name("bar")))
134
+ imp = ImportFrom(module=Name("baz"), names=[alias])
135
+ with raises(
136
+ _ParseImportAliasError,
137
+ match=re.compile(
138
+ r"Invalid alias name; got module 'baz' and attribute 'Name\(.*\)'",
139
+ flags=DOTALL,
140
+ ),
141
+ ):
142
+ _ = parse_import(imp)
143
+
144
+
145
+ class TestRenderModule:
146
+ @SKIPIF_CI
147
+ def test_main(self) -> None:
148
+ module = Module([SimpleStatementLine([generate_import("foo")])])
149
+ result = render_module(module)
150
+ expected = "import foo\n"
151
+ assert result == expected
152
+
153
+
154
+ class TestSplitAndJoinDottedStr:
155
+ @given(text=sampled_from(["foo", "foo.bar", "foo.bar.baz"]))
156
+ def test_main(self, *, text: str) -> None:
157
+ result = join_dotted_str(split_dotted_str(text))
158
+ assert result == text
@@ -6,12 +6,7 @@ from re import search
6
6
  from typing import TYPE_CHECKING, Any, cast
7
7
 
8
8
  from loguru import logger
9
- from loguru._recattrs import (
10
- RecordFile, # pyright: ignore[reportPrivateImportUsage]
11
- RecordLevel, # pyright: ignore[reportPrivateImportUsage]
12
- RecordProcess, # pyright: ignore[reportPrivateImportUsage]
13
- RecordThread, # pyright: ignore[reportPrivateImportUsage]
14
- )
9
+ from loguru._recattrs import RecordFile, RecordLevel, RecordProcess, RecordThread
15
10
  from pytest import CaptureFixture, fixture, mark, param, raises
16
11
 
17
12
  from utilities.loguru import (
@@ -51,10 +51,7 @@ from polars import (
51
51
  lit,
52
52
  struct,
53
53
  )
54
- from polars._typing import (
55
- IntoExprColumn, # pyright: ignore[reportPrivateImportUsage]
56
- SchemaDict, # pyright: ignore[reportPrivateImportUsage]
57
- )
54
+ from polars._typing import IntoExprColumn, SchemaDict
58
55
  from polars.exceptions import ComputeError
59
56
  from polars.testing import assert_frame_equal, assert_series_equal
60
57
  from pytest import raises
@@ -177,11 +174,7 @@ if TYPE_CHECKING:
177
174
  from collections.abc import Callable, Iterable, Mapping, Sequence
178
175
  from zoneinfo import ZoneInfo
179
176
 
180
- from polars._typing import (
181
- IntoExprColumn, # pyright: ignore[reportPrivateImportUsage]
182
- PolarsDataType, # pyright: ignore[reportPrivateImportUsage]
183
- SchemaDict, # pyright: ignore[reportPrivateImportUsage]
184
- )
177
+ from polars._typing import IntoExprColumn, PolarsDataType, SchemaDict
185
178
  from polars.datatypes import DataTypeClass
186
179
 
187
180
  from utilities.types import MaybeType, StrMapping, WeekDay
@@ -19,7 +19,7 @@ from utilities.pytest import (
19
19
  if TYPE_CHECKING:
20
20
  from collections.abc import Sequence
21
21
 
22
- from _pytest.legacypath import Testdir # pyright: ignore[reportPrivateImportUsage]
22
+ from _pytest.legacypath import Testdir
23
23
 
24
24
 
25
25
  _ = random_state
@@ -111,9 +111,7 @@ from utilities.sqlalchemy_polars import (
111
111
  if TYPE_CHECKING:
112
112
  from collections.abc import Callable, Iterable, Sequence
113
113
 
114
- from polars._typing import (
115
- PolarsDataType, # pyright: ignore[reportPrivateImportUsage]
116
- )
114
+ from polars._typing import PolarsDataType
117
115
  from polars.datatypes import DataTypeClass
118
116
  from sqlalchemy.ext.asyncio import AsyncEngine
119
117
 
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.125.3"
3
+ __version__ = "0.125.5"
@@ -25,7 +25,6 @@ from typing import (
25
25
  Any,
26
26
  Generic,
27
27
  Literal,
28
- Self,
29
28
  TypeGuard,
30
29
  TypeVar,
31
30
  assert_never,
@@ -45,7 +44,7 @@ from utilities.math import (
45
44
  )
46
45
  from utilities.reprlib import get_repr
47
46
  from utilities.sentinel import Sentinel, sentinel
48
- from utilities.types import Sign, THashable, THashable2, TSupportsAdd, TSupportsLT
47
+ from utilities.types import Sign, THashable, TSupportsAdd, TSupportsLT
49
48
  from utilities.zoneinfo import UTC
50
49
 
51
50
  if TYPE_CHECKING:
@@ -722,57 +721,6 @@ def chunked(iterable: Iterable[_T], n: int, /) -> Iterator[Sequence[_T]]:
722
721
  ##
723
722
 
724
723
 
725
- class Collection(frozenset[THashable]):
726
- """A collection of hashable, sortable items."""
727
-
728
- def __new__(cls, *item_or_items: MaybeIterable[THashable]) -> Self:
729
- items = list(chain(*map(always_iterable, item_or_items)))
730
- cls.check_items(items)
731
- return super().__new__(cls, items)
732
-
733
- def __init__(self, *item_or_items: MaybeIterable[THashable]) -> None:
734
- super().__init__()
735
- _ = item_or_items
736
-
737
- @override
738
- def __and__(self, other: MaybeIterable[THashable], /) -> Self:
739
- if isinstance(other, type(self)):
740
- return type(self)(super().__and__(other))
741
- return self.__and__(type(self)(other))
742
-
743
- @override
744
- def __or__(self, other: MaybeIterable[THashable], /) -> Self:
745
- if isinstance(other, type(self)):
746
- return type(self)(super().__or__(other))
747
- return self.__or__(type(self)(other))
748
-
749
- @override
750
- def __sub__(self, other: MaybeIterable[THashable], /) -> Self:
751
- if isinstance(other, type(self)):
752
- return type(self)(super().__sub__(other))
753
- return self.__sub__(type(self)(other))
754
-
755
- @classmethod
756
- def check_items(cls, items: Iterable[THashable], /) -> None:
757
- _ = items
758
-
759
- def filter(self, func: Callable[[THashable], bool], /) -> Self:
760
- return type(self)(filter(func, self))
761
-
762
- def map(self, func: Callable[[THashable], THashable2], /) -> Collection[THashable2]:
763
- values = cast("Any", map(func, self))
764
- return cast("Any", type(self)(values))
765
-
766
- def partition(self, func: Callable[[THashable], bool], /) -> tuple[Self, Self]:
767
- from more_itertools import partition
768
-
769
- is_false, is_true = partition(func, self)
770
- return type(self)(is_false), type(self)(is_true)
771
-
772
-
773
- ##
774
-
775
-
776
724
  def ensure_hashables(
777
725
  *args: Any, **kwargs: Any
778
726
  ) -> tuple[list[Hashable], dict[str, Hashable]]: