dycw-utilities 0.112.1__tar.gz → 0.112.3__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.112.1 → dycw_utilities-0.112.3}/PKG-INFO +1 -1
  2. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/pyproject.toml +2 -2
  3. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_dataclasses.py +17 -8
  4. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_parse.py +30 -23
  5. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_sentinel.py +4 -3
  6. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_text.py +8 -8
  7. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_typing.py +214 -102
  8. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/__init__.py +1 -1
  9. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/polars.py +7 -6
  10. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/sentinel.py +1 -1
  11. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/text.py +3 -3
  12. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/typing.py +76 -11
  13. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/.gitignore +0 -0
  14. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/LICENSE +0 -0
  15. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/README.md +0 -0
  16. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/__init__.py +0 -0
  17. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/conftest.py +0 -0
  18. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/__init__.py +0 -0
  19. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_missing/__init__.py +0 -0
  20. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_missing/module.py +0 -0
  21. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/__init__.py +0 -0
  22. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/outer_1.py +0 -0
  23. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/outer_2.py +0 -0
  24. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  25. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  26. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  27. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  28. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_without/__init__.py +0 -0
  29. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_without/module_1.py +0 -0
  30. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/package_without/module_2.py +0 -0
  31. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/standalone.py +0 -0
  32. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/modules/with_imports.py +0 -0
  33. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  34. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  35. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  36. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  37. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  38. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  39. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  40. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  41. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/__init__.py +0 -0
  42. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_async_service/__init__.py +0 -0
  43. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_async_service/__main__.py +0 -0
  44. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_async_service/run.sh +0 -0
  45. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_queue_processor/__init__.py +0 -0
  46. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_queue_processor/__main__.py +0 -0
  47. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/scripts/test_queue_processor/run.sh +0 -0
  48. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_altair.py +0 -0
  49. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_astor.py +0 -0
  50. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_asyncio.py +0 -0
  51. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_atomicwrites.py +0 -0
  52. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_atools.py +0 -0
  53. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_cachetools.py +0 -0
  54. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_click.py +0 -0
  55. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_concurrent.py +0 -0
  56. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_contextlib.py +0 -0
  57. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_contextvars.py +0 -0
  58. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_cryptography.py +0 -0
  59. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_cvxpy.py +0 -0
  60. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_datetime.py +0 -0
  61. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_enum.py +0 -0
  62. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_errors.py +0 -0
  63. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_eventkit.py +0 -0
  64. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_fastapi.py +0 -0
  65. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_fpdf2.py +0 -0
  66. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_functions.py +0 -0
  67. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_functools.py +0 -0
  68. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_getpass.py +0 -0
  69. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_git.py +0 -0
  70. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_hashlib.py +0 -0
  71. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_http.py +0 -0
  72. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_hypothesis.py +0 -0
  73. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_ipython.py +0 -0
  74. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_iterables.py +0 -0
  75. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_jupyter.py +0 -0
  76. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_lightweight_charts.py +0 -0
  77. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_logging.py +0 -0
  78. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_loguru.py +0 -0
  79. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_luigi.py +0 -0
  80. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_math.py +0 -0
  81. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_memory_profiler.py +0 -0
  82. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_modules.py +0 -0
  83. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_more_itertools.py +0 -0
  84. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_numpy.py +0 -0
  85. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_operator.py +0 -0
  86. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_optuna.py +0 -0
  87. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_orjson.py +0 -0
  88. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_os.py +0 -0
  89. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pathlib.py +0 -0
  90. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_period.py +0 -0
  91. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pickle.py +0 -0
  92. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_platform.py +0 -0
  93. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_polars.py +0 -0
  94. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_polars_ols.py +0 -0
  95. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pqdm.py +0 -0
  96. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pydantic.py +0 -0
  97. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pyinstrument.py +0 -0
  98. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pyrsistent.py +0 -0
  99. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pytest.py +0 -0
  100. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_pytest_regressions.py +0 -0
  101. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_python_dotenv.py +0 -0
  102. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_random.py +0 -0
  103. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_re.py +0 -0
  104. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_redis.py +0 -0
  105. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_reprlib.py +0 -0
  106. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_rich.py +0 -0
  107. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_scipy.py +0 -0
  108. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_shelve.py +0 -0
  109. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_slack_sdk.py +0 -0
  110. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_socket.py +0 -0
  111. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_sqlalchemy.py +0 -0
  112. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_sqlalchemy_polars.py +0 -0
  113. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_statsmodel.py +0 -0
  114. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_streamlit.py +0 -0
  115. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_sys.py +0 -0
  116. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_tempfile.py +0 -0
  117. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_tenacity.py +0 -0
  118. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_threading.py +0 -0
  119. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_timer.py +0 -0
  120. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback.py +0 -0
  121. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/__init__.py +0 -0
  122. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/chain.py +0 -0
  123. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
  124. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
  125. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/error_bind.py +0 -0
  126. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/many.py +0 -0
  127. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/one.py +0 -0
  128. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/recursive.py +0 -0
  129. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
  130. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
  131. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/two.py +0 -0
  132. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_traceback_funcs/untraced.py +0 -0
  133. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_types.py +0 -0
  134. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_typing_funcs/__init__.py +0 -0
  135. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_typing_funcs/no_future.py +0 -0
  136. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_typing_funcs/with_future.py +0 -0
  137. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_tzdata.py +0 -0
  138. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_tzlocal.py +0 -0
  139. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_uuid.py +0 -0
  140. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_version.py +0 -0
  141. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_warnings.py +0 -0
  142. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_whenever.py +0 -0
  143. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_zipfile.py +0 -0
  144. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/tests/test_zoneinfo.py +0 -0
  145. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/altair.py +0 -0
  146. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/astor.py +0 -0
  147. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/asyncio.py +0 -0
  148. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/atomicwrites.py +0 -0
  149. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/atools.py +0 -0
  150. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/cachetools.py +0 -0
  151. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/click.py +0 -0
  152. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/concurrent.py +0 -0
  153. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/contextlib.py +0 -0
  154. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/contextvars.py +0 -0
  155. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/cryptography.py +0 -0
  156. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/cvxpy.py +0 -0
  157. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/dataclasses.py +0 -0
  158. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/datetime.py +0 -0
  159. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/enum.py +0 -0
  160. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/errors.py +0 -0
  161. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/eventkit.py +0 -0
  162. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/fastapi.py +0 -0
  163. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/fpdf2.py +0 -0
  164. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/functions.py +0 -0
  165. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/functools.py +0 -0
  166. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/getpass.py +0 -0
  167. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/git.py +0 -0
  168. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/hashlib.py +0 -0
  169. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/http.py +0 -0
  170. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/hypothesis.py +0 -0
  171. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/ipython.py +0 -0
  172. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/iterables.py +0 -0
  173. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/jupyter.py +0 -0
  174. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/lightweight_charts.py +0 -0
  175. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/logging.py +0 -0
  176. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/loguru.py +0 -0
  177. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/luigi.py +0 -0
  178. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/math.py +0 -0
  179. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/memory_profiler.py +0 -0
  180. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/modules.py +0 -0
  181. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/more_itertools.py +0 -0
  182. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/numpy.py +0 -0
  183. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/operator.py +0 -0
  184. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/optuna.py +0 -0
  185. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/orjson.py +0 -0
  186. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/os.py +0 -0
  187. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/parse.py +0 -0
  188. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pathlib.py +0 -0
  189. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/period.py +0 -0
  190. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pickle.py +0 -0
  191. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/platform.py +0 -0
  192. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/polars_ols.py +0 -0
  193. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pqdm.py +0 -0
  194. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/py.typed +0 -0
  195. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pydantic.py +0 -0
  196. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pyinstrument.py +0 -0
  197. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pyrsistent.py +0 -0
  198. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pytest.py +0 -0
  199. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/pytest_regressions.py +0 -0
  200. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/python_dotenv.py +0 -0
  201. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/random.py +0 -0
  202. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/re.py +0 -0
  203. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/redis.py +0 -0
  204. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/reprlib.py +0 -0
  205. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/rich.py +0 -0
  206. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/scipy.py +0 -0
  207. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/shelve.py +0 -0
  208. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/slack_sdk.py +0 -0
  209. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/socket.py +0 -0
  210. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/sqlalchemy.py +0 -0
  211. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/sqlalchemy_polars.py +0 -0
  212. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/statsmodels.py +0 -0
  213. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/streamlit.py +0 -0
  214. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/sys.py +0 -0
  215. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/tempfile.py +0 -0
  216. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/tenacity.py +0 -0
  217. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/threading.py +0 -0
  218. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/timer.py +0 -0
  219. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/traceback.py +0 -0
  220. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/types.py +0 -0
  221. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/tzdata.py +0 -0
  222. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/tzlocal.py +0 -0
  223. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/uuid.py +0 -0
  224. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/version.py +0 -0
  225. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/warnings.py +0 -0
  226. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/whenever.py +0 -0
  227. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/zipfile.py +0 -0
  228. {dycw_utilities-0.112.1 → dycw_utilities-0.112.3}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.112.1
3
+ Version: 0.112.3
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.112.1"
97
+ version = "0.112.3"
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.112.1"
340
+ current_version = "0.112.3"
341
341
 
342
342
  [[tool.bumpversion.files]]
343
343
  filename = "src/utilities/__init__.py"
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from dataclasses import dataclass, field
4
4
  from pathlib import Path
5
5
  from types import NoneType
6
- from typing import Any, cast, override
6
+ from typing import Any, Literal, cast, override
7
7
 
8
8
  from hypothesis import given
9
9
  from hypothesis.strategies import booleans, integers, lists, sampled_from
@@ -406,7 +406,18 @@ class TestSerializeAndParseDataClass:
406
406
  assert result == obj
407
407
 
408
408
  @given(int_=integers())
409
- def test_extra_type(self, *, int_: int) -> None:
409
+ def test_literal_type(self, *, int_: int) -> None:
410
+ obj = DataClassFutureInt(int_=int_)
411
+ serialized = serialize_dataclass(obj)
412
+ result = parse_dataclass(
413
+ serialized,
414
+ DataClassFutureInt,
415
+ extra_parsers={Literal["lit"]: NotImplementedError},
416
+ )
417
+ assert result == obj
418
+
419
+ @given(int_=integers())
420
+ def test_type_extra(self, *, int_: int) -> None:
410
421
  obj = DataClassFutureNestedOuterFirstOuter(
411
422
  inner=DataClassFutureNestedOuterFirstInner(int_=int_)
412
423
  )
@@ -625,9 +636,8 @@ class TestYieldFields:
625
636
  assert result == expected
626
637
  assert is_optional_type(result.type_)
627
638
  args = get_args(result.type_)
628
- assert args == (TrueOrFalseFutureLit,)
629
- arg = one(args)
630
- assert get_args(arg) == ("true", "false")
639
+ assert args == (TrueOrFalseFutureLit, NoneType)
640
+ assert get_args(args[0]) == ("true", "false")
631
641
 
632
642
  def test_class_future_nested(self) -> None:
633
643
  result = one(
@@ -665,9 +675,8 @@ class TestYieldFields:
665
675
  assert result == expected
666
676
  assert is_optional_type(result.type_)
667
677
  args = get_args(result.type_)
668
- assert args == (TrueOrFalseFutureTypeLit,)
669
- arg = one(args)
670
- assert get_args(arg) == ("true", "false")
678
+ assert args == (TrueOrFalseFutureTypeLit, NoneType)
679
+ assert get_args(args[0]) == ("true", "false")
671
680
 
672
681
  def test_class_orjson_log_record(self) -> None:
673
682
  result = list(yield_fields(OrjsonLogRecord, globalns=globals()))
@@ -57,6 +57,7 @@ from utilities.parse import (
57
57
  serialize_object,
58
58
  )
59
59
  from utilities.sentinel import Sentinel, sentinel
60
+ from utilities.text import parse_bool
60
61
  from utilities.types import Duration, Number
61
62
  from utilities.version import Version
62
63
 
@@ -98,28 +99,17 @@ class TestSerializeAndParseObject:
98
99
  result = parse_object(TruthEnum, serialized)
99
100
  assert result is truth
100
101
 
101
- @given(int_=integers())
102
- def test_extra_type(self, *, int_: int) -> None:
103
- serialized = serialize_object(int_)
104
- result = parse_object(
105
- DataClassFutureInt,
106
- serialized,
107
- extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
108
- )
109
- expected = DataClassFutureInt(int_=int_)
110
- assert result == expected
111
-
112
102
  @given(float_=floats())
113
103
  def test_float(self, *, float_: float) -> None:
114
104
  serialized = serialize_object(float_)
115
105
  result = parse_object(float, serialized)
116
106
  assert is_equal(result, float_)
117
107
 
118
- @given(values=frozensets(dates()))
119
- def test_frozenset(self, *, values: frozenset[dt.date]) -> None:
120
- serialized = serialize_object(values)
108
+ @given(dates=frozensets(dates()))
109
+ def test_frozenset(self, *, dates: frozenset[dt.date]) -> None:
110
+ serialized = serialize_object(dates)
121
111
  result = parse_object(frozenset[dt.date], serialized)
122
- assert result == values
112
+ assert result == dates
123
113
 
124
114
  @given(int_=integers())
125
115
  def test_int(self, *, int_: int) -> None:
@@ -127,11 +117,17 @@ class TestSerializeAndParseObject:
127
117
  result = parse_object(int, serialized)
128
118
  assert result == int_
129
119
 
130
- @given(values=lists(dates()))
131
- def test_list(self, *, values: list[dt.date]) -> None:
132
- serialized = serialize_object(values)
120
+ @given(dates=lists(dates()))
121
+ def test_list(self, *, dates: list[dt.date]) -> None:
122
+ serialized = serialize_object(dates)
133
123
  result = parse_object(list[dt.date], serialized)
134
- assert result == values
124
+ assert result == dates
125
+
126
+ @given(bool_=booleans())
127
+ def test_literal_extra(self, *, bool_: bool) -> None:
128
+ text = serialize_object(bool_)
129
+ result = parse_object(bool, text, extra={Literal["lit"]: parse_bool})
130
+ assert result is bool_
135
131
 
136
132
  @given(truth=sampled_from(["true", "false"]))
137
133
  def test_literal(self, *, truth: Literal["true", "false"]) -> None:
@@ -205,11 +201,11 @@ class TestSerializeAndParseObject:
205
201
  result = parse_object(Sentinel, serialized)
206
202
  assert result is sentinel
207
203
 
208
- @given(values=sets(dates()))
209
- def test_set(self, *, values: set[dt.date]) -> None:
210
- serialized = serialize_object(values)
204
+ @given(dates=sets(dates()))
205
+ def test_set(self, *, dates: set[dt.date]) -> None:
206
+ serialized = serialize_object(dates)
211
207
  result = parse_object(set[dt.date], serialized)
212
- assert result == values
208
+ assert result == dates
213
209
 
214
210
  @given(serialized=text_ascii())
215
211
  def test_to_serialized(self, *, serialized: str) -> None:
@@ -234,6 +230,17 @@ class TestSerializeAndParseObject:
234
230
  result = parse_object(tuple[int, int], serialized)
235
231
  assert result == (x, y)
236
232
 
233
+ @given(int_=integers())
234
+ def test_type_extra(self, *, int_: int) -> None:
235
+ serialized = serialize_object(int_)
236
+ result = parse_object(
237
+ DataClassFutureInt,
238
+ serialized,
239
+ extra={DataClassFutureInt: lambda text: DataClassFutureInt(int_=int(text))},
240
+ )
241
+ expected = DataClassFutureInt(int_=int_)
242
+ assert result == expected
243
+
237
244
  @given(truth=sampled_from(["true", "false"]))
238
245
  def test_type_literal(self, *, truth: Literal["true", "false"]) -> None:
239
246
  result = parse_object(TrueOrFalseFutureTypeLit, truth)
@@ -26,11 +26,12 @@ class TestParseSentinel:
26
26
  result = parse_sentinel(text_use)
27
27
  assert result is sentinel
28
28
 
29
- def test_error(self) -> None:
29
+ @given(text=sampled_from(["invalid", "ssentinell"]))
30
+ def test_error(self, *, text: str) -> None:
30
31
  with raises(
31
- ParseSentinelError, match="Unable to parse sentinel value; got 'invalid'"
32
+ ParseSentinelError, match="Unable to parse sentinel value; got '.*'"
32
33
  ):
33
- _ = parse_sentinel("invalid")
34
+ _ = parse_sentinel(text)
34
35
 
35
36
 
36
37
  class TestSentinel:
@@ -51,11 +51,10 @@ class TestParseBool:
51
51
  result = parse_bool(text_use)
52
52
  assert result is value
53
53
 
54
- def test_error(self) -> None:
55
- with raises(
56
- ParseBoolError, match="Unable to parse boolean value; got 'invalid'"
57
- ):
58
- _ = parse_bool("invalid")
54
+ @given(text=sampled_from(["invalid", "11", "00", "ttruee", "ffalsee"]))
55
+ def test_error(self, *, text: str) -> None:
56
+ with raises(ParseBoolError, match="Unable to parse boolean value; got '.*'"):
57
+ _ = parse_bool(text)
59
58
 
60
59
 
61
60
  class TestParseNone:
@@ -66,9 +65,10 @@ class TestParseNone:
66
65
  result = parse_none(text_use)
67
66
  assert result is None
68
67
 
69
- def test_error(self) -> None:
70
- with raises(ParseNoneError, match="Unable to parse null value; got 'invalid'"):
71
- _ = parse_none("invalid")
68
+ @given(text=sampled_from(["invalid", "nnonee"]))
69
+ def test_error(self, *, text: str) -> None:
70
+ with raises(ParseNoneError, match="Unable to parse null value; got '.*'"):
71
+ _ = parse_none(text)
72
72
 
73
73
 
74
74
  class TestReprEncode:
@@ -6,7 +6,7 @@ from dataclasses import dataclass
6
6
  from pathlib import Path
7
7
  from random import Random
8
8
  from types import NoneType
9
- from typing import TYPE_CHECKING, Any, Literal, NamedTuple, Self
9
+ from typing import TYPE_CHECKING, Any, Final, Literal, NamedTuple, Self
10
10
  from uuid import UUID
11
11
 
12
12
  from hypothesis import given
@@ -22,8 +22,10 @@ from hypothesis.strategies import (
22
22
  just,
23
23
  none,
24
24
  sampled_from,
25
+ sets,
26
+ tuples,
25
27
  )
26
- from pytest import mark, param, raises
28
+ from pytest import raises
27
29
 
28
30
  from tests.test_typing_funcs.no_future import (
29
31
  DataClassNoFutureNestedInnerFirstInner,
@@ -54,6 +56,8 @@ from tests.test_typing_funcs.with_future import (
54
56
  from utilities.sentinel import Sentinel
55
57
  from utilities.types import Duration, LogLevel, Number, Parallelism, Seed
56
58
  from utilities.typing import (
59
+ IsInstanceGenError,
60
+ IsSubclassGenError,
57
61
  _GetTypeClassesTupleError,
58
62
  _GetTypeClassesTypeError,
59
63
  _GetUnionTypeClassesInternalTypeError,
@@ -85,32 +89,40 @@ if TYPE_CHECKING:
85
89
 
86
90
 
87
91
  class TestContainsSelf:
88
- @mark.parametrize("obj", [param(Self), param(Self | None)])
92
+ @given(obj=sampled_from([Self, Self | None]))
89
93
  def test_main(self, *, obj: Any) -> None:
90
94
  assert contains_self(obj)
91
95
 
92
96
 
93
97
  class TestGetArgs:
94
- @mark.parametrize(
95
- ("obj", "expected"),
96
- [
97
- param(dict[int, int], (int, int)),
98
- param(frozenset[int], (int,)),
99
- param(int | None, (int,)),
100
- param(int | str, (int, str)),
101
- param(list[int], (int,)),
102
- param(Literal["a", "b", "c"], ("a", "b", "c")),
103
- param(Mapping[int, int], (int, int)),
104
- param(Sequence[int], (int,)),
105
- param(set[int], (int,)),
106
- param(LogLevel, ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL")),
107
- param(Parallelism, ("processes", "threads")),
108
- ],
98
+ @given(
99
+ case=sampled_from([
100
+ (dict[int, int], (int, int)),
101
+ (frozenset[int], (int,)),
102
+ (int | None, (int, NoneType)),
103
+ (int | str, (int, str)),
104
+ (list[int], (int,)),
105
+ (Literal["a", "b", "c"], ("a", "b", "c")),
106
+ (Mapping[int, int], (int, int)),
107
+ (Sequence[int], (int,)),
108
+ (set[int], (int,)),
109
+ (LogLevel, ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL")),
110
+ (Parallelism, ("processes", "threads")),
111
+ ])
109
112
  )
110
- def test_main(self, *, obj: Any, expected: tuple[Any, ...]) -> None:
113
+ def test_main(self, *, case: tuple[Any, tuple[Any, ...]]) -> None:
114
+ obj, expected = case
111
115
  result = get_args(obj)
112
116
  assert result == expected
113
117
 
118
+ @given(case=sampled_from([(int | None, (int,)), (int | str | None, (int, str))]))
119
+ def test_optional_drop_none(
120
+ self, *, case: tuple[Any, tuple[type[Any], ...]]
121
+ ) -> None:
122
+ obj, expected = case
123
+ result = get_args(obj, optional_drop_none=True)
124
+ assert result == expected
125
+
114
126
 
115
127
  type _PlusOrMinusOneLit = Literal[1, -1]
116
128
  type _TruthLit = Literal["true", "false"]
@@ -417,73 +429,71 @@ class TestGetUnionTypeClasses:
417
429
 
418
430
 
419
431
  class TestIsAnnotationOfType:
420
- @mark.parametrize(
421
- ("func", "obj", "expected"),
422
- [
423
- param(is_dict_type, Mapping[int, int], False),
424
- param(is_dict_type, Sequence[int], False),
425
- param(is_dict_type, dict[int, int], True),
426
- param(is_dict_type, frozenset[int], False),
427
- param(is_dict_type, list[int], False),
428
- param(is_dict_type, set[int], False),
429
- param(is_dict_type, tuple[int, int], False),
430
- param(is_frozenset_type, Mapping[int, int], False),
431
- param(is_frozenset_type, Sequence[int], False),
432
- param(is_frozenset_type, dict[int, int], False),
433
- param(is_frozenset_type, frozenset[int], True),
434
- param(is_frozenset_type, list[int], False),
435
- param(is_frozenset_type, set[int], False),
436
- param(is_frozenset_type, tuple[int, int], False),
437
- param(is_list_type, Mapping[int, int], False),
438
- param(is_list_type, Sequence[int], False),
439
- param(is_list_type, dict[int, int], False),
440
- param(is_list_type, frozenset[int], False),
441
- param(is_list_type, list[int], True),
442
- param(is_list_type, set[int], False),
443
- param(is_list_type, tuple[int, int], False),
444
- param(is_literal_type, Literal["a", "b", "c"], True),
445
- param(is_literal_type, list[int], False),
446
- param(is_mapping_type, Mapping[int, int], True),
447
- param(is_mapping_type, Sequence[int], False),
448
- param(is_mapping_type, dict[int, int], False),
449
- param(is_mapping_type, frozenset[int], False),
450
- param(is_mapping_type, list[int], False),
451
- param(is_mapping_type, set[int], False),
452
- param(is_mapping_type, tuple[int, int], False),
453
- param(is_optional_type, Literal["a", "b", "c"] | None, True),
454
- param(is_optional_type, Literal["a", "b", "c"], False),
455
- param(is_optional_type, int | None, True),
456
- param(is_optional_type, int | str, False),
457
- param(is_optional_type, list[int] | None, True),
458
- param(is_optional_type, list[int], False),
459
- param(is_sequence_type, Mapping[int, int], False),
460
- param(is_sequence_type, Sequence[int], True),
461
- param(is_sequence_type, dict[int, int], False),
462
- param(is_sequence_type, frozenset[int], False),
463
- param(is_sequence_type, list[int], False),
464
- param(is_sequence_type, set[int], False),
465
- param(is_sequence_type, tuple[int, int], False),
466
- param(is_set_type, Mapping[int, int], False),
467
- param(is_set_type, Sequence[int], False),
468
- param(is_set_type, dict[int, int], False),
469
- param(is_set_type, frozenset[int], False),
470
- param(is_set_type, list[int], False),
471
- param(is_set_type, set[int], True),
472
- param(is_set_type, tuple[int, int], False),
473
- param(is_tuple_type, Mapping[int, int], False),
474
- param(is_tuple_type, Sequence[int], False),
475
- param(is_tuple_type, dict[int, int], False),
476
- param(is_tuple_type, frozenset[int], False),
477
- param(is_tuple_type, list[int], False),
478
- param(is_tuple_type, set[int], False),
479
- param(is_tuple_type, tuple[int, int], True),
480
- param(is_union_type, int | str, True),
481
- param(is_union_type, list[int], False),
482
- ],
432
+ @given(
433
+ case=sampled_from([
434
+ (is_dict_type, Mapping[int, int], False),
435
+ (is_dict_type, Sequence[int], False),
436
+ (is_dict_type, dict[int, int], True),
437
+ (is_dict_type, frozenset[int], False),
438
+ (is_dict_type, list[int], False),
439
+ (is_dict_type, set[int], False),
440
+ (is_dict_type, tuple[int, int], False),
441
+ (is_frozenset_type, Mapping[int, int], False),
442
+ (is_frozenset_type, Sequence[int], False),
443
+ (is_frozenset_type, dict[int, int], False),
444
+ (is_frozenset_type, frozenset[int], True),
445
+ (is_frozenset_type, list[int], False),
446
+ (is_frozenset_type, set[int], False),
447
+ (is_frozenset_type, tuple[int, int], False),
448
+ (is_list_type, Mapping[int, int], False),
449
+ (is_list_type, Sequence[int], False),
450
+ (is_list_type, dict[int, int], False),
451
+ (is_list_type, frozenset[int], False),
452
+ (is_list_type, list[int], True),
453
+ (is_list_type, set[int], False),
454
+ (is_list_type, tuple[int, int], False),
455
+ (is_literal_type, Literal["a", "b", "c"], True),
456
+ (is_literal_type, list[int], False),
457
+ (is_mapping_type, Mapping[int, int], True),
458
+ (is_mapping_type, Sequence[int], False),
459
+ (is_mapping_type, dict[int, int], False),
460
+ (is_mapping_type, frozenset[int], False),
461
+ (is_mapping_type, list[int], False),
462
+ (is_mapping_type, set[int], False),
463
+ (is_mapping_type, tuple[int, int], False),
464
+ (is_optional_type, Literal["a", "b", "c"] | None, True),
465
+ (is_optional_type, Literal["a", "b", "c"], False),
466
+ (is_optional_type, int | None, True),
467
+ (is_optional_type, int | str, False),
468
+ (is_optional_type, list[int] | None, True),
469
+ (is_optional_type, list[int], False),
470
+ (is_sequence_type, Mapping[int, int], False),
471
+ (is_sequence_type, Sequence[int], True),
472
+ (is_sequence_type, dict[int, int], False),
473
+ (is_sequence_type, frozenset[int], False),
474
+ (is_sequence_type, list[int], False),
475
+ (is_sequence_type, set[int], False),
476
+ (is_sequence_type, tuple[int, int], False),
477
+ (is_set_type, Mapping[int, int], False),
478
+ (is_set_type, Sequence[int], False),
479
+ (is_set_type, dict[int, int], False),
480
+ (is_set_type, frozenset[int], False),
481
+ (is_set_type, list[int], False),
482
+ (is_set_type, set[int], True),
483
+ (is_set_type, tuple[int, int], False),
484
+ (is_tuple_type, Mapping[int, int], False),
485
+ (is_tuple_type, Sequence[int], False),
486
+ (is_tuple_type, dict[int, int], False),
487
+ (is_tuple_type, frozenset[int], False),
488
+ (is_tuple_type, list[int], False),
489
+ (is_tuple_type, set[int], False),
490
+ (is_tuple_type, tuple[int, int], True),
491
+ (is_union_type, int | str, True),
492
+ (is_union_type, list[int], False),
493
+ ])
483
494
  )
484
- def test_main(
485
- self, *, func: Callable[[Any], bool], obj: Any, expected: bool
486
- ) -> None:
495
+ def test_main(self, *, case: tuple[Callable[[Any], bool], Any, bool]) -> None:
496
+ func, obj, expected = case
487
497
  assert func(obj) is expected
488
498
 
489
499
 
@@ -491,27 +501,75 @@ class TestIsInstanceGen:
491
501
  @given(
492
502
  data=data(),
493
503
  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),
504
+ # types - bool/int
505
+ (booleans(), bool, None, True),
506
+ (booleans(), int, None, False),
507
+ (integers(), bool, None, False),
508
+ (integers(), int, None, True),
509
+ (booleans(), (bool, int), None, True),
510
+ (integers(), (bool, int), None, True),
511
+ # types - datetime/date
512
+ (dates(), dt.date, None, True),
513
+ (dates(), dt.datetime, None, False),
514
+ (datetimes(), dt.date, None, False),
515
+ (datetimes(), dt.datetime, None, True),
516
+ # parent union
517
+ (booleans(), Number, None, False),
518
+ (integers(), Number, None, True),
519
+ (floats(), Number, None, True),
520
+ # child tuple/union - skip
521
+ # literals
522
+ (sampled_from([1, 2]), Literal[1, 2, 3], 2, True),
523
+ (sampled_from([1, 2, 3]), Literal[1, 2, 3], 3, True),
524
+ (sampled_from([1, 2, 3]), Literal[1, 2], 3, False),
525
+ (sampled_from([1, 2, 3]), int, 3, True),
526
+ (sampled_from([1, 2, 3]), bool, 3, False),
527
+ (sampled_from(["1", "2", "3"]), str, 3, True),
528
+ (sampled_from(["1", "2", "3"]), bool, 3, False),
529
+ (sampled_from([1, "2", 3]), int | str, 3, True),
530
+ (sampled_from([1, "2", 3]), int, 3, False),
531
+ (sampled_from([1, "2", 3]), str, 3, False),
532
+ (booleans(), Literal[1, 2, 3], None, False),
533
+ # tuple types
534
+ (tuples(booleans()), tuple[bool], None, True),
535
+ (tuples(booleans()), tuple[int], None, False),
536
+ (tuples(integers()), tuple[bool], None, False),
537
+ (tuples(integers()), tuple[int], None, True),
538
+ (tuples(booleans()), tuple[Number], None, False),
539
+ (tuples(integers()), tuple[Number], None, True),
540
+ (tuples(floats()), tuple[Number], None, True),
541
+ (tuples(booleans()), bool, None, False),
542
+ (tuples(just("a"), booleans()), tuple[Literal["a"], bool], None, True),
543
+ (tuples(just("a"), booleans()), tuple[Literal["a"], int], None, False),
544
+ (tuples(just("a"), integers()), tuple[Literal["a"], bool], None, False),
545
+ (tuples(just("a"), integers()), tuple[Literal["a"], int], None, True),
546
+ (tuples(just("a"), booleans()), tuple[Literal["a", "b"], bool], None, True),
547
+ (tuples(just("a"), booleans()), tuple[Literal["a", "b"], int], None, False),
548
+ (
549
+ tuples(just("a"), integers()),
550
+ tuple[Literal["a", "b"], bool],
551
+ None,
552
+ False,
553
+ ),
554
+ (tuples(just("a"), integers()), tuple[Literal["a", "b"], int], None, True),
507
555
  ]),
508
556
  )
509
557
  def test_main(
510
- self, *, data: DataObject, case: tuple[SearchStrategy[Any], Any, bool]
558
+ self,
559
+ *,
560
+ data: DataObject,
561
+ case: tuple[SearchStrategy[Any], Any, int | None, bool],
511
562
  ) -> None:
512
- strategy, type_, expected = case
513
- value = data.draw(strategy)
514
- assert is_instance_gen(value, type_) is expected
563
+ strategy, type_, min_size, expected = case
564
+ match expected:
565
+ case True:
566
+ value = data.draw(strategy)
567
+ assert is_instance_gen(value, type_)
568
+ case False:
569
+ values = data.draw(
570
+ sets(strategy, min_size=100 if min_size is None else min_size)
571
+ )
572
+ assert not all(is_instance_gen(v, type_) for v in values)
515
573
 
516
574
  @given(bool_=booleans())
517
575
  def test_bool_value_vs_custom_int(self, *, bool_: bool) -> None:
@@ -526,6 +584,12 @@ class TestIsInstanceGen:
526
584
  assert not is_instance_gen(int_, MyInt)
527
585
  assert is_instance_gen(MyInt(int_), MyInt)
528
586
 
587
+ def test_error(self) -> None:
588
+ with raises(
589
+ IsInstanceGenError, match=r"Invalid arguments; got None and typing\.Final"
590
+ ):
591
+ _ = is_instance_gen(None, Final)
592
+
529
593
 
530
594
  class TestIsNamedTuple:
531
595
  def test_main(self) -> None:
@@ -547,19 +611,63 @@ class TestIsNamedTuple:
547
611
  class TestIsSubclassGen:
548
612
  @given(
549
613
  case=sampled_from([
614
+ # types - bool/int
550
615
  (bool, bool, True),
551
616
  (bool, int, False),
552
617
  (int, bool, False),
553
618
  (int, int, True),
554
619
  (bool, (bool, int), True),
555
620
  (int, (bool, int), True),
621
+ # types - datetime/date
556
622
  (dt.date, dt.date, True),
557
623
  (dt.date, dt.datetime, False),
558
624
  (dt.datetime, dt.date, False),
559
625
  (dt.datetime, dt.datetime, True),
626
+ # parent union
560
627
  (bool, Number, False),
561
628
  (int, Number, True),
562
629
  (float, Number, True),
630
+ # child tuple
631
+ ((bool,), bool, True),
632
+ ((bool,), int, False),
633
+ ((int,), bool, False),
634
+ ((int,), int, True),
635
+ ((bool, int), int, False),
636
+ ((bool, int), (bool, int), True),
637
+ ((bool, int), (bool, int, float), True),
638
+ # child union
639
+ (bool, bool | None, True),
640
+ (bool | None, bool, False),
641
+ (bool | None, bool | None, True),
642
+ # literals
643
+ (Literal[1, 2], Literal[1, 2, 3], True),
644
+ (Literal[1, 2, 3], Literal[1, 2, 3], True),
645
+ (Literal[1, 2, 3], Literal[1, 2], False),
646
+ (Literal[1, 2, 3], int, True),
647
+ (Literal[1, 2, 3], bool, False),
648
+ (Literal["1", "2", "3"], str, True),
649
+ (Literal["1", "2", "3"], bool, False),
650
+ (Literal[1, "2", 3], int | str, True),
651
+ (Literal[1, "2", 3], int, False),
652
+ (Literal[1, "2", 3], str, False),
653
+ (bool, Literal[1, 2, 3], False),
654
+ # tuple types
655
+ (tuple[bool], tuple[bool], True),
656
+ (tuple[bool], tuple[int], False),
657
+ (tuple[int], tuple[bool], False),
658
+ (tuple[int], tuple[int], True),
659
+ (tuple[bool], tuple[Number], False),
660
+ (tuple[int], tuple[Number], True),
661
+ (tuple[float], tuple[Number], True),
662
+ (tuple[bool], bool, False),
663
+ (tuple[Literal["a"], bool], tuple[Literal["a"], bool], True),
664
+ (tuple[Literal["a"], bool], tuple[Literal["a"], int], False),
665
+ (tuple[Literal["a"], int], tuple[Literal["a"], bool], False),
666
+ (tuple[Literal["a"], int], tuple[Literal["a"], int], True),
667
+ (tuple[Literal["a"], bool], tuple[Literal["a", "b"], bool], True),
668
+ (tuple[Literal["a"], bool], tuple[Literal["a", "b"], int], False),
669
+ (tuple[Literal["a"], int], tuple[Literal["a", "b"], bool], False),
670
+ (tuple[Literal["a"], int], tuple[Literal["a", "b"], int], True),
563
671
  ])
564
672
  )
565
673
  def test_main(self, *, case: tuple[type[Any], Any, bool]) -> None:
@@ -574,3 +682,7 @@ class TestIsSubclassGen:
574
682
  assert not is_subclass_gen(int, MyInt)
575
683
  assert is_subclass_gen(MyInt, int)
576
684
  assert is_subclass_gen(MyInt, MyInt)
685
+
686
+ def test_error(self) -> None:
687
+ with raises(IsSubclassGenError, match="Argument must be a class; got None"):
688
+ _ = is_subclass_gen(None, NoneType)
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.112.1"
3
+ __version__ = "0.112.3"