dycw-utilities 0.165.3__tar.gz → 0.166.0__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.3 → dycw_utilities-0.166.0}/PKG-INFO +1 -1
  2. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/pyproject.toml +2 -2
  3. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_polars.py +75 -74
  4. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/__init__.py +1 -1
  5. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/polars.py +68 -21
  6. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/.gitignore +0 -0
  7. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/LICENSE +0 -0
  8. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/README.md +0 -0
  9. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/__init__.py +0 -0
  10. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/conftest.py +0 -0
  11. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/__init__.py +0 -0
  12. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_missing/__init__.py +0 -0
  13. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_missing/module.py +0 -0
  14. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/__init__.py +0 -0
  15. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/outer_1.py +0 -0
  16. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/outer_2.py +0 -0
  17. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  18. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  19. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  20. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  21. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_without/__init__.py +0 -0
  22. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_without/module_1.py +0 -0
  23. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/package_without/module_2.py +0 -0
  24. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/standalone.py +0 -0
  25. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/modules/with_imports.py +0 -0
  26. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  27. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  28. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  29. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  30. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  31. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  32. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  33. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  34. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_aeventkit.py +0 -0
  35. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_altair.py +0 -0
  36. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_asyncio.py +0 -0
  37. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_atomicwrites.py +0 -0
  38. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_atools.py +0 -0
  39. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_cachetools.py +0 -0
  40. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_click.py +0 -0
  41. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_concurrent.py +0 -0
  42. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_contextlib.py +0 -0
  43. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_contextvars.py +0 -0
  44. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_cryptography.py +0 -0
  45. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_cvxpy.py +0 -0
  46. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_dataclasses.py +0 -0
  47. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_enum.py +0 -0
  48. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_errors.py +0 -0
  49. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_fastapi.py +0 -0
  50. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_fpdf2.py +0 -0
  51. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_functions.py +0 -0
  52. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_functools.py +0 -0
  53. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_getpass.py +0 -0
  54. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_gzip.py +0 -0
  55. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_hashlib.py +0 -0
  56. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_http.py +0 -0
  57. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_hypothesis.py +0 -0
  58. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_importlib.py +0 -0
  59. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_inflect.py +0 -0
  60. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_ipython.py +0 -0
  61. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_iterables.py +0 -0
  62. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_json.py +0 -0
  63. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_jupyter.py +0 -0
  64. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_libcst.py +0 -0
  65. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_lightweight_charts.py +0 -0
  66. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_logging.py +0 -0
  67. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_math.py +0 -0
  68. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_memory_profiler.py +0 -0
  69. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_modules.py +0 -0
  70. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_more_itertools.py +0 -0
  71. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_numpy.py +0 -0
  72. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_objects/__init__.py +0 -0
  73. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_objects/objects.py +0 -0
  74. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_operator.py +0 -0
  75. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_optuna.py +0 -0
  76. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_orjson.py +0 -0
  77. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_os.py +0 -0
  78. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_parse.py +0 -0
  79. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pathlib.py +0 -0
  80. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pickle.py +0 -0
  81. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_platform.py +0 -0
  82. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_polars_ols.py +0 -0
  83. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_postgres.py +0 -0
  84. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pottery.py +0 -0
  85. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pqdm.py +0 -0
  86. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_psutil.py +0 -0
  87. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pyinstrument.py +0 -0
  88. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pytest.py +0 -0
  89. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pytest_randomly.py +0 -0
  90. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_pytest_regressions.py +0 -0
  91. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_random.py +0 -0
  92. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_re.py +0 -0
  93. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_redis.py +0 -0
  94. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_reprlib.py +0 -0
  95. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_scipy.py +0 -0
  96. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_sentinel.py +0 -0
  97. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_shelve.py +0 -0
  98. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_slack_sdk.py +0 -0
  99. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_socket.py +0 -0
  100. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_sqlalchemy.py +0 -0
  101. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_sqlalchemy_polars.py +0 -0
  102. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_statsmodels.py +0 -0
  103. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_string.py +0 -0
  104. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_tempfile.py +0 -0
  105. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_testbook.py +0 -0
  106. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_text.py +0 -0
  107. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_threading.py +0 -0
  108. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_timer.py +0 -0
  109. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_traceback.py +0 -0
  110. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_typed_settings.py +0 -0
  111. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_types.py +0 -0
  112. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_typing.py +0 -0
  113. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_typing_funcs/__init__.py +0 -0
  114. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_typing_funcs/no_future.py +0 -0
  115. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_typing_funcs/with_future.py +0 -0
  116. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_tzdata.py +0 -0
  117. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_tzlocal.py +0 -0
  118. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_uuid.py +0 -0
  119. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_version.py +0 -0
  120. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_warnings.py +0 -0
  121. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_whenever.py +0 -0
  122. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_zipfile.py +0 -0
  123. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/tests/test_zoneinfo.py +0 -0
  124. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/aeventkit.py +0 -0
  125. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/altair.py +0 -0
  126. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/asyncio.py +0 -0
  127. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/atomicwrites.py +0 -0
  128. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/atools.py +0 -0
  129. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/cachetools.py +0 -0
  130. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/click.py +0 -0
  131. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/concurrent.py +0 -0
  132. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/contextlib.py +0 -0
  133. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/contextvars.py +0 -0
  134. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/cryptography.py +0 -0
  135. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/cvxpy.py +0 -0
  136. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/dataclasses.py +0 -0
  137. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/enum.py +0 -0
  138. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/errors.py +0 -0
  139. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/fastapi.py +0 -0
  140. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/fpdf2.py +0 -0
  141. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/functions.py +0 -0
  142. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/functools.py +0 -0
  143. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/getpass.py +0 -0
  144. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/gzip.py +0 -0
  145. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/hashlib.py +0 -0
  146. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/http.py +0 -0
  147. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/hypothesis.py +0 -0
  148. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/importlib.py +0 -0
  149. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/inflect.py +0 -0
  150. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/ipython.py +0 -0
  151. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/iterables.py +0 -0
  152. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/json.py +0 -0
  153. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/jupyter.py +0 -0
  154. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/libcst.py +0 -0
  155. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/lightweight_charts.py +0 -0
  156. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/logging.py +0 -0
  157. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/math.py +0 -0
  158. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/memory_profiler.py +0 -0
  159. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/modules.py +0 -0
  160. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/more_itertools.py +0 -0
  161. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/numpy.py +0 -0
  162. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/operator.py +0 -0
  163. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/optuna.py +0 -0
  164. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/orjson.py +0 -0
  165. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/os.py +0 -0
  166. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/parse.py +0 -0
  167. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pathlib.py +0 -0
  168. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pickle.py +0 -0
  169. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/platform.py +0 -0
  170. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/polars_ols.py +0 -0
  171. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/postgres.py +0 -0
  172. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pottery.py +0 -0
  173. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pqdm.py +0 -0
  174. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/psutil.py +0 -0
  175. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/py.typed +0 -0
  176. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pyinstrument.py +0 -0
  177. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pytest.py +0 -0
  178. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pytest_plugins/__init__.py +0 -0
  179. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  180. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  181. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/pytest_regressions.py +0 -0
  182. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/random.py +0 -0
  183. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/re.py +0 -0
  184. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/redis.py +0 -0
  185. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/reprlib.py +0 -0
  186. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/scipy.py +0 -0
  187. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/sentinel.py +0 -0
  188. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/shelve.py +0 -0
  189. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/slack_sdk.py +0 -0
  190. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/socket.py +0 -0
  191. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/sqlalchemy.py +0 -0
  192. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/sqlalchemy_polars.py +0 -0
  193. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/statsmodels.py +0 -0
  194. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/string.py +0 -0
  195. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/tempfile.py +0 -0
  196. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/testbook.py +0 -0
  197. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/text.py +0 -0
  198. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/threading.py +0 -0
  199. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/timer.py +0 -0
  200. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/traceback.py +0 -0
  201. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/typed_settings.py +0 -0
  202. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/types.py +0 -0
  203. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/typing.py +0 -0
  204. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/tzdata.py +0 -0
  205. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/tzlocal.py +0 -0
  206. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/uuid.py +0 -0
  207. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/version.py +0 -0
  208. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/warnings.py +0 -0
  209. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/whenever.py +0 -0
  210. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/src/utilities/zipfile.py +0 -0
  211. {dycw_utilities-0.165.3 → dycw_utilities-0.166.0}/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.3
3
+ Version: 0.166.0
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.3"
236
+ version = "0.166.0"
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.3"
269
+ current_version = "0.166.0"
270
270
 
271
271
  [[tool.bumpversion.files]]
272
272
  filename = "src/utilities/__init__.py"
@@ -83,7 +83,6 @@ from utilities.hypothesis import (
83
83
  from utilities.numpy import DEFAULT_RNG
84
84
  from utilities.pathlib import PWD
85
85
  from utilities.polars import (
86
- AppendDataClassError,
87
86
  BooleanValueCountsError,
88
87
  ColumnsToDictError,
89
88
  DatePeriodDType,
@@ -102,6 +101,10 @@ from utilities.polars import (
102
101
  SelectExactError,
103
102
  SetFirstRowAsColumnsError,
104
103
  TimePeriodDType,
104
+ _AppendRowExtraKeysError,
105
+ _AppendRowMissingKeysError,
106
+ _AppendRowNullColumnsError,
107
+ _AppendRowPredicateError,
105
108
  _check_polars_dataframe_predicates,
106
109
  _check_polars_dataframe_schema_list,
107
110
  _check_polars_dataframe_schema_set,
@@ -145,7 +148,7 @@ from utilities.polars import (
145
148
  all_series,
146
149
  any_dataframe_columns,
147
150
  any_series,
148
- append_dataclass,
151
+ append_row,
149
152
  are_frames_equal,
150
153
  bernoulli,
151
154
  boolean_value_counts,
@@ -360,91 +363,89 @@ class TestAnyAllDataFrameColumnsSeries:
360
363
  assert_series_equal(result, self.exp_any)
361
364
 
362
365
 
363
- class TestAppendDataClass:
364
- @given(
365
- data=fixed_dictionaries({
366
- "a": int64s() | none(),
367
- "b": floats() | none(),
368
- "c": text_ascii() | none(),
369
- })
370
- )
371
- def test_columns_and_fields_equal(self, *, data: StrMapping) -> None:
372
- df = DataFrame(schema={"a": Int64, "b": Float64, "c": String})
373
-
374
- @dataclass(kw_only=True, slots=True)
375
- class Row:
376
- a: int | None = None
377
- b: float | None = None
378
- c: str | None = None
366
+ class TestAppendRow:
367
+ rows: ClassVar[list[tuple[int, int]]] = [(i, 2 * i) for i in range(3)]
368
+ schema: ClassVar[SchemaDict] = {"x": Int64, "y": Int64}
369
+ df: ClassVar[DataFrame] = DataFrame(data=rows, schema=schema, orient="row")
379
370
 
380
- row = Row(**data)
381
- result = append_dataclass(df, row)
382
- height = 0 if (row.a is None) and (row.b is None) and (row.c is None) else 1
383
- check_polars_dataframe(result, height=height, schema_list=df.schema)
384
-
385
- @given(data=fixed_dictionaries({"a": int64s() | none(), "b": floats() | none()}))
386
- def test_extra_column(self, *, data: StrMapping) -> None:
387
- df = DataFrame(schema={"a": Int64, "b": Float64, "c": String})
388
-
389
- @dataclass(kw_only=True, slots=True)
390
- class Row:
391
- a: int | None = None
392
- b: float | None = None
371
+ @mark.parametrize(
372
+ "row", [param({"x": 3, "y": 6}), param({"x": 3, "y": 6, "z": None})]
373
+ )
374
+ def test_main(self, *, row: StrMapping) -> None:
375
+ result = append_row(self.df, row)
376
+ expected = DataFrame(
377
+ data=[*self.rows, (3, 6)], schema=self.schema, orient="row"
378
+ )
379
+ assert_frame_equal(result, expected)
393
380
 
394
- row = Row(**data)
395
- result = append_dataclass(df, row)
396
- height = 0 if (row.a is None) and (row.b is None) else 1
397
- check_polars_dataframe(result, height=height, schema_list=df.schema)
381
+ def test_missing_key(self) -> None:
382
+ row = {"x": 3}
383
+ result = append_row(self.df, row)
384
+ expected = DataFrame(
385
+ data=[*self.rows, (3, None)], schema=self.schema, orient="row"
386
+ )
387
+ assert_frame_equal(result, expected)
398
388
 
399
- @given(data=fixed_dictionaries({"a": int64s() | none(), "b": floats() | none()}))
400
- def test_extra_field_but_none(self, *, data: StrMapping) -> None:
401
- df = DataFrame(schema={"a": Int64, "b": Float64})
389
+ def test_disallow_missing_selected(self) -> None:
390
+ row = {"x": 3}
391
+ result = append_row(self.df, row, disallow_missing="x")
392
+ expected = DataFrame(
393
+ data=[*self.rows, (3, None)], schema=self.schema, orient="row"
394
+ )
395
+ assert_frame_equal(result, expected)
402
396
 
403
- @dataclass(kw_only=True, slots=True)
404
- class Row:
405
- a: int | None = None
406
- b: float | None = None
407
- c: str | None = None
397
+ def test_disallow_null_selected(self) -> None:
398
+ row = {"x": 3, "y": None}
399
+ result = append_row(self.df, row, disallow_null="x")
400
+ expected = DataFrame(
401
+ data=[*self.rows, (3, None)], schema=self.schema, orient="row"
402
+ )
403
+ assert_frame_equal(result, expected)
408
404
 
409
- row = Row(**data)
410
- result = append_dataclass(df, row)
411
- height = 0 if (row.a is None) and (row.b is None) else 1
412
- check_polars_dataframe(result, height=height, schema_list=df.schema)
405
+ def test_in_place(self) -> None:
406
+ df = DataFrame(data=self.rows, schema=self.schema, orient="row")
407
+ assert df.height == 3
408
+ row = {"x": 3, "y": 6}
409
+ _ = append_row(df, row, in_place=True)
410
+ assert df.height == 4
413
411
 
414
- @given(data=fixed_dictionaries({"datetime": zoned_date_times()}))
415
- def test_zoned_datetime(self, *, data: StrMapping) -> None:
416
- df = DataFrame(schema={"datetime": DatetimeUTC})
412
+ def test_error_predicate(self) -> None:
413
+ row = {"x": 3}
414
+ with raises(_AppendRowPredicateError, match="Predicate failed; got {'x': 3}"):
415
+ _ = append_row(self.df, row, predicate=lambda row: "y" in row)
417
416
 
418
- @dataclass(kw_only=True, slots=True)
419
- class Row:
420
- datetime: ZonedDateTime
417
+ def test_error_disallow_extra(self) -> None:
418
+ row = {"x": 3, "y": 6, "z": None}
419
+ with raises(_AppendRowExtraKeysError, match=r"Extra key\(s\) found; got {'z'}"):
420
+ _ = append_row(self.df, row, disallow_extra=True)
421
421
 
422
- row = Row(**data)
423
- result = append_dataclass(df, row)
424
- check_polars_dataframe(result, height=1, schema_list=df.schema)
422
+ def test_error_disallow_missing_all(self) -> None:
423
+ with raises(
424
+ _AppendRowMissingKeysError,
425
+ match=r"Missing key\(s\) found; got {'[xy]', '[xy]'}",
426
+ ):
427
+ _ = append_row(self.df, {}, disallow_missing=True)
425
428
 
426
- @given(
427
- data=fixed_dictionaries({
428
- "a": int64s() | none(),
429
- "b": floats() | none(),
430
- "c": text_ascii(),
431
- })
432
- )
433
- def test_error(self, *, data: StrMapping) -> None:
434
- df = DataFrame(schema={"a": Int64, "b": Float64})
429
+ def test_error_disallow_missing_selected(self) -> None:
430
+ with raises(
431
+ _AppendRowMissingKeysError, match=r"Missing key\(s\) found; got {'x'}"
432
+ ):
433
+ _ = append_row(self.df, {}, disallow_missing="x")
435
434
 
436
- @dataclass(kw_only=True, slots=True)
437
- class Row:
438
- a: int | None = None
439
- b: float | None = None
440
- c: str
435
+ def test_error_disallow_null_all(self) -> None:
436
+ row = {"x": None, "y": None}
437
+ with raises(
438
+ _AppendRowNullColumnsError,
439
+ match=r"Null column\(s\) found; got {'[xy]', '[xy]'}",
440
+ ):
441
+ _ = append_row(self.df, row, disallow_null=True)
441
442
 
442
- row = Row(**data)
443
+ def test_error_disallow_null_selected(self) -> None:
444
+ row = {"x": None, "y": None}
443
445
  with raises(
444
- AppendDataClassError,
445
- match="Dataclass fields .* must be a subset of DataFrame columns .*; dataclass had extra items .*",
446
+ _AppendRowNullColumnsError, match=r"Null column\(s\) found; got {'x'}"
446
447
  ):
447
- _ = append_dataclass(df, row)
448
+ _ = append_row(self.df, row, disallow_null="x")
448
449
 
449
450
 
450
451
  class TestAreFramesEqual:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.165.3"
3
+ __version__ = "0.166.0"
@@ -61,14 +61,12 @@ from utilities.gzip import read_binary
61
61
  from utilities.iterables import (
62
62
  CheckIterablesEqualError,
63
63
  CheckMappingsEqualError,
64
- CheckSubSetError,
65
64
  CheckSuperMappingError,
66
65
  OneEmptyError,
67
66
  OneNonUniqueError,
68
67
  always_iterable,
69
68
  check_iterables_equal,
70
69
  check_mappings_equal,
71
- check_subset,
72
70
  check_supermapping,
73
71
  is_iterable_not_str,
74
72
  one,
@@ -301,29 +299,77 @@ def any_series(series: Series, /, *columns: ExprOrSeries) -> Series:
301
299
  ##
302
300
 
303
301
 
304
- def append_dataclass(df: DataFrame, obj: Dataclass, /) -> DataFrame:
305
- """Append a dataclass object to a DataFrame."""
306
- non_null_fields = {k: v for k, v in asdict(obj).items() if v is not None}
307
- try:
308
- check_subset(non_null_fields, df.columns)
309
- except CheckSubSetError as error:
310
- raise AppendDataClassError(
311
- left=error.left, right=error.right, extra=error.extra
312
- ) from None
313
- row_cols = set(df.columns) & set(non_null_fields)
314
- row = dataclass_to_dataframe(obj).select(*row_cols)
315
- return concat([df, row], how="diagonal")
302
+ def append_row(
303
+ df: DataFrame,
304
+ row: StrMapping,
305
+ /,
306
+ *,
307
+ predicate: Callable[[StrMapping], bool] | None = None,
308
+ disallow_extra: bool = False,
309
+ disallow_missing: bool | MaybeIterable[str] = False,
310
+ disallow_null: bool | MaybeIterable[str] = False,
311
+ in_place: bool = False,
312
+ ) -> DataFrame:
313
+ """Append a row to a DataFrame."""
314
+ if (predicate is not None) and not predicate(row):
315
+ raise _AppendRowPredicateError(df=df, row=row)
316
+ if disallow_extra and (len(extra := set(row) - set(df.columns)) >= 1):
317
+ raise _AppendRowExtraKeysError(df=df, row=row, extra=extra)
318
+ if disallow_missing is not False:
319
+ missing = set(df.columns) - set(row)
320
+ if disallow_missing is not True:
321
+ missing &= set(always_iterable(disallow_missing))
322
+ if len(missing) >= 1:
323
+ raise _AppendRowMissingKeysError(df=df, row=row, missing=missing)
324
+ other = DataFrame(data=[row], schema=df.schema)
325
+ if disallow_null:
326
+ other_null = other.select(col(c).is_null().any() for c in other.columns)
327
+ null = {k for k, v in other_null.row(0, named=True).items() if v}
328
+ if disallow_null is not True:
329
+ null &= set(always_iterable(disallow_null))
330
+ if len(null) >= 1:
331
+ raise _AppendRowNullColumnsError(df=df, row=row, columns=null)
332
+ return df.extend(other) if in_place else df.vstack(other)
333
+
334
+
335
+ @dataclass(kw_only=True, slots=True)
336
+ class AppendRowError(Exception):
337
+ df: DataFrame
338
+ row: StrMapping
339
+
340
+
341
+ @dataclass(kw_only=True, slots=True)
342
+ class _AppendRowPredicateError(AppendRowError):
343
+ @override
344
+ def __str__(self) -> str:
345
+ return f"Predicate failed; got {get_repr(self.row)}"
346
+
347
+
348
+ @dataclass(kw_only=True, slots=True)
349
+ class _AppendRowExtraKeysError(AppendRowError):
350
+ extra: AbstractSet[str]
351
+
352
+ @override
353
+ def __str__(self) -> str:
354
+ return f"Extra key(s) found; got {get_repr(self.extra)}"
355
+
356
+
357
+ @dataclass(kw_only=True, slots=True)
358
+ class _AppendRowMissingKeysError(AppendRowError):
359
+ missing: AbstractSet[str]
360
+
361
+ @override
362
+ def __str__(self) -> str:
363
+ return f"Missing key(s) found; got {get_repr(self.missing)}"
316
364
 
317
365
 
318
366
  @dataclass(kw_only=True, slots=True)
319
- class AppendDataClassError[T](Exception):
320
- left: AbstractSet[T]
321
- right: AbstractSet[T]
322
- extra: AbstractSet[T]
367
+ class _AppendRowNullColumnsError(AppendRowError):
368
+ columns: AbstractSet[str]
323
369
 
324
370
  @override
325
371
  def __str__(self) -> str:
326
- return f"Dataclass fields {get_repr(self.left)} must be a subset of DataFrame columns {get_repr(self.right)}; dataclass had extra items {get_repr(self.extra)}"
372
+ return f"Null column(s) found; got {get_repr(self.columns)}"
327
373
 
328
374
 
329
375
  ##
@@ -2469,7 +2515,7 @@ def search_period(
2469
2515
  start_or_end: Literal["start", "end"] = "end",
2470
2516
  ) -> int | None:
2471
2517
  """Search a series of periods for the one containing a given date-time."""
2472
- start, end = [series.struct[k] for k in ["start", "end"]]
2518
+ end = series.struct["end"]
2473
2519
  py_date_time = date_time.py_datetime()
2474
2520
  match start_or_end:
2475
2521
  case "start":
@@ -2701,6 +2747,7 @@ def zoned_date_time_period_dtype(
2701
2747
 
2702
2748
 
2703
2749
  __all__ = [
2750
+ "AppendRowError",
2704
2751
  "BooleanValueCountsError",
2705
2752
  "CheckPolarsDataFrameError",
2706
2753
  "ColumnsToDictError",
@@ -2731,7 +2778,7 @@ __all__ = [
2731
2778
  "all_series",
2732
2779
  "any_dataframe_columns",
2733
2780
  "any_series",
2734
- "append_dataclass",
2781
+ "append_row",
2735
2782
  "are_frames_equal",
2736
2783
  "bernoulli",
2737
2784
  "boolean_value_counts",