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