dycw-utilities 0.109.6__tar.gz → 0.109.8__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 (222) hide show
  1. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/PKG-INFO +2 -2
  2. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/pyproject.toml +4 -4
  3. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_parse.py +70 -3
  4. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_typing_funcs/with_future.py +16 -0
  5. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/dataclasses.py +3 -3
  7. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/parse.py +15 -12
  8. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/python_dotenv.py +4 -7
  9. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/types.py +5 -0
  10. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/.gitignore +0 -0
  11. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/LICENSE +0 -0
  12. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/README.md +0 -0
  13. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/__init__.py +0 -0
  39. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_async_service/__init__.py +0 -0
  40. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_async_service/__main__.py +0 -0
  41. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_async_service/run.sh +0 -0
  42. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  43. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  44. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  45. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_altair.py +0 -0
  46. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_astor.py +0 -0
  47. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_asyncio.py +0 -0
  48. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_atomicwrites.py +0 -0
  49. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_atools.py +0 -0
  50. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_cachetools.py +0 -0
  51. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_click.py +0 -0
  52. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_concurrent.py +0 -0
  53. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_contextlib.py +0 -0
  54. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_contextvars.py +0 -0
  55. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_cryptography.py +0 -0
  56. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_cvxpy.py +0 -0
  57. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_dataclasses.py +0 -0
  58. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_datetime.py +0 -0
  59. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_enum.py +0 -0
  60. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_errors.py +0 -0
  61. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_eventkit.py +0 -0
  62. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_fastapi.py +0 -0
  63. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_fpdf2.py +0 -0
  64. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_functions.py +0 -0
  65. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_functools.py +0 -0
  66. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_getpass.py +0 -0
  67. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_git.py +0 -0
  68. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_hashlib.py +0 -0
  69. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_http.py +0 -0
  70. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_hypothesis.py +0 -0
  71. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_ipython.py +0 -0
  72. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_iterables.py +0 -0
  73. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_jupyter.py +0 -0
  74. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_logging.py +0 -0
  75. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_loguru.py +0 -0
  76. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_luigi.py +0 -0
  77. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_math.py +0 -0
  78. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_memory_profiler.py +0 -0
  79. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_modules.py +0 -0
  80. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_more_itertools.py +0 -0
  81. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_numpy.py +0 -0
  82. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_operator.py +0 -0
  83. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_optuna.py +0 -0
  84. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_orjson.py +0 -0
  85. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_os.py +0 -0
  86. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pathlib.py +0 -0
  87. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_period.py +0 -0
  88. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pickle.py +0 -0
  89. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_platform.py +0 -0
  90. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_polars.py +0 -0
  91. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pqdm.py +0 -0
  92. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pydantic.py +0 -0
  93. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pyinstrument.py +0 -0
  94. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pyrsistent.py +0 -0
  95. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pytest.py +0 -0
  96. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_pytest_regressions.py +0 -0
  97. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_python_dotenv.py +0 -0
  98. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_random.py +0 -0
  99. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_re.py +0 -0
  100. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_redis.py +0 -0
  101. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_reprlib.py +0 -0
  102. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_rich.py +0 -0
  103. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_scipy.py +0 -0
  104. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_sentinel.py +0 -0
  105. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_shelve.py +0 -0
  106. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_slack_sdk.py +0 -0
  107. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_socket.py +0 -0
  108. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_sqlalchemy.py +0 -0
  109. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_sqlalchemy_polars.py +0 -0
  110. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_streamlit.py +0 -0
  111. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_sys.py +0 -0
  112. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_tempfile.py +0 -0
  113. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_tenacity.py +0 -0
  114. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_text.py +0 -0
  115. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_threading.py +0 -0
  116. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_timer.py +0 -0
  117. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback.py +0 -0
  118. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/__init__.py +0 -0
  119. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/chain.py +0 -0
  120. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  121. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  122. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  123. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/many.py +0 -0
  124. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/one.py +0 -0
  125. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/recursive.py +0 -0
  126. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  127. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  128. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/two.py +0 -0
  129. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_traceback_funcs/untraced.py +0 -0
  130. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_types.py +0 -0
  131. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_typing.py +0 -0
  132. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_typing_funcs/__init__.py +0 -0
  133. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_typing_funcs/no_future.py +0 -0
  134. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_tzdata.py +0 -0
  135. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_tzlocal.py +0 -0
  136. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_uuid.py +0 -0
  137. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_version.py +0 -0
  138. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_warnings.py +0 -0
  139. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_whenever.py +0 -0
  140. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_zipfile.py +0 -0
  141. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/tests/test_zoneinfo.py +0 -0
  142. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/altair.py +0 -0
  143. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/astor.py +0 -0
  144. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/asyncio.py +0 -0
  145. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/atomicwrites.py +0 -0
  146. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/atools.py +0 -0
  147. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/cachetools.py +0 -0
  148. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/click.py +0 -0
  149. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/concurrent.py +0 -0
  150. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/contextlib.py +0 -0
  151. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/contextvars.py +0 -0
  152. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/cryptography.py +0 -0
  153. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/cvxpy.py +0 -0
  154. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/datetime.py +0 -0
  155. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/enum.py +0 -0
  156. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/errors.py +0 -0
  157. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/eventkit.py +0 -0
  158. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/fastapi.py +0 -0
  159. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/fpdf2.py +0 -0
  160. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/functions.py +0 -0
  161. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/functools.py +0 -0
  162. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/getpass.py +0 -0
  163. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/git.py +0 -0
  164. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/hashlib.py +0 -0
  165. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/http.py +0 -0
  166. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/hypothesis.py +0 -0
  167. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/ipython.py +0 -0
  168. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/iterables.py +0 -0
  169. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/jupyter.py +0 -0
  170. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/logging.py +0 -0
  171. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/loguru.py +0 -0
  172. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/luigi.py +0 -0
  173. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/math.py +0 -0
  174. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/memory_profiler.py +0 -0
  175. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/modules.py +0 -0
  176. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/more_itertools.py +0 -0
  177. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/numpy.py +0 -0
  178. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/operator.py +0 -0
  179. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/optuna.py +0 -0
  180. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/orjson.py +0 -0
  181. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/os.py +0 -0
  182. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pathlib.py +0 -0
  183. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/period.py +0 -0
  184. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pickle.py +0 -0
  185. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/platform.py +0 -0
  186. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/polars.py +0 -0
  187. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pqdm.py +0 -0
  188. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/py.typed +0 -0
  189. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pydantic.py +0 -0
  190. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pyinstrument.py +0 -0
  191. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pyrsistent.py +0 -0
  192. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pytest.py +0 -0
  193. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/pytest_regressions.py +0 -0
  194. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/random.py +0 -0
  195. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/re.py +0 -0
  196. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/redis.py +0 -0
  197. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/reprlib.py +0 -0
  198. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/rich.py +0 -0
  199. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/scipy.py +0 -0
  200. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/sentinel.py +0 -0
  201. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/shelve.py +0 -0
  202. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/slack_sdk.py +0 -0
  203. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/socket.py +0 -0
  204. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/sqlalchemy.py +0 -0
  205. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/sqlalchemy_polars.py +0 -0
  206. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/streamlit.py +0 -0
  207. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/sys.py +0 -0
  208. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/tempfile.py +0 -0
  209. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/tenacity.py +0 -0
  210. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/text.py +0 -0
  211. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/threading.py +0 -0
  212. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/timer.py +0 -0
  213. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/traceback.py +0 -0
  214. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/typing.py +0 -0
  215. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/tzdata.py +0 -0
  216. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/tzlocal.py +0 -0
  217. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/uuid.py +0 -0
  218. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/version.py +0 -0
  219. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/warnings.py +0 -0
  220. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/whenever.py +0 -0
  221. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/zipfile.py +0 -0
  222. {dycw_utilities-0.109.6 → dycw_utilities-0.109.8}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.109.6
3
+ Version: 0.109.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -177,7 +177,7 @@ Requires-Dist: scipy<1.16,>=1.15.2; extra == 'zzz-test-scipy'
177
177
  Provides-Extra: zzz-test-sentinel
178
178
  Provides-Extra: zzz-test-shelve
179
179
  Provides-Extra: zzz-test-slack-sdk
180
- Requires-Dist: aiohttp<3.12,>=3.11.17; extra == 'zzz-test-slack-sdk'
180
+ Requires-Dist: aiohttp<3.12,>=3.11.16; extra == 'zzz-test-slack-sdk'
181
181
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
182
182
  Provides-Extra: zzz-test-socket
183
183
  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.17, < 3.12", # for slack
11
+ "aiohttp >= 3.11.16, < 3.12", # for slack
12
12
  "aiosqlite >= 0.21.0, < 0.22",
13
13
  "altair >= 5.5.0, < 5.6",
14
14
  "astor >= 0.8.1, < 0.9",
@@ -89,7 +89,7 @@ dependencies = [
89
89
  name = "dycw-utilities"
90
90
  readme = "README.md"
91
91
  requires-python = ">= 3.12"
92
- version = "0.109.6"
92
+ version = "0.109.8"
93
93
 
94
94
  [project.optional-dependencies]
95
95
  test = [
@@ -268,7 +268,7 @@ zzz-test-scipy = ["scipy >= 1.15.2, < 1.16"]
268
268
  zzz-test-sentinel = []
269
269
  zzz-test-shelve = []
270
270
  zzz-test-slack-sdk = [
271
- "aiohttp >= 3.11.17, < 3.12", # for slack
271
+ "aiohttp >= 3.11.16, < 3.12", # for slack
272
272
  "slack-sdk >= 3.35.0, < 3.36",
273
273
  ]
274
274
  zzz-test-socket = []
@@ -332,7 +332,7 @@ zzz-test-zoneinfo = [
332
332
  # bump-my-version
333
333
  [tool.bumpversion]
334
334
  allow_dirty = true
335
- current_version = "0.109.6"
335
+ current_version = "0.109.8"
336
336
 
337
337
  [[tool.bumpversion.files]]
338
338
  filename = "src/utilities/__init__.py"
@@ -14,9 +14,14 @@ from pytest import raises
14
14
  from tests.test_operator import TruthEnum
15
15
  from tests.test_typing_funcs.with_future import (
16
16
  DataClassFutureInt,
17
+ DataClassFutureIntEven,
18
+ DataClassFutureIntEvenOrOddTypeUnion,
19
+ DataClassFutureIntEvenOrOddUnion,
20
+ DataClassFutureIntOdd,
17
21
  TrueOrFalseFutureLit,
18
22
  TrueOrFalseFutureTypeLit,
19
23
  )
24
+ from utilities.errors import ImpossibleCaseError
20
25
  from utilities.functions import ensure_path
21
26
  from utilities.hypothesis import (
22
27
  datetime_durations,
@@ -78,7 +83,7 @@ class TestParseText:
78
83
  assert result is truth
79
84
 
80
85
  @given(value=integers())
81
- def test_extra(self, *, value: int) -> None:
86
+ def test_extra_type(self, *, value: int) -> None:
82
87
  text = str(value)
83
88
  result = parse_text(
84
89
  DataClassFutureInt,
@@ -200,6 +205,60 @@ class TestParseText:
200
205
  result = parse_text(TrueOrFalseFutureTypeLit, truth)
201
206
  assert result == truth
202
207
 
208
+ @given(value=integers())
209
+ def test_type_union_with_extra(self, *, value: int) -> None:
210
+ def parse_even_or_odd(text: str, /) -> DataClassFutureIntEvenOrOddTypeUnion:
211
+ value = int(text)
212
+ match value % 2:
213
+ case 0:
214
+ return DataClassFutureIntEven(even_int=value)
215
+ case 1:
216
+ return DataClassFutureIntOdd(odd_int=value)
217
+ case _:
218
+ raise ImpossibleCaseError(case=[f"{value=}"])
219
+
220
+ text = str(value)
221
+ result = parse_text(
222
+ DataClassFutureIntEvenOrOddTypeUnion,
223
+ text,
224
+ extra={DataClassFutureIntEvenOrOddTypeUnion: parse_even_or_odd},
225
+ )
226
+ match value % 2:
227
+ case 0:
228
+ expected = DataClassFutureIntEven(even_int=value)
229
+ case 1:
230
+ expected = DataClassFutureIntOdd(odd_int=value)
231
+ case _:
232
+ raise ImpossibleCaseError(case=[f"{value=}"])
233
+ assert result == expected
234
+
235
+ @given(value=integers())
236
+ def test_union_with_extra(self, *, value: int) -> None:
237
+ def parse_even_or_odd(text: str, /) -> DataClassFutureIntEvenOrOddUnion:
238
+ value = int(text)
239
+ match value % 2:
240
+ case 0:
241
+ return DataClassFutureIntEven(even_int=value)
242
+ case 1:
243
+ return DataClassFutureIntOdd(odd_int=value)
244
+ case _:
245
+ raise ImpossibleCaseError(case=[f"{value=}"])
246
+
247
+ text = str(value)
248
+ result = parse_text(
249
+ DataClassFutureIntEvenOrOddUnion,
250
+ text,
251
+ extra={DataClassFutureIntEvenOrOddUnion: parse_even_or_odd},
252
+ )
253
+ match value % 2:
254
+ case 0:
255
+ expected = DataClassFutureIntEven(even_int=value)
256
+ case 1:
257
+ expected = DataClassFutureIntOdd(odd_int=value)
258
+ case _:
259
+ raise ImpossibleCaseError(case=[f"{value=}"])
260
+ assert result == expected
261
+
203
262
  @given(version=versions())
204
263
  def test_version(self, *, version: Version) -> None:
205
264
  text = str(version)
@@ -272,6 +331,13 @@ class TestParseText:
272
331
  },
273
332
  )
274
333
 
334
+ def test_error_union_type_extra(self) -> None:
335
+ with raises(
336
+ _ParseTextParseError,
337
+ match=r"Unable to parse tests\.test_typing_funcs\.with_future\.DataClassFutureIntEven \| tests\.test_typing_funcs\.with_future\.DataClassFutureIntOdd; got 'invalid'",
338
+ ):
339
+ _ = parse_text(DataClassFutureIntEvenOrOddUnion, "invalid", extra={})
340
+
275
341
  def test_error_float(self) -> None:
276
342
  with raises(
277
343
  _ParseTextParseError, match="Unable to parse <class 'float'>; got 'invalid'"
@@ -364,9 +430,10 @@ class TestParseText:
364
430
 
365
431
  def test_error_unknown_union_type(self) -> None:
366
432
  with raises(
367
- _ParseTextParseError, match=r"Unable to parse <class '.*'>; got 'invalid'"
433
+ _ParseTextParseError,
434
+ match=r"Unable to parse tests\.test_typing_funcs\.with_future\.DataClassFutureIntEven \| tests\.test_typing_funcs\.with_future\.DataClassFutureIntOdd; got 'invalid'",
368
435
  ):
369
- _ = parse_text(DataClassFutureInt | DataClassFutureInt, "invalid")
436
+ _ = parse_text(DataClassFutureIntEvenOrOddUnion, "invalid")
370
437
 
371
438
  def test_error_version(self) -> None:
372
439
  with raises(
@@ -54,6 +54,22 @@ class DataClassFutureIntDefault:
54
54
  int_: int = 0
55
55
 
56
56
 
57
+ @dataclass(order=True, unsafe_hash=True, kw_only=True)
58
+ class DataClassFutureIntEven:
59
+ even_int: int
60
+
61
+
62
+ @dataclass(order=True, unsafe_hash=True, kw_only=True)
63
+ class DataClassFutureIntOdd:
64
+ odd_int: int
65
+
66
+
67
+ DataClassFutureIntEvenOrOddUnion = DataClassFutureIntEven | DataClassFutureIntOdd
68
+ type DataClassFutureIntEvenOrOddTypeUnion = (
69
+ DataClassFutureIntEven | DataClassFutureIntOdd
70
+ )
71
+
72
+
57
73
  @dataclass(order=True, unsafe_hash=True, kw_only=True)
58
74
  class DataClassFutureIntNullable:
59
75
  int_: int | None = None
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.109.6"
3
+ __version__ = "0.109.8"
@@ -24,7 +24,7 @@ from utilities.iterables import OneStrEmptyError, OneStrNonUniqueError, one_str
24
24
  from utilities.operator import is_equal
25
25
  from utilities.parse import ParseTextError, parse_text
26
26
  from utilities.sentinel import Sentinel, sentinel
27
- from utilities.types import TDataclass
27
+ from utilities.types import ParseTextExtra, TDataclass
28
28
  from utilities.typing import get_type_hints
29
29
 
30
30
  if TYPE_CHECKING:
@@ -454,7 +454,7 @@ def text_to_dataclass(
454
454
  head: bool = False,
455
455
  case_sensitive: bool = False,
456
456
  allow_extra_keys: bool = False,
457
- extra_parsers: Mapping[type[_T], Callable[[str], _T]] | None = None,
457
+ extra_parsers: ParseTextExtra | None = None,
458
458
  ) -> TDataclass:
459
459
  """Construct a dataclass from a string or a mapping or strings."""
460
460
  match text_or_mapping:
@@ -524,7 +524,7 @@ def _text_to_dataclass_parse(
524
524
  *,
525
525
  head: bool = False,
526
526
  case_sensitive: bool = False,
527
- extra: Mapping[type[_T], Callable[[str], _T]] | None = None,
527
+ extra: ParseTextExtra | None = None,
528
528
  ) -> Any:
529
529
  try:
530
530
  return parse_text(
@@ -7,7 +7,7 @@ from enum import Enum
7
7
  from pathlib import Path
8
8
  from re import DOTALL
9
9
  from types import NoneType
10
- from typing import TYPE_CHECKING, Any, TypeVar, override
10
+ from typing import Any, override
11
11
 
12
12
  from utilities.datetime import is_subclass_date_not_datetime
13
13
  from utilities.enum import ParseEnumError, parse_enum
@@ -17,7 +17,7 @@ from utilities.math import ParseNumberError, parse_number
17
17
  from utilities.re import ExtractGroupError, extract_group
18
18
  from utilities.sentinel import ParseSentinelError, Sentinel, parse_sentinel
19
19
  from utilities.text import ParseBoolError, ParseNoneError, parse_bool, parse_none
20
- from utilities.types import Duration, Number
20
+ from utilities.types import Duration, Number, ParseTextExtra
21
21
  from utilities.typing import (
22
22
  get_args,
23
23
  is_literal_type,
@@ -27,12 +27,6 @@ from utilities.typing import (
27
27
  )
28
28
  from utilities.version import ParseVersionError, Version, parse_version
29
29
 
30
- if TYPE_CHECKING:
31
- from collections.abc import Callable, Mapping
32
-
33
-
34
- _T = TypeVar("_T")
35
-
36
30
 
37
31
  def parse_text(
38
32
  obj: Any,
@@ -41,7 +35,7 @@ def parse_text(
41
35
  *,
42
36
  head: bool = False,
43
37
  case_sensitive: bool = False,
44
- extra: Mapping[type[_T], Callable[[str], _T]] | None = None,
38
+ extra: ParseTextExtra | None = None,
45
39
  ) -> Any:
46
40
  """Parse text."""
47
41
  if obj is None:
@@ -76,7 +70,7 @@ def parse_text(
76
70
  for arg, text in zip(args, texts, strict=True)
77
71
  )
78
72
  if is_union_type(obj):
79
- return _parse_text_union_type(obj, text)
73
+ return _parse_text_union_type(obj, text, extra=extra)
80
74
  raise _ParseTextParseError(obj=obj, text=text) from None
81
75
 
82
76
 
@@ -86,7 +80,7 @@ def _parse_text_type(
86
80
  /,
87
81
  *,
88
82
  case_sensitive: bool = False,
89
- extra: Mapping[type[_T], Callable[[str], _T]] | None = None,
83
+ extra: ParseTextExtra | None = None,
90
84
  ) -> Any:
91
85
  """Parse text."""
92
86
  if issubclass(cls, NoneType):
@@ -170,7 +164,9 @@ def _parse_text_type(
170
164
  raise _ParseTextParseError(obj=cls, text=text) from None
171
165
 
172
166
 
173
- def _parse_text_union_type(obj: Any, text: str, /) -> Any:
167
+ def _parse_text_union_type(
168
+ obj: Any, text: str, /, *, extra: ParseTextExtra | None = None
169
+ ) -> Any:
174
170
  if obj is Number:
175
171
  try:
176
172
  return parse_number(text)
@@ -183,6 +179,13 @@ def _parse_text_union_type(obj: Any, text: str, /) -> Any:
183
179
  return parse_duration(text)
184
180
  except ParseDurationError:
185
181
  raise _ParseTextParseError(obj=obj, text=text) from None
182
+ if extra is not None:
183
+ try:
184
+ parser = one(p for c, p in extra.items() if c is obj)
185
+ except OneEmptyError:
186
+ pass
187
+ else:
188
+ return parser(text)
186
189
  raise _ParseTextParseError(obj=obj, text=text) from None
187
190
 
188
191
 
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
4
  from os import environ
5
- from typing import TYPE_CHECKING, TypeVar, override
5
+ from typing import TYPE_CHECKING, override
6
6
 
7
7
  from dotenv import dotenv_values
8
8
 
@@ -13,14 +13,11 @@ from utilities.pathlib import PWD
13
13
  from utilities.reprlib import get_repr
14
14
 
15
15
  if TYPE_CHECKING:
16
- from collections.abc import Callable, Mapping
16
+ from collections.abc import Mapping
17
17
  from collections.abc import Set as AbstractSet
18
18
  from pathlib import Path
19
19
 
20
- from utilities.types import PathLike, StrMapping, TDataclass
21
-
22
-
23
- _T = TypeVar("_T")
20
+ from utilities.types import ParseTextExtra, PathLike, StrMapping, TDataclass
24
21
 
25
22
 
26
23
  def load_settings(
@@ -33,7 +30,7 @@ def load_settings(
33
30
  warn_name_errors: bool = False,
34
31
  head: bool = False,
35
32
  case_sensitive: bool = False,
36
- extra_parsers: Mapping[type[_T], Callable[[str], _T]] | None = None,
33
+ extra_parsers: ParseTextExtra | None = None,
37
34
  ) -> TDataclass:
38
35
  """Load a set of settings from the `.env` file."""
39
36
  path = get_repo_root(cwd=cwd).joinpath(".env")
@@ -229,6 +229,10 @@ class SupportsRound(Protocol[_T_co]):
229
229
  def __round__(self, ndigits: int, /) -> _T_co: ...
230
230
 
231
231
 
232
+ # parse
233
+ type ParseTextExtra = Mapping[Any, Callable[[str], Any]]
234
+
235
+
232
236
  # pathlib
233
237
  type PathLike = MaybeStr[Path]
234
238
  type PathLikeOrCallable = PathLike | Callable[[], PathLike]
@@ -278,6 +282,7 @@ __all__ = [
278
282
  "OpenMode",
279
283
  "OptExcInfo",
280
284
  "Parallelism",
285
+ "ParseTextExtra",
281
286
  "PathLike",
282
287
  "PathLikeOrCallable",
283
288
  "RoundMode",