dycw-utilities 0.153.2__tar.gz → 0.153.4__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 (212) hide show
  1. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/PKG-INFO +1 -1
  2. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/pyproject.toml +3 -3
  3. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_polars.py +81 -1
  4. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/__init__.py +1 -1
  5. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/polars.py +151 -32
  6. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/.gitignore +0 -0
  7. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/LICENSE +0 -0
  8. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/README.md +0 -0
  9. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/__init__.py +0 -0
  10. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/conftest.py +0 -0
  11. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_altair.py +0 -0
  35. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_asyncio.py +0 -0
  36. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_atomicwrites.py +0 -0
  37. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_atools.py +0 -0
  38. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_cachetools.py +0 -0
  39. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_click.py +0 -0
  40. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_concurrent.py +0 -0
  41. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_contextlib.py +0 -0
  42. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_contextvars.py +0 -0
  43. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_cryptography.py +0 -0
  44. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_cvxpy.py +0 -0
  45. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_dataclasses.py +0 -0
  46. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_enum.py +0 -0
  47. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_errors.py +0 -0
  48. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_eventkit.py +0 -0
  49. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_fastapi.py +0 -0
  50. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_fpdf2.py +0 -0
  51. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_functions.py +0 -0
  52. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_functools.py +0 -0
  53. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_getpass.py +0 -0
  54. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_gzip.py +0 -0
  55. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_hashlib.py +0 -0
  56. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_http.py +0 -0
  57. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_hypothesis.py +0 -0
  58. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_importlib.py +0 -0
  59. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_inflect.py +0 -0
  60. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_ipython.py +0 -0
  61. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_iterables.py +0 -0
  62. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_json.py +0 -0
  63. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_jupyter.py +0 -0
  64. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_libcst.py +0 -0
  65. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_lightweight_charts.py +0 -0
  66. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_logging.py +0 -0
  67. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_math.py +0 -0
  68. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_memory_profiler.py +0 -0
  69. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_modules.py +0 -0
  70. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_more_itertools.py +0 -0
  71. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_numpy.py +0 -0
  72. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_objects/__init__.py +0 -0
  73. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_objects/objects.py +0 -0
  74. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_operator.py +0 -0
  75. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_optuna.py +0 -0
  76. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_orjson.py +0 -0
  77. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_os.py +0 -0
  78. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_parse.py +0 -0
  79. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pathlib.py +0 -0
  80. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pickle.py +0 -0
  81. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_platform.py +0 -0
  82. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_polars_ols.py +0 -0
  83. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_postgres.py +0 -0
  84. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pottery.py +0 -0
  85. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pqdm.py +0 -0
  86. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_psutil.py +0 -0
  87. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pyinstrument.py +0 -0
  88. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pytest.py +0 -0
  89. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pytest_randomly.py +0 -0
  90. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_pytest_regressions.py +0 -0
  91. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_random.py +0 -0
  92. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_re.py +0 -0
  93. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_redis.py +0 -0
  94. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_reprlib.py +0 -0
  95. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_scipy.py +0 -0
  96. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_sentinel.py +0 -0
  97. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_shelve.py +0 -0
  98. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_slack_sdk.py +0 -0
  99. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_socket.py +0 -0
  100. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_sqlalchemy.py +0 -0
  101. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_sqlalchemy_polars.py +0 -0
  102. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_statsmodels.py +0 -0
  103. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_string.py +0 -0
  104. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_tempfile.py +0 -0
  105. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_text.py +0 -0
  106. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_threading.py +0 -0
  107. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_timer.py +0 -0
  108. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_traceback.py +0 -0
  109. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_typed_settings.py +0 -0
  110. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_types.py +0 -0
  111. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_typing.py +0 -0
  112. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_typing_funcs/__init__.py +0 -0
  113. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_typing_funcs/no_future.py +0 -0
  114. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_typing_funcs/with_future.py +0 -0
  115. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_tzdata.py +0 -0
  116. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_tzlocal.py +0 -0
  117. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_uuid.py +0 -0
  118. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_version.py +0 -0
  119. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_warnings.py +0 -0
  120. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_whenever.py +0 -0
  121. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_yield_access/__init__.py +0 -0
  122. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_yield_access/script.py +0 -0
  123. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_yield_access/script.sh +0 -0
  124. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_zipfile.py +0 -0
  125. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/tests/test_zoneinfo.py +0 -0
  126. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/altair.py +0 -0
  127. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/asyncio.py +0 -0
  128. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/atomicwrites.py +0 -0
  129. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/atools.py +0 -0
  130. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/cachetools.py +0 -0
  131. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/click.py +0 -0
  132. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/concurrent.py +0 -0
  133. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/contextlib.py +0 -0
  134. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/contextvars.py +0 -0
  135. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/cryptography.py +0 -0
  136. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/cvxpy.py +0 -0
  137. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/dataclasses.py +0 -0
  138. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/enum.py +0 -0
  139. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/errors.py +0 -0
  140. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/eventkit.py +0 -0
  141. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/fastapi.py +0 -0
  142. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/fpdf2.py +0 -0
  143. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/functions.py +0 -0
  144. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/functools.py +0 -0
  145. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/getpass.py +0 -0
  146. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/gzip.py +0 -0
  147. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/hashlib.py +0 -0
  148. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/http.py +0 -0
  149. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/hypothesis.py +0 -0
  150. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/importlib.py +0 -0
  151. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/inflect.py +0 -0
  152. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/ipython.py +0 -0
  153. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/iterables.py +0 -0
  154. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/json.py +0 -0
  155. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/jupyter.py +0 -0
  156. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/libcst.py +0 -0
  157. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/lightweight_charts.py +0 -0
  158. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/logging.py +0 -0
  159. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/math.py +0 -0
  160. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/memory_profiler.py +0 -0
  161. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/modules.py +0 -0
  162. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/more_itertools.py +0 -0
  163. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/numpy.py +0 -0
  164. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/operator.py +0 -0
  165. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/optuna.py +0 -0
  166. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/orjson.py +0 -0
  167. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/os.py +0 -0
  168. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/parse.py +0 -0
  169. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pathlib.py +0 -0
  170. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pickle.py +0 -0
  171. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/platform.py +0 -0
  172. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/polars_ols.py +0 -0
  173. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/postgres.py +0 -0
  174. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pottery.py +0 -0
  175. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pqdm.py +0 -0
  176. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/psutil.py +0 -0
  177. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/py.typed +0 -0
  178. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pyinstrument.py +0 -0
  179. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pytest.py +0 -0
  180. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pytest_plugins/__init__.py +0 -0
  181. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  182. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  183. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/pytest_regressions.py +0 -0
  184. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/random.py +0 -0
  185. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/re.py +0 -0
  186. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/redis.py +0 -0
  187. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/reprlib.py +0 -0
  188. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/scipy.py +0 -0
  189. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/sentinel.py +0 -0
  190. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/shelve.py +0 -0
  191. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/slack_sdk.py +0 -0
  192. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/socket.py +0 -0
  193. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/sqlalchemy.py +0 -0
  194. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/sqlalchemy_polars.py +0 -0
  195. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/statsmodels.py +0 -0
  196. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/string.py +0 -0
  197. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/tempfile.py +0 -0
  198. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/text.py +0 -0
  199. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/threading.py +0 -0
  200. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/timer.py +0 -0
  201. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/traceback.py +0 -0
  202. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/typed_settings.py +0 -0
  203. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/types.py +0 -0
  204. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/typing.py +0 -0
  205. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/tzdata.py +0 -0
  206. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/tzlocal.py +0 -0
  207. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/uuid.py +0 -0
  208. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/version.py +0 -0
  209. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/warnings.py +0 -0
  210. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/whenever.py +0 -0
  211. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/zipfile.py +0 -0
  212. {dycw_utilities-0.153.2 → dycw_utilities-0.153.4}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.153.2
3
+ Version: 0.153.4
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -190,7 +190,7 @@ slack-sdk-test = [
190
190
  "aiohttp",
191
191
  ]
192
192
  sqlalchemy = [
193
- "sqlalchemy >=2.0.41, <2.1",
193
+ "sqlalchemy >=2.0.42, <2.1",
194
194
  "psycopg",
195
195
  ]
196
196
  sqlalchemy-polars = [
@@ -229,7 +229,7 @@ dependencies = [
229
229
  name = "dycw-utilities"
230
230
  readme = "README.md"
231
231
  requires-python = ">= 3.12"
232
- version = "0.153.2"
232
+ version = "0.153.4"
233
233
 
234
234
  [project.entry-points.pytest11]
235
235
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -262,7 +262,7 @@ test = [
262
262
  # bump-my-version
263
263
  [tool.bumpversion]
264
264
  allow_dirty = true
265
- current_version = "0.153.2"
265
+ current_version = "0.153.4"
266
266
 
267
267
  [[tool.bumpversion.files]]
268
268
  filename = "src/utilities/__init__.py"
@@ -58,7 +58,7 @@ from polars.exceptions import ComputeError
58
58
  from polars.schema import Schema
59
59
  from polars.testing import assert_frame_equal, assert_series_equal
60
60
  from pytest import mark, param, raises
61
- from whenever import TimeZoneNotFoundError
61
+ from whenever import Time, TimeZoneNotFoundError, ZonedDateTime
62
62
 
63
63
  import utilities.polars
64
64
  from utilities.hypothesis import (
@@ -84,6 +84,7 @@ from utilities.polars import (
84
84
  DatetimeUSEastern,
85
85
  DatetimeUTC,
86
86
  DropNullStructSeriesError,
87
+ ExprOrSeries,
87
88
  FiniteEWMMeanError,
88
89
  InsertAfterError,
89
90
  InsertBeforeError,
@@ -132,6 +133,10 @@ from utilities.polars import (
132
133
  ac_halflife,
133
134
  acf,
134
135
  adjust_frequencies,
136
+ all_dataframe_columns,
137
+ all_series,
138
+ any_dataframe_columns,
139
+ any_series,
135
140
  append_dataclass,
136
141
  are_frames_equal,
137
142
  bernoulli,
@@ -173,7 +178,9 @@ from utilities.polars import (
173
178
  nan_sum_agg,
174
179
  nan_sum_cols,
175
180
  normal,
181
+ offset_datetime,
176
182
  order_of_magnitude,
183
+ period_range,
177
184
  read_dataframe,
178
185
  read_series,
179
186
  reify_exprs,
@@ -203,6 +210,7 @@ if TYPE_CHECKING:
203
210
  from collections.abc import Callable, Iterable, Mapping, Sequence
204
211
  from zoneinfo import ZoneInfo
205
212
 
213
+ from _pytest.mark import ParameterSet
206
214
  from polars._typing import IntoExprColumn, PolarsDataType, SchemaDict
207
215
  from polars.datatypes import DataTypeClass
208
216
 
@@ -279,6 +287,56 @@ class TestAdjustFrequencies:
279
287
  assert isinstance(result, Series)
280
288
 
281
289
 
290
+ class TestAnyAllDataFrameColumnsSeries:
291
+ cases: ClassVar[list[ParameterSet]] = [
292
+ param(int_range(end=pl.len()) % 2 == 0),
293
+ param(int_range(end=4, eager=True) % 2 == 0),
294
+ ]
295
+ series: ClassVar[Series] = Series(
296
+ name="x", values=[True, True, False, False], dtype=Boolean
297
+ )
298
+ df: ClassVar[DataFrame] = series.to_frame()
299
+ exp_all: ClassVar[Series] = Series(
300
+ name="x", values=[True, False, False, False], dtype=Boolean
301
+ )
302
+ exp_any: ClassVar[Series] = Series(
303
+ name="x", values=[True, True, True, False], dtype=Boolean
304
+ )
305
+ exp_empty: ClassVar[Series] = Series(
306
+ name="x", values=[True, False, True, False], dtype=Boolean
307
+ )
308
+
309
+ @mark.parametrize("column", cases)
310
+ def test_df_all(self, *, column: ExprOrSeries) -> None:
311
+ result = all_dataframe_columns(self.df, "x", column)
312
+ assert_series_equal(result, self.exp_all)
313
+
314
+ @mark.parametrize("column", cases)
315
+ def test_df_any(self, *, column: ExprOrSeries) -> None:
316
+ result = any_dataframe_columns(self.df, "x", column)
317
+ assert_series_equal(result, self.exp_any)
318
+
319
+ @mark.parametrize("column", cases)
320
+ def test_df_all_empty(self, *, column: ExprOrSeries) -> None:
321
+ result = all_dataframe_columns(self.df, column.alias("x"))
322
+ assert_series_equal(result, self.exp_empty)
323
+
324
+ @mark.parametrize("column", cases)
325
+ def test_df_any_empty(self, *, column: ExprOrSeries) -> None:
326
+ result = any_dataframe_columns(self.df, column.alias("x"))
327
+ assert_series_equal(result, self.exp_empty)
328
+
329
+ @mark.parametrize("column", cases)
330
+ def test_series_all(self, *, column: ExprOrSeries) -> None:
331
+ result = all_series(self.series, column)
332
+ assert_series_equal(result, self.exp_all)
333
+
334
+ @mark.parametrize("column", cases)
335
+ def test_series_any_any_any(self, *, column: ExprOrSeries) -> None:
336
+ result = any_series(self.series, column)
337
+ assert_series_equal(result, self.exp_any)
338
+
339
+
282
340
  class TestAppendDataClass:
283
341
  @given(
284
342
  data=fixed_dictionaries({
@@ -2205,6 +2263,15 @@ class TestNormal:
2205
2263
  assert series.is_finite().all()
2206
2264
 
2207
2265
 
2266
+ class TestOffsetDateTime:
2267
+ @mark.parametrize(("n", "time"), [param(1, Time(13, 30)), param(2, Time(15))])
2268
+ def test_main(self, *, n: int, time: Time) -> None:
2269
+ datetime = ZonedDateTime(2000, 1, 1, 12, tz=UTC.key)
2270
+ result = offset_datetime(datetime, "1h30m", n=n)
2271
+ expected = datetime.replace_time(time)
2272
+ assert result == expected
2273
+
2274
+
2208
2275
  class TestOrderOfMagnitude:
2209
2276
  @given(
2210
2277
  sign=sampled_from([1, -1]),
@@ -2231,6 +2298,19 @@ class TestOrderOfMagnitude:
2231
2298
  assert (res_int == exp_int).all()
2232
2299
 
2233
2300
 
2301
+ class TestPeriodRange:
2302
+ start: ClassVar[ZonedDateTime] = ZonedDateTime(2000, 1, 1, 12, tz=UTC.key)
2303
+ end: ClassVar[ZonedDateTime] = ZonedDateTime(2000, 1, 1, 15, tz=UTC.key)
2304
+
2305
+ @mark.parametrize("end_or_length", [param(end), param(3)])
2306
+ def test_main(self, *, end_or_length: ZonedDateTime | int) -> None:
2307
+ rng = period_range(self.start, end_or_length, interval="1h", eager=True)
2308
+ assert len(rng) == 3
2309
+ assert rng.dtype == zoned_datetime_period_dtype()
2310
+ assert rng[0]["start"] == self.start.py_datetime()
2311
+ assert rng[-1]["end"] == self.end.py_datetime()
2312
+
2313
+
2234
2314
  class TestReifyExprs:
2235
2315
  @given(length=hypothesis.strategies.integers(0, 10), name=text_ascii())
2236
2316
  def test_one_expr(self, *, length: int, name: str) -> None:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.153.2"
3
+ __version__ = "0.153.4"
@@ -33,6 +33,7 @@ from polars import (
33
33
  any_horizontal,
34
34
  col,
35
35
  concat,
36
+ datetime_range,
36
37
  int_range,
37
38
  lit,
38
39
  struct,
@@ -49,6 +50,7 @@ from polars.exceptions import (
49
50
  )
50
51
  from polars.schema import Schema
51
52
  from polars.testing import assert_frame_equal, assert_series_equal
53
+ from whenever import ZonedDateTime
52
54
 
53
55
  from utilities.dataclasses import _YieldFieldsInstance, yield_fields
54
56
  from utilities.errors import ImpossibleCaseError
@@ -122,6 +124,7 @@ if TYPE_CHECKING:
122
124
 
123
125
 
124
126
  type ExprLike = MaybeStr[Expr]
127
+ type ExprOrSeries = Expr | Series
125
128
  DatetimeHongKong = Datetime(time_zone="Asia/Hong_Kong")
126
129
  DatetimeTokyo = Datetime(time_zone="Asia/Tokyo")
127
130
  DatetimeUSCentral = Datetime(time_zone="US/Central")
@@ -129,6 +132,7 @@ DatetimeUSEastern = Datetime(time_zone="US/Eastern")
129
132
  DatetimeUTC = Datetime(time_zone="UTC")
130
133
  _FINITE_EWM_MIN_WEIGHT = 0.9999
131
134
 
135
+
132
136
  ##
133
137
 
134
138
 
@@ -238,11 +242,6 @@ def _acf_process_qstats_pvalues(qstats: NDArrayF, pvalues: NDArrayF, /) -> DataF
238
242
  ##
239
243
 
240
244
 
241
- # def acf_halflife(series: Series,/)
242
-
243
- ##
244
-
245
-
246
245
  def adjust_frequencies(
247
246
  series: Series,
248
247
  /,
@@ -264,6 +263,37 @@ def adjust_frequencies(
264
263
  ##
265
264
 
266
265
 
266
+ def all_dataframe_columns(
267
+ df: DataFrame, expr: IntoExprColumn, /, *exprs: IntoExprColumn
268
+ ) -> Series:
269
+ """Return a DataFrame column with `AND` applied to additional exprs/series."""
270
+ name = get_expr_name(df, expr)
271
+ return df.select(all_horizontal(expr, *exprs).alias(name))[name]
272
+
273
+
274
+ def any_dataframe_columns(
275
+ df: DataFrame, expr: IntoExprColumn, /, *exprs: IntoExprColumn
276
+ ) -> Series:
277
+ """Return a DataFrame column with `OR` applied to additional exprs/series."""
278
+ name = get_expr_name(df, expr)
279
+ return df.select(any_horizontal(expr, *exprs).alias(name))[name]
280
+
281
+
282
+ def all_series(series: Series, /, *columns: ExprOrSeries) -> Series:
283
+ """Return a Series with `AND` applied to additional exprs/series."""
284
+ return all_dataframe_columns(series.to_frame(), series.name, *columns)
285
+
286
+
287
+ def any_series(series: Series, /, *columns: ExprOrSeries) -> Series:
288
+ """Return a Series with `OR` applied to additional exprs/series."""
289
+ df = series.to_frame()
290
+ name = series.name
291
+ return df.select(any_horizontal(name, *columns).alias(name))[name]
292
+
293
+
294
+ ##
295
+
296
+
267
297
  def append_dataclass(df: DataFrame, obj: Dataclass, /) -> DataFrame:
268
298
  """Append a dataclass object to a DataFrame."""
269
299
  non_null_fields = {k: v for k, v in asdict(obj).items() if v is not None}
@@ -427,8 +457,8 @@ def ceil_datetime(column: ExprLike, every: ExprLike, /) -> Expr: ...
427
457
  @overload
428
458
  def ceil_datetime(column: Series, every: ExprLike, /) -> Series: ...
429
459
  @overload
430
- def ceil_datetime(column: IntoExprColumn, every: ExprLike, /) -> Expr | Series: ...
431
- def ceil_datetime(column: IntoExprColumn, every: ExprLike, /) -> Expr | Series:
460
+ def ceil_datetime(column: IntoExprColumn, every: ExprLike, /) -> ExprOrSeries: ...
461
+ def ceil_datetime(column: IntoExprColumn, every: ExprLike, /) -> ExprOrSeries:
432
462
  """Compute the `ceil` of a datetime column."""
433
463
  column = ensure_expr_or_series(column)
434
464
  rounded = column.dt.round(every)
@@ -849,13 +879,13 @@ def cross(
849
879
  up_or_down: Literal["up", "down"],
850
880
  other: Number | IntoExprColumn,
851
881
  /,
852
- ) -> Expr | Series: ...
882
+ ) -> ExprOrSeries: ...
853
883
  def cross(
854
884
  expr: IntoExprColumn,
855
885
  up_or_down: Literal["up", "down"],
856
886
  other: Number | IntoExprColumn,
857
887
  /,
858
- ) -> Expr | Series:
888
+ ) -> ExprOrSeries:
859
889
  """Compute when a cross occurs."""
860
890
  return _cross_or_touch(expr, "cross", up_or_down, other)
861
891
 
@@ -874,13 +904,13 @@ def touch(
874
904
  up_or_down: Literal["up", "down"],
875
905
  other: Number | IntoExprColumn,
876
906
  /,
877
- ) -> Expr | Series: ...
907
+ ) -> ExprOrSeries: ...
878
908
  def touch(
879
909
  expr: IntoExprColumn,
880
910
  up_or_down: Literal["up", "down"],
881
911
  other: Number | IntoExprColumn,
882
912
  /,
883
- ) -> Expr | Series:
913
+ ) -> ExprOrSeries:
884
914
  """Compute when a touch occurs."""
885
915
  return _cross_or_touch(expr, "touch", up_or_down, other)
886
916
 
@@ -891,7 +921,7 @@ def _cross_or_touch(
891
921
  up_or_down: Literal["up", "down"],
892
922
  other: Number | IntoExprColumn,
893
923
  /,
894
- ) -> Expr | Series:
924
+ ) -> ExprOrSeries:
895
925
  """Compute when a column crosses/touches a threshold."""
896
926
  expr = ensure_expr_or_series(expr)
897
927
  match other:
@@ -963,7 +993,7 @@ def cross_rolling_quantile(
963
993
  weights: list[float] | None = None,
964
994
  min_samples: int | None = None,
965
995
  center: bool = False,
966
- ) -> Expr | Series: ...
996
+ ) -> ExprOrSeries: ...
967
997
  def cross_rolling_quantile(
968
998
  expr: IntoExprColumn,
969
999
  up_or_down: Literal["up", "down"],
@@ -975,7 +1005,7 @@ def cross_rolling_quantile(
975
1005
  weights: list[float] | None = None,
976
1006
  min_samples: int | None = None,
977
1007
  center: bool = False,
978
- ) -> Expr | Series:
1008
+ ) -> ExprOrSeries:
979
1009
  """Compute when a column crosses its rolling quantile."""
980
1010
  expr = ensure_expr_or_series(expr)
981
1011
  rolling = expr.rolling_quantile(
@@ -1180,8 +1210,8 @@ def ensure_expr_or_series(column: ExprLike, /) -> Expr: ...
1180
1210
  @overload
1181
1211
  def ensure_expr_or_series(column: Series, /) -> Series: ...
1182
1212
  @overload
1183
- def ensure_expr_or_series(column: IntoExprColumn, /) -> Expr | Series: ...
1184
- def ensure_expr_or_series(column: IntoExprColumn, /) -> Expr | Series:
1213
+ def ensure_expr_or_series(column: IntoExprColumn, /) -> ExprOrSeries: ...
1214
+ def ensure_expr_or_series(column: IntoExprColumn, /) -> ExprOrSeries:
1185
1215
  """Ensure a column expression or Series is returned."""
1186
1216
  return col(column) if isinstance(column, str) else column
1187
1217
 
@@ -1191,7 +1221,7 @@ def ensure_expr_or_series(column: IntoExprColumn, /) -> Expr | Series:
1191
1221
 
1192
1222
  def ensure_expr_or_series_many(
1193
1223
  *columns: IntoExprColumn, **named_columns: IntoExprColumn
1194
- ) -> Sequence[Expr | Series]:
1224
+ ) -> Sequence[ExprOrSeries]:
1195
1225
  """Ensure a set of column expressions and/or Series are returned."""
1196
1226
  args = map(ensure_expr_or_series, columns)
1197
1227
  kwargs = (ensure_expr_or_series(v).alias(k) for k, v in named_columns.items())
@@ -1233,7 +1263,7 @@ def finite_ewm_mean(
1233
1263
  half_life: float | None = None,
1234
1264
  alpha: float | None = None,
1235
1265
  min_weight: float = _FINITE_EWM_MIN_WEIGHT,
1236
- ) -> Expr | Series: ...
1266
+ ) -> ExprOrSeries: ...
1237
1267
  def finite_ewm_mean(
1238
1268
  column: IntoExprColumn,
1239
1269
  /,
@@ -1243,7 +1273,7 @@ def finite_ewm_mean(
1243
1273
  half_life: float | None = None,
1244
1274
  alpha: float | None = None,
1245
1275
  min_weight: float = _FINITE_EWM_MIN_WEIGHT,
1246
- ) -> Expr | Series:
1276
+ ) -> ExprOrSeries:
1247
1277
  """Compute a finite EWMA."""
1248
1278
  try:
1249
1279
  weights = _finite_ewm_weights(
@@ -1309,8 +1339,8 @@ def floor_datetime(column: ExprLike, every: ExprLike, /) -> Expr: ...
1309
1339
  @overload
1310
1340
  def floor_datetime(column: Series, every: ExprLike, /) -> Series: ...
1311
1341
  @overload
1312
- def floor_datetime(column: IntoExprColumn, every: ExprLike, /) -> Expr | Series: ...
1313
- def floor_datetime(column: IntoExprColumn, every: ExprLike, /) -> Expr | Series:
1342
+ def floor_datetime(column: IntoExprColumn, every: ExprLike, /) -> ExprOrSeries: ...
1343
+ def floor_datetime(column: IntoExprColumn, every: ExprLike, /) -> ExprOrSeries:
1314
1344
  """Compute the `floor` of a datetime column."""
1315
1345
  column = ensure_expr_or_series(column)
1316
1346
  rounded = column.dt.round(every)
@@ -1476,8 +1506,8 @@ def increasing_horizontal(*columns: ExprLike) -> Expr: ...
1476
1506
  @overload
1477
1507
  def increasing_horizontal(*columns: Series) -> Series: ...
1478
1508
  @overload
1479
- def increasing_horizontal(*columns: IntoExprColumn) -> Expr | Series: ...
1480
- def increasing_horizontal(*columns: IntoExprColumn) -> Expr | Series:
1509
+ def increasing_horizontal(*columns: IntoExprColumn) -> ExprOrSeries: ...
1510
+ def increasing_horizontal(*columns: IntoExprColumn) -> ExprOrSeries:
1481
1511
  """Check if a set of columns are increasing."""
1482
1512
  columns2 = ensure_expr_or_series_many(*columns)
1483
1513
  if len(columns2) == 0:
@@ -1490,8 +1520,8 @@ def decreasing_horizontal(*columns: ExprLike) -> Expr: ...
1490
1520
  @overload
1491
1521
  def decreasing_horizontal(*columns: Series) -> Series: ...
1492
1522
  @overload
1493
- def decreasing_horizontal(*columns: IntoExprColumn) -> Expr | Series: ...
1494
- def decreasing_horizontal(*columns: IntoExprColumn) -> Expr | Series:
1523
+ def decreasing_horizontal(*columns: IntoExprColumn) -> ExprOrSeries: ...
1524
+ def decreasing_horizontal(*columns: IntoExprColumn) -> ExprOrSeries:
1495
1525
  """Check if a set of columns are decreasing."""
1496
1526
  columns2 = ensure_expr_or_series_many(*columns)
1497
1527
  if len(columns2) == 0:
@@ -1650,13 +1680,13 @@ def is_near_event(
1650
1680
  before: int = 0,
1651
1681
  after: int = 0,
1652
1682
  **named_exprs: IntoExprColumn,
1653
- ) -> Expr | Series: ...
1683
+ ) -> ExprOrSeries: ...
1654
1684
  def is_near_event(
1655
1685
  *exprs: IntoExprColumn,
1656
1686
  before: int = 0,
1657
1687
  after: int = 0,
1658
1688
  **named_exprs: IntoExprColumn,
1659
- ) -> Expr | Series:
1689
+ ) -> ExprOrSeries:
1660
1690
  """Compute the rows near any event."""
1661
1691
  if before <= -1:
1662
1692
  raise _IsNearEventBeforeError(before=before)
@@ -2021,6 +2051,19 @@ def normal(
2021
2051
  ##
2022
2052
 
2023
2053
 
2054
+ def offset_datetime(
2055
+ datetime: ZonedDateTime, offset: str, /, *, n: int = 1
2056
+ ) -> ZonedDateTime:
2057
+ """Offset a datetime as `polars` would."""
2058
+ sr = Series(values=[datetime.py_datetime()])
2059
+ for _ in range(n):
2060
+ sr = sr.dt.offset_by(offset)
2061
+ return ZonedDateTime.from_py_datetime(sr.item())
2062
+
2063
+
2064
+ ##
2065
+
2066
+
2024
2067
  @overload
2025
2068
  def order_of_magnitude(column: ExprLike, /, *, round_: bool = False) -> Expr: ...
2026
2069
  @overload
@@ -2028,10 +2071,10 @@ def order_of_magnitude(column: Series, /, *, round_: bool = False) -> Series: ..
2028
2071
  @overload
2029
2072
  def order_of_magnitude(
2030
2073
  column: IntoExprColumn, /, *, round_: bool = False
2031
- ) -> Expr | Series: ...
2074
+ ) -> ExprOrSeries: ...
2032
2075
  def order_of_magnitude(
2033
2076
  column: IntoExprColumn, /, *, round_: bool = False
2034
- ) -> Expr | Series:
2077
+ ) -> ExprOrSeries:
2035
2078
  """Compute the order of magnitude of a column."""
2036
2079
  column = ensure_expr_or_series(column)
2037
2080
  result = column.abs().log10()
@@ -2041,6 +2084,75 @@ def order_of_magnitude(
2041
2084
  ##
2042
2085
 
2043
2086
 
2087
+ @overload
2088
+ def period_range(
2089
+ start: ZonedDateTime,
2090
+ end_or_length: ZonedDateTime | int,
2091
+ /,
2092
+ *,
2093
+ interval: str = "1d",
2094
+ time_unit: TimeUnit | None = None,
2095
+ time_zone: TimeZoneLike | None = None,
2096
+ eager: Literal[True],
2097
+ ) -> Series: ...
2098
+ @overload
2099
+ def period_range(
2100
+ start: ZonedDateTime,
2101
+ end_or_length: ZonedDateTime | int,
2102
+ /,
2103
+ *,
2104
+ interval: str = "1d",
2105
+ time_unit: TimeUnit | None = None,
2106
+ time_zone: TimeZoneLike | None = None,
2107
+ eager: Literal[False] = False,
2108
+ ) -> Expr: ...
2109
+ @overload
2110
+ def period_range(
2111
+ start: ZonedDateTime,
2112
+ end_or_length: ZonedDateTime | int,
2113
+ /,
2114
+ *,
2115
+ interval: str = "1d",
2116
+ time_unit: TimeUnit | None = None,
2117
+ time_zone: TimeZoneLike | None = None,
2118
+ eager: bool = False,
2119
+ ) -> Series | Expr: ...
2120
+ def period_range(
2121
+ start: ZonedDateTime,
2122
+ end_or_length: ZonedDateTime | int,
2123
+ /,
2124
+ *,
2125
+ interval: str = "1d",
2126
+ time_unit: TimeUnit | None = None,
2127
+ time_zone: TimeZoneLike | None = None,
2128
+ eager: bool = False,
2129
+ ) -> Series | Expr:
2130
+ """Construct a period range."""
2131
+ time_zone_use = None if time_zone is None else ensure_time_zone(time_zone).key
2132
+ match end_or_length:
2133
+ case ZonedDateTime() as end:
2134
+ ...
2135
+ case int() as length:
2136
+ end = offset_datetime(start, interval, n=length)
2137
+ case never:
2138
+ assert_never(never)
2139
+ starts = datetime_range(
2140
+ start.py_datetime(),
2141
+ end.py_datetime(),
2142
+ interval,
2143
+ closed="left",
2144
+ time_unit=time_unit,
2145
+ time_zone=time_zone_use,
2146
+ eager=eager,
2147
+ ).alias("start")
2148
+ ends = (starts.dt.offset_by(interval)).alias("end")
2149
+ period = struct(starts, ends)
2150
+ return try_reify_expr(period, starts, ends)
2151
+
2152
+
2153
+ ##
2154
+
2155
+
2044
2156
  def reify_exprs(
2045
2157
  *exprs: IntoExprColumn, **named_exprs: IntoExprColumn
2046
2158
  ) -> Expr | Series | DataFrame:
@@ -2363,7 +2475,7 @@ class _StructFromDataClassTypeError(StructFromDataClassError):
2363
2475
 
2364
2476
  def try_reify_expr(
2365
2477
  expr: IntoExprColumn, /, *exprs: IntoExprColumn, **named_exprs: IntoExprColumn
2366
- ) -> Expr | Series:
2478
+ ) -> ExprOrSeries:
2367
2479
  """Try reify an expression."""
2368
2480
  expr = ensure_expr_or_series(expr)
2369
2481
  all_exprs = ensure_expr_or_series_many(*exprs, **named_exprs)
@@ -2430,8 +2542,8 @@ def week_num(column: ExprLike, /, *, start: WeekDay = "mon") -> Expr: ...
2430
2542
  @overload
2431
2543
  def week_num(column: Series, /, *, start: WeekDay = "mon") -> Series: ...
2432
2544
  @overload
2433
- def week_num(column: IntoExprColumn, /, *, start: WeekDay = "mon") -> Expr | Series: ...
2434
- def week_num(column: IntoExprColumn, /, *, start: WeekDay = "mon") -> Expr | Series:
2545
+ def week_num(column: IntoExprColumn, /, *, start: WeekDay = "mon") -> ExprOrSeries: ...
2546
+ def week_num(column: IntoExprColumn, /, *, start: WeekDay = "mon") -> ExprOrSeries:
2435
2547
  """Compute the week number of a date column."""
2436
2548
  column = ensure_expr_or_series(column)
2437
2549
  epoch = column.dt.epoch(time_unit="d").alias("epoch")
@@ -2477,6 +2589,7 @@ __all__ = [
2477
2589
  "DatetimeUSEastern",
2478
2590
  "DatetimeUTC",
2479
2591
  "DropNullStructSeriesError",
2592
+ "ExprOrSeries",
2480
2593
  "FiniteEWMMeanError",
2481
2594
  "GetDataTypeOrSeriesTimeZoneError",
2482
2595
  "GetSeriesNumberOfDecimalsError",
@@ -2489,6 +2602,10 @@ __all__ = [
2489
2602
  "StructFromDataClassError",
2490
2603
  "acf",
2491
2604
  "adjust_frequencies",
2605
+ "all_dataframe_columns",
2606
+ "all_series",
2607
+ "any_dataframe_columns",
2608
+ "any_series",
2492
2609
  "append_dataclass",
2493
2610
  "are_frames_equal",
2494
2611
  "bernoulli",
@@ -2529,7 +2646,9 @@ __all__ = [
2529
2646
  "nan_sum_agg",
2530
2647
  "nan_sum_cols",
2531
2648
  "normal",
2649
+ "offset_datetime",
2532
2650
  "order_of_magnitude",
2651
+ "period_range",
2533
2652
  "read_dataframe",
2534
2653
  "read_series",
2535
2654
  "replace_time_zone",