dycw-utilities 0.151.3__tar.gz → 0.151.5__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 (218) hide show
  1. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/PKG-INFO +1 -1
  2. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/pyproject.toml +2 -2
  3. dycw_utilities-0.151.5/src/tests/test_atools.py +67 -0
  4. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_polars.py +32 -8
  5. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/__init__.py +1 -1
  6. dycw_utilities-0.151.5/src/utilities/atools.py +99 -0
  7. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/polars.py +28 -5
  8. dycw_utilities-0.151.3/src/tests/test_atools.py +0 -36
  9. dycw_utilities-0.151.3/src/utilities/atools.py +0 -39
  10. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/.gitignore +0 -0
  11. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/LICENSE +0 -0
  12. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/README.md +0 -0
  13. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_altair.py +0 -0
  39. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_asyncio.py +0 -0
  40. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_atomicwrites.py +0 -0
  41. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_cachetools.py +0 -0
  42. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_click.py +0 -0
  43. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_concurrent.py +0 -0
  44. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_contextlib.py +0 -0
  45. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_contextvars.py +0 -0
  46. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_cryptography.py +0 -0
  47. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_cvxpy.py +0 -0
  48. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_dataclasses.py +0 -0
  49. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_dnspython.py +0 -0
  50. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_enum.py +0 -0
  51. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_errors.py +0 -0
  52. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_eventkit.py +0 -0
  53. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_fastapi.py +0 -0
  54. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_fpdf2.py +0 -0
  55. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_functions.py +0 -0
  56. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_functools.py +0 -0
  57. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_getpass.py +0 -0
  58. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_gzip.py +0 -0
  59. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_hashlib.py +0 -0
  60. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_http.py +0 -0
  61. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_hypothesis.py +0 -0
  62. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_importlib.py +0 -0
  63. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_inflect.py +0 -0
  64. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_ipython.py +0 -0
  65. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_iterables.py +0 -0
  66. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_json.py +0 -0
  67. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_jupyter.py +0 -0
  68. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_libcst.py +0 -0
  69. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_lightweight_charts.py +0 -0
  70. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_logging.py +0 -0
  71. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_math.py +0 -0
  72. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_memory_profiler.py +0 -0
  73. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_modules.py +0 -0
  74. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_more_itertools.py +0 -0
  75. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_numpy.py +0 -0
  76. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_objects/__init__.py +0 -0
  77. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_objects/objects.py +0 -0
  78. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_period.py +0 -0
  85. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pickle.py +0 -0
  86. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_platform.py +0 -0
  87. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_polars_ols.py +0 -0
  88. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_postgres.py +0 -0
  89. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pottery.py +0 -0
  90. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pqdm.py +0 -0
  91. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_psutil.py +0 -0
  92. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pyinstrument.py +0 -0
  93. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pytest_randomly.py +0 -0
  95. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_pytest_regressions.py +0 -0
  96. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_redis.py +0 -0
  99. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_reprlib.py +0 -0
  100. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_scipy.py +0 -0
  101. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_sentinel.py +0 -0
  102. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_shelve.py +0 -0
  103. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_slack_sdk.py +0 -0
  104. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_socket.py +0 -0
  105. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_sqlalchemy.py +0 -0
  106. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_sqlalchemy_polars.py +0 -0
  107. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_statsmodels.py +0 -0
  108. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_string.py +0 -0
  109. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_tempfile.py +0 -0
  110. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_text.py +0 -0
  111. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_threading.py +0 -0
  112. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_timer.py +0 -0
  113. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_traceback.py +0 -0
  114. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_typed_settings.py +0 -0
  115. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_types.py +0 -0
  116. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_typing.py +0 -0
  117. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_typing_funcs/__init__.py +0 -0
  118. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_typing_funcs/no_future.py +0 -0
  119. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_typing_funcs/with_future.py +0 -0
  120. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_tzdata.py +0 -0
  121. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_tzlocal.py +0 -0
  122. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_uuid.py +0 -0
  123. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_version.py +0 -0
  124. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_warnings.py +0 -0
  125. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_whenever.py +0 -0
  126. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_yield_access/__init__.py +0 -0
  127. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_yield_access/script.py +0 -0
  128. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_yield_access/script.sh +0 -0
  129. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_zipfile.py +0 -0
  130. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/tests/test_zoneinfo.py +0 -0
  131. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/altair.py +0 -0
  132. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/asyncio.py +0 -0
  133. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/atomicwrites.py +0 -0
  134. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/cachetools.py +0 -0
  135. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/click.py +0 -0
  136. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/concurrent.py +0 -0
  137. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/contextlib.py +0 -0
  138. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/contextvars.py +0 -0
  139. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/cryptography.py +0 -0
  140. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/cvxpy.py +0 -0
  141. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/dataclasses.py +0 -0
  142. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/dnspython.py +0 -0
  143. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/enum.py +0 -0
  144. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/errors.py +0 -0
  145. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/eventkit.py +0 -0
  146. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/fastapi.py +0 -0
  147. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/fpdf2.py +0 -0
  148. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/functions.py +0 -0
  149. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/functools.py +0 -0
  150. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/getpass.py +0 -0
  151. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/gzip.py +0 -0
  152. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/hashlib.py +0 -0
  153. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/http.py +0 -0
  154. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/hypothesis.py +0 -0
  155. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/importlib.py +0 -0
  156. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/inflect.py +0 -0
  157. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/ipython.py +0 -0
  158. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/iterables.py +0 -0
  159. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/json.py +0 -0
  160. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/jupyter.py +0 -0
  161. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/libcst.py +0 -0
  162. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/lightweight_charts.py +0 -0
  163. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/logging.py +0 -0
  164. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/math.py +0 -0
  165. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/memory_profiler.py +0 -0
  166. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/modules.py +0 -0
  167. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/more_itertools.py +0 -0
  168. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/numpy.py +0 -0
  169. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/operator.py +0 -0
  170. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/optuna.py +0 -0
  171. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/orjson.py +0 -0
  172. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/os.py +0 -0
  173. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/parse.py +0 -0
  174. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pathlib.py +0 -0
  175. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/period.py +0 -0
  176. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pickle.py +0 -0
  177. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/platform.py +0 -0
  178. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/polars_ols.py +0 -0
  179. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/postgres.py +0 -0
  180. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pottery.py +0 -0
  181. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pqdm.py +0 -0
  182. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/psutil.py +0 -0
  183. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/py.typed +0 -0
  184. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pyinstrument.py +0 -0
  185. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pytest.py +0 -0
  186. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pytest_plugins/__init__.py +0 -0
  187. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  188. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  189. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/pytest_regressions.py +0 -0
  190. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/random.py +0 -0
  191. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/re.py +0 -0
  192. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/redis.py +0 -0
  193. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/reprlib.py +0 -0
  194. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/scipy.py +0 -0
  195. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/sentinel.py +0 -0
  196. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/shelve.py +0 -0
  197. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/slack_sdk.py +0 -0
  198. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/socket.py +0 -0
  199. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/sqlalchemy.py +0 -0
  200. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/sqlalchemy_polars.py +0 -0
  201. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/statsmodels.py +0 -0
  202. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/string.py +0 -0
  203. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/tempfile.py +0 -0
  204. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/text.py +0 -0
  205. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/threading.py +0 -0
  206. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/timer.py +0 -0
  207. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/traceback.py +0 -0
  208. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/typed_settings.py +0 -0
  209. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/types.py +0 -0
  210. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/typing.py +0 -0
  211. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/tzdata.py +0 -0
  212. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/tzlocal.py +0 -0
  213. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/uuid.py +0 -0
  214. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/version.py +0 -0
  215. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/warnings.py +0 -0
  216. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/whenever.py +0 -0
  217. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/zipfile.py +0 -0
  218. {dycw_utilities-0.151.3 → dycw_utilities-0.151.5}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.151.3
3
+ Version: 0.151.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -232,7 +232,7 @@ dependencies = [
232
232
  name = "dycw-utilities"
233
233
  readme = "README.md"
234
234
  requires-python = ">= 3.12"
235
- version = "0.151.3"
235
+ version = "0.151.5"
236
236
 
237
237
  [project.entry-points.pytest11]
238
238
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -265,7 +265,7 @@ test = [
265
265
  # bump-my-version
266
266
  [tool.bumpversion]
267
267
  allow_dirty = true
268
- current_version = "0.151.3"
268
+ current_version = "0.151.5"
269
269
 
270
270
  [[tool.bumpversion.files]]
271
271
  filename = "src/utilities/__init__.py"
@@ -0,0 +1,67 @@
1
+ from __future__ import annotations
2
+
3
+ from utilities.asyncio import sleep_td
4
+ from utilities.atools import call_memoized, memoize
5
+ from utilities.whenever import SECOND
6
+
7
+ _DELTA = 0.1 * SECOND
8
+
9
+
10
+ class TestCallMemoized:
11
+ async def test_main(self) -> None:
12
+ counter = 0
13
+
14
+ async def increment() -> int:
15
+ nonlocal counter
16
+ counter += 1
17
+ return counter
18
+
19
+ for i in range(1, 11):
20
+ assert (await call_memoized(increment)) == i
21
+ assert counter == i
22
+
23
+ async def test_refresh(self) -> None:
24
+ counter = 0
25
+
26
+ async def increment() -> int:
27
+ nonlocal counter
28
+ counter += 1
29
+ return counter
30
+
31
+ for _ in range(2):
32
+ assert (await call_memoized(increment, _DELTA)) == 1
33
+ assert counter == 1
34
+ await sleep_td(2 * _DELTA)
35
+ for _ in range(2):
36
+ assert (await call_memoized(increment, _DELTA)) == 2
37
+ assert counter == 2
38
+
39
+
40
+ class TestMemoize:
41
+ async def test_main(self) -> None:
42
+ counter = 0
43
+
44
+ @memoize
45
+ async def increment() -> int:
46
+ nonlocal counter
47
+ counter += 1
48
+ return counter
49
+
50
+ for _ in range(10):
51
+ assert await increment() == 1
52
+ assert counter == 1
53
+
54
+ async def test_with_arguments(self) -> None:
55
+ counter = 0
56
+
57
+ @memoize(duration=_DELTA)
58
+ async def increment() -> int:
59
+ nonlocal counter
60
+ counter += 1
61
+ return counter
62
+
63
+ assert await increment() == 1
64
+ assert counter == 1
65
+ await sleep_td(2 * _DELTA)
66
+ assert await increment() == 2
67
+ assert counter == 2
@@ -8,7 +8,7 @@ from enum import auto
8
8
  from itertools import chain, repeat
9
9
  from math import isfinite, nan
10
10
  from pathlib import Path
11
- from typing import TYPE_CHECKING, Any, ClassVar, Literal, cast
11
+ from typing import TYPE_CHECKING, Any, ClassVar, Literal, assert_never, cast
12
12
  from uuid import UUID, uuid4
13
13
 
14
14
  import hypothesis.strategies
@@ -114,6 +114,7 @@ from utilities.polars import (
114
114
  _FiniteEWMWeightsError,
115
115
  _GetDataTypeOrSeriesTimeZoneNotDateTimeError,
116
116
  _GetDataTypeOrSeriesTimeZoneNotZonedError,
117
+ _GetDataTypeOrSeriesTimeZoneStructNonUniqueError,
117
118
  _GetSeriesNumberOfDecimalsAllNullError,
118
119
  _GetSeriesNumberOfDecimalsNotFloatError,
119
120
  _InsertBetweenMissingColumnsError,
@@ -1483,18 +1484,32 @@ class TestFloorDateTime:
1483
1484
 
1484
1485
  class TestGetDataTypeOrSeriesTimeZone:
1485
1486
  @given(
1486
- time_zone=sampled_from([HongKong, UTC]), case=sampled_from(["dtype", "series"])
1487
+ time_zone=sampled_from([HongKong, UTC]),
1488
+ flat_or_struct=sampled_from(["flat", "struct"]),
1489
+ dtype_or_series=sampled_from(["dtype", "series"]),
1487
1490
  )
1488
1491
  def test_main(
1489
- self, *, time_zone: ZoneInfo, case: Literal["dtype", "series"]
1492
+ self,
1493
+ *,
1494
+ time_zone: ZoneInfo,
1495
+ flat_or_struct: Literal["flat", "struct"],
1496
+ dtype_or_series: Literal["dtype", "series"],
1490
1497
  ) -> None:
1491
- dtype = zoned_datetime_dtype(time_zone=time_zone)
1492
- match case:
1498
+ match flat_or_struct:
1499
+ case "flat":
1500
+ dtype = zoned_datetime_dtype(time_zone=time_zone)
1501
+ case "struct":
1502
+ dtype = zoned_datetime_period_dtype(time_zone=time_zone)
1503
+ case _ as never:
1504
+ assert_never(never)
1505
+ match dtype_or_series:
1493
1506
  case "dtype":
1494
- dtype_or_series = dtype
1507
+ obj = dtype
1495
1508
  case "series":
1496
- dtype_or_series = Series(dtype=dtype)
1497
- result = get_data_type_or_series_time_zone(dtype_or_series)
1509
+ obj = Series(dtype=dtype)
1510
+ case _ as never:
1511
+ assert_never(never)
1512
+ result = get_data_type_or_series_time_zone(obj)
1498
1513
  assert result is time_zone
1499
1514
 
1500
1515
  def test_error_not_datetime(self) -> None:
@@ -1511,6 +1526,15 @@ class TestGetDataTypeOrSeriesTimeZone:
1511
1526
  ):
1512
1527
  _ = get_data_type_or_series_time_zone(Datetime)
1513
1528
 
1529
+ def test_error_struct_non_unique(self) -> None:
1530
+ with raises(
1531
+ _GetDataTypeOrSeriesTimeZoneStructNonUniqueError,
1532
+ match="Struct data type must contain exactly one time zone; got .*, .* and perhaps more",
1533
+ ):
1534
+ _ = get_data_type_or_series_time_zone(
1535
+ struct_dtype(start=DatetimeHongKong, end=DatetimeUTC)
1536
+ )
1537
+
1514
1538
 
1515
1539
  class TestGetExprName:
1516
1540
  @given(n=hypothesis.strategies.integers(0, 10), name=text_ascii())
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.151.3"
3
+ __version__ = "0.151.5"
@@ -0,0 +1,99 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+ from functools import partial
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, Any, cast, overload
7
+
8
+ import atools
9
+ from whenever import TimeDelta
10
+
11
+ from utilities.types import Coro, PathLike
12
+
13
+ if TYPE_CHECKING:
14
+ from atools._memoize_decorator import Keygen, Pickler
15
+
16
+
17
+ type _Key[**P, T] = tuple[Callable[P, Coro[T]], TimeDelta]
18
+ _MEMOIZED_FUNCS: dict[_Key, Callable[..., Coro[Any]]] = {}
19
+
20
+
21
+ async def call_memoized[**P, T](
22
+ func: Callable[P, Coro[T]],
23
+ refresh: TimeDelta | None = None,
24
+ /,
25
+ *args: P.args,
26
+ **kwargs: P.kwargs,
27
+ ) -> T:
28
+ """Call an asynchronous function, with possible memoization."""
29
+ if refresh is None:
30
+ return await func(*args, **kwargs)
31
+ key: _Key = (func, refresh)
32
+ memoized_func: Callable[P, Coro[T]]
33
+ try:
34
+ memoized_func = _MEMOIZED_FUNCS[key]
35
+ except KeyError:
36
+ memoized_func = _MEMOIZED_FUNCS[(key)] = memoize(duration=refresh.in_seconds())(
37
+ func
38
+ )
39
+ return await memoized_func(*args, **kwargs)
40
+
41
+
42
+ ##
43
+
44
+
45
+ @overload
46
+ def memoize[F: Callable[..., Coro[Any]]](
47
+ func: F,
48
+ /,
49
+ *,
50
+ db_path: PathLike | None = None,
51
+ duration: float | TimeDelta | None = None,
52
+ keygen: Keygen | None = None,
53
+ pickler: Pickler | None = None,
54
+ size: int | None = None,
55
+ ) -> F: ...
56
+ @overload
57
+ def memoize[F: Callable[..., Coro[Any]]](
58
+ func: None = None,
59
+ /,
60
+ *,
61
+ db_path: PathLike | None = None,
62
+ duration: float | TimeDelta | None = None,
63
+ keygen: Keygen | None = None,
64
+ pickler: Pickler | None = None,
65
+ size: int | None = None,
66
+ ) -> Callable[[F], F]: ...
67
+ def memoize[F: Callable[..., Coro[Any]]](
68
+ func: F | None = None,
69
+ /,
70
+ *,
71
+ db_path: PathLike | None = None,
72
+ duration: float | TimeDelta | None = None,
73
+ keygen: Keygen | None = None,
74
+ pickler: Pickler | None = None,
75
+ size: int | None = None,
76
+ ) -> F | Callable[[F], F]:
77
+ """Memoize a function."""
78
+ if func is None:
79
+ result = partial(
80
+ memoize,
81
+ db_path=db_path,
82
+ duration=duration,
83
+ keygen=keygen,
84
+ pickler=pickler,
85
+ size=size,
86
+ )
87
+ return cast("Callable[[F], F]", result)
88
+ return atools.memoize(
89
+ db_path=None if db_path is None else Path(db_path),
90
+ duration=duration.py_timedelta()
91
+ if isinstance(duration, TimeDelta)
92
+ else duration,
93
+ keygen=keygen,
94
+ pickler=pickler,
95
+ size=size,
96
+ )(func)
97
+
98
+
99
+ __all__ = ["call_memoized"]
@@ -1340,11 +1340,22 @@ def get_data_type_or_series_time_zone(
1340
1340
  dtype = series.dtype
1341
1341
  case _ as never:
1342
1342
  assert_never(never)
1343
- if not isinstance(dtype, Datetime):
1344
- raise _GetDataTypeOrSeriesTimeZoneNotDateTimeError(dtype=dtype)
1345
- if dtype.time_zone is None:
1346
- raise _GetDataTypeOrSeriesTimeZoneNotZonedError(dtype=dtype)
1347
- return ZoneInfo(dtype.time_zone)
1343
+ match dtype:
1344
+ case Datetime() as datetime:
1345
+ if datetime.time_zone is None:
1346
+ raise _GetDataTypeOrSeriesTimeZoneNotZonedError(dtype=datetime)
1347
+ return ZoneInfo(datetime.time_zone)
1348
+ case Struct() as struct:
1349
+ try:
1350
+ return one({
1351
+ get_data_type_or_series_time_zone(f.dtype) for f in struct.fields
1352
+ })
1353
+ except OneNonUniqueError as error:
1354
+ raise _GetDataTypeOrSeriesTimeZoneStructNonUniqueError(
1355
+ dtype=struct, first=error.first, second=error.second
1356
+ ) from None
1357
+ case _:
1358
+ raise _GetDataTypeOrSeriesTimeZoneNotDateTimeError(dtype=dtype)
1348
1359
 
1349
1360
 
1350
1361
  @dataclass(kw_only=True, slots=True)
@@ -1366,6 +1377,18 @@ class _GetDataTypeOrSeriesTimeZoneNotZonedError(GetDataTypeOrSeriesTimeZoneError
1366
1377
  return f"Data type must be zoned; got {self.dtype}"
1367
1378
 
1368
1379
 
1380
+ @dataclass(kw_only=True, slots=True)
1381
+ class _GetDataTypeOrSeriesTimeZoneStructNonUniqueError(
1382
+ GetDataTypeOrSeriesTimeZoneError
1383
+ ):
1384
+ first: ZoneInfo
1385
+ second: ZoneInfo
1386
+
1387
+ @override
1388
+ def __str__(self) -> str:
1389
+ return f"Struct data type must contain exactly one time zone; got {self.first}, {self.second} and perhaps more"
1390
+
1391
+
1369
1392
  ##
1370
1393
 
1371
1394
 
@@ -1,36 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from utilities.asyncio import sleep_td
4
- from utilities.atools import call_memoized
5
- from utilities.whenever import SECOND
6
-
7
-
8
- class TestCallMemoized:
9
- async def test_main(self) -> None:
10
- counter = 0
11
-
12
- async def increment() -> int:
13
- nonlocal counter
14
- counter += 1
15
- return counter
16
-
17
- for i in range(1, 3):
18
- assert (await call_memoized(increment)) == i
19
- assert counter == i
20
-
21
- async def test_refresh(self) -> None:
22
- counter = 0
23
- delta = 0.1 * SECOND
24
-
25
- async def increment() -> int:
26
- nonlocal counter
27
- counter += 1
28
- return counter
29
-
30
- for _ in range(2):
31
- assert (await call_memoized(increment, delta)) == 1
32
- assert counter == 1
33
- await sleep_td(2 * delta)
34
- for _ in range(2):
35
- assert (await call_memoized(increment, delta)) == 2
36
- assert counter == 2
@@ -1,39 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Callable
4
- from typing import TYPE_CHECKING, Any
5
-
6
- from atools import memoize
7
-
8
- from utilities.types import Coro
9
-
10
- if TYPE_CHECKING:
11
- from whenever import TimeDelta
12
-
13
-
14
- type _Key[**P, T] = tuple[Callable[P, Coro[T]], TimeDelta]
15
- _MEMOIZED_FUNCS: dict[_Key, Callable[..., Coro[Any]]] = {}
16
-
17
-
18
- async def call_memoized[**P, T](
19
- func: Callable[P, Coro[T]],
20
- refresh: TimeDelta | None = None,
21
- /,
22
- *args: P.args,
23
- **kwargs: P.kwargs,
24
- ) -> T:
25
- """Call an asynchronous function, with possible memoization."""
26
- if refresh is None:
27
- return await func(*args, **kwargs)
28
- key: _Key = (func, refresh)
29
- memoized_func: Callable[P, Coro[T]]
30
- try:
31
- memoized_func = _MEMOIZED_FUNCS[key]
32
- except KeyError:
33
- memoized_func = _MEMOIZED_FUNCS[(key)] = memoize(duration=refresh.in_seconds())(
34
- func
35
- )
36
- return await memoized_func(*args, **kwargs)
37
-
38
-
39
- __all__ = ["call_memoized"]