pyproject.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Pyproject TOML file settings source."""
  2. from __future__ import annotations as _annotations
  3. from pathlib import Path
  4. from typing import (
  5. TYPE_CHECKING,
  6. )
  7. from .toml import TomlConfigSettingsSource
  8. if TYPE_CHECKING:
  9. from pydantic_settings.main import BaseSettings
  10. class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
  11. """
  12. A source class that loads variables from a `pyproject.toml` file.
  13. """
  14. def __init__(
  15. self,
  16. settings_cls: type[BaseSettings],
  17. toml_file: Path | None = None,
  18. ) -> None:
  19. self.toml_file_path = self._pick_pyproject_toml_file(
  20. toml_file, settings_cls.model_config.get('pyproject_toml_depth', 0)
  21. )
  22. self.toml_table_header: tuple[str, ...] = settings_cls.model_config.get(
  23. 'pyproject_toml_table_header', ('tool', 'pydantic-settings')
  24. )
  25. self.toml_data = self._read_files(self.toml_file_path)
  26. for key in self.toml_table_header:
  27. self.toml_data = self.toml_data.get(key, {})
  28. super(TomlConfigSettingsSource, self).__init__(settings_cls, self.toml_data)
  29. @staticmethod
  30. def _pick_pyproject_toml_file(provided: Path | None, depth: int) -> Path:
  31. """Pick a `pyproject.toml` file path to use.
  32. Args:
  33. provided: Explicit path provided when instantiating this class.
  34. depth: Number of directories up the tree to check of a pyproject.toml.
  35. """
  36. if provided:
  37. return provided.resolve()
  38. rv = Path.cwd() / 'pyproject.toml'
  39. count = 0
  40. if not rv.is_file():
  41. child = rv.parent.parent / 'pyproject.toml'
  42. while count < depth:
  43. if child.is_file():
  44. return child
  45. if str(child.parent) == rv.root:
  46. break # end discovery after checking system root once
  47. child = child.parent.parent / 'pyproject.toml'
  48. count += 1
  49. return rv
  50. __all__ = ['PyprojectTomlConfigSettingsSource']