dycw-utilities 0.131.11__tar.gz → 0.131.13__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 (225) hide show
  1. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/PKG-INFO +1 -1
  2. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/pyproject.toml +2 -2
  3. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/conftest.py +18 -2
  4. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_atools.py +6 -5
  5. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_cachetools.py +22 -9
  6. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_dataclasses.py +3 -1
  7. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_hypothesis.py +0 -55
  8. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_logging.py +36 -65
  9. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_orjson.py +39 -35
  10. dycw_utilities-0.131.13/src/tests/test_period.py +259 -0
  11. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pyinstrument.py +1 -1
  12. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_traceback.py +1 -1
  13. dycw_utilities-0.131.13/src/tests/test_tzdata.py +14 -0
  14. dycw_utilities-0.131.13/src/tests/test_tzlocal.py +15 -0
  15. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_whenever2.py +22 -3
  16. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_zoneinfo.py +3 -5
  17. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/__init__.py +1 -1
  18. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/atools.py +7 -9
  19. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/cachetools.py +8 -10
  20. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/datetime.py +2 -9
  21. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/fastapi.py +2 -4
  22. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/fpdf2.py +2 -2
  23. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/hypothesis.py +0 -136
  24. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/logging.py +54 -52
  25. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/orjson.py +46 -45
  26. dycw_utilities-0.131.13/src/utilities/period.py +154 -0
  27. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pyinstrument.py +2 -3
  28. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/traceback.py +18 -21
  29. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/typing.py +25 -1
  30. dycw_utilities-0.131.13/src/utilities/tzdata.py +11 -0
  31. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/tzlocal.py +2 -26
  32. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/whenever2.py +15 -2
  33. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/zoneinfo.py +2 -2
  34. dycw_utilities-0.131.11/src/tests/test_period.py +0 -387
  35. dycw_utilities-0.131.11/src/tests/test_tzdata.py +0 -60
  36. dycw_utilities-0.131.11/src/tests/test_tzlocal.py +0 -45
  37. dycw_utilities-0.131.11/src/utilities/period.py +0 -324
  38. dycw_utilities-0.131.11/src/utilities/tzdata.py +0 -63
  39. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/.gitignore +0 -0
  40. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/LICENSE +0 -0
  41. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/README.md +0 -0
  42. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/__init__.py +0 -0
  43. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/__init__.py +0 -0
  44. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_missing/__init__.py +0 -0
  45. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_missing/module.py +0 -0
  46. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/__init__.py +0 -0
  47. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/outer_1.py +0 -0
  48. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/outer_2.py +0 -0
  49. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  50. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  51. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  52. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  53. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_without/__init__.py +0 -0
  54. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_without/module_1.py +0 -0
  55. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/package_without/module_2.py +0 -0
  56. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/standalone.py +0 -0
  57. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/modules/with_imports.py +0 -0
  58. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  59. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  60. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  61. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  62. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  63. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  64. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  65. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  66. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_aiolimiter.py +0 -0
  67. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_altair.py +0 -0
  68. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_asyncio.py +0 -0
  69. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_asyncio_classes/__init__.py +0 -0
  70. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_asyncio_classes/loopers.py +0 -0
  71. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_asyncio_classes/redis.py +0 -0
  72. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_atomicwrites.py +0 -0
  73. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_click.py +0 -0
  74. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_concurrent.py +0 -0
  75. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_contextlib.py +0 -0
  76. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_contextvars.py +0 -0
  77. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_cryptography.py +0 -0
  78. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_cvxpy.py +0 -0
  79. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_datetime.py +0 -0
  80. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_enum.py +0 -0
  81. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_errors.py +0 -0
  82. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_eventkit.py +0 -0
  83. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_fastapi.py +0 -0
  84. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_fpdf2.py +0 -0
  85. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_functions.py +0 -0
  86. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_functools.py +0 -0
  87. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_getpass.py +0 -0
  88. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_git.py +0 -0
  89. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_hashlib.py +0 -0
  90. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_http.py +0 -0
  91. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_importlib.py +0 -0
  92. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_inflect.py +0 -0
  93. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_ipython.py +0 -0
  94. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_iterables.py +0 -0
  95. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_jupyter.py +0 -0
  96. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_libcst.py +0 -0
  97. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_lightweight_charts.py +0 -0
  98. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_luigi.py +0 -0
  99. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_math.py +0 -0
  100. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_memory_profiler.py +0 -0
  101. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_modules.py +0 -0
  102. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_more_itertools.py +0 -0
  103. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_numpy.py +0 -0
  104. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_operator.py +0 -0
  105. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_optuna.py +0 -0
  106. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_os.py +0 -0
  107. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_parse.py +0 -0
  108. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pathlib.py +0 -0
  109. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pickle.py +0 -0
  110. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_platform.py +0 -0
  111. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_polars.py +0 -0
  112. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_polars_ols.py +0 -0
  113. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pottery.py +0 -0
  114. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pqdm.py +0 -0
  115. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_psutil.py +0 -0
  116. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pydantic.py +0 -0
  117. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pyrsistent.py +0 -0
  118. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pytest.py +0 -0
  119. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_pytest_regressions.py +0 -0
  120. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_python_dotenv.py +0 -0
  121. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_random.py +0 -0
  122. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_re.py +0 -0
  123. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_redis.py +0 -0
  124. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_reprlib.py +0 -0
  125. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_scipy.py +0 -0
  126. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_sentinel.py +0 -0
  127. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_shelve.py +0 -0
  128. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_slack_sdk.py +0 -0
  129. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_socket.py +0 -0
  130. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_sqlalchemy.py +0 -0
  131. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_sqlalchemy_polars.py +0 -0
  132. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_statsmodel.py +0 -0
  133. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_streamlit.py +0 -0
  134. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_string.py +0 -0
  135. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_tempfile.py +0 -0
  136. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_tenacity.py +0 -0
  137. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_text.py +0 -0
  138. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_threading.py +0 -0
  139. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_timer.py +0 -0
  140. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_types.py +0 -0
  141. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_typing.py +0 -0
  142. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_typing_funcs/__init__.py +0 -0
  143. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_typing_funcs/no_future.py +0 -0
  144. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_typing_funcs/with_future.py +0 -0
  145. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_uuid.py +0 -0
  146. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_version.py +0 -0
  147. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_warnings.py +0 -0
  148. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_whenever.py +0 -0
  149. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/tests/test_zipfile.py +0 -0
  150. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/aiolimiter.py +0 -0
  151. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/altair.py +0 -0
  152. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/asyncio.py +0 -0
  153. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/atomicwrites.py +0 -0
  154. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/click.py +0 -0
  155. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/concurrent.py +0 -0
  156. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/contextlib.py +0 -0
  157. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/contextvars.py +0 -0
  158. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/cryptography.py +0 -0
  159. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/cvxpy.py +0 -0
  160. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/dataclasses.py +0 -0
  161. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/enum.py +0 -0
  162. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/errors.py +0 -0
  163. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/eventkit.py +0 -0
  164. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/functions.py +0 -0
  165. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/functools.py +0 -0
  166. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/getpass.py +0 -0
  167. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/git.py +0 -0
  168. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/hashlib.py +0 -0
  169. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/http.py +0 -0
  170. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/importlib.py +0 -0
  171. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/inflect.py +0 -0
  172. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/ipython.py +0 -0
  173. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/iterables.py +0 -0
  174. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/jupyter.py +0 -0
  175. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/libcst.py +0 -0
  176. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/lightweight_charts.py +0 -0
  177. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/luigi.py +0 -0
  178. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/math.py +0 -0
  179. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/memory_profiler.py +0 -0
  180. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/modules.py +0 -0
  181. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/more_itertools.py +0 -0
  182. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/numpy.py +0 -0
  183. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/operator.py +0 -0
  184. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/optuna.py +0 -0
  185. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/os.py +0 -0
  186. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/parse.py +0 -0
  187. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pathlib.py +0 -0
  188. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pickle.py +0 -0
  189. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/platform.py +0 -0
  190. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/polars.py +0 -0
  191. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/polars_ols.py +0 -0
  192. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pottery.py +0 -0
  193. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pqdm.py +0 -0
  194. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/psutil.py +0 -0
  195. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/py.typed +0 -0
  196. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pydantic.py +0 -0
  197. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pyrsistent.py +0 -0
  198. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pytest.py +0 -0
  199. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/pytest_regressions.py +0 -0
  200. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/python_dotenv.py +0 -0
  201. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/random.py +0 -0
  202. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/re.py +0 -0
  203. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/redis.py +0 -0
  204. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/reprlib.py +0 -0
  205. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/scipy.py +0 -0
  206. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/sentinel.py +0 -0
  207. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/shelve.py +0 -0
  208. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/slack_sdk.py +0 -0
  209. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/socket.py +0 -0
  210. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/sqlalchemy.py +0 -0
  211. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/sqlalchemy_polars.py +0 -0
  212. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/string.py +0 -0
  215. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/text.py +0 -0
  218. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/threading.py +0 -0
  219. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/timer.py +0 -0
  220. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/types.py +0 -0
  221. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/uuid.py +0 -0
  222. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/version.py +0 -0
  223. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/warnings.py +0 -0
  224. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/whenever.py +0 -0
  225. {dycw_utilities-0.131.11 → dycw_utilities-0.131.13}/src/utilities/zipfile.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.131.11
3
+ Version: 0.131.13
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -94,7 +94,7 @@ dependencies = [
94
94
  name = "dycw-utilities"
95
95
  readme = "README.md"
96
96
  requires-python = ">= 3.12"
97
- version = "0.131.11"
97
+ version = "0.131.13"
98
98
 
99
99
  [project.optional-dependencies]
100
100
  logging = [
@@ -121,7 +121,7 @@ test = [
121
121
  # bump-my-version
122
122
  [tool.bumpversion]
123
123
  allow_dirty = true
124
- current_version = "0.131.11"
124
+ current_version = "0.131.13"
125
125
 
126
126
  [[tool.bumpversion.files]]
127
127
  filename = "src/utilities/__init__.py"
@@ -2,7 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
  from asyncio import sleep
5
- from contextlib import suppress
5
+ from contextlib import AbstractContextManager, contextmanager, suppress
6
+ from logging import LogRecord, setLogRecordFactory
6
7
  from os import environ
7
8
  from re import MULTILINE, Pattern
8
9
  from typing import TYPE_CHECKING, Any
@@ -16,7 +17,7 @@ from utilities.re import ExtractGroupError, extract_group
16
17
  from utilities.text import strip_and_dedent
17
18
 
18
19
  if TYPE_CHECKING:
19
- from collections.abc import Sequence
20
+ from collections.abc import Iterator, Sequence
20
21
  from pathlib import Path
21
22
 
22
23
  from _pytest.fixtures import SubRequest
@@ -43,6 +44,21 @@ else:
43
44
  setup_hypothesis_profiles()
44
45
 
45
46
 
47
+ # fixture - logging
48
+
49
+
50
+ @fixture
51
+ def set_log_factory() -> AbstractContextManager[None]:
52
+ @contextmanager
53
+ def cm() -> Iterator[None]:
54
+ try:
55
+ yield
56
+ finally:
57
+ setLogRecordFactory(LogRecord)
58
+
59
+ return cm()
60
+
61
+
46
62
  # fixtures - sqlalchemy
47
63
 
48
64
 
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- from asyncio import sleep
4
-
3
+ from utilities.asyncio import sleep_dur
5
4
  from utilities.atools import call_memoized
5
+ from utilities.whenever2 import SECOND
6
6
 
7
7
 
8
8
  class TestCallMemoized:
@@ -20,6 +20,7 @@ class TestCallMemoized:
20
20
 
21
21
  async def test_refresh(self) -> None:
22
22
  counter = 0
23
+ delta = 0.05 * SECOND
23
24
 
24
25
  async def increment() -> int:
25
26
  nonlocal counter
@@ -27,9 +28,9 @@ class TestCallMemoized:
27
28
  return counter
28
29
 
29
30
  for _ in range(2):
30
- assert (await call_memoized(increment, 0.05)) == 1
31
+ assert (await call_memoized(increment, delta)) == 1
31
32
  assert counter == 1
32
- await sleep(0.1)
33
+ await sleep_dur(duration=2 * delta)
33
34
  for _ in range(2):
34
- assert (await call_memoized(increment, 0.05)) == 2
35
+ assert (await call_memoized(increment, delta)) == 2
35
36
  assert counter == 2
@@ -1,20 +1,32 @@
1
1
  from __future__ import annotations
2
2
 
3
- from time import sleep
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from hypothesis import example, given
6
- from hypothesis.strategies import floats, integers, none
6
+ from hypothesis.strategies import integers, none
7
7
 
8
+ from utilities.asyncio import sleep_dur
8
9
  from utilities.cachetools import TTLSet, cache
10
+ from utilities.hypothesis import time_deltas_whenever
11
+ from utilities.whenever2 import SECOND
12
+
13
+ if TYPE_CHECKING:
14
+ from whenever import TimeDelta
9
15
 
10
16
 
11
17
  class TestCache:
12
18
  @example(max_size=None, max_duration=None)
13
- @example(max_size=None, max_duration=1.0)
19
+ @example(max_size=None, max_duration=SECOND)
14
20
  @example(max_size=1, max_duration=None)
15
- @example(max_size=1, max_duration=1.0)
16
- @given(max_size=integers(1, 10) | none(), max_duration=floats(0.1, 10.0) | none())
17
- def test_main(self, *, max_size: int, max_duration: float) -> None:
21
+ @example(max_size=1, max_duration=SECOND)
22
+ @given(
23
+ max_size=integers(1, 10) | none(),
24
+ max_duration=time_deltas_whenever(
25
+ min_value=0.1 * SECOND, max_value=10.0 * SECOND
26
+ )
27
+ | none(),
28
+ )
29
+ def test_main(self, *, max_size: int, max_duration: TimeDelta) -> None:
18
30
  counter = 0
19
31
 
20
32
  @cache(max_size=max_size, max_duration=max_duration)
@@ -48,10 +60,11 @@ class TestTTLSet:
48
60
  set_ = TTLSet(range(3))
49
61
  assert len(set_) == 3
50
62
 
51
- def test_max_duration(self) -> None:
52
- set_ = TTLSet(range(3), max_duration=0.1)
63
+ async def test_max_duration(self) -> None:
64
+ delta = 0.1 * SECOND
65
+ set_ = TTLSet(range(3), max_duration=delta)
53
66
  assert set_ == {0, 1, 2}
54
- sleep(0.2)
67
+ await sleep_dur(duration=2 * delta)
55
68
  assert set_ == set()
56
69
 
57
70
  def test_max_size(self) -> None:
@@ -928,7 +928,9 @@ class TestYieldFields:
928
928
  assert get_args(args[0]) == ("true", "false")
929
929
 
930
930
  def test_class_orjson_log_record(self) -> None:
931
- result = list(yield_fields(OrjsonLogRecord, globalns=globals()))
931
+ result = list(
932
+ yield_fields(OrjsonLogRecord, globalns=globals(), warn_name_errors=True)
933
+ )
932
934
  exp_head = [
933
935
  _YieldFieldsClass(name="name", type_=str, kw_only=True),
934
936
  _YieldFieldsClass(name="message", type_=str, kw_only=True),
@@ -68,8 +68,6 @@ from utilities.hypothesis import (
68
68
  int_arrays,
69
69
  lists_fixed_length,
70
70
  min_and_max_datetimes,
71
- min_and_maybe_max_datetimes,
72
- min_and_maybe_max_sizes,
73
71
  months,
74
72
  namespace_mixins,
75
73
  numbers,
@@ -729,59 +727,6 @@ class TestMinAndMaxDateTimes:
729
727
  assert max_datetime == max_value
730
728
 
731
729
 
732
- class TestMinAndMaybeMaxDateTimes:
733
- @given(
734
- data=data(),
735
- min_value=zoned_datetimes() | none() | just(zoned_datetimes() | none()),
736
- max_value=zoned_datetimes()
737
- | none()
738
- | sentinels()
739
- | just(zoned_datetimes() | none() | sentinels()),
740
- )
741
- def test_main(
742
- self,
743
- *,
744
- data: DataObject,
745
- min_value: MaybeSearchStrategy[dt.datetime | None],
746
- max_value: MaybeSearchStrategy[dt.datetime | None | Sentinel],
747
- ) -> None:
748
- min_datetime, max_datetime = data.draw(
749
- min_and_maybe_max_datetimes(min_value=min_value, max_value=max_value)
750
- )
751
- assert (max_datetime is None) or (min_datetime <= max_datetime)
752
- if isinstance(min_value, dt.datetime):
753
- assert min_datetime == min_value
754
- if isinstance(max_value, dt.datetime) or (max_value is None):
755
- assert max_datetime == max_value
756
-
757
-
758
- class TestMinAndMaybeMaxSizes:
759
- @given(
760
- data=data(),
761
- min_value=integers(min_value=0) | none() | just(integers(min_value=0) | none()),
762
- max_value=integers(min_value=0)
763
- | none()
764
- | sentinels()
765
- | just(integers(min_value=0) | none() | sentinels()),
766
- )
767
- def test_main(
768
- self,
769
- *,
770
- data: DataObject,
771
- min_value: MaybeSearchStrategy[int | None],
772
- max_value: MaybeSearchStrategy[int | None | Sentinel],
773
- ) -> None:
774
- min_size, max_size = data.draw(
775
- min_and_maybe_max_sizes(min_value=min_value, max_value=max_value)
776
- )
777
- assert min_size >= 0
778
- assert (max_size is None) or (min_size <= max_size)
779
- if isinstance(min_value, int):
780
- assert min_size == min_value
781
- if isinstance(max_value, int) or (max_value is None):
782
- assert max_size == max_value
783
-
784
-
785
730
  class TestMonths:
786
731
  @given(data=data())
787
732
  def test_main(self, *, data: DataObject) -> None:
@@ -1,16 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from asyncio import sleep
4
- from contextlib import contextmanager
5
4
  from io import StringIO
6
- from logging import (
7
- Formatter,
8
- Logger,
9
- LogRecord,
10
- StreamHandler,
11
- getLogger,
12
- setLogRecordFactory,
13
- )
5
+ from logging import Formatter, Logger, StreamHandler, getLogger
14
6
  from pathlib import Path
15
7
  from re import search
16
8
  from typing import TYPE_CHECKING, Any, cast
@@ -20,13 +12,12 @@ from hypothesis.strategies import booleans, integers, none, sampled_from
20
12
  from pytest import LogCaptureFixture, mark, param, raises
21
13
 
22
14
  from tests.conftest import SKIPIF_CI_AND_WINDOWS
23
- from utilities.datetime import NOW_UTC, SECOND, serialize_compact
24
15
  from utilities.hypothesis import (
25
16
  assume_does_not_raise,
26
17
  pairs,
27
18
  temp_paths,
28
19
  text_ascii,
29
- zoned_datetimes,
20
+ zoned_datetimes_whenever,
30
21
  )
31
22
  from utilities.iterables import one
32
23
  from utilities.logging import (
@@ -47,19 +38,14 @@ from utilities.logging import (
47
38
  from utilities.text import unique_str
48
39
  from utilities.types import LogLevel
49
40
  from utilities.typing import get_args
41
+ from utilities.whenever2 import format_compact, get_now
50
42
 
51
43
  if TYPE_CHECKING:
52
- import datetime as dt
53
- from collections.abc import Iterator, Mapping
44
+ from collections.abc import Mapping
45
+ from contextlib import AbstractContextManager
54
46
  from logging import _FilterType
55
47
 
56
-
57
- @contextmanager
58
- def _temp_log_factory() -> Iterator[None]:
59
- try:
60
- yield
61
- finally:
62
- setLogRecordFactory(LogRecord)
48
+ from whenever import ZonedDateTime
63
49
 
64
50
 
65
51
  class TestAddFilters:
@@ -81,7 +67,6 @@ class TestAddFilters:
81
67
 
82
68
 
83
69
  class TestBasicConfig:
84
- @mark.parametrize("whenever", [param(True), param(False)])
85
70
  @mark.parametrize(
86
71
  "filters",
87
72
  [
@@ -94,21 +79,20 @@ class TestBasicConfig:
94
79
  self,
95
80
  *,
96
81
  caplog: LogCaptureFixture,
97
- whenever: bool,
98
82
  filters: _FilterType | None,
99
83
  plain: bool,
84
+ set_log_factory: AbstractContextManager[None],
100
85
  ) -> None:
101
86
  name = unique_str()
102
- with _temp_log_factory():
103
- basic_config(obj=name, whenever=whenever, filters=filters, plain=plain)
104
- getLogger(name).warning("message")
105
- record = one(r for r in caplog.records if r.name == name)
106
- assert record.message == "message"
87
+ with set_log_factory:
88
+ basic_config(obj=name, filters=filters, plain=plain)
89
+ getLogger(name).warning("message")
90
+ record = one(r for r in caplog.records if r.name == name)
91
+ assert record.message == "message"
107
92
 
108
- @mark.parametrize("whenever", [param(True), param(False)])
109
- def test_none(self, *, whenever: bool) -> None:
110
- with _temp_log_factory():
111
- basic_config(whenever=whenever)
93
+ def test_none(self, *, set_log_factory: AbstractContextManager[None]) -> None:
94
+ with set_log_factory:
95
+ basic_config()
112
96
 
113
97
 
114
98
  class TestComputeRolloverActions:
@@ -208,7 +192,7 @@ class TestComputeRolloverActions:
208
192
 
209
193
  await sleep(1)
210
194
  tmp_path.joinpath("log.txt").touch()
211
- now = serialize_compact(NOW_UTC)
195
+ now = format_compact(get_now())
212
196
  tmp_path.joinpath(f"log.99__{now}__{now}.txt").touch()
213
197
  actions = _compute_rollover_actions(tmp_path, "log", ".txt")
214
198
  assert len(actions.deletions) == 2
@@ -249,21 +233,20 @@ class TestFilterForKey:
249
233
 
250
234
 
251
235
  class TestGetFormatter:
252
- @mark.parametrize("whenever", [param(True), param(False)])
253
236
  @mark.parametrize("plain", [param(True), param(False)])
254
237
  @mark.parametrize("color_field_styles", [param({}), param(None)])
255
238
  def test_main(
256
239
  self,
257
240
  *,
258
- whenever: bool,
259
241
  plain: bool,
260
242
  color_field_styles: Mapping[str, _FieldStyleKeys] | None,
243
+ set_log_factory: AbstractContextManager[None],
261
244
  ) -> None:
262
- with _temp_log_factory():
245
+ with set_log_factory:
263
246
  formatter = get_formatter(
264
- whenever=whenever, plain=plain, color_field_styles=color_field_styles
247
+ plain=plain, color_field_styles=color_field_styles
265
248
  )
266
- assert isinstance(formatter, Formatter)
249
+ assert isinstance(formatter, Formatter)
267
250
 
268
251
 
269
252
  class TestGetLogger:
@@ -332,42 +315,35 @@ class TestRotatingLogFile:
332
315
  assert result.start is None
333
316
  assert result.end is None
334
317
 
335
- @given(
336
- index=integers(min_value=1),
337
- end=zoned_datetimes(round_="standard", timedelta=SECOND),
338
- )
318
+ @given(index=integers(min_value=1), end=zoned_datetimes_whenever())
339
319
  def test_from_path_with_index_and_end(
340
- self, *, index: int, end: dt.datetime
320
+ self, *, index: int, end: ZonedDateTime
341
321
  ) -> None:
342
- path = Path(f"log.{index}__{serialize_compact(end)}.txt")
322
+ path = Path(f"log.{index}__{format_compact(end)}.txt")
343
323
  result = _RotatingLogFile.from_path(path, "log", ".txt")
344
324
  assert result is not None
345
325
  assert result.stem == "log"
346
326
  assert result.suffix == ".txt"
347
327
  assert result.index == index
348
328
  assert result.start is None
349
- assert result.end == end
329
+ assert result.end == end.round()
350
330
 
351
331
  @given(
352
332
  index=integers(min_value=1),
353
- datetimes=pairs(
354
- zoned_datetimes(round_="standard", timedelta=SECOND), sorted=True
355
- ),
333
+ datetimes=pairs(zoned_datetimes_whenever(), sorted=True),
356
334
  )
357
335
  def test_from_path_with_index_start_and_end(
358
- self, *, index: int, datetimes: tuple[dt.datetime, dt.datetime]
336
+ self, *, index: int, datetimes: tuple[ZonedDateTime, ZonedDateTime]
359
337
  ) -> None:
360
338
  start, end = datetimes
361
- path = Path(
362
- f"log.{index}__{serialize_compact(start)}__{serialize_compact(end)}.txt"
363
- )
339
+ path = Path(f"log.{index}__{format_compact(start)}__{format_compact(end)}.txt")
364
340
  result = _RotatingLogFile.from_path(path, "log", ".txt")
365
341
  assert result is not None
366
342
  assert result.stem == "log"
367
343
  assert result.suffix == ".txt"
368
344
  assert result.index == index
369
- assert result.start == start
370
- assert result.end == end
345
+ assert result.start == start.round()
346
+ assert result.end == end.round()
371
347
 
372
348
  def test_from_path_none(self) -> None:
373
349
  path = Path("invalid.txt")
@@ -384,34 +360,30 @@ class TestRotatingLogFile:
384
360
  assert file.path == root.joinpath(f"log.{index}.txt")
385
361
 
386
362
  @given(
387
- root=temp_paths(),
388
- index=integers(min_value=1),
389
- end=zoned_datetimes(round_="standard", timedelta=SECOND),
363
+ root=temp_paths(), index=integers(min_value=1), end=zoned_datetimes_whenever()
390
364
  )
391
365
  def test_path_with_index_and_end(
392
- self, *, root: Path, index: int, end: dt.datetime
366
+ self, *, root: Path, index: int, end: ZonedDateTime
393
367
  ) -> None:
394
368
  file = _RotatingLogFile(
395
369
  directory=root, stem="log", suffix=".txt", index=index, end=end
396
370
  )
397
- assert file.path == root.joinpath(f"log.{index}__{serialize_compact(end)}.txt")
371
+ assert file.path == root.joinpath(f"log.{index}__{format_compact(end)}.txt")
398
372
 
399
373
  @given(
400
374
  root=temp_paths(),
401
375
  index=integers(min_value=1),
402
- datetimes=pairs(
403
- zoned_datetimes(round_="standard", timedelta=SECOND), sorted=True
404
- ),
376
+ datetimes=pairs(zoned_datetimes_whenever(), sorted=True),
405
377
  )
406
378
  def test_path_with_index_start_and_end(
407
- self, *, root: Path, index: int, datetimes: tuple[dt.datetime, dt.datetime]
379
+ self, *, root: Path, index: int, datetimes: tuple[ZonedDateTime, ZonedDateTime]
408
380
  ) -> None:
409
381
  start, end = datetimes
410
382
  file = _RotatingLogFile(
411
383
  directory=root, stem="log", suffix=".txt", index=index, start=start, end=end
412
384
  )
413
385
  assert file.path == root.joinpath(
414
- f"log.{index}__{serialize_compact(start)}__{serialize_compact(end)}.txt"
386
+ f"log.{index}__{format_compact(start)}__{format_compact(end)}.txt"
415
387
  )
416
388
 
417
389
 
@@ -440,8 +412,7 @@ class TestSizeAndTimeRotatingFileHandler:
440
412
  filename = tmp_path.joinpath("log")
441
413
  logger.addHandler(SizeAndTimeRotatingFileHandler(filename=filename))
442
414
  logger.warning("message")
443
- with filename.open() as fh:
444
- content = fh.read()
415
+ content = filename.read_text()
445
416
  assert content == "message\n"
446
417
 
447
418
  def test_create_parents(self, *, tmp_path: Path) -> None:
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import datetime as dt
4
3
  from collections.abc import Iterable
5
4
  from io import StringIO
6
5
  from logging import DEBUG, WARNING, FileHandler, StreamHandler, getLogger
@@ -12,7 +11,6 @@ from hypothesis import assume, given
12
11
  from hypothesis.strategies import (
13
12
  booleans,
14
13
  builds,
15
- dates,
16
14
  dictionaries,
17
15
  integers,
18
16
  lists,
@@ -51,16 +49,16 @@ from tests.test_typing_funcs.with_future import (
51
49
  DataClassFutureTypeLiteral,
52
50
  DataClassFutureTypeLiteralNullable,
53
51
  )
54
- from utilities.datetime import MINUTE, SECOND, get_now
55
52
  from utilities.functions import is_sequence_of
56
53
  from utilities.hypothesis import (
57
54
  assume_does_not_raise,
55
+ dates_whenever,
58
56
  int64s,
59
57
  paths,
60
58
  temp_paths,
61
59
  text_ascii,
62
60
  text_printable,
63
- zoned_datetimes,
61
+ zoned_datetimes_whenever,
64
62
  )
65
63
  from utilities.iterables import always_iterable, one
66
64
  from utilities.logging import get_logging_level_number
@@ -81,13 +79,16 @@ from utilities.orjson import (
81
79
  )
82
80
  from utilities.polars import check_polars_dataframe, zoned_datetime
83
81
  from utilities.sentinel import Sentinel, sentinel
84
- from utilities.types import DateOrDateTime, LogLevel, MaybeIterable, PathLike
82
+ from utilities.types import LogLevel, MaybeIterable, PathLike
85
83
  from utilities.typing import get_args
86
- from utilities.tzlocal import get_now_local
84
+ from utilities.tzlocal import LOCAL_TIME_ZONE
85
+ from utilities.whenever2 import MINUTE, SECOND, get_now
87
86
 
88
87
  if TYPE_CHECKING:
89
88
  from collections.abc import Sequence
90
89
 
90
+ from whenever import Date, ZonedDateTime
91
+
91
92
  from utilities.types import Dataclass, StrMapping
92
93
 
93
94
 
@@ -169,7 +170,7 @@ class TestGetLogRecords:
169
170
  "level": UInt64,
170
171
  "path_name": String,
171
172
  "line_num": UInt64,
172
- "datetime": zoned_datetime(time_zone="local"),
173
+ "datetime": zoned_datetime(time_zone=LOCAL_TIME_ZONE),
173
174
  "func_name": String,
174
175
  "stack_info": String,
175
176
  "extra": Object,
@@ -195,9 +196,12 @@ class TestGetLogRecords:
195
196
  level=sampled_from(get_args(LogLevel)) | none(),
196
197
  min_level=sampled_from(get_args(LogLevel)) | none(),
197
198
  max_level=sampled_from(get_args(LogLevel)) | none(),
198
- date_or_datetime=dates() | zoned_datetimes() | none(),
199
- min_date_or_datetime=dates() | zoned_datetimes() | none(),
200
- max_date_or_datetime=dates() | zoned_datetimes() | none(),
199
+ date=dates_whenever() | none(),
200
+ min_date=dates_whenever() | none(),
201
+ max_date=dates_whenever() | none(),
202
+ datetime=zoned_datetimes_whenever() | none(),
203
+ min_datetime=zoned_datetimes_whenever() | none(),
204
+ max_datetime=zoned_datetimes_whenever() | none(),
201
205
  func_name=booleans() | text_ascii() | none(),
202
206
  extra=booleans() | text_ascii() | sets(text_ascii()) | none(),
203
207
  log_file=booleans() | paths() | text_ascii() | none(),
@@ -218,9 +222,12 @@ class TestGetLogRecords:
218
222
  level: LogLevel | None,
219
223
  min_level: LogLevel | None,
220
224
  max_level: LogLevel | None,
221
- date_or_datetime: DateOrDateTime | None,
222
- min_date_or_datetime: DateOrDateTime | None,
223
- max_date_or_datetime: DateOrDateTime | None,
225
+ date: Date | None,
226
+ min_date: Date | None,
227
+ max_date: Date | None,
228
+ datetime: ZonedDateTime | None,
229
+ min_datetime: ZonedDateTime | None,
230
+ max_datetime: ZonedDateTime | None,
224
231
  func_name: bool | str | None,
225
232
  extra: bool | MaybeIterable[str] | None,
226
233
  log_file: bool | PathLike | None,
@@ -245,9 +252,12 @@ class TestGetLogRecords:
245
252
  level=level,
246
253
  min_level=min_level,
247
254
  max_level=max_level,
248
- date_or_datetime=date_or_datetime,
249
- min_date_or_datetime=min_date_or_datetime,
250
- max_date_or_datetime=max_date_or_datetime,
255
+ date=date,
256
+ min_date=min_date,
257
+ max_date=max_date,
258
+ datetime=datetime,
259
+ min_datetime=min_datetime,
260
+ max_datetime=max_datetime,
251
261
  func_name=func_name,
252
262
  extra=extra,
253
263
  log_file=log_file,
@@ -272,24 +282,18 @@ class TestGetLogRecords:
272
282
  assert all(r.level >= get_logging_level_number(min_level) for r in records)
273
283
  if max_level is not None:
274
284
  assert all(r.level <= get_logging_level_number(max_level) for r in records)
275
- if date_or_datetime is not None:
276
- match date_or_datetime:
277
- case dt.datetime() as datetime:
278
- assert all(r.datetime == datetime for r in records)
279
- case dt.date() as date:
280
- assert all(r.date == date for r in records)
281
- if min_date_or_datetime is not None:
282
- match min_date_or_datetime:
283
- case dt.datetime() as min_datetime:
284
- assert all(r.datetime >= min_datetime for r in records)
285
- case dt.date() as min_date:
286
- assert all(r.date >= min_date for r in records)
287
- if max_date_or_datetime is not None:
288
- match max_date_or_datetime:
289
- case dt.datetime() as max_datetime:
290
- assert all(r.datetime <= max_datetime for r in records)
291
- case dt.date() as max_date:
292
- assert all(r.date <= max_date for r in records)
285
+ if date is not None:
286
+ assert all(r.date == date for r in records)
287
+ if min_date is not None:
288
+ assert all(r.date >= min_date for r in records)
289
+ if max_date is not None:
290
+ assert all(r.date <= max_date for r in records)
291
+ if datetime is not None:
292
+ assert all(r.datetime == datetime for r in records)
293
+ if min_datetime is not None:
294
+ assert all(r.datetime >= min_datetime for r in records)
295
+ if max_datetime is not None:
296
+ assert all(r.datetime <= max_datetime for r in records)
293
297
  if func_name is not None:
294
298
  match func_name:
295
299
  case bool() as has_func_name:
@@ -425,7 +429,7 @@ class TestOrjsonFormatter:
425
429
  assert record.message == "message"
426
430
  assert record.level == WARNING
427
431
  assert record.path_name == Path(__file__)
428
- assert abs(record.datetime - get_now_local()) <= SECOND
432
+ assert abs(record.datetime - get_now()) <= SECOND
429
433
  assert record.func_name == TestOrjsonFormatter.test_main.__name__
430
434
  assert record.stack_info is None
431
435
  assert record.extra == {"a": 1, "b": 2}