dycw-utilities 0.166.6__tar.gz → 0.166.8__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 (217) hide show
  1. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/PKG-INFO +1 -1
  2. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/pyproject.toml +11 -2
  3. dycw_utilities-0.166.8/src/tests/test_git.py +19 -0
  4. dycw_utilities-0.166.8/src/tests/test_pydantic_settings.py +77 -0
  5. dycw_utilities-0.166.8/src/tests/test_pydantic_settings_sops.py +49 -0
  6. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/__init__.py +1 -1
  7. dycw_utilities-0.166.8/src/utilities/git.py +19 -0
  8. dycw_utilities-0.166.8/src/utilities/pydantic_settings.py +59 -0
  9. dycw_utilities-0.166.8/src/utilities/pydantic_settings_sops.py +40 -0
  10. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/.gitignore +0 -0
  11. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/LICENSE +0 -0
  12. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/README.md +0 -0
  13. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/__init__.py +0 -0
  14. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/conftest.py +0 -0
  15. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/__init__.py +0 -0
  16. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_missing/__init__.py +0 -0
  17. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_missing/module.py +0 -0
  18. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/__init__.py +0 -0
  19. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/outer_1.py +0 -0
  20. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/outer_2.py +0 -0
  21. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  22. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  23. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  24. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  25. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_without/__init__.py +0 -0
  26. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_without/module_1.py +0 -0
  27. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/package_without/module_2.py +0 -0
  28. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/standalone.py +0 -0
  29. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/modules/with_imports.py +0 -0
  30. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  31. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  32. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  33. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  34. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  35. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  36. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  37. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  38. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_aeventkit.py +0 -0
  39. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_altair.py +0 -0
  40. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_asyncio.py +0 -0
  41. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_atomicwrites.py +0 -0
  42. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_atools.py +0 -0
  43. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_cachetools.py +0 -0
  44. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_click.py +0 -0
  45. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_concurrent.py +0 -0
  46. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_contextlib.py +0 -0
  47. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_contextvars.py +0 -0
  48. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_cryptography.py +0 -0
  49. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_cvxpy.py +0 -0
  50. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_dataclasses.py +0 -0
  51. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_enum.py +0 -0
  52. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_errors.py +0 -0
  53. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_fastapi.py +0 -0
  54. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_fpdf2.py +0 -0
  55. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_functions.py +0 -0
  56. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_functools.py +0 -0
  57. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_getpass.py +0 -0
  58. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_gzip.py +0 -0
  59. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_hashlib.py +0 -0
  60. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_http.py +0 -0
  61. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_hypothesis.py +0 -0
  62. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_importlib.py +0 -0
  63. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_inflect.py +0 -0
  64. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_ipython.py +0 -0
  65. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_iterables.py +0 -0
  66. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_json.py +0 -0
  67. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_jupyter.py +0 -0
  68. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_libcst.py +0 -0
  69. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_lightweight_charts.py +0 -0
  70. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_logging.py +0 -0
  71. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_math.py +0 -0
  72. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_memory_profiler.py +0 -0
  73. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_modules.py +0 -0
  74. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_more_itertools.py +0 -0
  75. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_numpy.py +0 -0
  76. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_objects/__init__.py +0 -0
  77. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_objects/objects.py +0 -0
  78. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_operator.py +0 -0
  79. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_optuna.py +0 -0
  80. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_orjson.py +0 -0
  81. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_os.py +0 -0
  82. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_parse.py +0 -0
  83. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pathlib.py +0 -0
  84. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pickle.py +0 -0
  85. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_platform.py +0 -0
  86. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_polars.py +0 -0
  87. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_polars_ols.py +0 -0
  88. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_postgres.py +0 -0
  89. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pottery.py +0 -0
  90. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pqdm.py +0 -0
  91. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_psutil.py +0 -0
  92. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pyinstrument.py +0 -0
  93. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pytest.py +0 -0
  94. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pytest_randomly.py +0 -0
  95. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_pytest_regressions.py +0 -0
  96. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_random.py +0 -0
  97. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_re.py +0 -0
  98. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_redis.py +0 -0
  99. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_reprlib.py +0 -0
  100. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_scipy.py +0 -0
  101. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_sentinel.py +0 -0
  102. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_shelve.py +0 -0
  103. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_slack_sdk.py +0 -0
  104. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_socket.py +0 -0
  105. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_sqlalchemy.py +0 -0
  106. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_sqlalchemy_polars.py +0 -0
  107. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_statsmodels.py +0 -0
  108. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_string.py +0 -0
  109. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_tempfile.py +0 -0
  110. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_testbook.py +0 -0
  111. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_text.py +0 -0
  112. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_threading.py +0 -0
  113. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_timer.py +0 -0
  114. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_traceback.py +0 -0
  115. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_typed_settings.py +0 -0
  116. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_types.py +0 -0
  117. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_typing.py +0 -0
  118. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_typing_funcs/__init__.py +0 -0
  119. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_typing_funcs/no_future.py +0 -0
  120. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_typing_funcs/with_future.py +0 -0
  121. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_tzdata.py +0 -0
  122. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_tzlocal.py +0 -0
  123. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_uuid.py +0 -0
  124. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_version.py +0 -0
  125. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_warnings.py +0 -0
  126. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_whenever.py +0 -0
  127. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_zipfile.py +0 -0
  128. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/tests/test_zoneinfo.py +0 -0
  129. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/aeventkit.py +0 -0
  130. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/altair.py +0 -0
  131. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/asyncio.py +0 -0
  132. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/atomicwrites.py +0 -0
  133. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/atools.py +0 -0
  134. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/cachetools.py +0 -0
  135. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/click.py +0 -0
  136. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/concurrent.py +0 -0
  137. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/contextlib.py +0 -0
  138. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/contextvars.py +0 -0
  139. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/cryptography.py +0 -0
  140. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/cvxpy.py +0 -0
  141. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/dataclasses.py +0 -0
  142. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/enum.py +0 -0
  143. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/errors.py +0 -0
  144. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/fastapi.py +0 -0
  145. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/fpdf2.py +0 -0
  146. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/functions.py +0 -0
  147. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/functools.py +0 -0
  148. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/getpass.py +0 -0
  149. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/gzip.py +0 -0
  150. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/hashlib.py +0 -0
  151. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/http.py +0 -0
  152. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/hypothesis.py +0 -0
  153. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/importlib.py +0 -0
  154. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/inflect.py +0 -0
  155. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/ipython.py +0 -0
  156. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/iterables.py +0 -0
  157. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/json.py +0 -0
  158. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/jupyter.py +0 -0
  159. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/libcst.py +0 -0
  160. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/lightweight_charts.py +0 -0
  161. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/logging.py +0 -0
  162. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/math.py +0 -0
  163. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/memory_profiler.py +0 -0
  164. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/modules.py +0 -0
  165. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/more_itertools.py +0 -0
  166. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/numpy.py +0 -0
  167. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/operator.py +0 -0
  168. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/optuna.py +0 -0
  169. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/orjson.py +0 -0
  170. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/os.py +0 -0
  171. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/parse.py +0 -0
  172. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pathlib.py +0 -0
  173. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pickle.py +0 -0
  174. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/platform.py +0 -0
  175. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/polars.py +0 -0
  176. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/polars_ols.py +0 -0
  177. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/postgres.py +0 -0
  178. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pottery.py +0 -0
  179. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pqdm.py +0 -0
  180. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/psutil.py +0 -0
  181. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/py.typed +0 -0
  182. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pyinstrument.py +0 -0
  183. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pytest.py +0 -0
  184. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pytest_plugins/__init__.py +0 -0
  185. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  186. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  187. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/pytest_regressions.py +0 -0
  188. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/random.py +0 -0
  189. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/re.py +0 -0
  190. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/redis.py +0 -0
  191. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/reprlib.py +0 -0
  192. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/scipy.py +0 -0
  193. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/sentinel.py +0 -0
  194. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/shelve.py +0 -0
  195. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/slack_sdk.py +0 -0
  196. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/socket.py +0 -0
  197. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/sqlalchemy.py +0 -0
  198. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/sqlalchemy_polars.py +0 -0
  199. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/statsmodels.py +0 -0
  200. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/string.py +0 -0
  201. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/tempfile.py +0 -0
  202. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/testbook.py +0 -0
  203. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/text.py +0 -0
  204. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/threading.py +0 -0
  205. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/timer.py +0 -0
  206. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/traceback.py +0 -0
  207. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/typed_settings.py +0 -0
  208. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/types.py +0 -0
  209. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/typing.py +0 -0
  210. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/tzdata.py +0 -0
  211. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/tzlocal.py +0 -0
  212. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/uuid.py +0 -0
  213. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/version.py +0 -0
  214. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/warnings.py +0 -0
  215. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/whenever.py +0 -0
  216. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/zipfile.py +0 -0
  217. {dycw_utilities-0.166.6 → dycw_utilities-0.166.8}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.166.6
3
+ Version: 0.166.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -61,6 +61,9 @@ fastapi-test = [
61
61
  fpdf2 = [
62
62
  "fpdf2 >=2.8.3, <2.9",
63
63
  ]
64
+ gitpython = [
65
+ "gitpython >=3.1.45, <3.2",
66
+ ]
64
67
  hashlib-test = [
65
68
  "orjson",
66
69
  ]
@@ -143,6 +146,12 @@ pqdm = [
143
146
  psutil = [
144
147
  "psutil >=7.0.0, <7.1",
145
148
  ]
149
+ pydantic-settings = [
150
+ "pydantic-settings",
151
+ ]
152
+ pydantic-settings-sops = [
153
+ "pydantic-settings-sops",
154
+ ]
146
155
  pyinstrument = [
147
156
  "pyinstrument >=5.1.0, <5.2",
148
157
  ]
@@ -233,7 +242,7 @@ dependencies = [
233
242
  name = "dycw-utilities"
234
243
  readme = "README.md"
235
244
  requires-python = ">= 3.12"
236
- version = "0.166.6"
245
+ version = "0.166.8"
237
246
 
238
247
  [project.entry-points.pytest11]
239
248
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -266,7 +275,7 @@ test = [
266
275
  # bump-my-version
267
276
  [tool.bumpversion]
268
277
  allow_dirty = true
269
- current_version = "0.166.6"
278
+ current_version = "0.166.8"
270
279
 
271
280
  [[tool.bumpversion.files]]
272
281
  filename = "src/utilities/__init__.py"
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from hypothesis import given, settings
6
+
7
+ from utilities.git import get_repo
8
+ from utilities.hypothesis import git_repos, paths
9
+
10
+
11
+ class TestGetRepo:
12
+ @given(repo=git_repos(), tail=paths())
13
+ @settings(max_examples=1)
14
+ def test_main(self, *, repo: Path, tail: Path) -> None:
15
+ obj = get_repo(repo.joinpath(tail))
16
+ expected = repo.resolve()
17
+ assert obj.working_tree_dir is not None
18
+ root = Path(obj.working_tree_dir).resolve()
19
+ assert root == expected
@@ -0,0 +1,77 @@
1
+ from __future__ import annotations
2
+
3
+ from json import dumps
4
+ from typing import TYPE_CHECKING, ClassVar
5
+
6
+ from pydantic_settings import BaseSettings, SettingsConfigDict
7
+
8
+ from utilities.os import temp_environ
9
+ from utilities.pydantic_settings import CustomBaseSettings, load_settings
10
+
11
+ if TYPE_CHECKING:
12
+ from pathlib import Path
13
+
14
+ from utilities.types import MaybeIterable, PathLike
15
+
16
+
17
+ class TestCustomBaseSettings:
18
+ def test_main(self, *, tmp_path: Path) -> None:
19
+ file = tmp_path.joinpath("settings.toml")
20
+ _ = file.write_text(dumps({"x": 1, "y": 2}))
21
+
22
+ class Settings(CustomBaseSettings):
23
+ json_files: ClassVar[MaybeIterable[PathLike]] = file
24
+ x: int
25
+ y: int
26
+
27
+ settings = load_settings(Settings)
28
+ assert settings.x == 1
29
+ assert settings.y == 2
30
+
31
+ def test_env_var(self) -> None:
32
+ class Settings(CustomBaseSettings):
33
+ x: int
34
+
35
+ with temp_environ(x="1"):
36
+ settings = load_settings(Settings)
37
+ assert settings.x == 1
38
+
39
+ def test_env_var_with_prefix(self) -> None:
40
+ class Settings(CustomBaseSettings):
41
+ model_config = SettingsConfigDict(env_prefix="test_")
42
+ x: int
43
+
44
+ with temp_environ(test_x="1"):
45
+ settings = load_settings(Settings)
46
+ assert settings.x == 1
47
+
48
+ def test_env_var_with_nested(self) -> None:
49
+ class Settings(CustomBaseSettings):
50
+ inner: Inner
51
+
52
+ class Inner(BaseSettings):
53
+ x: int
54
+
55
+ _ = Settings.model_rebuild()
56
+
57
+ with temp_environ(inner__x="1"):
58
+ settings = load_settings(Settings)
59
+ assert settings.inner.x == 1
60
+
61
+ def test_env_var_with_prefix_and_nested(self) -> None:
62
+ class Settings(CustomBaseSettings):
63
+ model_config = SettingsConfigDict(env_prefix="test__")
64
+ inner: Inner
65
+
66
+ class Inner(BaseSettings):
67
+ x: int
68
+
69
+ _ = Settings.model_rebuild()
70
+ with temp_environ(test__inner__x="1"):
71
+ settings = load_settings(Settings)
72
+ assert settings.inner.x == 1
73
+
74
+ def test_no_files(self) -> None:
75
+ class Settings(CustomBaseSettings): ...
76
+
77
+ _ = load_settings(Settings)
@@ -0,0 +1,49 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from json import dumps
5
+ from subprocess import check_call
6
+ from typing import TYPE_CHECKING, ClassVar
7
+
8
+ from tests.conftest import SKIPIF_CI
9
+ from utilities.iterables import one
10
+ from utilities.os import temp_environ
11
+ from utilities.pydantic_settings import load_settings
12
+ from utilities.pydantic_settings_sops import SopsBaseSettings
13
+ from utilities.re import extract_group
14
+
15
+ if TYPE_CHECKING:
16
+ from pathlib import Path
17
+
18
+ from utilities.types import MaybeIterable, PathLike
19
+
20
+
21
+ class TestSOPSBaseSettings:
22
+ @SKIPIF_CI
23
+ def test_main(self, *, tmp_path: Path) -> None:
24
+ unencrypted_file = tmp_path.joinpath("unencrypted.json")
25
+ _ = unencrypted_file.write_text(dumps({"x": 1, "y": 2}))
26
+ key_file = tmp_path.joinpath("keys.txt")
27
+ with key_file.open(mode="w") as file:
28
+ _ = check_call(["age-keygen"], stdout=file)
29
+ pattern = re.compile(r"^# public key: (age.+)$")
30
+ public_line = one(
31
+ line for line in key_file.read_text().splitlines() if pattern.search(line)
32
+ )
33
+ public_key = extract_group(pattern, public_line)
34
+ encrypted_file = tmp_path.joinpath("encrypted.json")
35
+ with (
36
+ temp_environ(SOPS_AGE_RECIPIENTS=public_key),
37
+ encrypted_file.open(mode="w") as file,
38
+ ):
39
+ _ = check_call(["sops", "encrypt", str(unencrypted_file)], stdout=file)
40
+
41
+ class Settings(SopsBaseSettings):
42
+ secret_files: ClassVar[MaybeIterable[PathLike]] = encrypted_file
43
+ x: int
44
+ y: int
45
+
46
+ with temp_environ(SOPS_AGE_KEY_FILE=str(key_file)):
47
+ settings = load_settings(Settings)
48
+ assert settings.x == 1
49
+ assert settings.y == 2
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.166.6"
3
+ __version__ = "0.166.8"
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING
5
+
6
+ from git import Repo
7
+
8
+ from utilities.pathlib import to_path
9
+
10
+ if TYPE_CHECKING:
11
+ from utilities.types import MaybeCallablePathLike
12
+
13
+
14
+ def get_repo(path: MaybeCallablePathLike = Path.cwd, /) -> Repo:
15
+ """Get the repo object."""
16
+ return Repo(to_path(path), search_parent_directories=True)
17
+
18
+
19
+ __all__ = ["get_repo"]
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, ClassVar, override
4
+
5
+ from pydantic_settings import (
6
+ BaseSettings,
7
+ JsonConfigSettingsSource,
8
+ PydanticBaseSettingsSource,
9
+ SettingsConfigDict,
10
+ )
11
+
12
+ from utilities.iterables import always_iterable
13
+
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Iterator
16
+
17
+ from utilities.types import MaybeIterable, PathLike
18
+
19
+
20
+ class CustomBaseSettings(BaseSettings):
21
+ """Base settings for loading JSON files."""
22
+
23
+ # paths
24
+ json_files: ClassVar[MaybeIterable[PathLike]] = ()
25
+
26
+ # config
27
+ model_config = SettingsConfigDict(env_nested_delimiter="__")
28
+
29
+ @classmethod
30
+ @override
31
+ def settings_customise_sources(
32
+ cls,
33
+ settings_cls: type[BaseSettings],
34
+ init_settings: PydanticBaseSettingsSource,
35
+ env_settings: PydanticBaseSettingsSource,
36
+ dotenv_settings: PydanticBaseSettingsSource,
37
+ file_secret_settings: PydanticBaseSettingsSource,
38
+ ) -> tuple[PydanticBaseSettingsSource, ...]:
39
+ _ = (init_settings, dotenv_settings, file_secret_settings)
40
+ return tuple(cls._yield_base_settings_sources(settings_cls, env_settings))
41
+
42
+ @classmethod
43
+ def _yield_base_settings_sources(
44
+ cls,
45
+ settings_cls: type[BaseSettings],
46
+ env_settings: PydanticBaseSettingsSource,
47
+ /,
48
+ ) -> Iterator[PydanticBaseSettingsSource]:
49
+ yield env_settings
50
+ for file in always_iterable(cls.json_files):
51
+ yield JsonConfigSettingsSource(settings_cls, json_file=file)
52
+
53
+
54
+ def load_settings[T: BaseSettings](cls: type[T], /) -> T:
55
+ """Load a set of settings."""
56
+ return cls()
57
+
58
+
59
+ __all__ = ["CustomBaseSettings", "load_settings"]
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, ClassVar, override
4
+
5
+ from pydantic_settings_sops import SOPSConfigSettingsSource
6
+
7
+ from utilities.iterables import always_iterable
8
+ from utilities.pydantic_settings import CustomBaseSettings
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Iterator
12
+
13
+ from pydantic_settings import BaseSettings, PydanticBaseSettingsSource
14
+
15
+ from utilities.types import MaybeIterable, PathLike
16
+
17
+
18
+ class SopsBaseSettings(CustomBaseSettings):
19
+ """Base settings for loading secrets using `sops/age`."""
20
+
21
+ # paths
22
+ secret_files: ClassVar[MaybeIterable[PathLike]] = ()
23
+
24
+ @classmethod
25
+ @override
26
+ def _yield_base_settings_sources(
27
+ cls,
28
+ settings_cls: type[BaseSettings],
29
+ env_settings: PydanticBaseSettingsSource,
30
+ /,
31
+ ) -> Iterator[PydanticBaseSettingsSource]:
32
+ yield from super()._yield_base_settings_sources(settings_cls, env_settings)
33
+ for file in always_iterable(cls.secret_files):
34
+ yield SOPSConfigSettingsSource(
35
+ settings_cls, # pyright: ignore[reportArgumentType],
36
+ json_file=file,
37
+ )
38
+
39
+
40
+ __all__ = ["SopsBaseSettings"]