dycw-utilities 0.110.5__tar.gz → 0.110.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/PKG-INFO +1 -1
  2. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/pyproject.toml +2 -2
  3. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_functions.py +55 -13
  4. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_modules.py +3 -1
  5. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/eventkit.py +5 -5
  7. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/functions.py +52 -23
  8. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/modules.py +3 -1
  9. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/parse.py +2 -2
  10. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pyrsistent.py +3 -1
  11. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/redis.py +35 -9
  12. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/types.py +5 -3
  13. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/warnings.py +5 -7
  14. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/.gitignore +0 -0
  15. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/LICENSE +0 -0
  16. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/README.md +0 -0
  17. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/__init__.py +0 -0
  18. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/conftest.py +0 -0
  19. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/__init__.py +0 -0
  20. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_missing/__init__.py +0 -0
  21. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_missing/module.py +0 -0
  22. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/__init__.py +0 -0
  23. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/outer_1.py +0 -0
  24. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/outer_2.py +0 -0
  25. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  26. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  27. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  28. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  29. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_without/__init__.py +0 -0
  30. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_without/module_1.py +0 -0
  31. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/package_without/module_2.py +0 -0
  32. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/standalone.py +0 -0
  33. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/modules/with_imports.py +0 -0
  34. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  35. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  36. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  37. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  38. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  39. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  40. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  41. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  42. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/__init__.py +0 -0
  43. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_async_service/__init__.py +0 -0
  44. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_async_service/__main__.py +0 -0
  45. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_async_service/run.sh +0 -0
  46. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  47. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  48. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  49. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_altair.py +0 -0
  50. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_astor.py +0 -0
  51. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_asyncio.py +0 -0
  52. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_atomicwrites.py +0 -0
  53. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_atools.py +0 -0
  54. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_cachetools.py +0 -0
  55. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_click.py +0 -0
  56. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_concurrent.py +0 -0
  57. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_contextlib.py +0 -0
  58. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_contextvars.py +0 -0
  59. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_cryptography.py +0 -0
  60. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_cvxpy.py +0 -0
  61. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_dataclasses.py +0 -0
  62. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_datetime.py +0 -0
  63. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_enum.py +0 -0
  64. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_errors.py +0 -0
  65. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_eventkit.py +0 -0
  66. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_fastapi.py +0 -0
  67. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_fpdf2.py +0 -0
  68. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_functools.py +0 -0
  69. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_getpass.py +0 -0
  70. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_git.py +0 -0
  71. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_hashlib.py +0 -0
  72. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_http.py +0 -0
  73. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_hypothesis.py +0 -0
  74. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_ipython.py +0 -0
  75. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_iterables.py +0 -0
  76. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_jupyter.py +0 -0
  77. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_lightweight_charts.py +0 -0
  78. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_logging.py +0 -0
  79. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_loguru.py +0 -0
  80. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_luigi.py +0 -0
  81. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_math.py +0 -0
  82. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_memory_profiler.py +0 -0
  83. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_more_itertools.py +0 -0
  84. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_numpy.py +0 -0
  85. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_operator.py +0 -0
  86. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_optuna.py +0 -0
  87. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_orjson.py +0 -0
  88. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_os.py +0 -0
  89. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_parse.py +0 -0
  90. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pathlib.py +0 -0
  91. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_period.py +0 -0
  92. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pickle.py +0 -0
  93. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_platform.py +0 -0
  94. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_polars.py +0 -0
  95. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_polars_ols.py +0 -0
  96. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pqdm.py +0 -0
  97. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pydantic.py +0 -0
  98. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pyinstrument.py +0 -0
  99. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pyrsistent.py +0 -0
  100. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pytest.py +0 -0
  101. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_pytest_regressions.py +0 -0
  102. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_python_dotenv.py +0 -0
  103. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_random.py +0 -0
  104. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_re.py +0 -0
  105. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_redis.py +0 -0
  106. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_reprlib.py +0 -0
  107. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_rich.py +0 -0
  108. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_scipy.py +0 -0
  109. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_sentinel.py +0 -0
  110. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_shelve.py +0 -0
  111. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_slack_sdk.py +0 -0
  112. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_socket.py +0 -0
  113. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_sqlalchemy.py +0 -0
  114. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_sqlalchemy_polars.py +0 -0
  115. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_statsmodel.py +0 -0
  116. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_streamlit.py +0 -0
  117. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_sys.py +0 -0
  118. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_tempfile.py +0 -0
  119. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_tenacity.py +0 -0
  120. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_text.py +0 -0
  121. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_threading.py +0 -0
  122. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_timer.py +0 -0
  123. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback.py +0 -0
  124. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/__init__.py +0 -0
  125. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/chain.py +0 -0
  126. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  127. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  128. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  129. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/many.py +0 -0
  130. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/one.py +0 -0
  131. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/recursive.py +0 -0
  132. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  133. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  134. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/two.py +0 -0
  135. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_traceback_funcs/untraced.py +0 -0
  136. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_types.py +0 -0
  137. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_typing.py +0 -0
  138. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_typing_funcs/__init__.py +0 -0
  139. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_typing_funcs/no_future.py +0 -0
  140. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_typing_funcs/with_future.py +0 -0
  141. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_tzdata.py +0 -0
  142. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_tzlocal.py +0 -0
  143. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_uuid.py +0 -0
  144. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_version.py +0 -0
  145. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_warnings.py +0 -0
  146. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_whenever.py +0 -0
  147. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_zipfile.py +0 -0
  148. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/tests/test_zoneinfo.py +0 -0
  149. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/altair.py +0 -0
  150. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/astor.py +0 -0
  151. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/asyncio.py +0 -0
  152. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/atomicwrites.py +0 -0
  153. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/atools.py +0 -0
  154. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/cachetools.py +0 -0
  155. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/click.py +0 -0
  156. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/concurrent.py +0 -0
  157. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/contextlib.py +0 -0
  158. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/contextvars.py +0 -0
  159. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/cryptography.py +0 -0
  160. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/cvxpy.py +0 -0
  161. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/dataclasses.py +0 -0
  162. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/datetime.py +0 -0
  163. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/enum.py +0 -0
  164. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/errors.py +0 -0
  165. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/fastapi.py +0 -0
  166. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/fpdf2.py +0 -0
  167. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/functools.py +0 -0
  168. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/getpass.py +0 -0
  169. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/git.py +0 -0
  170. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/hashlib.py +0 -0
  171. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/http.py +0 -0
  172. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/hypothesis.py +0 -0
  173. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/ipython.py +0 -0
  174. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/iterables.py +0 -0
  175. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/jupyter.py +0 -0
  176. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/lightweight_charts.py +0 -0
  177. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/logging.py +0 -0
  178. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/loguru.py +0 -0
  179. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/luigi.py +0 -0
  180. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/math.py +0 -0
  181. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/memory_profiler.py +0 -0
  182. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/more_itertools.py +0 -0
  183. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/numpy.py +0 -0
  184. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/operator.py +0 -0
  185. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/optuna.py +0 -0
  186. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/orjson.py +0 -0
  187. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/os.py +0 -0
  188. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pathlib.py +0 -0
  189. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/period.py +0 -0
  190. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pickle.py +0 -0
  191. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/platform.py +0 -0
  192. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/polars.py +0 -0
  193. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/polars_ols.py +0 -0
  194. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pqdm.py +0 -0
  195. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/py.typed +0 -0
  196. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pydantic.py +0 -0
  197. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pyinstrument.py +0 -0
  198. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pytest.py +0 -0
  199. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/pytest_regressions.py +0 -0
  200. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/python_dotenv.py +0 -0
  201. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/random.py +0 -0
  202. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/re.py +0 -0
  203. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/reprlib.py +0 -0
  204. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/rich.py +0 -0
  205. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/scipy.py +0 -0
  206. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/sentinel.py +0 -0
  207. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/shelve.py +0 -0
  208. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/slack_sdk.py +0 -0
  209. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/socket.py +0 -0
  210. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/sqlalchemy.py +0 -0
  211. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/sqlalchemy_polars.py +0 -0
  212. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/sys.py +0 -0
  215. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/text.py +0 -0
  218. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/threading.py +0 -0
  219. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/timer.py +0 -0
  220. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/traceback.py +0 -0
  221. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/typing.py +0 -0
  222. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/tzdata.py +0 -0
  223. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/tzlocal.py +0 -0
  224. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/uuid.py +0 -0
  225. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/version.py +0 -0
  226. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/whenever.py +0 -0
  227. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/src/utilities/zipfile.py +0 -0
  228. {dycw_utilities-0.110.5 → dycw_utilities-0.110.7}/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.5
3
+ Version: 0.110.7
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.5"
97
+ version = "0.110.7"
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.5"
340
+ current_version = "0.110.7"
341
341
 
342
342
  [[tool.bumpversion.files]]
343
343
  filename = "src/utilities/__init__.py"
@@ -12,6 +12,7 @@ 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,
15
16
  booleans,
16
17
  builds,
17
18
  data,
@@ -73,7 +74,7 @@ from utilities.functions import (
73
74
  is_dataclass_class,
74
75
  is_dataclass_instance,
75
76
  is_hashable,
76
- is_instance_int_not_bool,
77
+ is_instance_not_bool_int,
77
78
  is_iterable_of,
78
79
  is_none,
79
80
  is_not_none,
@@ -82,7 +83,7 @@ from utilities.functions import (
82
83
  is_sized,
83
84
  is_sized_not_str,
84
85
  is_string_mapping,
85
- is_subclass_int_not_bool,
86
+ is_subclass_not_bool_int,
86
87
  is_tuple,
87
88
  is_tuple_or_str_mapping,
88
89
  make_isinstance,
@@ -621,14 +622,37 @@ class TestIsHashable:
621
622
  assert is_hashable(obj) is expected
622
623
 
623
624
 
624
- class TestIsInstanceIntNotBool:
625
- @given(int_=integers())
626
- def test_int(self, *, int_: int) -> None:
627
- assert is_instance_int_not_bool(int_)
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
628
643
 
629
644
  @given(bool_=booleans())
630
- def test_bool(self, *, bool_: bool) -> None:
631
- assert not is_instance_int_not_bool(bool_)
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)
632
656
 
633
657
 
634
658
  class TestIsIterableOf:
@@ -751,11 +775,29 @@ class TestIsStringMapping:
751
775
  assert result is expected
752
776
 
753
777
 
754
- class TestIsSubclassIntNotBool:
755
- @given(case=sampled_from([(int, True), (bool, False)]))
756
- def test_main(self, *, case: tuple[type[Any], bool]) -> None:
757
- type_, expected = case
758
- assert is_subclass_int_not_bool(type_) is expected
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)
759
801
 
760
802
 
761
803
  class TestIsTuple:
@@ -28,6 +28,8 @@ if TYPE_CHECKING:
28
28
  from collections.abc import Callable
29
29
  from types import ModuleType
30
30
 
31
+ from utilities.types import TypeLike
32
+
31
33
 
32
34
  class TestIsInstalled:
33
35
  @given(case=sampled_from([("importlib", True), ("invalid", False)]))
@@ -90,7 +92,7 @@ class TestYieldModuleContents:
90
92
  self,
91
93
  *,
92
94
  case1: tuple[ModuleType, bool, int],
93
- case2: tuple[type[Any] | tuple[type[Any], ...], Callable[[Any], bool], int],
95
+ case2: tuple[TypeLike[Any], Callable[[Any], bool], int],
94
96
  ) -> None:
95
97
  module, recursive, factor = case1
96
98
  type_, predicate, expected = case2
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.110.5"
3
+ __version__ = "0.110.7"
@@ -39,7 +39,7 @@ from eventkit import (
39
39
  from utilities.functions import apply_decorators
40
40
  from utilities.iterables import always_iterable
41
41
  from utilities.logging import get_logger
42
- from utilities.types import TCallable, TCallableMaybeCoroutine1None
42
+ from utilities.types import TCallable, TCallableMaybeCoroutine1None, TypeLike
43
43
 
44
44
  if TYPE_CHECKING:
45
45
  from collections.abc import Callable
@@ -59,7 +59,7 @@ def add_listener(
59
59
  /,
60
60
  *,
61
61
  error: Callable[[Event, BaseException], MaybeCoroutine1[None]] | None = None,
62
- ignore: type[BaseException] | tuple[type[BaseException], ...] | None = None,
62
+ ignore: TypeLike[BaseException] | None = None,
63
63
  logger: LoggerOrName | None = None,
64
64
  decorators: MaybeIterable[Callable[[TCallable], TCallable]] | None = None,
65
65
  done: Callable[..., MaybeCoroutine1[None]] | None = None,
@@ -104,7 +104,7 @@ class LiftedEvent(Generic[TCallableMaybeCoroutine1None]):
104
104
  /,
105
105
  *,
106
106
  error: Callable[[Event, BaseException], MaybeCoroutine1[None]] | None = None,
107
- ignore: type[BaseException] | tuple[type[BaseException], ...] | None = None,
107
+ ignore: TypeLike[BaseException] | None = None,
108
108
  logger: LoggerOrName | None = None,
109
109
  decorators: MaybeIterable[Callable[[TCallable], TCallable]] | None = None,
110
110
  done: Callable[..., MaybeCoroutine1[None]] | None = None,
@@ -267,7 +267,7 @@ class TypedEvent(Event, Generic[TCallableMaybeCoroutine1None]):
267
267
  done: Callable[[Self], MaybeCoroutine1[None]] | None = None,
268
268
  keep_ref: bool = False,
269
269
  *,
270
- ignore: type[BaseException] | tuple[type[BaseException], ...] | None = None,
270
+ ignore: TypeLike[BaseException] | None = None,
271
271
  logger: LoggerOrName | None = None,
272
272
  decorators: MaybeIterable[Callable[[TCallable], TCallable]] | None = None,
273
273
  ) -> Self:
@@ -295,7 +295,7 @@ def lift_listener(
295
295
  /,
296
296
  *,
297
297
  error: Callable[[Event, BaseException], MaybeCoroutine1[None]] | None = None,
298
- ignore: type[BaseException] | tuple[type[BaseException], ...] | None = None,
298
+ ignore: TypeLike[BaseException] | None = None,
299
299
  logger: LoggerOrName | None = None,
300
300
  decorators: MaybeIterable[Callable[[TCallable], TCallable]] | None = None,
301
301
  ) -> Callable[..., MaybeCoroutine1[None]]:
@@ -22,6 +22,7 @@ from typing import (
22
22
  Literal,
23
23
  TypeGuard,
24
24
  TypeVar,
25
+ assert_never,
25
26
  cast,
26
27
  overload,
27
28
  override,
@@ -40,6 +41,7 @@ from utilities.types import (
40
41
  TCallable2,
41
42
  TSupportsRichComparison,
42
43
  TupleOrStrMapping,
44
+ TypeLike,
43
45
  )
44
46
 
45
47
  if TYPE_CHECKING:
@@ -181,9 +183,9 @@ def ensure_class(
181
183
  *,
182
184
  nullable: Literal[False] = False,
183
185
  ) -> _T1 | _T2 | _T3 | _T4 | _T5: ...
184
- def ensure_class(
185
- obj: Any, cls: type[_T] | tuple[type[_T], ...], /, *, nullable: bool = False
186
- ) -> Any:
186
+ @overload
187
+ def ensure_class(obj: Any, cls: TypeLike[_T], /, *, nullable: bool = False) -> Any: ...
188
+ def ensure_class(obj: Any, cls: TypeLike[_T], /, *, nullable: bool = False) -> Any:
187
189
  """Ensure an object is of the required class."""
188
190
  if isinstance(obj, cls) or ((obj is None) and nullable):
189
191
  return obj
@@ -193,7 +195,7 @@ def ensure_class(
193
195
  @dataclass(kw_only=True, slots=True)
194
196
  class EnsureClassError(Exception):
195
197
  obj: Any
196
- cls: type[Any] | tuple[type[Any], ...]
198
+ cls: TypeLike[Any]
197
199
  nullable: bool
198
200
 
199
201
  @override
@@ -658,9 +660,23 @@ def is_hashable(obj: Any, /) -> TypeGuard[Hashable]:
658
660
  ##
659
661
 
660
662
 
661
- def is_instance_int_not_bool(obj: Any, /) -> TypeGuard[int]:
662
- """Check if an object is an integer, and not a boolean."""
663
- return isinstance(obj, int) and not isinstance(obj, bool)
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
+ )
664
680
 
665
681
 
666
682
  ##
@@ -686,7 +702,9 @@ def is_iterable_of(
686
702
  def is_iterable_of(
687
703
  obj: Any, cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
688
704
  ) -> TypeGuard[Iterable[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
689
- def is_iterable_of(obj: Any, cls: Any, /) -> TypeGuard[Iterable[Any]]:
705
+ @overload
706
+ def is_iterable_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Iterable[_T]]: ...
707
+ def is_iterable_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Iterable[_T]]:
690
708
  """Check if an object is a iterable of tuple or string mappings."""
691
709
  return isinstance(obj, Iterable) and all(map(make_isinstance(cls), obj))
692
710
 
@@ -730,7 +748,9 @@ def is_sequence_of(
730
748
  def is_sequence_of(
731
749
  obj: Any, cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
732
750
  ) -> TypeGuard[Sequence[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
733
- def is_sequence_of(obj: Any, cls: Any, /) -> TypeGuard[Sequence[Any]]:
751
+ @overload
752
+ def is_sequence_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Sequence[_T]]: ...
753
+ def is_sequence_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Sequence[_T]]:
734
754
  """Check if an object is a sequence of tuple or string mappings."""
735
755
  return isinstance(obj, Sequence) and is_iterable_of(obj, cls)
736
756
 
@@ -776,9 +796,23 @@ def is_string_mapping(obj: Any, /) -> TypeGuard[StrMapping]:
776
796
  ##
777
797
 
778
798
 
779
- def is_subclass_int_not_bool(cls: type[Any], /) -> TypeGuard[type[int]]:
780
- """Check if a class is an integer, and not a boolean."""
781
- return issubclass(cls, int) and not issubclass(cls, bool)
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
+ )
782
816
 
783
817
 
784
818
  ##
@@ -820,19 +854,14 @@ def make_isinstance(
820
854
  def make_isinstance(
821
855
  cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
822
856
  ) -> Callable[[Any], TypeGuard[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
823
- def make_isinstance(
824
- cls: type[_T] | tuple[type[_T], ...], /
825
- ) -> Callable[[Any], TypeGuard[Any]]:
857
+ @overload
858
+ def make_isinstance(cls: TypeLike[_T], /) -> Callable[[Any], TypeGuard[_T]]: ...
859
+ def make_isinstance(cls: TypeLike[_T], /) -> Callable[[Any], TypeGuard[_T]]:
826
860
  """Make a curried `isinstance` function."""
827
861
  return partial(_make_instance_core, cls=cls)
828
862
 
829
863
 
830
- ##
831
-
832
-
833
- def _make_instance_core(
834
- obj: Any, /, *, cls: type[_T] | tuple[type[_T], ...]
835
- ) -> TypeGuard[_T]:
864
+ def _make_instance_core(obj: Any, /, *, cls: TypeLike[_T]) -> TypeGuard[_T]:
836
865
  return isinstance(obj, cls)
837
866
 
838
867
 
@@ -1046,7 +1075,7 @@ __all__ = [
1046
1075
  "is_dataclass_class",
1047
1076
  "is_dataclass_instance",
1048
1077
  "is_hashable",
1049
- "is_instance_int_not_bool",
1078
+ "is_instance_not_bool_int",
1050
1079
  "is_iterable_of",
1051
1080
  "is_none",
1052
1081
  "is_not_none",
@@ -1054,7 +1083,7 @@ __all__ = [
1054
1083
  "is_sized",
1055
1084
  "is_sized_not_str",
1056
1085
  "is_string_mapping",
1057
- "is_subclass_int_not_bool",
1086
+ "is_subclass_not_bool_int",
1058
1087
  "is_tuple",
1059
1088
  "is_tuple_or_str_mapping",
1060
1089
  "make_isinstance",
@@ -11,6 +11,8 @@ if TYPE_CHECKING:
11
11
  from collections.abc import Callable, Iterable, Iterator
12
12
  from types import ModuleType
13
13
 
14
+ from utilities.types import TypeLike
15
+
14
16
 
15
17
  def is_installed(module: str, /) -> bool:
16
18
  """Check if a module is installed."""
@@ -63,7 +65,7 @@ def yield_module_contents(
63
65
  *,
64
66
  missing_ok: Iterable[str] | None = None,
65
67
  recursive: bool = False,
66
- type: type[Any] | tuple[type[Any], ...] | None = None, # noqa: A002
68
+ type: TypeLike[Any] | None = None, # noqa: A002
67
69
  predicate: Callable[[Any], bool] | None = None,
68
70
  ) -> Iterator[Any]:
69
71
  """Yield all the module contents under a package.
@@ -14,7 +14,7 @@ from utilities.datetime import (
14
14
  is_subclass_date_not_datetime,
15
15
  )
16
16
  from utilities.enum import ParseEnumError, parse_enum
17
- from utilities.functions import is_subclass_int_not_bool
17
+ from utilities.functions import is_subclass_not_bool_int
18
18
  from utilities.iterables import OneEmptyError, OneNonUniqueError, one, one_str
19
19
  from utilities.math import ParseNumberError, parse_number
20
20
  from utilities.re import ExtractGroupError, extract_group
@@ -174,7 +174,7 @@ def _parse_object_type(
174
174
  return parse_bool(text)
175
175
  except ParseBoolError:
176
176
  raise _ParseObjectParseError(type_=cls, text=text) from None
177
- if is_subclass_int_not_bool(cls):
177
+ if is_subclass_not_bool_int(cls, int):
178
178
  try:
179
179
  return int(text)
180
180
  except ValueError:
@@ -15,6 +15,8 @@ from pyrsistent._field_common import (
15
15
  if TYPE_CHECKING:
16
16
  from collections.abc import Callable
17
17
 
18
+ from utilities.types import TypeLike
19
+
18
20
 
19
21
  _T = TypeVar("_T")
20
22
  _U = TypeVar("_U")
@@ -62,7 +64,7 @@ def field(
62
64
  ) -> Any: ...
63
65
  def field(
64
66
  *,
65
- type: type[_T] | tuple[type[_T], ...] = PFIELD_NO_TYPE, # noqa: A002
67
+ type: TypeLike[_T] = PFIELD_NO_TYPE, # noqa: A002
66
68
  invariant: Callable[[Any], tuple[bool, Any]] = PFIELD_NO_INVARIANT,
67
69
  default: Any = PFIELD_NO_INITIAL,
68
70
  mandatory: bool = False,
@@ -42,7 +42,7 @@ if TYPE_CHECKING:
42
42
  from redis.typing import ResponseT
43
43
 
44
44
  from utilities.iterables import MaybeIterable
45
- from utilities.types import Duration
45
+ from utilities.types import Duration, TypeLike
46
46
 
47
47
 
48
48
  _K = TypeVar("_K")
@@ -69,9 +69,9 @@ class RedisHashMapKey(Generic[_K, _V]):
69
69
  """A hashmap key in a redis store."""
70
70
 
71
71
  name: str
72
- key: type[_K]
72
+ key: TypeLike[_K]
73
73
  key_serializer: Callable[[_K], bytes] | None = None
74
- value: type[_V]
74
+ value: TypeLike[_V]
75
75
  value_serializer: Callable[[_V], bytes] | None = None
76
76
  value_deserializer: Callable[[bytes], _V] | None = None
77
77
  timeout: Duration | None = None
@@ -262,10 +262,24 @@ def redis_hash_map_key(
262
262
  error: type[Exception] = TimeoutError,
263
263
  ttl: Duration | None = None,
264
264
  ) -> RedisHashMapKey[_K1 | _K2 | _K3, _V1 | _V2 | _V3]: ...
265
+ @overload
266
+ def redis_hash_map_key(
267
+ name: str,
268
+ key: TypeLike[_K],
269
+ value: TypeLike[_V],
270
+ /,
271
+ *,
272
+ key_serializer: Callable[[_K1 | _K2 | _K3], bytes] | None = None,
273
+ value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
274
+ value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
275
+ timeout: Duration | None = None,
276
+ error: type[Exception] = TimeoutError,
277
+ ttl: Duration | None = None,
278
+ ) -> RedisHashMapKey[_K, _V]: ...
265
279
  def redis_hash_map_key(
266
280
  name: str,
267
- key: Any,
268
- value: Any,
281
+ key: TypeLike[_K],
282
+ value: TypeLike[_V],
269
283
  /,
270
284
  *,
271
285
  key_serializer: Callable[[Any], bytes] | None = None,
@@ -274,7 +288,7 @@ def redis_hash_map_key(
274
288
  timeout: Duration | None = None,
275
289
  ttl: Duration | None = None,
276
290
  error: type[Exception] = TimeoutError,
277
- ) -> RedisHashMapKey[Any, Any]:
291
+ ) -> RedisHashMapKey[_K, _V]:
278
292
  """Create a redis key."""
279
293
  return RedisHashMapKey( # skipif-ci-and-not-linux
280
294
  name=name,
@@ -297,7 +311,7 @@ class RedisKey(Generic[_T]):
297
311
  """A key in a redis store."""
298
312
 
299
313
  name: str
300
- type: type[_T]
314
+ type: TypeLike[_T]
301
315
  serializer: Callable[[_T], bytes] | None = None
302
316
  deserializer: Callable[[bytes], _T] | None = None
303
317
  timeout: Duration | None = None
@@ -420,9 +434,21 @@ def redis_key(
420
434
  error: type[Exception] = TimeoutError,
421
435
  ttl: Duration | None = None,
422
436
  ) -> RedisKey[_T1 | _T2 | _T3 | _T4 | _T5]: ...
437
+ @overload
438
+ def redis_key(
439
+ name: str,
440
+ type_: TypeLike[_T],
441
+ /,
442
+ *,
443
+ serializer: Callable[[_T1 | _T2 | _T3 | _T4 | _T5], bytes] | None = None,
444
+ deserializer: Callable[[bytes], _T1 | _T2 | _T3 | _T4 | _T5] | None = None,
445
+ timeout: Duration | None = None,
446
+ error: type[Exception] = TimeoutError,
447
+ ttl: Duration | None = None,
448
+ ) -> RedisKey[_T]: ...
423
449
  def redis_key(
424
450
  name: str,
425
- type_: Any,
451
+ type_: TypeLike[_T],
426
452
  /,
427
453
  *,
428
454
  serializer: Callable[[Any], bytes] | None = None,
@@ -430,7 +456,7 @@ def redis_key(
430
456
  timeout: Duration | None = None,
431
457
  error: type[Exception] = TimeoutError,
432
458
  ttl: Duration | None = None,
433
- ) -> RedisKey[Any]:
459
+ ) -> RedisKey[_T]:
434
460
  """Create a redis key."""
435
461
  return RedisKey( # skipif-ci-and-not-linux
436
462
  name=name,
@@ -45,12 +45,13 @@ type OpenMode = Literal[
45
45
  "x+b",
46
46
  "a+b",
47
47
  ]
48
- type StrMapping = Mapping[str, Any]
49
- type StrStrMapping = Mapping[str, str]
50
- type TupleOrStrMapping = tuple[Any, ...] | StrMapping
51
48
  type MaybeCallable[_T] = _T | Callable[[], _T]
52
49
  type MaybeStr[_T] = _T | str
53
50
  type MaybeType[_T] = _T | type[_T]
51
+ type StrMapping = Mapping[str, Any]
52
+ type StrStrMapping = Mapping[str, str]
53
+ type TypeLike[_T] = type[_T] | tuple[type[_T], ...]
54
+ type TupleOrStrMapping = tuple[Any, ...] | StrMapping
54
55
 
55
56
 
56
57
  # asyncio
@@ -327,5 +328,6 @@ __all__ = [
327
328
  "TimeZone",
328
329
  "TimeZoneLike",
329
330
  "TupleOrStrMapping",
331
+ "TypeLike",
330
332
  "WeekDay",
331
333
  ]
@@ -7,12 +7,12 @@ from warnings import catch_warnings, filterwarnings
7
7
  if TYPE_CHECKING:
8
8
  from collections.abc import Iterator
9
9
 
10
+ from utilities.types import TypeLike
11
+
10
12
 
11
13
  @contextmanager
12
14
  def catch_warnings_as_errors(
13
- *,
14
- message: str = "",
15
- category: type[Warning] | tuple[type[Warning], ...] | None = None,
15
+ *, message: str = "", category: TypeLike[Warning] | None = None
16
16
  ) -> Iterator[None]:
17
17
  """Catch warnings as errors."""
18
18
  with _handle_warnings("error", message=message, category=category):
@@ -21,9 +21,7 @@ def catch_warnings_as_errors(
21
21
 
22
22
  @contextmanager
23
23
  def suppress_warnings(
24
- *,
25
- message: str = "",
26
- category: type[Warning] | tuple[type[Warning], ...] | None = None,
24
+ *, message: str = "", category: TypeLike[Warning] | None = None
27
25
  ) -> Iterator[None]:
28
26
  """Suppress warnings."""
29
27
  with _handle_warnings("ignore", message=message, category=category):
@@ -38,7 +36,7 @@ def _handle_warnings(
38
36
  /,
39
37
  *,
40
38
  message: str = "",
41
- category: type[Warning] | tuple[type[Warning], ...] | None = None,
39
+ category: TypeLike[Warning] | None = None,
42
40
  ) -> ExitStack:
43
41
  """Handle a set of warnings."""
44
42
  stack = ExitStack()