dycw-utilities 0.110.4__tar.gz → 0.110.6__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.4 → dycw_utilities-0.110.6}/PKG-INFO +1 -1
  2. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/pyproject.toml +2 -2
  3. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_modules.py +3 -1
  4. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_parse.py +108 -51
  5. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/eventkit.py +5 -5
  7. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/functions.py +13 -15
  8. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/modules.py +3 -1
  9. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/parse.py +6 -1
  10. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pyrsistent.py +3 -1
  11. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/redis.py +35 -9
  12. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/types.py +6 -4
  13. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/warnings.py +5 -7
  14. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/.gitignore +0 -0
  15. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/LICENSE +0 -0
  16. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/README.md +0 -0
  17. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/__init__.py +0 -0
  18. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/conftest.py +0 -0
  19. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/__init__.py +0 -0
  20. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_missing/__init__.py +0 -0
  21. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_missing/module.py +0 -0
  22. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/__init__.py +0 -0
  23. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/outer_1.py +0 -0
  24. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/outer_2.py +0 -0
  25. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  26. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  27. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  28. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  29. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_without/__init__.py +0 -0
  30. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_without/module_1.py +0 -0
  31. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/package_without/module_2.py +0 -0
  32. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/standalone.py +0 -0
  33. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/modules/with_imports.py +0 -0
  34. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  35. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  36. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  37. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  38. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  39. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  40. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  41. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  42. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/__init__.py +0 -0
  43. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_async_service/__init__.py +0 -0
  44. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_async_service/__main__.py +0 -0
  45. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_async_service/run.sh +0 -0
  46. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  47. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  48. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  49. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_altair.py +0 -0
  50. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_astor.py +0 -0
  51. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_asyncio.py +0 -0
  52. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_atomicwrites.py +0 -0
  53. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_atools.py +0 -0
  54. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_cachetools.py +0 -0
  55. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_click.py +0 -0
  56. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_concurrent.py +0 -0
  57. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_contextlib.py +0 -0
  58. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_contextvars.py +0 -0
  59. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_cryptography.py +0 -0
  60. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_cvxpy.py +0 -0
  61. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_dataclasses.py +0 -0
  62. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_datetime.py +0 -0
  63. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_enum.py +0 -0
  64. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_errors.py +0 -0
  65. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_eventkit.py +0 -0
  66. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_fastapi.py +0 -0
  67. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_fpdf2.py +0 -0
  68. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_functions.py +0 -0
  69. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_functools.py +0 -0
  70. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_getpass.py +0 -0
  71. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_git.py +0 -0
  72. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_hashlib.py +0 -0
  73. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_http.py +0 -0
  74. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_hypothesis.py +0 -0
  75. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_ipython.py +0 -0
  76. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_iterables.py +0 -0
  77. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_jupyter.py +0 -0
  78. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_lightweight_charts.py +0 -0
  79. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_logging.py +0 -0
  80. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_loguru.py +0 -0
  81. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_luigi.py +0 -0
  82. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_math.py +0 -0
  83. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_memory_profiler.py +0 -0
  84. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_more_itertools.py +0 -0
  85. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_numpy.py +0 -0
  86. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_operator.py +0 -0
  87. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_optuna.py +0 -0
  88. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_orjson.py +0 -0
  89. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_os.py +0 -0
  90. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pathlib.py +0 -0
  91. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_period.py +0 -0
  92. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pickle.py +0 -0
  93. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_platform.py +0 -0
  94. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_polars.py +0 -0
  95. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_polars_ols.py +0 -0
  96. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pqdm.py +0 -0
  97. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pydantic.py +0 -0
  98. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pyinstrument.py +0 -0
  99. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pyrsistent.py +0 -0
  100. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pytest.py +0 -0
  101. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_pytest_regressions.py +0 -0
  102. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_python_dotenv.py +0 -0
  103. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_random.py +0 -0
  104. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_re.py +0 -0
  105. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_redis.py +0 -0
  106. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_reprlib.py +0 -0
  107. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_rich.py +0 -0
  108. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_scipy.py +0 -0
  109. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_sentinel.py +0 -0
  110. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_shelve.py +0 -0
  111. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_slack_sdk.py +0 -0
  112. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_socket.py +0 -0
  113. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_sqlalchemy.py +0 -0
  114. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_sqlalchemy_polars.py +0 -0
  115. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_statsmodel.py +0 -0
  116. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_streamlit.py +0 -0
  117. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_sys.py +0 -0
  118. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_tempfile.py +0 -0
  119. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_tenacity.py +0 -0
  120. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_text.py +0 -0
  121. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_threading.py +0 -0
  122. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_timer.py +0 -0
  123. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback.py +0 -0
  124. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/__init__.py +0 -0
  125. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/chain.py +0 -0
  126. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  127. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  128. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  129. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/many.py +0 -0
  130. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/one.py +0 -0
  131. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/recursive.py +0 -0
  132. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  133. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  134. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/two.py +0 -0
  135. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_traceback_funcs/untraced.py +0 -0
  136. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_types.py +0 -0
  137. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_typing.py +0 -0
  138. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_typing_funcs/__init__.py +0 -0
  139. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_typing_funcs/no_future.py +0 -0
  140. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_typing_funcs/with_future.py +0 -0
  141. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_tzdata.py +0 -0
  142. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_tzlocal.py +0 -0
  143. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_uuid.py +0 -0
  144. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_version.py +0 -0
  145. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_warnings.py +0 -0
  146. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_whenever.py +0 -0
  147. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_zipfile.py +0 -0
  148. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/tests/test_zoneinfo.py +0 -0
  149. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/altair.py +0 -0
  150. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/astor.py +0 -0
  151. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/asyncio.py +0 -0
  152. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/atomicwrites.py +0 -0
  153. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/atools.py +0 -0
  154. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/cachetools.py +0 -0
  155. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/click.py +0 -0
  156. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/concurrent.py +0 -0
  157. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/contextlib.py +0 -0
  158. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/contextvars.py +0 -0
  159. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/cryptography.py +0 -0
  160. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/cvxpy.py +0 -0
  161. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/dataclasses.py +0 -0
  162. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/datetime.py +0 -0
  163. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/enum.py +0 -0
  164. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/errors.py +0 -0
  165. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/fastapi.py +0 -0
  166. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/fpdf2.py +0 -0
  167. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/functools.py +0 -0
  168. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/getpass.py +0 -0
  169. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/git.py +0 -0
  170. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/hashlib.py +0 -0
  171. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/http.py +0 -0
  172. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/hypothesis.py +0 -0
  173. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/ipython.py +0 -0
  174. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/iterables.py +0 -0
  175. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/jupyter.py +0 -0
  176. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/lightweight_charts.py +0 -0
  177. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/logging.py +0 -0
  178. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/loguru.py +0 -0
  179. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/luigi.py +0 -0
  180. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/math.py +0 -0
  181. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/memory_profiler.py +0 -0
  182. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/more_itertools.py +0 -0
  183. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/numpy.py +0 -0
  184. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/operator.py +0 -0
  185. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/optuna.py +0 -0
  186. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/orjson.py +0 -0
  187. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/os.py +0 -0
  188. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pathlib.py +0 -0
  189. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/period.py +0 -0
  190. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pickle.py +0 -0
  191. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/platform.py +0 -0
  192. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/polars.py +0 -0
  193. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/polars_ols.py +0 -0
  194. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pqdm.py +0 -0
  195. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/py.typed +0 -0
  196. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pydantic.py +0 -0
  197. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pyinstrument.py +0 -0
  198. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pytest.py +0 -0
  199. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/pytest_regressions.py +0 -0
  200. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/python_dotenv.py +0 -0
  201. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/random.py +0 -0
  202. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/re.py +0 -0
  203. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/reprlib.py +0 -0
  204. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/rich.py +0 -0
  205. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/scipy.py +0 -0
  206. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/sentinel.py +0 -0
  207. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/shelve.py +0 -0
  208. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/slack_sdk.py +0 -0
  209. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/socket.py +0 -0
  210. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/sqlalchemy.py +0 -0
  211. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/sqlalchemy_polars.py +0 -0
  212. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/sys.py +0 -0
  215. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/text.py +0 -0
  218. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/threading.py +0 -0
  219. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/timer.py +0 -0
  220. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/traceback.py +0 -0
  221. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/typing.py +0 -0
  222. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/tzdata.py +0 -0
  223. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/tzlocal.py +0 -0
  224. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/uuid.py +0 -0
  225. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/version.py +0 -0
  226. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/whenever.py +0 -0
  227. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/src/utilities/zipfile.py +0 -0
  228. {dycw_utilities-0.110.4 → dycw_utilities-0.110.6}/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.4
3
+ Version: 0.110.6
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.4"
97
+ version = "0.110.6"
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.4"
340
+ current_version = "0.110.6"
341
341
 
342
342
  [[tool.bumpversion.files]]
343
343
  filename = "src/utilities/__init__.py"
@@ -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
@@ -61,11 +61,11 @@ from utilities.version import Version
61
61
 
62
62
 
63
63
  class TestSerializeAndParseObject:
64
- @given(value=booleans())
65
- def test_bool(self, *, value: bool) -> None:
66
- serialized = serialize_object(value)
64
+ @given(bool_=booleans())
65
+ def test_bool(self, *, bool_: bool) -> None:
66
+ serialized = serialize_object(bool_)
67
67
  result = parse_object(bool, serialized)
68
- assert result is value
68
+ assert result is bool_
69
69
 
70
70
  @given(date=dates())
71
71
  def test_date(self, *, date: dt.date) -> None:
@@ -79,11 +79,11 @@ class TestSerializeAndParseObject:
79
79
  result = parse_object(dt.datetime, serialized)
80
80
  assert result == datetime
81
81
 
82
- @given(value=dictionaries(dates(), zoned_datetimes()))
83
- def test_dict(self, *, value: dict[dt.date, dt.datetime]) -> None:
84
- serialized = serialize_object(value)
82
+ @given(mapping=dictionaries(dates(), zoned_datetimes()))
83
+ def test_dict(self, *, mapping: dict[dt.date, dt.datetime]) -> None:
84
+ serialized = serialize_object(mapping)
85
85
  result = parse_object(dict[dt.date, dt.datetime], serialized)
86
- assert result == value
86
+ assert result == mapping
87
87
 
88
88
  @given(duration=datetime_durations(two_way=True))
89
89
  def test_duration(self, *, duration: Duration) -> None:
@@ -97,22 +97,22 @@ class TestSerializeAndParseObject:
97
97
  result = parse_object(TruthEnum, serialized)
98
98
  assert result is truth
99
99
 
100
- @given(value=integers())
101
- def test_extra_type(self, *, value: int) -> None:
102
- serialized = serialize_object(value)
100
+ @given(int_=integers())
101
+ def test_extra_type(self, *, int_: int) -> None:
102
+ serialized = serialize_object(int_)
103
103
  result = parse_object(
104
104
  DataClassFutureInt,
105
105
  serialized,
106
106
  extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
107
107
  )
108
- expected = DataClassFutureInt(int_=value)
108
+ expected = DataClassFutureInt(int_=int_)
109
109
  assert result == expected
110
110
 
111
- @given(value=floats())
112
- def test_float(self, *, value: float) -> None:
113
- serialized = serialize_object(value)
111
+ @given(float_=floats())
112
+ def test_float(self, *, float_: float) -> None:
113
+ serialized = serialize_object(float_)
114
114
  result = parse_object(float, serialized)
115
- assert is_equal(result, value)
115
+ assert is_equal(result, float_)
116
116
 
117
117
  @given(values=frozensets(dates()))
118
118
  def test_frozenset(self, *, values: frozenset[dt.date]) -> None:
@@ -120,11 +120,11 @@ class TestSerializeAndParseObject:
120
120
  result = parse_object(frozenset[dt.date], serialized)
121
121
  assert result == values
122
122
 
123
- @given(value=integers())
124
- def test_int(self, *, value: int) -> None:
125
- serialized = serialize_object(value)
123
+ @given(int_=integers())
124
+ def test_int(self, *, int_: int) -> None:
125
+ serialized = serialize_object(int_)
126
126
  result = parse_object(int, serialized)
127
- assert result == value
127
+ assert result == int_
128
128
 
129
129
  @given(values=lists(dates()))
130
130
  def test_list(self, *, values: list[dt.date]) -> None:
@@ -193,11 +193,11 @@ class TestSerializeAndParseObject:
193
193
  result = parse_object(int | None, serialized)
194
194
  assert result is None
195
195
 
196
- @given(value=integers())
197
- def test_nullable_int_int(self, *, value: int) -> None:
198
- serialized = serialize_object(value)
196
+ @given(int_=integers())
197
+ def test_nullable_int_int(self, *, int_: int) -> None:
198
+ serialized = serialize_object(int_)
199
199
  result = parse_object(int | None, serialized)
200
- assert result == value
200
+ assert result == int_
201
201
 
202
202
  def test_sentinel(self) -> None:
203
203
  serialized = serialize_object(sentinel)
@@ -238,58 +238,58 @@ class TestSerializeAndParseObject:
238
238
  result = parse_object(TrueOrFalseFutureTypeLit, truth)
239
239
  assert result == truth
240
240
 
241
- @given(value=integers())
242
- def test_type_union_with_extra(self, *, value: int) -> None:
241
+ @given(int_=integers())
242
+ def test_type_union_with_extra(self, *, int_: int) -> None:
243
243
  def parser(text: str, /) -> DataClassFutureIntEvenOrOddTypeUnion:
244
- value = int(text)
245
- match value % 2:
244
+ int_ = int(text)
245
+ match int_ % 2:
246
246
  case 0:
247
- return DataClassFutureIntEven(even_int=value)
247
+ return DataClassFutureIntEven(even_int=int_)
248
248
  case 1:
249
- return DataClassFutureIntOdd(odd_int=value)
249
+ return DataClassFutureIntOdd(odd_int=int_)
250
250
  case _:
251
- raise ImpossibleCaseError(case=[f"{value=}"])
251
+ raise ImpossibleCaseError(case=[f"{int_=}"])
252
252
 
253
- serialized = serialize_object(value)
253
+ serialized = serialize_object(int_)
254
254
  result = parse_object(
255
255
  DataClassFutureIntEvenOrOddTypeUnion,
256
256
  serialized,
257
257
  extra={DataClassFutureIntEvenOrOddTypeUnion: parser},
258
258
  )
259
- match value % 2:
259
+ match int_ % 2:
260
260
  case 0:
261
- expected = DataClassFutureIntEven(even_int=value)
261
+ expected = DataClassFutureIntEven(even_int=int_)
262
262
  case 1:
263
- expected = DataClassFutureIntOdd(odd_int=value)
263
+ expected = DataClassFutureIntOdd(odd_int=int_)
264
264
  case _:
265
- raise ImpossibleCaseError(case=[f"{value=}"])
265
+ raise ImpossibleCaseError(case=[f"{int_=}"])
266
266
  assert result == expected
267
267
 
268
- @given(value=integers())
269
- def test_union_with_extra(self, *, value: int) -> None:
268
+ @given(int_=integers())
269
+ def test_union_with_extra(self, *, int_: int) -> None:
270
270
  def parser(text: str, /) -> DataClassFutureIntEvenOrOddUnion:
271
- value = int(text)
272
- match value % 2:
271
+ int_ = int(text)
272
+ match int_ % 2:
273
273
  case 0:
274
- return DataClassFutureIntEven(even_int=value)
274
+ return DataClassFutureIntEven(even_int=int_)
275
275
  case 1:
276
- return DataClassFutureIntOdd(odd_int=value)
276
+ return DataClassFutureIntOdd(odd_int=int_)
277
277
  case _:
278
- raise ImpossibleCaseError(case=[f"{value=}"])
278
+ raise ImpossibleCaseError(case=[f"{int_=}"])
279
279
 
280
- serialized = serialize_object(value)
280
+ serialized = serialize_object(int_)
281
281
  result = parse_object(
282
282
  DataClassFutureIntEvenOrOddUnion,
283
283
  serialized,
284
284
  extra={DataClassFutureIntEvenOrOddUnion: parser},
285
285
  )
286
- match value % 2:
286
+ match int_ % 2:
287
287
  case 0:
288
- expected = DataClassFutureIntEven(even_int=value)
288
+ expected = DataClassFutureIntEven(even_int=int_)
289
289
  case 1:
290
- expected = DataClassFutureIntOdd(odd_int=value)
290
+ expected = DataClassFutureIntOdd(odd_int=int_)
291
291
  case _:
292
- raise ImpossibleCaseError(case=[f"{value=}"])
292
+ raise ImpossibleCaseError(case=[f"{int_=}"])
293
293
  assert result == expected
294
294
 
295
295
  @given(version=versions())
@@ -355,15 +355,15 @@ class TestParseObject:
355
355
  ):
356
356
  _ = parse_object(DataClassFutureInt, "invalid", extra={})
357
357
 
358
- @given(value=integers())
359
- def test_error_extra_non_unique(self, *, value: int) -> None:
358
+ @given(int_=integers())
359
+ def test_error_extra_non_unique(self, *, int_: int) -> None:
360
360
  with raises(
361
361
  _ParseObjectExtraNonUniqueError,
362
362
  match="Unable to parse <class '.*'> since `extra` must contain exactly one parent class; got <function .*>, <function .*> and perhaps more",
363
363
  ):
364
364
  _ = parse_object(
365
365
  DataClassFutureIntChild,
366
- serialize_object(value),
366
+ serialize_object(int_),
367
367
  extra={
368
368
  DataClassFutureIntParentFirst: lambda text: DataClassFutureIntChild(
369
369
  int1=int(text), int2=0
@@ -531,6 +531,63 @@ class TestParseObject:
531
531
 
532
532
 
533
533
  class TestSerializeObject:
534
+ @given(int_=integers())
535
+ def test_type_with_extra(self, *, int_: int) -> None:
536
+ obj = DataClassFutureInt(int_=int_)
537
+
538
+ def serializer(obj: DataClassFutureInt, /) -> str:
539
+ return str(obj.int_)
540
+
541
+ serialized = serialize_object(obj, extra={DataClassFutureInt: serializer})
542
+ expected = str(int_)
543
+ assert serialized == expected
544
+
545
+ @given(int_=integers())
546
+ def test_type_union_with_extra(self, *, int_: int) -> None:
547
+ match int_ % 2:
548
+ case 0:
549
+ obj = DataClassFutureIntEven(even_int=int_)
550
+ case 1:
551
+ obj = DataClassFutureIntOdd(odd_int=int_)
552
+ case _:
553
+ raise ImpossibleCaseError(case=[f"{int_=}"])
554
+
555
+ def serializer(obj: DataClassFutureIntEvenOrOddTypeUnion, /) -> str:
556
+ match obj:
557
+ case DataClassFutureIntEven():
558
+ return str(obj.even_int)
559
+ case DataClassFutureIntOdd():
560
+ return str(obj.odd_int)
561
+
562
+ serialized = serialize_object(
563
+ obj, extra={DataClassFutureIntEvenOrOddTypeUnion: serializer}
564
+ )
565
+ expected = str(int_)
566
+ assert serialized == expected
567
+
568
+ @given(int_=integers())
569
+ def test_union_with_extra(self, *, int_: int) -> None:
570
+ match int_ % 2:
571
+ case 0:
572
+ obj = DataClassFutureIntEven(even_int=int_)
573
+ case 1:
574
+ obj = DataClassFutureIntOdd(odd_int=int_)
575
+ case _:
576
+ raise ImpossibleCaseError(case=[f"{int_=}"])
577
+
578
+ def serializer(obj: DataClassFutureIntEvenOrOddUnion, /) -> str:
579
+ match obj:
580
+ case DataClassFutureIntEven():
581
+ return str(obj.even_int)
582
+ case DataClassFutureIntOdd():
583
+ return str(obj.odd_int)
584
+
585
+ serialized = serialize_object(
586
+ obj, extra={DataClassFutureIntEvenOrOddUnion: serializer}
587
+ )
588
+ expected = str(int_)
589
+ assert serialized == expected
590
+
534
591
  def test_error_extra_empty(self) -> None:
535
592
  with raises(
536
593
  _SerializeObjectSerializeError,
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.110.4"
3
+ __version__ = "0.110.6"
@@ -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]]:
@@ -40,6 +40,7 @@ from utilities.types import (
40
40
  TCallable2,
41
41
  TSupportsRichComparison,
42
42
  TupleOrStrMapping,
43
+ TypeLike,
43
44
  )
44
45
 
45
46
  if TYPE_CHECKING:
@@ -181,9 +182,7 @@ def ensure_class(
181
182
  *,
182
183
  nullable: Literal[False] = False,
183
184
  ) -> _T1 | _T2 | _T3 | _T4 | _T5: ...
184
- def ensure_class(
185
- obj: Any, cls: type[_T] | tuple[type[_T], ...], /, *, nullable: bool = False
186
- ) -> Any:
185
+ def ensure_class(obj: Any, cls: TypeLike[_T], /, *, nullable: bool = False) -> Any:
187
186
  """Ensure an object is of the required class."""
188
187
  if isinstance(obj, cls) or ((obj is None) and nullable):
189
188
  return obj
@@ -193,7 +192,7 @@ def ensure_class(
193
192
  @dataclass(kw_only=True, slots=True)
194
193
  class EnsureClassError(Exception):
195
194
  obj: Any
196
- cls: type[Any] | tuple[type[Any], ...]
195
+ cls: TypeLike[Any]
197
196
  nullable: bool
198
197
 
199
198
  @override
@@ -686,7 +685,9 @@ def is_iterable_of(
686
685
  def is_iterable_of(
687
686
  obj: Any, cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
688
687
  ) -> TypeGuard[Iterable[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
689
- def is_iterable_of(obj: Any, cls: Any, /) -> TypeGuard[Iterable[Any]]:
688
+ @overload
689
+ def is_iterable_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Iterable[_T]]: ...
690
+ def is_iterable_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Iterable[_T]]:
690
691
  """Check if an object is a iterable of tuple or string mappings."""
691
692
  return isinstance(obj, Iterable) and all(map(make_isinstance(cls), obj))
692
693
 
@@ -730,7 +731,9 @@ def is_sequence_of(
730
731
  def is_sequence_of(
731
732
  obj: Any, cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
732
733
  ) -> TypeGuard[Sequence[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
733
- def is_sequence_of(obj: Any, cls: Any, /) -> TypeGuard[Sequence[Any]]:
734
+ @overload
735
+ def is_sequence_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Sequence[_T]]: ...
736
+ def is_sequence_of(obj: Any, cls: TypeLike[_T], /) -> TypeGuard[Sequence[_T]]:
734
737
  """Check if an object is a sequence of tuple or string mappings."""
735
738
  return isinstance(obj, Sequence) and is_iterable_of(obj, cls)
736
739
 
@@ -820,19 +823,14 @@ def make_isinstance(
820
823
  def make_isinstance(
821
824
  cls: tuple[type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], /
822
825
  ) -> Callable[[Any], TypeGuard[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
823
- def make_isinstance(
824
- cls: type[_T] | tuple[type[_T], ...], /
825
- ) -> Callable[[Any], TypeGuard[Any]]:
826
+ @overload
827
+ def make_isinstance(cls: TypeLike[_T], /) -> Callable[[Any], TypeGuard[_T]]: ...
828
+ def make_isinstance(cls: TypeLike[_T], /) -> Callable[[Any], TypeGuard[_T]]:
826
829
  """Make a curried `isinstance` function."""
827
830
  return partial(_make_instance_core, cls=cls)
828
831
 
829
832
 
830
- ##
831
-
832
-
833
- def _make_instance_core(
834
- obj: Any, /, *, cls: type[_T] | tuple[type[_T], ...]
835
- ) -> TypeGuard[_T]:
833
+ def _make_instance_core(obj: Any, /, *, cls: TypeLike[_T]) -> TypeGuard[_T]:
836
834
  return isinstance(obj, cls)
837
835
 
838
836
 
@@ -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.
@@ -539,7 +539,12 @@ def _serialize_object_dict(
539
539
 
540
540
  def _serialize_object_extra(obj: Any, extra: SerializeObjectExtra, /) -> str:
541
541
  try:
542
- serializer = one(s for c, s in extra.items() if isinstance(obj, c))
542
+ serializer = one(
543
+ s
544
+ for c, s in extra.items()
545
+ if (isinstance(c, type) and isinstance(obj, c))
546
+ or isinstance(obj, get_args(c))
547
+ )
543
548
  except OneEmptyError:
544
549
  raise _SerializeObjectSerializeError(obj=obj) from None
545
550
  except OneNonUniqueError as error:
@@ -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
@@ -232,7 +233,7 @@ class SupportsRound(Protocol[_T_co]):
232
233
 
233
234
  # parse
234
235
  type ParseObjectExtra = Mapping[Any, Callable[[str], Any]]
235
- type SerializeObjectExtra = Mapping[type[Any], Callable[[Any], str]]
236
+ type SerializeObjectExtra = Mapping[Any, Callable[[Any], str]]
236
237
 
237
238
 
238
239
  # pathlib
@@ -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()