dycw-utilities 0.113.2__tar.gz → 0.113.3__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 (228) hide show
  1. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/PKG-INFO +3 -3
  2. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/pyproject.toml +5 -5
  3. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_datetime.py +82 -0
  4. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/__init__.py +1 -1
  5. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/datetime.py +98 -1
  6. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/.gitignore +0 -0
  7. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/LICENSE +0 -0
  8. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/README.md +0 -0
  9. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/__init__.py +0 -0
  10. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/conftest.py +0 -0
  11. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/__init__.py +0 -0
  35. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_async_service/__init__.py +0 -0
  36. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_async_service/__main__.py +0 -0
  37. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_async_service/run.sh +0 -0
  38. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  39. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  40. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  41. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_altair.py +0 -0
  42. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_astor.py +0 -0
  43. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_asyncio.py +0 -0
  44. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_atomicwrites.py +0 -0
  45. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_atools.py +0 -0
  46. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_cachetools.py +0 -0
  47. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_click.py +0 -0
  48. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_concurrent.py +0 -0
  49. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_contextlib.py +0 -0
  50. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_contextvars.py +0 -0
  51. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_cryptography.py +0 -0
  52. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_cvxpy.py +0 -0
  53. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_dataclasses.py +0 -0
  54. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_enum.py +0 -0
  55. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_errors.py +0 -0
  56. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_eventkit.py +0 -0
  57. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_fastapi.py +0 -0
  58. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_fpdf2.py +0 -0
  59. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_functions.py +0 -0
  60. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_functools.py +0 -0
  61. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_getpass.py +0 -0
  62. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_git.py +0 -0
  63. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_hashlib.py +0 -0
  64. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_http.py +0 -0
  65. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_hypothesis.py +0 -0
  66. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_ipython.py +0 -0
  67. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_iterables.py +0 -0
  68. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_jupyter.py +0 -0
  69. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_lightweight_charts.py +0 -0
  70. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_logging.py +0 -0
  71. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_loguru.py +0 -0
  72. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_luigi.py +0 -0
  73. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_math.py +0 -0
  74. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_memory_profiler.py +0 -0
  75. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_modules.py +0 -0
  76. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_more_itertools.py +0 -0
  77. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_numpy.py +0 -0
  78. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_period.py +0 -0
  85. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pickle.py +0 -0
  86. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_platform.py +0 -0
  87. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_polars.py +0 -0
  88. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_polars_ols.py +0 -0
  89. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pqdm.py +0 -0
  90. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pydantic.py +0 -0
  91. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pyrsistent.py +0 -0
  93. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_python_dotenv.py +0 -0
  96. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_redis.py +0 -0
  99. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_reprlib.py +0 -0
  100. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_rich.py +0 -0
  101. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_scipy.py +0 -0
  102. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_sentinel.py +0 -0
  103. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_shelve.py +0 -0
  104. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_slack_sdk.py +0 -0
  105. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_socket.py +0 -0
  106. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_sqlalchemy.py +0 -0
  107. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_sqlalchemy_polars.py +0 -0
  108. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_statsmodel.py +0 -0
  109. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_streamlit.py +0 -0
  110. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_sys.py +0 -0
  111. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_tempfile.py +0 -0
  112. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_tenacity.py +0 -0
  113. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_text.py +0 -0
  114. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_threading.py +0 -0
  115. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_timer.py +0 -0
  116. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback.py +0 -0
  117. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/__init__.py +0 -0
  118. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/chain.py +0 -0
  119. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  120. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  121. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  122. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/many.py +0 -0
  123. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/one.py +0 -0
  124. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/recursive.py +0 -0
  125. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  126. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  127. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/two.py +0 -0
  128. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_traceback_funcs/untraced.py +0 -0
  129. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_types.py +0 -0
  130. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_typing.py +0 -0
  131. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_typing_funcs/__init__.py +0 -0
  132. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_typing_funcs/no_future.py +0 -0
  133. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_typing_funcs/with_future.py +0 -0
  134. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_tzdata.py +0 -0
  135. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_tzlocal.py +0 -0
  136. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_uuid.py +0 -0
  137. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_version.py +0 -0
  138. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_warnings.py +0 -0
  139. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_whenever.py +0 -0
  140. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_zipfile.py +0 -0
  141. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/tests/test_zoneinfo.py +0 -0
  142. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/altair.py +0 -0
  143. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/astor.py +0 -0
  144. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/asyncio.py +0 -0
  145. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/atomicwrites.py +0 -0
  146. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/atools.py +0 -0
  147. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/cachetools.py +0 -0
  148. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/click.py +0 -0
  149. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/concurrent.py +0 -0
  150. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/contextlib.py +0 -0
  151. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/contextvars.py +0 -0
  152. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/cryptography.py +0 -0
  153. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/cvxpy.py +0 -0
  154. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/dataclasses.py +0 -0
  155. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/enum.py +0 -0
  156. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/errors.py +0 -0
  157. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/eventkit.py +0 -0
  158. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/fastapi.py +0 -0
  159. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/fpdf2.py +0 -0
  160. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/functions.py +0 -0
  161. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/functools.py +0 -0
  162. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/getpass.py +0 -0
  163. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/git.py +0 -0
  164. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/hashlib.py +0 -0
  165. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/http.py +0 -0
  166. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/hypothesis.py +0 -0
  167. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/ipython.py +0 -0
  168. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/iterables.py +0 -0
  169. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/jupyter.py +0 -0
  170. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/lightweight_charts.py +0 -0
  171. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/logging.py +0 -0
  172. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/loguru.py +0 -0
  173. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/luigi.py +0 -0
  174. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/math.py +0 -0
  175. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/memory_profiler.py +0 -0
  176. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/modules.py +0 -0
  177. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/more_itertools.py +0 -0
  178. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/numpy.py +0 -0
  179. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/operator.py +0 -0
  180. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/optuna.py +0 -0
  181. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/orjson.py +0 -0
  182. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/os.py +0 -0
  183. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/parse.py +0 -0
  184. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pathlib.py +0 -0
  185. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/period.py +0 -0
  186. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pickle.py +0 -0
  187. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/platform.py +0 -0
  188. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/polars.py +0 -0
  189. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/polars_ols.py +0 -0
  190. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pqdm.py +0 -0
  191. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/py.typed +0 -0
  192. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pydantic.py +0 -0
  193. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pyinstrument.py +0 -0
  194. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pyrsistent.py +0 -0
  195. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pytest.py +0 -0
  196. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/pytest_regressions.py +0 -0
  197. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/python_dotenv.py +0 -0
  198. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/random.py +0 -0
  199. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/re.py +0 -0
  200. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/redis.py +0 -0
  201. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/reprlib.py +0 -0
  202. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/rich.py +0 -0
  203. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/scipy.py +0 -0
  204. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/sentinel.py +0 -0
  205. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/shelve.py +0 -0
  206. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/slack_sdk.py +0 -0
  207. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/socket.py +0 -0
  208. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/sqlalchemy.py +0 -0
  209. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/sqlalchemy_polars.py +0 -0
  210. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/statsmodels.py +0 -0
  211. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/streamlit.py +0 -0
  212. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/sys.py +0 -0
  213. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/tempfile.py +0 -0
  214. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/tenacity.py +0 -0
  215. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/text.py +0 -0
  216. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/threading.py +0 -0
  217. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/timer.py +0 -0
  218. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/traceback.py +0 -0
  219. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/types.py +0 -0
  220. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/typing.py +0 -0
  221. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/tzdata.py +0 -0
  222. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/tzlocal.py +0 -0
  223. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/uuid.py +0 -0
  224. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/version.py +0 -0
  225. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/warnings.py +0 -0
  226. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/whenever.py +0 -0
  227. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/zipfile.py +0 -0
  228. {dycw_utilities-0.113.2 → dycw_utilities-0.113.3}/src/utilities/zoneinfo.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.113.2
3
+ Version: 0.113.3
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.10; extra == 'test'
9
+ Requires-Dist: hypothesis<6.132,>=6.131.14; 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'
@@ -80,7 +80,7 @@ Provides-Extra: zzz-test-hypothesis
80
80
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
81
81
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
82
82
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
83
- Requires-Dist: hypothesis<6.132,>=6.131.10; extra == 'zzz-test-hypothesis'
83
+ Requires-Dist: hypothesis<6.132,>=6.131.14; extra == 'zzz-test-hypothesis'
84
84
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
85
85
  Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-hypothesis'
86
86
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
@@ -26,7 +26,7 @@ dev = [
26
26
  "fpdf2 >= 2.8.3, < 2.9",
27
27
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
28
28
  "httpx >= 0.28.1, < 0.29", # for fastapi
29
- "hypothesis >= 6.131.10, < 6.132",
29
+ "hypothesis >= 6.131.14, < 6.132",
30
30
  "img2pdf >= 0.6.0, < 0.7",
31
31
  "lightweight-charts >= 2.1, < 2.2",
32
32
  "loguru >= 0.7.3, < 0.8",
@@ -92,11 +92,11 @@ dependencies = [
92
92
  name = "dycw-utilities"
93
93
  readme = "README.md"
94
94
  requires-python = ">= 3.12"
95
- version = "0.113.2"
95
+ version = "0.113.3"
96
96
 
97
97
  [project.optional-dependencies]
98
98
  test = [
99
- "hypothesis >= 6.131.10, < 6.132",
99
+ "hypothesis >= 6.131.14, < 6.132",
100
100
  "pytest >= 8.3.5, < 8.4",
101
101
  "pytest-asyncio >= 0.26.0, < 0.27",
102
102
  "pytest-cov >= 6.1.1, < 6.2",
@@ -174,7 +174,7 @@ zzz-test-hypothesis = [
174
174
  "aiosqlite >= 0.21.0, < 0.22",
175
175
  "asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
176
176
  "greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
177
- "hypothesis >= 6.131.10, < 6.132",
177
+ "hypothesis >= 6.131.14, < 6.132",
178
178
  "luigi >= 3.6.0, < 3.7",
179
179
  "numpy >= 2.2.5, < 2.3",
180
180
  "pathvalidate >= 3.2.3, < 3.3",
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
334
334
  # bump-my-version
335
335
  [tool.bumpversion]
336
336
  allow_dirty = true
337
- current_version = "0.113.2"
337
+ current_version = "0.113.3"
338
338
 
339
339
  [[tool.bumpversion.files]]
340
340
  filename = "src/utilities/__init__.py"
@@ -50,6 +50,7 @@ from utilities.datetime import (
50
50
  AreEqualDateTimesError,
51
51
  CheckDateNotDateTimeError,
52
52
  EnsureMonthError,
53
+ GetMinMaxDateError,
53
54
  MeanDateTimeError,
54
55
  MeanTimeDeltaError,
55
56
  MillisecondsSinceEpochError,
@@ -67,6 +68,11 @@ from utilities.datetime import (
67
68
  _DateDurationToIntTimeDeltaError,
68
69
  _DateDurationToTimeDeltaFloatError,
69
70
  _DateDurationToTimeDeltaTimeDeltaError,
71
+ _GetMinMaxDateMaxAgeError,
72
+ _GetMinMaxDateMaxDateError,
73
+ _GetMinMaxDateMinAgeError,
74
+ _GetMinMaxDateMinDateError,
75
+ _GetMinMaxDatePeriodError,
70
76
  _ParseTwoDigitYearInvalidIntegerError,
71
77
  _ParseTwoDigitYearInvalidStringError,
72
78
  add_duration,
@@ -91,6 +97,7 @@ from utilities.datetime import (
91
97
  get_date,
92
98
  get_datetime,
93
99
  get_half_years,
100
+ get_min_max_date,
94
101
  get_months,
95
102
  get_now,
96
103
  get_quarters,
@@ -129,6 +136,7 @@ from utilities.datetime import (
129
136
  from utilities.functions import not_func
130
137
  from utilities.hypothesis import (
131
138
  assume_does_not_raise,
139
+ date_durations,
132
140
  int32s,
133
141
  months,
134
142
  pairs,
@@ -148,6 +156,7 @@ if TYPE_CHECKING:
148
156
  from utilities.sentinel import Sentinel
149
157
  from utilities.types import (
150
158
  DateOrDateTime,
159
+ Duration,
151
160
  MaybeCallableDate,
152
161
  MaybeCallableDateTime,
153
162
  Number,
@@ -675,6 +684,79 @@ class TestGetDateTime:
675
684
  assert get_datetime(datetime=lambda: datetime) == datetime
676
685
 
677
686
 
687
+ class TestGetMinMaxDate:
688
+ @given(
689
+ min_date=dates(max_value=TODAY_UTC) | none(),
690
+ max_date=dates(max_value=TODAY_UTC) | none(),
691
+ min_age=date_durations(min_int=0, min_timedelta=ZERO_TIME) | none(),
692
+ max_age=date_durations(min_int=0, min_timedelta=ZERO_TIME) | none(),
693
+ )
694
+ def test_main(
695
+ self,
696
+ *,
697
+ min_date: dt.date | None,
698
+ max_date: dt.date | None,
699
+ min_age: Duration | None,
700
+ max_age: Duration | None,
701
+ ) -> None:
702
+ with assume_does_not_raise(GetMinMaxDateError, OverflowError):
703
+ min_date_use, max_date_use = get_min_max_date(
704
+ min_date=min_date, max_date=max_date, min_age=min_age, max_age=max_age
705
+ )
706
+ if (min_date is None) and (max_age is None):
707
+ assert min_date_use is None
708
+ else:
709
+ assert min_date_use is not None
710
+ if (max_date is None) and (min_age is None):
711
+ assert max_date_use is None
712
+ else:
713
+ assert max_date_use is not None
714
+ if min_date_use is not None:
715
+ assert min_date_use <= get_today()
716
+ if max_date_use is not None:
717
+ assert max_date_use <= get_today()
718
+ if (min_date_use is not None) and (max_date_use is not None):
719
+ assert min_date_use <= max_date_use
720
+
721
+ @given(date=dates(min_value=TODAY_UTC + DAY))
722
+ def test_error_min_date(self, *, date: dt.date) -> None:
723
+ with raises(
724
+ _GetMinMaxDateMinDateError,
725
+ match="Min date must be at most today; got .* > .*",
726
+ ):
727
+ _ = get_min_max_date(min_date=date)
728
+
729
+ @given(duration=date_durations(max_int=-1, max_timedelta=-DAY))
730
+ def test_error_min_age(self, *, duration: Duration) -> None:
731
+ with raises(
732
+ _GetMinMaxDateMinAgeError, match="Min age must be non-negative; got .*"
733
+ ):
734
+ _ = get_min_max_date(min_age=duration)
735
+
736
+ @given(date=dates(min_value=TODAY_UTC + DAY))
737
+ def test_error_max_date(self, *, date: dt.date) -> None:
738
+ with raises(
739
+ _GetMinMaxDateMaxDateError,
740
+ match="Max date must be at most today; got .* > .*",
741
+ ):
742
+ _ = get_min_max_date(max_date=date)
743
+
744
+ @given(duration=date_durations(max_int=-1, max_timedelta=-DAY))
745
+ def test_error_max_age(self, *, duration: Duration) -> None:
746
+ with raises(
747
+ _GetMinMaxDateMaxAgeError, match="Max age must be non-negative; got .*"
748
+ ):
749
+ _ = get_min_max_date(max_age=duration)
750
+
751
+ @given(dates=pairs(dates(max_value=TODAY_UTC), unique=True, sorted=True))
752
+ def test_error_period(self, *, dates: tuple[dt.date, dt.date]) -> None:
753
+ with raises(
754
+ _GetMinMaxDatePeriodError,
755
+ match="Min date must be at most max date; got .* > .*",
756
+ ):
757
+ _ = get_min_max_date(min_date=dates[1], max_date=dates[0])
758
+
759
+
678
760
  class TestGetNow:
679
761
  @given(time_zone=timezones())
680
762
  def test_function(self, *, time_zone: ZoneInfo) -> None:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.113.2"
3
+ __version__ = "0.113.3"
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime as dt
4
- from collections.abc import Callable, Iterable
4
+ from collections.abc import Callable, Iterable, Sequence
5
5
  from dataclasses import dataclass, replace
6
6
  from re import search, sub
7
7
  from statistics import fmean
@@ -495,6 +495,101 @@ def get_half_years(*, n: int = 1) -> dt.timedelta:
495
495
 
496
496
  HALF_YEAR = get_half_years(n=1)
497
497
 
498
+ ##
499
+
500
+
501
+ def get_min_max_date(
502
+ *,
503
+ min_date: dt.date | None = None,
504
+ max_date: dt.date | None = None,
505
+ min_age: Duration | None = None,
506
+ max_age: Duration | None = None,
507
+ time_zone: TimeZoneLike = UTC,
508
+ ) -> tuple[dt.date | None, dt.date | None]:
509
+ """Get the min/max date given a combination of dates/ages."""
510
+ today = get_today(time_zone=time_zone)
511
+ min_parts: Sequence[dt.date] = []
512
+ if min_date is not None:
513
+ if min_date > today:
514
+ raise _GetMinMaxDateMinDateError(min_date=min_date, today=today)
515
+ min_parts.append(min_date)
516
+ if max_age is not None:
517
+ if date_duration_to_timedelta(max_age) < ZERO_TIME:
518
+ raise _GetMinMaxDateMaxAgeError(max_age=max_age)
519
+ min_parts.append(sub_duration(today, duration=max_age))
520
+ min_date_use = max(min_parts, default=None)
521
+ max_parts: Sequence[dt.date] = []
522
+ if max_date is not None:
523
+ if max_date > today:
524
+ raise _GetMinMaxDateMaxDateError(max_date=max_date, today=today)
525
+ max_parts.append(max_date)
526
+ if min_age is not None:
527
+ if date_duration_to_timedelta(min_age) < ZERO_TIME:
528
+ raise _GetMinMaxDateMinAgeError(min_age=min_age)
529
+ max_parts.append(sub_duration(today, duration=min_age))
530
+ max_date_use = min(max_parts, default=None)
531
+ if (
532
+ (min_date_use is not None)
533
+ and (max_date_use is not None)
534
+ and (min_date_use > max_date_use)
535
+ ):
536
+ raise _GetMinMaxDatePeriodError(min_date=min_date_use, max_date=max_date_use)
537
+ return min_date_use, max_date_use
538
+
539
+
540
+ @dataclass(kw_only=True, slots=True)
541
+ class GetMinMaxDateError(Exception): ...
542
+
543
+
544
+ @dataclass(kw_only=True, slots=True)
545
+ class _GetMinMaxDateMinDateError(GetMinMaxDateError):
546
+ min_date: dt.date
547
+ today: dt.date
548
+
549
+ @override
550
+ def __str__(self) -> str:
551
+ return f"Min date must be at most today; got {self.min_date} > {self.today}"
552
+
553
+
554
+ @dataclass(kw_only=True, slots=True)
555
+ class _GetMinMaxDateMinAgeError(GetMinMaxDateError):
556
+ min_age: Duration
557
+
558
+ @override
559
+ def __str__(self) -> str:
560
+ return f"Min age must be non-negative; got {self.min_age}"
561
+
562
+
563
+ @dataclass(kw_only=True, slots=True)
564
+ class _GetMinMaxDateMaxDateError(GetMinMaxDateError):
565
+ max_date: dt.date
566
+ today: dt.date
567
+
568
+ @override
569
+ def __str__(self) -> str:
570
+ return f"Max date must be at most today; got {self.max_date} > {self.today}"
571
+
572
+
573
+ @dataclass(kw_only=True, slots=True)
574
+ class _GetMinMaxDateMaxAgeError(GetMinMaxDateError):
575
+ max_age: Duration
576
+
577
+ @override
578
+ def __str__(self) -> str:
579
+ return f"Max age must be non-negative; got {self.max_age}"
580
+
581
+
582
+ @dataclass(kw_only=True, slots=True)
583
+ class _GetMinMaxDatePeriodError(GetMinMaxDateError):
584
+ min_date: dt.date
585
+ max_date: dt.date
586
+
587
+ @override
588
+ def __str__(self) -> str:
589
+ return (
590
+ f"Min date must be at most max date; got {self.min_date} > {self.max_date}"
591
+ )
592
+
498
593
 
499
594
  ##
500
595
 
@@ -1244,6 +1339,7 @@ __all__ = [
1244
1339
  "CheckDateNotDateTimeError",
1245
1340
  "DateOrMonth",
1246
1341
  "EnsureMonthError",
1342
+ "GetMinMaxDateError",
1247
1343
  "MeanDateTimeError",
1248
1344
  "MeanTimeDeltaError",
1249
1345
  "MillisecondsSinceEpochError",
@@ -1280,6 +1376,7 @@ __all__ = [
1280
1376
  "get_date",
1281
1377
  "get_datetime",
1282
1378
  "get_half_years",
1379
+ "get_min_max_date",
1283
1380
  "get_months",
1284
1381
  "get_now",
1285
1382
  "get_quarters",