dycw-utilities 0.165.1__tar.gz → 0.165.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 (211) hide show
  1. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/PKG-INFO +1 -1
  2. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/pyproject.toml +2 -2
  3. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_polars.py +90 -0
  4. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_typing.py +90 -11
  5. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_typing_funcs/no_future.py +11 -1
  6. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_typing_funcs/with_future.py +6 -1
  7. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/__init__.py +1 -1
  8. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/polars.py +30 -0
  9. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/typing.py +53 -10
  10. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/.gitignore +0 -0
  11. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/LICENSE +0 -0
  12. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/README.md +0 -0
  13. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_aeventkit.py +0 -0
  39. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_altair.py +0 -0
  40. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_asyncio.py +0 -0
  41. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_atomicwrites.py +0 -0
  42. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_atools.py +0 -0
  43. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_cachetools.py +0 -0
  44. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_click.py +0 -0
  45. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_concurrent.py +0 -0
  46. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_contextlib.py +0 -0
  47. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_contextvars.py +0 -0
  48. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_cryptography.py +0 -0
  49. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_cvxpy.py +0 -0
  50. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_dataclasses.py +0 -0
  51. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_enum.py +0 -0
  52. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_errors.py +0 -0
  53. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_fastapi.py +0 -0
  54. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_fpdf2.py +0 -0
  55. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_functions.py +0 -0
  56. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_functools.py +0 -0
  57. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_getpass.py +0 -0
  58. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_gzip.py +0 -0
  59. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_hashlib.py +0 -0
  60. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_http.py +0 -0
  61. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_hypothesis.py +0 -0
  62. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_importlib.py +0 -0
  63. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_inflect.py +0 -0
  64. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_ipython.py +0 -0
  65. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_iterables.py +0 -0
  66. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_json.py +0 -0
  67. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_jupyter.py +0 -0
  68. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_libcst.py +0 -0
  69. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_lightweight_charts.py +0 -0
  70. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_logging.py +0 -0
  71. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_math.py +0 -0
  72. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_memory_profiler.py +0 -0
  73. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_modules.py +0 -0
  74. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_more_itertools.py +0 -0
  75. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_numpy.py +0 -0
  76. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_objects/__init__.py +0 -0
  77. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_objects/objects.py +0 -0
  78. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pickle.py +0 -0
  85. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_platform.py +0 -0
  86. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_polars_ols.py +0 -0
  87. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_postgres.py +0 -0
  88. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pottery.py +0 -0
  89. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pqdm.py +0 -0
  90. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_psutil.py +0 -0
  91. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pyinstrument.py +0 -0
  92. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pytest.py +0 -0
  93. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pytest_randomly.py +0 -0
  94. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_pytest_regressions.py +0 -0
  95. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_random.py +0 -0
  96. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_re.py +0 -0
  97. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_redis.py +0 -0
  98. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_reprlib.py +0 -0
  99. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_scipy.py +0 -0
  100. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_sentinel.py +0 -0
  101. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_shelve.py +0 -0
  102. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_slack_sdk.py +0 -0
  103. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_socket.py +0 -0
  104. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_sqlalchemy.py +0 -0
  105. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_sqlalchemy_polars.py +0 -0
  106. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_statsmodels.py +0 -0
  107. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_string.py +0 -0
  108. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_tempfile.py +0 -0
  109. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_testbook.py +0 -0
  110. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_text.py +0 -0
  111. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_threading.py +0 -0
  112. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_timer.py +0 -0
  113. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_traceback.py +0 -0
  114. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_typed_settings.py +0 -0
  115. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_types.py +0 -0
  116. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_typing_funcs/__init__.py +0 -0
  117. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_tzdata.py +0 -0
  118. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_tzlocal.py +0 -0
  119. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_uuid.py +0 -0
  120. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_version.py +0 -0
  121. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_warnings.py +0 -0
  122. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_whenever.py +0 -0
  123. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_zipfile.py +0 -0
  124. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/tests/test_zoneinfo.py +0 -0
  125. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/aeventkit.py +0 -0
  126. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/altair.py +0 -0
  127. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/asyncio.py +0 -0
  128. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/atomicwrites.py +0 -0
  129. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/atools.py +0 -0
  130. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/cachetools.py +0 -0
  131. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/click.py +0 -0
  132. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/concurrent.py +0 -0
  133. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/contextlib.py +0 -0
  134. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/contextvars.py +0 -0
  135. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/cryptography.py +0 -0
  136. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/cvxpy.py +0 -0
  137. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/dataclasses.py +0 -0
  138. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/enum.py +0 -0
  139. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/errors.py +0 -0
  140. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/fastapi.py +0 -0
  141. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/fpdf2.py +0 -0
  142. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/functions.py +0 -0
  143. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/functools.py +0 -0
  144. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/getpass.py +0 -0
  145. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/gzip.py +0 -0
  146. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/hashlib.py +0 -0
  147. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/http.py +0 -0
  148. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/hypothesis.py +0 -0
  149. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/importlib.py +0 -0
  150. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/inflect.py +0 -0
  151. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/ipython.py +0 -0
  152. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/iterables.py +0 -0
  153. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/json.py +0 -0
  154. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/jupyter.py +0 -0
  155. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/libcst.py +0 -0
  156. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/lightweight_charts.py +0 -0
  157. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/logging.py +0 -0
  158. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/math.py +0 -0
  159. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/memory_profiler.py +0 -0
  160. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/modules.py +0 -0
  161. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/more_itertools.py +0 -0
  162. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/numpy.py +0 -0
  163. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/operator.py +0 -0
  164. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/optuna.py +0 -0
  165. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/orjson.py +0 -0
  166. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/os.py +0 -0
  167. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/parse.py +0 -0
  168. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pathlib.py +0 -0
  169. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pickle.py +0 -0
  170. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/platform.py +0 -0
  171. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/polars_ols.py +0 -0
  172. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/postgres.py +0 -0
  173. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pottery.py +0 -0
  174. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pqdm.py +0 -0
  175. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/psutil.py +0 -0
  176. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/py.typed +0 -0
  177. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pyinstrument.py +0 -0
  178. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pytest.py +0 -0
  179. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pytest_plugins/__init__.py +0 -0
  180. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  181. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  182. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/pytest_regressions.py +0 -0
  183. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/random.py +0 -0
  184. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/re.py +0 -0
  185. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/redis.py +0 -0
  186. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/reprlib.py +0 -0
  187. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/scipy.py +0 -0
  188. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/sentinel.py +0 -0
  189. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/shelve.py +0 -0
  190. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/slack_sdk.py +0 -0
  191. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/socket.py +0 -0
  192. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/sqlalchemy.py +0 -0
  193. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/sqlalchemy_polars.py +0 -0
  194. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/statsmodels.py +0 -0
  195. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/string.py +0 -0
  196. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/tempfile.py +0 -0
  197. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/testbook.py +0 -0
  198. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/text.py +0 -0
  199. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/threading.py +0 -0
  200. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/timer.py +0 -0
  201. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/traceback.py +0 -0
  202. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/typed_settings.py +0 -0
  203. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/types.py +0 -0
  204. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/tzdata.py +0 -0
  205. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/tzlocal.py +0 -0
  206. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/uuid.py +0 -0
  207. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/version.py +0 -0
  208. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/warnings.py +0 -0
  209. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/whenever.py +0 -0
  210. {dycw_utilities-0.165.1 → dycw_utilities-0.165.3}/src/utilities/zipfile.py +0 -0
  211. {dycw_utilities-0.165.1 → dycw_utilities-0.165.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.165.1
3
+ Version: 0.165.3
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -233,7 +233,7 @@ dependencies = [
233
233
  name = "dycw-utilities"
234
234
  readme = "README.md"
235
235
  requires-python = ">= 3.12"
236
- version = "0.165.1"
236
+ version = "0.165.3"
237
237
 
238
238
  [project.entry-points.pytest11]
239
239
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -266,7 +266,7 @@ test = [
266
266
  # bump-my-version
267
267
  [tool.bumpversion]
268
268
  allow_dirty = true
269
- current_version = "0.165.1"
269
+ current_version = "0.165.3"
270
270
 
271
271
  [[tool.bumpversion.files]]
272
272
  filename = "src/utilities/__init__.py"
@@ -194,6 +194,7 @@ from utilities.polars import (
194
194
  reify_exprs,
195
195
  replace_time_zone,
196
196
  round_to_float,
197
+ search_period,
197
198
  select_exact,
198
199
  serialize_dataframe,
199
200
  serialize_series,
@@ -224,6 +225,7 @@ from utilities.whenever import (
224
225
  get_now,
225
226
  get_now_plain,
226
227
  get_today,
228
+ to_zoned_date_time,
227
229
  )
228
230
  from utilities.zoneinfo import UTC, to_time_zone_name
229
231
 
@@ -2474,6 +2476,94 @@ class TestRoundToFloat:
2474
2476
  _ = round_to_float(cast("Any", x), cast("Any", y))
2475
2477
 
2476
2478
 
2479
+ class TestSearchPeriod:
2480
+ @mark.parametrize(
2481
+ ("time", "exp_start", "exp_end"),
2482
+ [
2483
+ param(whenever.Time(8, 58), None, None),
2484
+ param(whenever.Time(8, 59), None, None),
2485
+ param(whenever.Time(9), 0, None),
2486
+ param(whenever.Time(9, 1), 0, 0),
2487
+ param(whenever.Time(9, 59), 0, 0),
2488
+ param(whenever.Time(10), 1, 0),
2489
+ param(whenever.Time(10, 1), 1, 1),
2490
+ param(whenever.Time(10, 59), 1, 1),
2491
+ param(whenever.Time(11), 2, 1),
2492
+ param(whenever.Time(11, 1), 2, 2),
2493
+ param(whenever.Time(11, 59), 2, 2),
2494
+ param(whenever.Time(12), None, 2),
2495
+ param(whenever.Time(12, 1), None, None),
2496
+ param(whenever.Time(12, 59), None, None),
2497
+ param(whenever.Time(13), 3, None),
2498
+ param(whenever.Time(13, 1), 3, 3),
2499
+ param(whenever.Time(13, 59), 3, 3),
2500
+ param(whenever.Time(14), None, 3),
2501
+ param(whenever.Time(14, 1), None, None),
2502
+ param(whenever.Time(14, 59), None, None),
2503
+ param(whenever.Time(15), 4, None),
2504
+ param(whenever.Time(15, 1), 4, 4),
2505
+ param(whenever.Time(15, 59), 4, 4),
2506
+ param(whenever.Time(16), None, 4),
2507
+ param(whenever.Time(16, 1), None, None),
2508
+ param(whenever.Time(16, 2), None, None),
2509
+ ],
2510
+ )
2511
+ @mark.parametrize("start_or_end", [param("start"), param("end")])
2512
+ def test_main(
2513
+ self,
2514
+ *,
2515
+ time: whenever.Time,
2516
+ start_or_end: Literal["start", "end"],
2517
+ exp_start: int | None,
2518
+ exp_end: int | None,
2519
+ ) -> None:
2520
+ date = whenever.Date(2000, 1, 1)
2521
+ sr = DataFrame(
2522
+ data=[
2523
+ (
2524
+ date.at(whenever.Time(s)).py_datetime(),
2525
+ date.at(whenever.Time(e)).py_datetime(),
2526
+ )
2527
+ for s, e in [(9, 10), (10, 11), (11, 12), (13, 14), (15, 16)]
2528
+ ],
2529
+ schema={"start": DatetimeUTC, "end": DatetimeUTC},
2530
+ orient="row",
2531
+ ).with_columns(datetime=struct("start", "end"))["datetime"]
2532
+ assert len(sr) == 5
2533
+ date_time = date.at(time).assume_tz(UTC.key)
2534
+ match start_or_end:
2535
+ case "start":
2536
+ expected = exp_start
2537
+ case "end":
2538
+ expected = exp_end
2539
+ case never:
2540
+ assert_never(never)
2541
+ index = search_period(sr, date_time, start_or_end=start_or_end)
2542
+ if expected is None:
2543
+ assert index is None
2544
+ else:
2545
+ assert index is not None
2546
+ assert 0 <= index <= (len(sr) - 1)
2547
+ start, end = map(
2548
+ to_zoned_date_time, cast("Iterable[dt.datetime]", sr[index].values())
2549
+ )
2550
+ match start_or_end:
2551
+ case "start":
2552
+ assert start <= date_time < end
2553
+ case "end":
2554
+ assert start < date_time <= end
2555
+ case never:
2556
+ assert_never(never)
2557
+ if index > 0:
2558
+ prev_end = to_zoned_date_time(cast("dt.datetime", sr[index - 1]["end"]))
2559
+ assert prev_end <= date_time
2560
+ if index < (len(sr) - 1):
2561
+ next_start = to_zoned_date_time(
2562
+ cast("dt.datetime", sr[index + 1]["start"])
2563
+ )
2564
+ assert date_time <= next_start
2565
+
2566
+
2477
2567
  class TestSelectExact:
2478
2568
  df: ClassVar[DataFrame] = DataFrame(
2479
2569
  data=[(True, False), (False, None), (None, True)],
@@ -10,9 +10,11 @@ from typing import (
10
10
  TYPE_CHECKING,
11
11
  Any,
12
12
  Final,
13
+ ForwardRef,
13
14
  Literal,
14
15
  NamedTuple,
15
- TypedDict,
16
+ NotRequired,
17
+ _TypedDictMeta, # pyright: ignore[reportAttributeAccessIssue]
16
18
  assert_never,
17
19
  )
18
20
  from uuid import UUID
@@ -50,6 +52,8 @@ from tests.test_typing_funcs.no_future import (
50
52
  DataClassNoFutureNestedInnerFirstOuter,
51
53
  DataClassNoFutureNestedOuterFirstInner,
52
54
  DataClassNoFutureNestedOuterFirstOuter,
55
+ TypedDictNoFutureIntFloat,
56
+ TypedDictNoFutureIntFloatOptional,
53
57
  )
54
58
  from tests.test_typing_funcs.with_future import (
55
59
  DataClassFutureDate,
@@ -80,10 +84,11 @@ from tests.test_typing_funcs.with_future import (
80
84
  TrueOrFalseFutureLit,
81
85
  TrueOrFalseFutureTypeLit,
82
86
  TypedDictFutureIntFloat,
87
+ TypedDictFutureIntFloatOptional,
83
88
  )
84
89
  from utilities.hypothesis import text_ascii
85
90
  from utilities.sentinel import Sentinel
86
- from utilities.types import LogLevel, Number, Parallelism, Seed
91
+ from utilities.types import LogLevel, Number, Parallelism, Seed, StrMapping
87
92
  from utilities.typing import (
88
93
  IsInstanceGenError,
89
94
  IsSubclassGenError,
@@ -92,6 +97,7 @@ from utilities.typing import (
92
97
  _GetUnionTypeClassesInternalTypeError,
93
98
  _GetUnionTypeClassesUnionTypeError,
94
99
  get_args,
100
+ get_forward_ref_args,
95
101
  get_literal_elements,
96
102
  get_type_classes,
97
103
  get_type_hints,
@@ -107,6 +113,8 @@ from utilities.typing import (
107
113
  is_mapping_type,
108
114
  is_namedtuple_class,
109
115
  is_namedtuple_instance,
116
+ is_not_required_annotation,
117
+ is_not_required_type,
110
118
  is_optional_type,
111
119
  is_sequence_of,
112
120
  is_sequence_of_tuple_or_str_mapping,
@@ -158,6 +166,13 @@ class TestGetArgs:
158
166
  assert result == expected
159
167
 
160
168
 
169
+ class TestGetForwardRefArgs:
170
+ def test_main(self) -> None:
171
+ args = get_forward_ref_args(TypedDictFutureIntFloat)
172
+ expected = {"int_": "int", "float_": "float"}
173
+ assert args == expected
174
+
175
+
161
176
  type _PlusOrMinusOneLit = Literal[1, -1]
162
177
  type _TruthLit = Literal["true", "false"]
163
178
  type _True = Literal["true"]
@@ -495,13 +510,23 @@ class TestGetTypeHints:
495
510
  expected = {"truth": TrueOrFalseFutureTypeLit}
496
511
  assert hints == expected
497
512
 
498
- def test_typed_dict(self) -> None:
499
- class Example(TypedDict):
500
- int_: int
501
- float_: float
502
-
503
- hints = get_type_hints(Example)
504
- expected = {"int_": int, "float_": float}
513
+ @mark.parametrize(
514
+ ("obj", "expected"),
515
+ [
516
+ param(TypedDictNoFutureIntFloat, {"int_": int, "float_": float}),
517
+ param(TypedDictFutureIntFloat, {"int_": int, "float_": float}),
518
+ param(
519
+ TypedDictNoFutureIntFloatOptional,
520
+ {"int_": int, "float_": NotRequired[float]},
521
+ ),
522
+ param(
523
+ TypedDictFutureIntFloatOptional,
524
+ {"int_": int, "float_": NotRequired[float]},
525
+ ),
526
+ ],
527
+ )
528
+ def test_typed_dict(self, *, obj: _TypedDictMeta, expected: StrMapping) -> None:
529
+ hints = get_type_hints(obj)
505
530
  assert hints == expected
506
531
 
507
532
  @given(data=data())
@@ -637,6 +662,8 @@ class TestIsAnnotationOfType:
637
662
  param(is_mapping_type, list[int], False),
638
663
  param(is_mapping_type, set[int], False),
639
664
  param(is_mapping_type, tuple[int, int], False),
665
+ param(is_not_required_type, NotRequired, True),
666
+ param(is_not_required_type, NotRequired[int], True),
640
667
  param(is_optional_type, Literal["a", "b", "c"] | None, True),
641
668
  param(is_optional_type, Literal["a", "b", "c"], False),
642
669
  param(is_optional_type, int | None, True),
@@ -824,8 +851,39 @@ class TestIsInstanceGen:
824
851
  param({"int_": 0, "float_": 0.0, "extra": None}, True),
825
852
  ],
826
853
  )
827
- def test_typed_dict(self, *, obj: Any, expected: bool) -> None:
828
- result = is_instance_gen(obj, TypedDictFutureIntFloat)
854
+ @mark.parametrize(
855
+ "cls", [param(TypedDictNoFutureIntFloat), param(TypedDictFutureIntFloat)]
856
+ )
857
+ def test_typed_dict(self, *, obj: Any, cls: _TypedDictMeta, expected: bool) -> None:
858
+ result = is_instance_gen(obj, cls)
859
+ assert result is expected
860
+
861
+ @mark.parametrize(
862
+ ("obj", "expected"),
863
+ [
864
+ param(None, False),
865
+ param({}, False),
866
+ param({None: False}, False),
867
+ param({"int_": None}, False),
868
+ param({"int_": 0}, True),
869
+ param({"int_": None, "float_": None}, False),
870
+ param({"int_": 0, "float_": None}, True),
871
+ param({"int_": None, "float_": 0.0}, False),
872
+ param({"int_": 0, "float_": 0.0}, True),
873
+ param({"int_": 0, "float_": 0.0, "extra": None}, True),
874
+ ],
875
+ )
876
+ @mark.parametrize(
877
+ "cls",
878
+ [
879
+ param(TypedDictNoFutureIntFloatOptional),
880
+ param(TypedDictFutureIntFloatOptional),
881
+ ],
882
+ )
883
+ def test_typed_dict_optional(
884
+ self, *, obj: Any, cls: _TypedDictMeta, expected: bool
885
+ ) -> None:
886
+ result = is_instance_gen(obj, cls)
829
887
  assert result is expected
830
888
 
831
889
  def test_error(self) -> None:
@@ -884,6 +942,27 @@ class TestIsNamedTuple:
884
942
  assert not is_namedtuple_instance(Example(x=0))
885
943
 
886
944
 
945
+ class TestIsNotRequiredAnnotation:
946
+ @mark.parametrize(
947
+ ("obj", "expected"),
948
+ [
949
+ param(NotRequired, True),
950
+ param(NotRequired[int], True),
951
+ param(int, False),
952
+ param("NotRequired", True),
953
+ param("NotRequired[int]", True),
954
+ param("int", False),
955
+ param(ForwardRef("NotRequired"), True),
956
+ param(ForwardRef("NotRequired[int]"), True),
957
+ param(ForwardRef("int"), False),
958
+ param(None, False),
959
+ ],
960
+ )
961
+ def test_main(self, *, obj: Any, expected: bool) -> None:
962
+ result = is_not_required_annotation(obj)
963
+ assert result is expected
964
+
965
+
887
966
  class TestIsSequenceOf:
888
967
  @mark.parametrize(
889
968
  ("obj", "expected"),
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import Literal
2
+ from typing import Literal, NotRequired, TypedDict
3
3
 
4
4
  TrueOrFalseNoFutureLit = Literal["true", "false"]
5
5
  type TrueOrFalseNoFutureTypeLit = Literal["true", "false"]
@@ -33,3 +33,13 @@ class DataClassNoFutureNestedOuterFirstOuter:
33
33
  @dataclass(kw_only=True)
34
34
  class DataClassNoFutureNestedOuterFirstInner:
35
35
  int_: int
36
+
37
+
38
+ class TypedDictNoFutureIntFloat(TypedDict):
39
+ int_: int
40
+ float_: float
41
+
42
+
43
+ class TypedDictNoFutureIntFloatOptional(TypedDict):
44
+ int_: int
45
+ float_: NotRequired[float]
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import TYPE_CHECKING, Literal, TypedDict, override
4
+ from typing import TYPE_CHECKING, Literal, NotRequired, TypedDict, override
5
5
 
6
6
  if TYPE_CHECKING:
7
7
  from pathlib import Path
@@ -239,3 +239,8 @@ class DataClassFutureZonedDateTimePeriod:
239
239
  class TypedDictFutureIntFloat(TypedDict):
240
240
  int_: int
241
241
  float_: float
242
+
243
+
244
+ class TypedDictFutureIntFloatOptional(TypedDict):
245
+ int_: int
246
+ float_: NotRequired[float]
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.165.1"
3
+ __version__ = "0.165.3"
@@ -105,6 +105,7 @@ from utilities.whenever import (
105
105
  from utilities.zoneinfo import UTC, to_time_zone_name
106
106
 
107
107
  if TYPE_CHECKING:
108
+ import datetime as dt
108
109
  from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
109
110
  from collections.abc import Set as AbstractSet
110
111
 
@@ -2460,6 +2461,34 @@ class RoundToFloatError(Exception):
2460
2461
  ##
2461
2462
 
2462
2463
 
2464
+ def search_period(
2465
+ series: Series,
2466
+ date_time: ZonedDateTime,
2467
+ /,
2468
+ *,
2469
+ start_or_end: Literal["start", "end"] = "end",
2470
+ ) -> int | None:
2471
+ """Search a series of periods for the one containing a given date-time."""
2472
+ start, end = [series.struct[k] for k in ["start", "end"]]
2473
+ py_date_time = date_time.py_datetime()
2474
+ match start_or_end:
2475
+ case "start":
2476
+ index = end.search_sorted(py_date_time, side="right")
2477
+ if index >= len(series):
2478
+ return None
2479
+ item: dt.datetime = series[index]["start"]
2480
+ return index if py_date_time >= item else None
2481
+ case "end":
2482
+ index = end.search_sorted(py_date_time, side="left")
2483
+ if index >= len(series):
2484
+ return None
2485
+ item: dt.datetime = series[index]["start"]
2486
+ return index if py_date_time > item else None
2487
+
2488
+
2489
+ ##
2490
+
2491
+
2463
2492
  def select_exact(
2464
2493
  df: DataFrame, /, *columns: IntoExprColumn, drop: MaybeIterable[str] | None = None
2465
2494
  ) -> DataFrame:
@@ -2750,6 +2779,7 @@ __all__ = [
2750
2779
  "read_series",
2751
2780
  "replace_time_zone",
2752
2781
  "round_to_float",
2782
+ "search_period",
2753
2783
  "select_exact",
2754
2784
  "serialize_dataframe",
2755
2785
  "set_first_row_as_columns",
@@ -6,12 +6,14 @@ from dataclasses import dataclass, is_dataclass
6
6
  from functools import partial
7
7
  from itertools import chain
8
8
  from pathlib import Path
9
+ from re import search
9
10
  from types import NoneType, UnionType
10
11
  from typing import (
11
12
  Any,
12
13
  ForwardRef,
13
14
  Literal,
14
15
  NamedTuple,
16
+ NotRequired,
15
17
  Optional, # pyright: ignore[reportDeprecated]
16
18
  TypeAliasType,
17
19
  TypeGuard,
@@ -56,6 +58,18 @@ def get_args(obj: Any, /, *, optional_drop_none: bool = False) -> tuple[Any, ...
56
58
  ##
57
59
 
58
60
 
61
+ def get_forward_ref_args(obj: Any, /) -> Mapping[str, str]:
62
+ """Get the forward args."""
63
+ return {
64
+ k: v.__forward_arg__
65
+ for k, v in obj.__annotations__.items()
66
+ if isinstance(v, ForwardRef)
67
+ }
68
+
69
+
70
+ ##
71
+
72
+
59
73
  def get_literal_elements(obj: Any, /) -> list[Any]:
60
74
  """Get the elements of a literal annotation."""
61
75
  return _get_literal_elements_inner(obj)
@@ -151,21 +165,20 @@ def get_type_hints(
151
165
  globalns_use = globals() | ({} if globalns is None else dict(globalns))
152
166
  localns_use = {} if localns is None else dict(localns)
153
167
  result: dict[str, Any] = obj.__annotations__
154
- result = {
155
- k: v.__forward_arg__ if isinstance(v, ForwardRef) else v
156
- for k, v in result.items()
157
- }
168
+ result = result | dict(get_forward_ref_args(obj))
158
169
  try:
159
- hints = _get_type_hints(obj, globalns=globalns_use, localns=localns_use)
170
+ hints = _get_type_hints(
171
+ obj, globalns=globalns_use, localns=localns_use, include_extras=True
172
+ )
160
173
  except NameError as error:
161
174
  if warn_name_errors:
162
175
  warn(f"Error getting type hints for {obj!r}; {error}", stacklevel=2)
163
176
  else:
164
- result.update({
177
+ result = result | {
165
178
  key: value
166
179
  for key, value in hints.items()
167
180
  if (key not in result) or isinstance(result[key], str)
168
- })
181
+ }
169
182
  return result
170
183
 
171
184
 
@@ -393,17 +406,21 @@ def _is_instance_typed_dict[T: _TypedDictMeta](
393
406
  hints = get_type_hints(
394
407
  type_, globalns=globalns, localns=localns, warn_name_errors=warn_name_errors
395
408
  )
396
- if not set(obj).issuperset(hints):
409
+ optional = {
410
+ k for k, v in type_.__annotations__.items() if is_not_required_annotation(v)
411
+ }
412
+ required = {k: v for k, v in hints.items() if k not in optional}
413
+ if not set(obj).issuperset(required):
397
414
  return False
398
415
  return all(
399
416
  is_instance_gen(
400
417
  obj[k],
401
- hints[k],
418
+ required[k],
402
419
  globalns=globalns,
403
420
  localns=localns,
404
421
  warn_name_errors=warn_name_errors,
405
422
  )
406
- for k in hints
423
+ for k in required
407
424
  )
408
425
 
409
426
 
@@ -577,6 +594,30 @@ def _is_namedtuple_core(obj: Any, /) -> bool:
577
594
  ##
578
595
 
579
596
 
597
+ def is_not_required_annotation(obj: Any) -> bool:
598
+ """Check if an annotation is not required."""
599
+ if is_not_required_type(obj):
600
+ return True
601
+ match obj:
602
+ case str() as text:
603
+ return bool(search("NotRequired", text))
604
+ case ForwardRef() as fr:
605
+ return is_not_required_annotation(fr.__forward_arg__)
606
+ case _:
607
+ return False
608
+
609
+
610
+ ##
611
+
612
+
613
+ def is_not_required_type(obj: Any, /) -> bool:
614
+ """Check if an object is a not-required type annotation."""
615
+ return (obj is NotRequired) or _is_annotation_of_type(obj, NotRequired)
616
+
617
+
618
+ ##
619
+
620
+
580
621
  def is_optional_type(obj: Any, /) -> bool:
581
622
  """Check if an object is an optional type annotation."""
582
623
  is_optional = _is_annotation_of_type(obj, Optional) # pyright: ignore[reportDeprecated]
@@ -889,6 +930,8 @@ __all__ = [
889
930
  "is_mapping_type",
890
931
  "is_namedtuple_class",
891
932
  "is_namedtuple_instance",
933
+ "is_not_required_annotation",
934
+ "is_not_required_type",
892
935
  "is_optional_type",
893
936
  "is_sequence_of",
894
937
  "is_sequence_of_tuple_or_str_mapping",