dycw-utilities 0.110.7__tar.gz → 0.111.0__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 (229) hide show
  1. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/PKG-INFO +1 -1
  2. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/pyproject.toml +2 -2
  3. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_datetime.py +0 -19
  4. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_functions.py +0 -61
  5. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_orjson.py +1 -3
  6. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_typing.py +155 -2
  7. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/__init__.py +1 -1
  8. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/datetime.py +4 -21
  9. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/functions.py +0 -47
  10. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/orjson.py +1 -0
  11. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/parse.py +8 -11
  12. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/period.py +10 -5
  13. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/polars.py +2 -2
  14. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/sqlalchemy_polars.py +12 -12
  15. dycw_utilities-0.111.0/src/utilities/typing.py +424 -0
  16. dycw_utilities-0.110.7/src/utilities/typing.py +0 -225
  17. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/.gitignore +0 -0
  18. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/LICENSE +0 -0
  19. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/README.md +0 -0
  20. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/__init__.py +0 -0
  21. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/conftest.py +0 -0
  22. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/__init__.py +0 -0
  23. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_missing/__init__.py +0 -0
  24. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_missing/module.py +0 -0
  25. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/__init__.py +0 -0
  26. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/outer_1.py +0 -0
  27. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/outer_2.py +0 -0
  28. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  29. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  30. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  31. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  32. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_without/__init__.py +0 -0
  33. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_without/module_1.py +0 -0
  34. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/package_without/module_2.py +0 -0
  35. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/standalone.py +0 -0
  36. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/modules/with_imports.py +0 -0
  37. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  38. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  39. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  40. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  41. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  42. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  43. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  44. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  45. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/__init__.py +0 -0
  46. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_async_service/__init__.py +0 -0
  47. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_async_service/__main__.py +0 -0
  48. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_async_service/run.sh +0 -0
  49. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  50. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  51. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  52. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_altair.py +0 -0
  53. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_astor.py +0 -0
  54. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_asyncio.py +0 -0
  55. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_atomicwrites.py +0 -0
  56. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_atools.py +0 -0
  57. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_cachetools.py +0 -0
  58. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_click.py +0 -0
  59. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_concurrent.py +0 -0
  60. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_contextlib.py +0 -0
  61. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_contextvars.py +0 -0
  62. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_cryptography.py +0 -0
  63. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_cvxpy.py +0 -0
  64. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_dataclasses.py +0 -0
  65. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_enum.py +0 -0
  66. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_errors.py +0 -0
  67. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_eventkit.py +0 -0
  68. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_fastapi.py +0 -0
  69. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_fpdf2.py +0 -0
  70. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_functools.py +0 -0
  71. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_getpass.py +0 -0
  72. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_git.py +0 -0
  73. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_hashlib.py +0 -0
  74. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_http.py +0 -0
  75. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_hypothesis.py +0 -0
  76. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_ipython.py +0 -0
  77. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_iterables.py +0 -0
  78. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_jupyter.py +0 -0
  79. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_lightweight_charts.py +0 -0
  80. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_logging.py +0 -0
  81. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_loguru.py +0 -0
  82. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_luigi.py +0 -0
  83. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_math.py +0 -0
  84. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_memory_profiler.py +0 -0
  85. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_modules.py +0 -0
  86. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_more_itertools.py +0 -0
  87. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_numpy.py +0 -0
  88. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_operator.py +0 -0
  89. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_optuna.py +0 -0
  90. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_os.py +0 -0
  91. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_parse.py +0 -0
  92. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pathlib.py +0 -0
  93. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_period.py +0 -0
  94. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pickle.py +0 -0
  95. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_platform.py +0 -0
  96. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_polars.py +0 -0
  97. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_polars_ols.py +0 -0
  98. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pqdm.py +0 -0
  99. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pydantic.py +0 -0
  100. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pyinstrument.py +0 -0
  101. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pyrsistent.py +0 -0
  102. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pytest.py +0 -0
  103. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_pytest_regressions.py +0 -0
  104. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_python_dotenv.py +0 -0
  105. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_random.py +0 -0
  106. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_re.py +0 -0
  107. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_redis.py +0 -0
  108. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_reprlib.py +0 -0
  109. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_rich.py +0 -0
  110. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_scipy.py +0 -0
  111. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_sentinel.py +0 -0
  112. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_shelve.py +0 -0
  113. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_slack_sdk.py +0 -0
  114. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_socket.py +0 -0
  115. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_sqlalchemy.py +0 -0
  116. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_sqlalchemy_polars.py +0 -0
  117. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_statsmodel.py +0 -0
  118. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_streamlit.py +0 -0
  119. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_sys.py +0 -0
  120. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_tempfile.py +0 -0
  121. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_tenacity.py +0 -0
  122. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_text.py +0 -0
  123. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_threading.py +0 -0
  124. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_timer.py +0 -0
  125. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback.py +0 -0
  126. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/__init__.py +0 -0
  127. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/chain.py +0 -0
  128. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  129. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  130. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  131. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/many.py +0 -0
  132. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/one.py +0 -0
  133. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/recursive.py +0 -0
  134. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  135. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  136. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/two.py +0 -0
  137. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_traceback_funcs/untraced.py +0 -0
  138. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_types.py +0 -0
  139. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_typing_funcs/__init__.py +0 -0
  140. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_typing_funcs/no_future.py +0 -0
  141. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_typing_funcs/with_future.py +0 -0
  142. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_tzdata.py +0 -0
  143. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_tzlocal.py +0 -0
  144. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_uuid.py +0 -0
  145. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_version.py +0 -0
  146. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_warnings.py +0 -0
  147. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_whenever.py +0 -0
  148. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_zipfile.py +0 -0
  149. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/tests/test_zoneinfo.py +0 -0
  150. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/altair.py +0 -0
  151. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/astor.py +0 -0
  152. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/asyncio.py +0 -0
  153. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/atomicwrites.py +0 -0
  154. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/atools.py +0 -0
  155. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/cachetools.py +0 -0
  156. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/click.py +0 -0
  157. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/concurrent.py +0 -0
  158. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/contextlib.py +0 -0
  159. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/contextvars.py +0 -0
  160. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/cryptography.py +0 -0
  161. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/cvxpy.py +0 -0
  162. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/dataclasses.py +0 -0
  163. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/enum.py +0 -0
  164. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/errors.py +0 -0
  165. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/eventkit.py +0 -0
  166. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/fastapi.py +0 -0
  167. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/fpdf2.py +0 -0
  168. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/functools.py +0 -0
  169. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/getpass.py +0 -0
  170. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/git.py +0 -0
  171. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/hashlib.py +0 -0
  172. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/http.py +0 -0
  173. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/hypothesis.py +0 -0
  174. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/ipython.py +0 -0
  175. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/iterables.py +0 -0
  176. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/jupyter.py +0 -0
  177. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/lightweight_charts.py +0 -0
  178. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/logging.py +0 -0
  179. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/loguru.py +0 -0
  180. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/luigi.py +0 -0
  181. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/math.py +0 -0
  182. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/memory_profiler.py +0 -0
  183. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/modules.py +0 -0
  184. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/more_itertools.py +0 -0
  185. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/numpy.py +0 -0
  186. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/operator.py +0 -0
  187. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/optuna.py +0 -0
  188. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/os.py +0 -0
  189. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pathlib.py +0 -0
  190. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pickle.py +0 -0
  191. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/platform.py +0 -0
  192. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/polars_ols.py +0 -0
  193. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pqdm.py +0 -0
  194. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/py.typed +0 -0
  195. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pydantic.py +0 -0
  196. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pyinstrument.py +0 -0
  197. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pyrsistent.py +0 -0
  198. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pytest.py +0 -0
  199. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/pytest_regressions.py +0 -0
  200. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/python_dotenv.py +0 -0
  201. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/random.py +0 -0
  202. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/re.py +0 -0
  203. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/redis.py +0 -0
  204. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/reprlib.py +0 -0
  205. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/rich.py +0 -0
  206. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/scipy.py +0 -0
  207. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/sentinel.py +0 -0
  208. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/shelve.py +0 -0
  209. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/slack_sdk.py +0 -0
  210. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/socket.py +0 -0
  211. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/sqlalchemy.py +0 -0
  212. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/sys.py +0 -0
  215. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/text.py +0 -0
  218. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/threading.py +0 -0
  219. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/timer.py +0 -0
  220. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/traceback.py +0 -0
  221. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/types.py +0 -0
  222. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/tzdata.py +0 -0
  223. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/tzlocal.py +0 -0
  224. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/uuid.py +0 -0
  225. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/version.py +0 -0
  226. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/warnings.py +0 -0
  227. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/whenever.py +0 -0
  228. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/zipfile.py +0 -0
  229. {dycw_utilities-0.110.7 → dycw_utilities-0.111.0}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.110.7
3
+ Version: 0.111.0
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.110.7"
97
+ version = "0.111.0"
98
98
 
99
99
  [project.optional-dependencies]
100
100
  test = [
@@ -337,7 +337,7 @@ zzz-test-zoneinfo = [
337
337
  # bump-my-version
338
338
  [tool.bumpversion]
339
339
  allow_dirty = true
340
- current_version = "0.110.7"
340
+ current_version = "0.111.0"
341
341
 
342
342
  [[tool.bumpversion.files]]
343
343
  filename = "src/utilities/__init__.py"
@@ -107,10 +107,8 @@ from utilities.datetime import (
107
107
  get_today_local,
108
108
  get_today_tokyo,
109
109
  get_years,
110
- is_instance_date_not_datetime,
111
110
  is_integral_timedelta,
112
111
  is_local_datetime,
113
- is_subclass_date_not_datetime,
114
112
  is_weekday,
115
113
  is_zero_time,
116
114
  is_zoned_datetime,
@@ -751,16 +749,6 @@ class TestGetToday:
751
749
  assert isinstance(today, dt.date)
752
750
 
753
751
 
754
- class TestIsInstanceDateNotDateTime:
755
- @given(date=dates())
756
- def test_date(self, *, date: dt.date) -> None:
757
- assert is_instance_date_not_datetime(date)
758
-
759
- @given(datetime=datetimes())
760
- def test_datetime(self, *, datetime: dt.datetime) -> None:
761
- assert not is_instance_date_not_datetime(datetime)
762
-
763
-
764
752
  class TestIsIntegralTimeDelta:
765
753
  @given(n=integers())
766
754
  def test_integral(self, *, n: int) -> None:
@@ -794,13 +782,6 @@ class TestIsLocalDateTime:
794
782
  assert result is expected
795
783
 
796
784
 
797
- class TestIsSubClassDateNotDateTime:
798
- @given(case=sampled_from([(dt.date, True), (dt.datetime, False)]))
799
- def test_date(self, *, case: tuple[type[Any], bool]) -> None:
800
- type_, expected = case
801
- assert is_subclass_date_not_datetime(type_) is expected
802
-
803
-
804
785
  class TestIsWeekday:
805
786
  @given(date=dates())
806
787
  def test_main(self, *, date: dt.date) -> None:
@@ -12,7 +12,6 @@ from typing import TYPE_CHECKING, Any, ClassVar, ParamSpec, TypeVar, cast
12
12
  from hypothesis import given
13
13
  from hypothesis.strategies import (
14
14
  DataObject,
15
- SearchStrategy,
16
15
  booleans,
17
16
  builds,
18
17
  data,
@@ -74,7 +73,6 @@ from utilities.functions import (
74
73
  is_dataclass_class,
75
74
  is_dataclass_instance,
76
75
  is_hashable,
77
- is_instance_not_bool_int,
78
76
  is_iterable_of,
79
77
  is_none,
80
78
  is_not_none,
@@ -83,7 +81,6 @@ from utilities.functions import (
83
81
  is_sized,
84
82
  is_sized_not_str,
85
83
  is_string_mapping,
86
- is_subclass_not_bool_int,
87
84
  is_tuple,
88
85
  is_tuple_or_str_mapping,
89
86
  make_isinstance,
@@ -622,39 +619,6 @@ class TestIsHashable:
622
619
  assert is_hashable(obj) is expected
623
620
 
624
621
 
625
- class TestIsInstanceNotIntBool:
626
- @given(
627
- data=data(),
628
- case=sampled_from([
629
- (booleans(), bool, True),
630
- (booleans(), int, False),
631
- (integers(), bool, False),
632
- (integers(), int, True),
633
- (booleans(), (bool, int), True),
634
- (integers(), (bool, int), True),
635
- ]),
636
- )
637
- def test_main(
638
- self, *, data: DataObject, case: tuple[SearchStrategy[Any], type[Any], bool]
639
- ) -> None:
640
- strategy, type_, expected = case
641
- value = data.draw(strategy)
642
- assert is_instance_not_bool_int(value, type_) is expected
643
-
644
- @given(bool_=booleans())
645
- def test_bool_value_vs_custom_int(self, *, bool_: bool) -> None:
646
- class MyInt(int): ...
647
-
648
- assert not is_instance_not_bool_int(bool_, MyInt)
649
-
650
- @given(int_=integers())
651
- def test_int_value_vs_custom_int(self, *, int_: int) -> None:
652
- class MyInt(int): ...
653
-
654
- assert not is_instance_not_bool_int(int_, MyInt)
655
- assert is_instance_not_bool_int(MyInt(int_), MyInt)
656
-
657
-
658
622
  class TestIsIterableOf:
659
623
  @given(
660
624
  case=sampled_from([
@@ -775,31 +739,6 @@ class TestIsStringMapping:
775
739
  assert result is expected
776
740
 
777
741
 
778
- class TestIsSubclassNotBoolInt:
779
- @given(
780
- case=sampled_from([
781
- (bool, bool, True),
782
- (bool, int, False),
783
- (int, bool, False),
784
- (int, int, True),
785
- (bool, (bool, int), True),
786
- (int, (bool, int), True),
787
- ])
788
- )
789
- def test_main(self, *, case: tuple[type[Any], type[Any], bool]) -> None:
790
- child, parent, expected = case
791
- assert is_subclass_not_bool_int(child, parent) is expected
792
-
793
- def test_custom_int(self) -> None:
794
- class MyInt(int): ...
795
-
796
- assert not is_subclass_not_bool_int(bool, MyInt)
797
- assert not is_subclass_not_bool_int(MyInt, bool)
798
- assert not is_subclass_not_bool_int(int, MyInt)
799
- assert is_subclass_not_bool_int(MyInt, int)
800
- assert is_subclass_not_bool_int(MyInt, MyInt)
801
-
802
-
803
742
  class TestIsTuple:
804
743
  @given(case=sampled_from([(None, False), ((1, 2, 3), True), ([1, 2, 3], False)]))
805
744
  def test_main(self, *, case: tuple[Any, bool]) -> None:
@@ -23,7 +23,7 @@ from hypothesis.strategies import (
23
23
  )
24
24
  from orjson import JSONDecodeError
25
25
  from polars import Object, String, UInt64
26
- from pytest import approx, mark, raises
26
+ from pytest import approx, raises
27
27
 
28
28
  from tests.conftest import SKIPIF_CI_AND_WINDOWS
29
29
  from tests.test_operator import (
@@ -147,7 +147,6 @@ class TestGetLogRecords:
147
147
  ),
148
148
  root=temp_paths(),
149
149
  )
150
- @mark.flaky
151
150
  def test_dataframe(
152
151
  self, *, root: Path, items: Sequence[tuple[LogLevel, str, StrMapping]]
153
152
  ) -> None:
@@ -205,7 +204,6 @@ class TestGetLogRecords:
205
204
  min_log_file_line_num=integers() | none(),
206
205
  max_log_file_line_num=integers() | none(),
207
206
  )
208
- @mark.flaky
209
207
  def test_filter(
210
208
  self,
211
209
  *,
@@ -4,12 +4,25 @@ import datetime as dt
4
4
  from collections.abc import Mapping, Sequence
5
5
  from dataclasses import dataclass
6
6
  from pathlib import Path
7
+ from random import Random
7
8
  from types import NoneType
8
9
  from typing import TYPE_CHECKING, Any, Literal, NamedTuple, Self
9
10
  from uuid import UUID
10
11
 
11
12
  from hypothesis import given
12
- from hypothesis.strategies import DataObject, data, just, none, sampled_from
13
+ from hypothesis.strategies import (
14
+ DataObject,
15
+ SearchStrategy,
16
+ booleans,
17
+ data,
18
+ dates,
19
+ datetimes,
20
+ floats,
21
+ integers,
22
+ just,
23
+ none,
24
+ sampled_from,
25
+ )
13
26
  from pytest import mark, param, raises
14
27
 
15
28
  from tests.test_typing_funcs.no_future import (
@@ -39,14 +52,21 @@ from tests.test_typing_funcs.with_future import (
39
52
  TrueOrFalseFutureTypeLit,
40
53
  )
41
54
  from utilities.sentinel import Sentinel
42
- from utilities.types import LogLevel, Parallelism
55
+ from utilities.types import Duration, LogLevel, Number, Parallelism, Seed
43
56
  from utilities.typing import (
57
+ _GetTypeClassesTupleError,
58
+ _GetTypeClassesTypeError,
59
+ _GetUnionTypeClassesInternalTypeError,
60
+ _GetUnionTypeClassesUnionTypeError,
44
61
  contains_self,
45
62
  get_args,
46
63
  get_literal_elements,
64
+ get_type_classes,
47
65
  get_type_hints,
66
+ get_union_type_classes,
48
67
  is_dict_type,
49
68
  is_frozenset_type,
69
+ is_instance_gen,
50
70
  is_list_type,
51
71
  is_literal_type,
52
72
  is_mapping_type,
@@ -55,6 +75,7 @@ from utilities.typing import (
55
75
  is_optional_type,
56
76
  is_sequence_type,
57
77
  is_set_type,
78
+ is_subclass_gen,
58
79
  is_tuple_type,
59
80
  is_union_type,
60
81
  )
@@ -114,6 +135,38 @@ class TestGetLiteralElements:
114
135
  assert result == expected
115
136
 
116
137
 
138
+ class TestGetTypeClasses:
139
+ @given(
140
+ case=sampled_from([
141
+ (int, (int,)),
142
+ ((int, float), (int, float)),
143
+ (Duration, (int, float, dt.timedelta)),
144
+ (Number, (int, float)),
145
+ (Seed, (int, float, str, bytes, bytearray, Random)),
146
+ ((int, Number), (int, int, float)),
147
+ ((int, (Number,)), (int, int, float)),
148
+ ])
149
+ )
150
+ def test_main(self, *, case: tuple[Any, tuple[type[Any], ...]]) -> None:
151
+ obj, expected = case
152
+ result = get_type_classes(obj)
153
+ assert result == expected
154
+
155
+ def test_error_type(self) -> None:
156
+ with raises(
157
+ _GetTypeClassesTypeError,
158
+ match="Object must be a type, tuple or Union type; got None",
159
+ ):
160
+ _ = get_type_classes(None)
161
+
162
+ def test_error_tuple(self) -> None:
163
+ with raises(
164
+ _GetTypeClassesTupleError,
165
+ match="Tuple must contain types, tuples or Union types only; got None",
166
+ ):
167
+ _ = get_type_classes((None,))
168
+
169
+
117
170
  class TestGetTypeHints:
118
171
  @given(data=data())
119
172
  def test_date(self, *, data: DataObject) -> None:
@@ -335,6 +388,34 @@ class TestGetTypeHints:
335
388
  _ = get_type_hints(Outer, warn_name_errors=True)
336
389
 
337
390
 
391
+ class TestGetUnionTypeClasses:
392
+ @given(
393
+ case=sampled_from([
394
+ (Duration, (int, float, dt.timedelta)),
395
+ (Number, (int, float)),
396
+ (Seed, (int, float, str, bytes, bytearray, Random)),
397
+ ])
398
+ )
399
+ def test_main(self, *, case: tuple[Any, tuple[type[Any], ...]]) -> None:
400
+ obj, expected = case
401
+ result = get_union_type_classes(obj)
402
+ assert result == expected
403
+
404
+ def test_error_union_type(self) -> None:
405
+ with raises(
406
+ _GetUnionTypeClassesUnionTypeError,
407
+ match="Object must be a Union type; got None",
408
+ ):
409
+ _ = get_union_type_classes(None)
410
+
411
+ def test_error_interal_type(self) -> None:
412
+ with raises(
413
+ _GetUnionTypeClassesInternalTypeError,
414
+ match=r"Union type must contain types only; got typing\.Literal\[True\]",
415
+ ):
416
+ _ = get_union_type_classes(Literal[True] | None)
417
+
418
+
338
419
  class TestIsAnnotationOfType:
339
420
  @mark.parametrize(
340
421
  ("func", "obj", "expected"),
@@ -406,6 +487,46 @@ class TestIsAnnotationOfType:
406
487
  assert func(obj) is expected
407
488
 
408
489
 
490
+ class TestIsInstanceGen:
491
+ @given(
492
+ data=data(),
493
+ case=sampled_from([
494
+ (booleans(), bool, True),
495
+ (booleans(), int, False),
496
+ (integers(), bool, False),
497
+ (integers(), int, True),
498
+ (booleans(), (bool, int), True),
499
+ (integers(), (bool, int), True),
500
+ (dates(), dt.date, True),
501
+ (dates(), dt.datetime, False),
502
+ (datetimes(), dt.date, False),
503
+ (datetimes(), dt.datetime, True),
504
+ (booleans(), Number, False),
505
+ (integers(), Number, True),
506
+ (floats(), Number, True),
507
+ ]),
508
+ )
509
+ def test_main(
510
+ self, *, data: DataObject, case: tuple[SearchStrategy[Any], Any, bool]
511
+ ) -> None:
512
+ strategy, type_, expected = case
513
+ value = data.draw(strategy)
514
+ assert is_instance_gen(value, type_) is expected
515
+
516
+ @given(bool_=booleans())
517
+ def test_bool_value_vs_custom_int(self, *, bool_: bool) -> None:
518
+ class MyInt(int): ...
519
+
520
+ assert not is_instance_gen(bool_, MyInt)
521
+
522
+ @given(int_=integers())
523
+ def test_int_value_vs_custom_int(self, *, int_: int) -> None:
524
+ class MyInt(int): ...
525
+
526
+ assert not is_instance_gen(int_, MyInt)
527
+ assert is_instance_gen(MyInt(int_), MyInt)
528
+
529
+
409
530
  class TestIsNamedTuple:
410
531
  def test_main(self) -> None:
411
532
  class Example(NamedTuple):
@@ -421,3 +542,35 @@ class TestIsNamedTuple:
421
542
 
422
543
  assert not is_namedtuple_class(Example)
423
544
  assert not is_namedtuple_instance(Example(x=0))
545
+
546
+
547
+ class TestIsSubclassGen:
548
+ @given(
549
+ case=sampled_from([
550
+ (bool, bool, True),
551
+ (bool, int, False),
552
+ (int, bool, False),
553
+ (int, int, True),
554
+ (bool, (bool, int), True),
555
+ (int, (bool, int), True),
556
+ (dt.date, dt.date, True),
557
+ (dt.date, dt.datetime, False),
558
+ (dt.datetime, dt.date, False),
559
+ (dt.datetime, dt.datetime, True),
560
+ (bool, Number, False),
561
+ (int, Number, True),
562
+ (float, Number, True),
563
+ ])
564
+ )
565
+ def test_main(self, *, case: tuple[type[Any], Any, bool]) -> None:
566
+ child, parent, expected = case
567
+ assert is_subclass_gen(child, parent) is expected
568
+
569
+ def test_custom_int(self) -> None:
570
+ class MyInt(int): ...
571
+
572
+ assert not is_subclass_gen(bool, MyInt)
573
+ assert not is_subclass_gen(MyInt, bool)
574
+ assert not is_subclass_gen(int, MyInt)
575
+ assert is_subclass_gen(MyInt, int)
576
+ assert is_subclass_gen(MyInt, MyInt)
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.110.7"
3
+ __version__ = "0.111.0"
@@ -22,6 +22,7 @@ from utilities.math import SafeRoundError, round_, safe_round
22
22
  from utilities.platform import SYSTEM
23
23
  from utilities.sentinel import Sentinel, sentinel
24
24
  from utilities.types import MaybeStr
25
+ from utilities.typing import is_instance_gen
25
26
  from utilities.zoneinfo import (
26
27
  UTC,
27
28
  HongKong,
@@ -140,9 +141,9 @@ def are_equal_dates_or_datetimes(
140
141
  x: DateOrDateTime, y: DateOrDateTime, /, *, strict: bool = False
141
142
  ) -> bool:
142
143
  """Check if x == y for dates/datetimes."""
143
- if is_instance_date_not_datetime(x) and is_instance_date_not_datetime(y):
144
+ if is_instance_gen(x, dt.date) and is_instance_gen(y, dt.date):
144
145
  return x == y
145
- if isinstance(x, dt.datetime) and isinstance(y, dt.datetime):
146
+ if is_instance_gen(x, dt.datetime) and is_instance_gen(y, dt.datetime):
146
147
  return are_equal_datetimes(x, y, strict=strict)
147
148
  raise AreEqualDatesOrDateTimesError(x=x, y=y)
148
149
 
@@ -210,7 +211,7 @@ def are_equal_months(x: DateOrMonth, y: DateOrMonth, /) -> bool:
210
211
 
211
212
  def check_date_not_datetime(date: dt.date, /) -> None:
212
213
  """Check if a date is not a datetime."""
213
- if not is_instance_date_not_datetime(date):
214
+ if not is_instance_gen(date, dt.date):
214
215
  raise CheckDateNotDateTimeError(date=date)
215
216
 
216
217
 
@@ -604,14 +605,6 @@ YEAR = get_years(n=1)
604
605
  ##
605
606
 
606
607
 
607
- def is_instance_date_not_datetime(obj: Any, /) -> TypeGuard[dt.date]:
608
- """Check if an object is a date, and not a datetime."""
609
- return isinstance(obj, dt.date) and not isinstance(obj, dt.datetime)
610
-
611
-
612
- ##
613
-
614
-
615
608
  def is_integral_timedelta(timedelta: dt.timedelta, /) -> bool:
616
609
  """Check if a timedelta is integral."""
617
610
  return (timedelta.seconds == 0) and (timedelta.microseconds == 0)
@@ -628,14 +621,6 @@ def is_local_datetime(obj: Any, /) -> TypeGuard[dt.datetime]:
628
621
  ##
629
622
 
630
623
 
631
- def is_subclass_date_not_datetime(cls: type[Any], /) -> TypeGuard[type[dt.date]]:
632
- """Check if a class is a date, and not a datetime."""
633
- return issubclass(cls, dt.date) and not issubclass(cls, dt.datetime)
634
-
635
-
636
- ##
637
-
638
-
639
624
  _FRIDAY = 5
640
625
 
641
626
 
@@ -1359,10 +1344,8 @@ __all__ = [
1359
1344
  "get_today_local",
1360
1345
  "get_today_tokyo",
1361
1346
  "get_years",
1362
- "is_instance_date_not_datetime",
1363
1347
  "is_integral_timedelta",
1364
1348
  "is_local_datetime",
1365
- "is_subclass_date_not_datetime",
1366
1349
  "is_weekday",
1367
1350
  "is_zero_time",
1368
1351
  "is_zoned_datetime",
@@ -22,7 +22,6 @@ from typing import (
22
22
  Literal,
23
23
  TypeGuard,
24
24
  TypeVar,
25
- assert_never,
26
25
  cast,
27
26
  overload,
28
27
  override,
@@ -660,28 +659,6 @@ def is_hashable(obj: Any, /) -> TypeGuard[Hashable]:
660
659
  ##
661
660
 
662
661
 
663
- def is_instance_not_bool_int(
664
- obj: Any, class_or_tuple: TypeLike[Any], /
665
- ) -> TypeGuard[int]:
666
- """Check if an instance relationship holds, except bool<int."""
667
- match class_or_tuple:
668
- case type() as type_:
669
- return _is_instance_not_bool_int(obj, type_)
670
- case tuple() as types:
671
- return any(_is_instance_not_bool_int(obj, p) for p in types)
672
- case _ as never:
673
- assert_never(never)
674
-
675
-
676
- def _is_instance_not_bool_int(obj: Any, type_: type[Any], /) -> bool:
677
- return isinstance(obj, type_) and not (
678
- isinstance(obj, bool) and issubclass(type_, int) and not issubclass(type_, bool)
679
- )
680
-
681
-
682
- ##
683
-
684
-
685
662
  @overload
686
663
  def is_iterable_of(obj: Any, cls: type[_T], /) -> TypeGuard[Iterable[_T]]: ...
687
664
  @overload
@@ -796,28 +773,6 @@ def is_string_mapping(obj: Any, /) -> TypeGuard[StrMapping]:
796
773
  ##
797
774
 
798
775
 
799
- def is_subclass_not_bool_int(cls: type[Any], class_or_tuple: TypeLike[Any], /) -> bool:
800
- """Check if a subclass relationship holds, except bool<int."""
801
- match class_or_tuple:
802
- case type() as parent:
803
- return _is_subclass_int_not_bool_one(cls, parent)
804
- case tuple() as parents:
805
- return any(_is_subclass_int_not_bool_one(cls, p) for p in parents)
806
- case _ as never:
807
- assert_never(never)
808
-
809
-
810
- def _is_subclass_int_not_bool_one(cls: type[Any], parent: type[Any], /) -> bool:
811
- return issubclass(cls, parent) and not (
812
- issubclass(cls, bool)
813
- and issubclass(parent, int)
814
- and not issubclass(parent, bool)
815
- )
816
-
817
-
818
- ##
819
-
820
-
821
776
  def is_tuple(obj: Any, /) -> TypeGuard[tuple[Any, ...]]:
822
777
  """Check if an object is a tuple or string mapping."""
823
778
  return make_isinstance(tuple)(obj)
@@ -1075,7 +1030,6 @@ __all__ = [
1075
1030
  "is_dataclass_class",
1076
1031
  "is_dataclass_instance",
1077
1032
  "is_hashable",
1078
- "is_instance_not_bool_int",
1079
1033
  "is_iterable_of",
1080
1034
  "is_none",
1081
1035
  "is_not_none",
@@ -1083,7 +1037,6 @@ __all__ = [
1083
1037
  "is_sized",
1084
1038
  "is_sized_not_str",
1085
1039
  "is_string_mapping",
1086
- "is_subclass_not_bool_int",
1087
1040
  "is_tuple",
1088
1041
  "is_tuple_or_str_mapping",
1089
1042
  "make_isinstance",
@@ -692,6 +692,7 @@ _LOG_RECORD_DEFAULT_ATTRS = {
692
692
  "exc_text",
693
693
  "filename",
694
694
  "funcName",
695
+ "getMessage",
695
696
  "levelname",
696
697
  "levelno",
697
698
  "lineno",
@@ -9,12 +9,7 @@ from re import DOTALL
9
9
  from types import NoneType
10
10
  from typing import TYPE_CHECKING, Any, override
11
11
 
12
- from utilities.datetime import (
13
- is_instance_date_not_datetime,
14
- is_subclass_date_not_datetime,
15
- )
16
12
  from utilities.enum import ParseEnumError, parse_enum
17
- from utilities.functions import is_subclass_not_bool_int
18
13
  from utilities.iterables import OneEmptyError, OneNonUniqueError, one, one_str
19
14
  from utilities.math import ParseNumberError, parse_number
20
15
  from utilities.re import ExtractGroupError, extract_group
@@ -36,10 +31,12 @@ from utilities.typing import (
36
31
  get_args,
37
32
  is_dict_type,
38
33
  is_frozenset_type,
34
+ is_instance_gen,
39
35
  is_list_type,
40
36
  is_literal_type,
41
37
  is_optional_type,
42
38
  is_set_type,
39
+ is_subclass_gen,
43
40
  is_tuple_type,
44
41
  is_union_type,
45
42
  )
@@ -169,12 +166,12 @@ def _parse_object_type(
169
166
  raise _ParseObjectParseError(type_=cls, text=text) from None
170
167
  if issubclass(cls, str):
171
168
  return text
172
- if issubclass(cls, bool):
169
+ if is_subclass_gen(cls, bool):
173
170
  try:
174
171
  return parse_bool(text)
175
172
  except ParseBoolError:
176
173
  raise _ParseObjectParseError(type_=cls, text=text) from None
177
- if is_subclass_not_bool_int(cls, int):
174
+ if is_subclass_gen(cls, int):
178
175
  try:
179
176
  return int(text)
180
177
  except ValueError:
@@ -201,14 +198,14 @@ def _parse_object_type(
201
198
  return parse_version(text)
202
199
  except ParseVersionError:
203
200
  raise _ParseObjectParseError(type_=cls, text=text) from None
204
- if is_subclass_date_not_datetime(cls):
201
+ if is_subclass_gen(cls, dt.date):
205
202
  from utilities.whenever import ParseDateError, parse_date
206
203
 
207
204
  try:
208
205
  return parse_date(text)
209
206
  except ParseDateError:
210
207
  raise _ParseObjectParseError(type_=cls, text=text) from None
211
- if issubclass(cls, dt.datetime):
208
+ if is_subclass_gen(cls, dt.datetime):
212
209
  from utilities.whenever import ParseDateTimeError, parse_datetime
213
210
 
214
211
  try:
@@ -473,11 +470,11 @@ def serialize_object(
473
470
  obj, bool | int | float | str | Path | Sentinel | Version
474
471
  ):
475
472
  return str(obj)
476
- if is_instance_date_not_datetime(obj):
473
+ if is_instance_gen(obj, dt.date):
477
474
  from utilities.whenever import serialize_date
478
475
 
479
476
  return serialize_date(obj)
480
- if isinstance(obj, dt.datetime):
477
+ if is_instance_gen(obj, dt.datetime):
481
478
  from utilities.whenever import serialize_datetime
482
479
 
483
480
  return serialize_datetime(obj)
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import datetime as dt
4
4
  from dataclasses import dataclass, field
5
5
  from functools import cached_property
6
+ from itertools import permutations
6
7
  from typing import (
7
8
  TYPE_CHECKING,
8
9
  Generic,
@@ -15,10 +16,11 @@ from typing import (
15
16
  override,
16
17
  )
17
18
 
18
- from utilities.datetime import ZERO_TIME, is_instance_date_not_datetime
19
+ from utilities.datetime import ZERO_TIME
19
20
  from utilities.functions import get_class_name
20
21
  from utilities.iterables import OneUniqueNonUniqueError, always_iterable, one_unique
21
22
  from utilities.sentinel import Sentinel, sentinel
23
+ from utilities.typing import is_instance_gen
22
24
  from utilities.whenever import (
23
25
  serialize_date,
24
26
  serialize_local_datetime,
@@ -32,6 +34,7 @@ if TYPE_CHECKING:
32
34
  from utilities.iterables import MaybeIterable
33
35
  from utilities.types import DateOrDateTime
34
36
 
37
+
35
38
  type _DateOrDateTime = Literal["date", "datetime"]
36
39
  _TPeriod = TypeVar("_TPeriod", dt.date, dt.datetime)
37
40
 
@@ -54,9 +57,11 @@ class Period(Generic[_TPeriod]):
54
57
  max_duration: dt.timedelta | None = field(default=None, repr=False, kw_only=True)
55
58
 
56
59
  def __post_init__(self) -> None:
57
- if is_instance_date_not_datetime(
58
- self.start
59
- ) is not is_instance_date_not_datetime(self.end):
60
+ if any(
61
+ is_instance_gen(left, cls) is not is_instance_gen(right, cls)
62
+ for left, right in permutations([self.start, self.end], 2)
63
+ for cls in [dt.date, dt.datetime]
64
+ ):
60
65
  raise _PeriodDateAndDateTimeMixedError(start=self.start, end=self.end)
61
66
  for date in [self.start, self.end]:
62
67
  if isinstance(date, dt.datetime):
@@ -166,7 +171,7 @@ class Period(Generic[_TPeriod]):
166
171
  @cached_property
167
172
  def kind(self) -> _DateOrDateTime:
168
173
  """The kind of the period."""
169
- return "date" if is_instance_date_not_datetime(self.start) else "datetime"
174
+ return "date" if is_instance_gen(self.start, dt.date) else "datetime"
170
175
 
171
176
  def replace(
172
177
  self,