dycw-utilities 0.150.9__tar.gz → 0.150.11__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 (216) hide show
  1. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/PKG-INFO +2 -2
  2. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/pyproject.toml +4 -4
  3. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_period.py +118 -2
  4. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_text.py +7 -0
  5. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/period.py +57 -5
  7. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/text.py +9 -1
  8. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/.gitignore +0 -0
  9. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/LICENSE +0 -0
  10. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/README.md +0 -0
  11. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/__init__.py +0 -0
  12. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/conftest.py +0 -0
  13. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/__init__.py +0 -0
  14. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_missing/__init__.py +0 -0
  15. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_missing/module.py +0 -0
  16. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/__init__.py +0 -0
  17. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/outer_1.py +0 -0
  18. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/outer_2.py +0 -0
  19. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  20. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  21. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  22. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  23. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_without/__init__.py +0 -0
  24. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_without/module_1.py +0 -0
  25. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/package_without/module_2.py +0 -0
  26. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/standalone.py +0 -0
  27. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/modules/with_imports.py +0 -0
  28. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  29. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  30. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  31. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  32. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  33. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  34. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  35. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  36. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_altair.py +0 -0
  37. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_asyncio.py +0 -0
  38. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_atomicwrites.py +0 -0
  39. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_atools.py +0 -0
  40. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_cachetools.py +0 -0
  41. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_click.py +0 -0
  42. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_concurrent.py +0 -0
  43. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_contextlib.py +0 -0
  44. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_contextvars.py +0 -0
  45. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_cryptography.py +0 -0
  46. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_cvxpy.py +0 -0
  47. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_dataclasses.py +0 -0
  48. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_dnspython.py +0 -0
  49. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_enum.py +0 -0
  50. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_errors.py +0 -0
  51. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_eventkit.py +0 -0
  52. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_fastapi.py +0 -0
  53. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_fpdf2.py +0 -0
  54. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_functions.py +0 -0
  55. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_functools.py +0 -0
  56. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_getpass.py +0 -0
  57. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_gzip.py +0 -0
  58. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_hashlib.py +0 -0
  59. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_http.py +0 -0
  60. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_hypothesis.py +0 -0
  61. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_importlib.py +0 -0
  62. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_inflect.py +0 -0
  63. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_ipython.py +0 -0
  64. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_iterables.py +0 -0
  65. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_json.py +0 -0
  66. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_jupyter.py +0 -0
  67. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_libcst.py +0 -0
  68. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_lightweight_charts.py +0 -0
  69. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_logging.py +0 -0
  70. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_math.py +0 -0
  71. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_memory_profiler.py +0 -0
  72. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_modules.py +0 -0
  73. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_more_itertools.py +0 -0
  74. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_numpy.py +0 -0
  75. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_objects/__init__.py +0 -0
  76. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_objects/objects.py +0 -0
  77. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_operator.py +0 -0
  78. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_optuna.py +0 -0
  79. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_orjson.py +0 -0
  80. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_os.py +0 -0
  81. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_parse.py +0 -0
  82. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pathlib.py +0 -0
  83. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pickle.py +0 -0
  84. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_platform.py +0 -0
  85. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_polars.py +0 -0
  86. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_polars_ols.py +0 -0
  87. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_postgres.py +0 -0
  88. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pottery.py +0 -0
  89. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pqdm.py +0 -0
  90. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_psutil.py +0 -0
  91. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pytest.py +0 -0
  93. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pytest_randomly.py +0 -0
  94. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_random.py +0 -0
  96. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_re.py +0 -0
  97. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_redis.py +0 -0
  98. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_reprlib.py +0 -0
  99. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_scipy.py +0 -0
  100. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_sentinel.py +0 -0
  101. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_shelve.py +0 -0
  102. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_sqlalchemy.py +0 -0
  105. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_sqlalchemy_polars.py +0 -0
  106. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_statsmodels.py +0 -0
  107. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_string.py +0 -0
  108. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_tempfile.py +0 -0
  109. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_threading.py +0 -0
  110. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_timer.py +0 -0
  111. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_traceback.py +0 -0
  112. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_typed_settings.py +0 -0
  113. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_types.py +0 -0
  114. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_typing.py +0 -0
  115. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_typing_funcs/__init__.py +0 -0
  116. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_typing_funcs/no_future.py +0 -0
  117. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_typing_funcs/with_future.py +0 -0
  118. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_tzdata.py +0 -0
  119. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_tzlocal.py +0 -0
  120. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_uuid.py +0 -0
  121. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_version.py +0 -0
  122. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_warnings.py +0 -0
  123. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_whenever.py +0 -0
  124. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_yield_access/__init__.py +0 -0
  125. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_yield_access/script.py +0 -0
  126. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_yield_access/script.sh +0 -0
  127. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_zipfile.py +0 -0
  128. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/tests/test_zoneinfo.py +0 -0
  129. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/altair.py +0 -0
  130. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/asyncio.py +0 -0
  131. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/atomicwrites.py +0 -0
  132. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/atools.py +0 -0
  133. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/cachetools.py +0 -0
  134. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/click.py +0 -0
  135. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/concurrent.py +0 -0
  136. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/contextlib.py +0 -0
  137. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/contextvars.py +0 -0
  138. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/cryptography.py +0 -0
  139. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/cvxpy.py +0 -0
  140. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/dataclasses.py +0 -0
  141. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/dnspython.py +0 -0
  142. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/enum.py +0 -0
  143. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/errors.py +0 -0
  144. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/eventkit.py +0 -0
  145. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/fastapi.py +0 -0
  146. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/fpdf2.py +0 -0
  147. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/functions.py +0 -0
  148. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/functools.py +0 -0
  149. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/getpass.py +0 -0
  150. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/gzip.py +0 -0
  151. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/hashlib.py +0 -0
  152. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/http.py +0 -0
  153. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/hypothesis.py +0 -0
  154. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/importlib.py +0 -0
  155. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/inflect.py +0 -0
  156. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/ipython.py +0 -0
  157. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/iterables.py +0 -0
  158. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/json.py +0 -0
  159. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/jupyter.py +0 -0
  160. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/libcst.py +0 -0
  161. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/lightweight_charts.py +0 -0
  162. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/logging.py +0 -0
  163. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/math.py +0 -0
  164. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/memory_profiler.py +0 -0
  165. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/modules.py +0 -0
  166. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/more_itertools.py +0 -0
  167. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/numpy.py +0 -0
  168. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/operator.py +0 -0
  169. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/optuna.py +0 -0
  170. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/orjson.py +0 -0
  171. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/os.py +0 -0
  172. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/parse.py +0 -0
  173. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pathlib.py +0 -0
  174. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pickle.py +0 -0
  175. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/platform.py +0 -0
  176. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/polars.py +0 -0
  177. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/polars_ols.py +0 -0
  178. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/postgres.py +0 -0
  179. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pottery.py +0 -0
  180. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pqdm.py +0 -0
  181. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/psutil.py +0 -0
  182. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/py.typed +0 -0
  183. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pyinstrument.py +0 -0
  184. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pytest.py +0 -0
  185. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pytest_plugins/__init__.py +0 -0
  186. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  187. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  188. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/pytest_regressions.py +0 -0
  189. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/random.py +0 -0
  190. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/re.py +0 -0
  191. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/redis.py +0 -0
  192. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/reprlib.py +0 -0
  193. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/scipy.py +0 -0
  194. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/sentinel.py +0 -0
  195. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/shelve.py +0 -0
  196. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/slack_sdk.py +0 -0
  197. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/socket.py +0 -0
  198. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/sqlalchemy.py +0 -0
  199. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/sqlalchemy_polars.py +0 -0
  200. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/statsmodels.py +0 -0
  201. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/string.py +0 -0
  202. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/tempfile.py +0 -0
  203. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/threading.py +0 -0
  204. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/timer.py +0 -0
  205. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/traceback.py +0 -0
  206. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/typed_settings.py +0 -0
  207. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/types.py +0 -0
  208. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/typing.py +0 -0
  209. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/tzdata.py +0 -0
  210. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/tzlocal.py +0 -0
  211. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/uuid.py +0 -0
  212. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/version.py +0 -0
  213. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/warnings.py +0 -0
  214. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/whenever.py +0 -0
  215. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/zipfile.py +0 -0
  216. {dycw_utilities-0.150.9 → dycw_utilities-0.150.11}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.150.9
3
+ Version: 0.150.11
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -12,7 +12,7 @@ Provides-Extra: logging
12
12
  Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
13
13
  Provides-Extra: test
14
14
  Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
15
- Requires-Dist: hypothesis<6.137,>=6.136.0; extra == 'test'
15
+ Requires-Dist: hypothesis<6.137,>=6.136.1; extra == 'test'
16
16
  Requires-Dist: pudb<2025.2,>=2025.1; extra == 'test'
17
17
  Requires-Dist: pytest-asyncio<1.2,>=1.1.0; extra == 'test'
18
18
  Requires-Dist: pytest-cov<6.3,>=6.2.1; extra == 'test'
@@ -41,7 +41,7 @@ fastapi-test = ["httpx", "uvicorn"]
41
41
  fpdf2 = ["fpdf2 >= 2.8.3, < 2.9"]
42
42
  hashlib-test = ["orjson"]
43
43
  http-test = ["orjson"]
44
- hypothesis = ["hypothesis >= 6.136.0, < 6.137"]
44
+ hypothesis = ["hypothesis >= 6.136.1, < 6.137"]
45
45
  hypothesis-test = ["libcst", "pathvalidate", "numpy", "pytest-rerunfailures"]
46
46
  inflect = ["inflect >= 7.5.0, < 7.6"]
47
47
  jupyter-test = ["pandas", "polars"]
@@ -103,7 +103,7 @@ dependencies = [
103
103
  name = "dycw-utilities"
104
104
  readme = "README.md"
105
105
  requires-python = ">= 3.12"
106
- version = "0.150.9"
106
+ version = "0.150.11"
107
107
 
108
108
  [project.entry-points.pytest11]
109
109
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -115,7 +115,7 @@ logging = [
115
115
  ]
116
116
  test = [
117
117
  "dycw-pytest-only >= 2.1.1, < 2.2",
118
- "hypothesis >= 6.136.0, < 6.137",
118
+ "hypothesis >= 6.136.1, < 6.137",
119
119
  "pudb >= 2025.1, < 2025.2",
120
120
  "pytest >= 8.4.1, < 8.5",
121
121
  "pytest-asyncio >= 1.1.0, < 1.2",
@@ -136,7 +136,7 @@ test = [
136
136
  # bump-my-version
137
137
  [tool.bumpversion]
138
138
  allow_dirty = true
139
- current_version = "0.150.9"
139
+ current_version = "0.150.11"
140
140
 
141
141
  [[tool.bumpversion.files]]
142
142
  filename = "src/utilities/__init__.py"
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any, cast
6
6
  from hypothesis import HealthCheck, given, settings
7
7
  from hypothesis.strategies import DataObject, data
8
8
  from pytest import mark, param, raises
9
- from whenever import Date, ZonedDateTime
9
+ from whenever import Date, Time, ZonedDateTime
10
10
 
11
11
  from utilities.hypothesis import (
12
12
  assume_does_not_raise,
@@ -15,10 +15,12 @@ from utilities.hypothesis import (
15
15
  pairs,
16
16
  plain_datetimes,
17
17
  time_deltas,
18
+ times,
18
19
  zoned_datetimes,
19
20
  )
20
21
  from utilities.period import (
21
22
  DatePeriod,
23
+ TimePeriod,
22
24
  ZonedDateTimePeriod,
23
25
  _PeriodAsDict,
24
26
  _PeriodExactEqArgumentsError,
@@ -26,7 +28,7 @@ from utilities.period import (
26
28
  _PeriodTimeZoneError,
27
29
  )
28
30
  from utilities.tzdata import USCentral, USEastern
29
- from utilities.whenever import DAY
31
+ from utilities.whenever import DAY, SECOND
30
32
  from utilities.zoneinfo import UTC, get_time_zone_name
31
33
 
32
34
  if TYPE_CHECKING:
@@ -46,6 +48,31 @@ class TestDatePeriod:
46
48
  expected = DatePeriod(start + delta, end + delta)
47
49
  assert result == expected
48
50
 
51
+ @given(dates=pairs(dates(), sorted=True), time=times())
52
+ def test_at_time(self, *, dates: tuple[Date, Date], time: Time) -> None:
53
+ start, end = dates
54
+ period = DatePeriod(start, end)
55
+ result = period.at(time)
56
+ expected = ZonedDateTimePeriod(
57
+ start.at(time).assume_tz(UTC.key), end.at(time).assume_tz(UTC.key)
58
+ )
59
+ assert result.exact_eq(expected)
60
+
61
+ @given(dates=pairs(dates(), sorted=True), times=pairs(times()))
62
+ def test_at_times(
63
+ self, *, dates: tuple[Date, Date], times: tuple[Time, Time]
64
+ ) -> None:
65
+ start_date, end_date = dates
66
+ period = DatePeriod(start_date, end_date)
67
+ start_time, end_time = times
68
+ with assume_does_not_raise(_PeriodInvalidError):
69
+ result = period.at((start_time, end_time))
70
+ expected = ZonedDateTimePeriod(
71
+ start_date.at(start_time).assume_tz(UTC.key),
72
+ end_date.at(end_time).assume_tz(UTC.key),
73
+ )
74
+ assert result.exact_eq(expected)
75
+
49
76
  @given(date=dates(), dates=pairs(dates(), sorted=True))
50
77
  def test_contains(self, *, date: Date, dates: tuple[Date, Date]) -> None:
51
78
  start, end = dates
@@ -82,6 +109,14 @@ class TestDatePeriod:
82
109
  period = DatePeriod(start, end)
83
110
  _ = hash(period)
84
111
 
112
+ @given(dates=pairs(dates(), sorted=True))
113
+ def test_replace(self, *, dates: tuple[Date, Date]) -> None:
114
+ start, end = dates
115
+ period = DatePeriod(start, end)
116
+ new = period.replace(start=start - DAY, end=end + DAY)
117
+ assert new.start == (start - DAY)
118
+ assert new.end == (end + DAY)
119
+
85
120
  @given(dates=pairs(dates(), sorted=True))
86
121
  @mark.parametrize("func", [param(repr), param(str)])
87
122
  def test_repr(self, *, dates: tuple[Date, Date], func: Callable[..., str]) -> None:
@@ -125,6 +160,79 @@ class TestDatePeriod:
125
160
  _ = DatePeriod(end, start)
126
161
 
127
162
 
163
+ class TestTimePeriod:
164
+ @given(times=pairs(times()), date=dates())
165
+ def test_at_day(self, *, times: tuple[Time, Time], date: Date) -> None:
166
+ start, end = times
167
+ period = TimePeriod(start, end)
168
+ with assume_does_not_raise(_PeriodInvalidError):
169
+ result = period.at(date)
170
+ expected = ZonedDateTimePeriod(
171
+ date.at(start).assume_tz(UTC.key), date.at(end).assume_tz(UTC.key)
172
+ )
173
+ assert result.exact_eq(expected)
174
+
175
+ @given(times=pairs(times()), dates=pairs(dates(), sorted=True))
176
+ def test_at_days(
177
+ self, *, times: tuple[Time, Time], dates: tuple[Date, Date]
178
+ ) -> None:
179
+ start_time, end_time = times
180
+ period = TimePeriod(start_time, end_time)
181
+ start_date, end_date = dates
182
+ with assume_does_not_raise(_PeriodInvalidError):
183
+ result = period.at((start_date, end_date))
184
+ expected = ZonedDateTimePeriod(
185
+ start_date.at(start_time).assume_tz(UTC.key),
186
+ end_date.at(end_time).assume_tz(UTC.key),
187
+ )
188
+ assert result.exact_eq(expected)
189
+
190
+ @given(dates=pairs(dates(), sorted=True), times=pairs(times()))
191
+ def test_at_times(
192
+ self, *, dates: tuple[Date, Date], times: tuple[Time, Time]
193
+ ) -> None:
194
+ start_date, end_date = dates
195
+ period = DatePeriod(start_date, end_date)
196
+ start_time, end_time = times
197
+ with assume_does_not_raise(_PeriodInvalidError):
198
+ result = period.at((start_time, end_time))
199
+ expected = ZonedDateTimePeriod(
200
+ start_date.at(start_time).assume_tz(UTC.key),
201
+ end_date.at(end_time).assume_tz(UTC.key),
202
+ )
203
+ assert result.exact_eq(expected)
204
+
205
+ @given(times=pairs(times()), new_times=pairs(times()))
206
+ def test_replace(
207
+ self, *, times: tuple[Time, Time], new_times: tuple[Time, Time]
208
+ ) -> None:
209
+ start, end = times
210
+ period = TimePeriod(start, end)
211
+ new_start, new_end = new_times
212
+ new = period.replace(start=new_start, end=new_end)
213
+ assert new.start == new_start
214
+ assert new.end == new_end
215
+
216
+ @given(times=pairs(times()))
217
+ @mark.parametrize("func", [param(repr), param(str)])
218
+ def test_repr(self, *, times: tuple[Time, Time], func: Callable[..., str]) -> None:
219
+ start, end = times
220
+ period = TimePeriod(start, end)
221
+ result = func(period)
222
+ assert search(
223
+ r"^TimePeriod\(\d{2}:\d{2}:\d{2}(\.\d{1,6})?, \d{2}:\d{2}:\d{2}(\.\d{1,6})?\)$",
224
+ result,
225
+ )
226
+
227
+ @given(times=pairs(times()))
228
+ def test_to_dict(self, *, times: tuple[Time, Time]) -> None:
229
+ start, end = times
230
+ period = TimePeriod(start, end)
231
+ result = period.to_dict()
232
+ expected = _PeriodAsDict(start=start, end=end)
233
+ assert result == expected
234
+
235
+
128
236
  class TestZonedDateTimePeriod:
129
237
  @given(datetimes=pairs(zoned_datetimes(), sorted=True), delta=time_deltas())
130
238
  @settings(suppress_health_check={HealthCheck.filter_too_much})
@@ -292,6 +400,14 @@ class TestZonedDateTimePeriod:
292
400
  period = ZonedDateTimePeriod(start, end)
293
401
  _ = hash(period)
294
402
 
403
+ @given(datetimes=pairs(zoned_datetimes(), sorted=True))
404
+ def test_replace(self, *, datetimes: tuple[ZonedDateTime, ZonedDateTime]) -> None:
405
+ start, end = datetimes
406
+ period = ZonedDateTimePeriod(start, end)
407
+ new = period.replace(start=start - SECOND, end=end + SECOND)
408
+ assert new.start == (start - SECOND)
409
+ assert new.end == (end + SECOND)
410
+
295
411
  @given(data=data(), datetimes=pairs(zoned_datetimes(), sorted=True))
296
412
  @mark.parametrize("func", [param(repr), param(str)])
297
413
  def test_repr(
@@ -112,6 +112,13 @@ class TestSecretStr:
112
112
  assert repr(s) == secret_str._REPR
113
113
  assert str(s) == secret_str._REPR
114
114
 
115
+ def test_open(self) -> None:
116
+ s = secret_str("text")
117
+ assert isinstance(s.str, str)
118
+ assert not isinstance(s.str, secret_str)
119
+ assert repr(s.str) == repr("text")
120
+ assert str(s.str) == "text"
121
+
115
122
 
116
123
  class TestSnakeCase:
117
124
  @given(
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.150.9"
3
+ __version__ = "0.150.11"
@@ -1,22 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Self, TypedDict, overload, override
4
+ from typing import TYPE_CHECKING, Any, Self, TypedDict, assert_never, overload, override
5
5
  from zoneinfo import ZoneInfo
6
6
 
7
- from whenever import Date, DateDelta, PlainDateTime, TimeDelta, ZonedDateTime
7
+ from whenever import Date, DateDelta, PlainDateTime, Time, TimeDelta, ZonedDateTime
8
8
 
9
9
  from utilities.dataclasses import replace_non_sentinel
10
10
  from utilities.functions import get_class_name
11
11
  from utilities.sentinel import Sentinel, sentinel
12
12
  from utilities.whenever import format_compact
13
- from utilities.zoneinfo import get_time_zone_name
13
+ from utilities.zoneinfo import UTC, ensure_time_zone, get_time_zone_name
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from utilities.types import TimeZoneLike
17
17
 
18
18
 
19
- class _PeriodAsDict[T: (Date, ZonedDateTime)](TypedDict):
19
+ class _PeriodAsDict[T: (Date, Time, ZonedDateTime)](TypedDict):
20
20
  start: T
21
21
  end: T
22
22
 
@@ -49,6 +49,22 @@ class DatePeriod:
49
49
  """Offset the period."""
50
50
  return self.replace(start=self.start - other, end=self.end - other)
51
51
 
52
+ def at(
53
+ self, obj: Time | tuple[Time, Time], /, *, time_zone: TimeZoneLike = UTC
54
+ ) -> ZonedDateTimePeriod:
55
+ """Combine a date with a time to create a datetime."""
56
+ match obj:
57
+ case Time() as time:
58
+ start = end = time
59
+ case Time() as start, Time() as end:
60
+ ...
61
+ case _ as never:
62
+ assert_never(never)
63
+ tz = ensure_time_zone(time_zone).key
64
+ return ZonedDateTimePeriod(
65
+ self.start.at(start).assume_tz(tz), self.end.at(end).assume_tz(tz)
66
+ )
67
+
52
68
  @property
53
69
  def delta(self) -> DateDelta:
54
70
  """The delta of the period."""
@@ -76,6 +92,42 @@ class DatePeriod:
76
92
  return _PeriodAsDict(start=self.start, end=self.end)
77
93
 
78
94
 
95
+ @dataclass(repr=False, order=True, unsafe_hash=True, kw_only=False)
96
+ class TimePeriod:
97
+ """A period of times."""
98
+
99
+ start: Time
100
+ end: Time
101
+
102
+ @override
103
+ def __repr__(self) -> str:
104
+ cls = get_class_name(self)
105
+ return f"{cls}({self.start}, {self.end})"
106
+
107
+ def replace(
108
+ self, *, start: Time | Sentinel = sentinel, end: Time | Sentinel = sentinel
109
+ ) -> Self:
110
+ """Replace elements of the period."""
111
+ return replace_non_sentinel(self, start=start, end=end)
112
+
113
+ def at(
114
+ self, obj: Date | tuple[Date, Date], /, *, time_zone: TimeZoneLike = UTC
115
+ ) -> ZonedDateTimePeriod:
116
+ """Combine a date with a time to create a datetime."""
117
+ match obj:
118
+ case Date() as date:
119
+ start = end = date
120
+ case Date() as start, Date() as end:
121
+ ...
122
+ case _ as never:
123
+ assert_never(never)
124
+ return DatePeriod(start, end).at((self.start, self.end), time_zone=time_zone)
125
+
126
+ def to_dict(self) -> _PeriodAsDict[Time]:
127
+ """Convert the period to a dictionary."""
128
+ return _PeriodAsDict(start=self.start, end=self.end)
129
+
130
+
79
131
  @dataclass(repr=False, order=True, unsafe_hash=True, kw_only=False)
80
132
  class ZonedDateTimePeriod:
81
133
  """A period of time."""
@@ -234,4 +286,4 @@ class _PeriodExactEqArgumentsError(PeriodError):
234
286
  return f"Invalid arguments; got {self.args}"
235
287
 
236
288
 
237
- __all__ = ["DatePeriod", "PeriodError", "ZonedDateTimePeriod"]
289
+ __all__ = ["DatePeriod", "PeriodError", "TimePeriod", "ZonedDateTimePeriod"]
@@ -388,9 +388,13 @@ def _escape_separator(*, separator: str = DEFAULT_SEPARATOR) -> str:
388
388
  class secret_str(str): # noqa: N801
389
389
  """A string with an obfuscated representation."""
390
390
 
391
- __slots__ = ()
391
+ __slots__ = ("_text",)
392
392
  _REPR: ClassVar[str] = "***"
393
393
 
394
+ def __init__(self, text: str, /) -> None:
395
+ super().__init__()
396
+ self._text = text
397
+
394
398
  @override
395
399
  def __repr__(self) -> str:
396
400
  return self._REPR
@@ -399,6 +403,10 @@ class secret_str(str): # noqa: N801
399
403
  def __str__(self) -> str:
400
404
  return self._REPR
401
405
 
406
+ @property
407
+ def str(self) -> str:
408
+ return self._text
409
+
402
410
 
403
411
  ##
404
412