From deebc43f1b095983dfe2a62b30c414085f0c1e7b Mon Sep 17 00:00:00 2001 From: Adrian Cederberg <77076023+acederberg@users.noreply.github.com> Date: Thu, 18 Jul 2024 08:38:06 -0600 Subject: [PATCH 1/2] Fix/issue 29 (#30) fix(load): Fixed ``yaml_files`` keys cannot be strings Should fix #29. --- tests/extra/whatever.yaml | 5 +++++ tests/test_extra.py | 34 ++++++++++++++++++++++++++++++ yaml_settings_pydantic/__init__.py | 30 +++++++++++--------------- 3 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 tests/extra/whatever.yaml create mode 100644 tests/test_extra.py diff --git a/tests/extra/whatever.yaml b/tests/extra/whatever.yaml new file mode 100644 index 0000000..9fff4ce --- /dev/null +++ b/tests/extra/whatever.yaml @@ -0,0 +1,5 @@ +whatever: + the: heck + should: be + here: dude + diff --git a/tests/test_extra.py b/tests/test_extra.py new file mode 100644 index 0000000..5f9c6ef --- /dev/null +++ b/tests/test_extra.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from pathlib import Path + +from yaml_settings_pydantic import ( + BaseYamlSettings, + YamlFileConfigDict, + YamlSettingsConfigDict, +) + +WHATEVER = Path(__file__).parent / "extra" / "whatever.yaml" + + +def test_yaml_files_dict_string_keys() -> None: + """For now, make sure that this does not fail.""" + + class Settings(BaseYamlSettings): + the: str + should: str + here: str + + model_config = YamlSettingsConfigDict( + yaml_files={ + WHATEVER: YamlFileConfigDict( + subpath="whatever", + required=True, + ) + } + ) + + settings = Settings.model_validate({}) + assert settings.the == "heck" + assert settings.should == "be" + assert settings.here == "dude" diff --git a/yaml_settings_pydantic/__init__.py b/yaml_settings_pydantic/__init__.py index 9936081..ed77a38 100644 --- a/yaml_settings_pydantic/__init__.py +++ b/yaml_settings_pydantic/__init__.py @@ -24,11 +24,7 @@ from jsonpath_ng import parse from pydantic.fields import FieldInfo from pydantic.v1.utils import deep_update -from pydantic_settings import ( - BaseSettings, - PydanticBaseSettingsSource, - SettingsConfigDict, -) +from pydantic_settings import BaseSettings, PydanticBaseSettingsSource, SettingsConfigDict from typing_extensions import Doc, NotRequired, TypedDict from yaml import safe_load @@ -236,25 +232,28 @@ def validate_files( ): msg = "`{0}` must be a sequence or set, got type `{1}`." raise ValueError(msg.format(item, type(found_value))) + # NOTE: Not including makes the editor think the the code below is # unreachable, I do not know why, so the ``else`` statement shall # remain. else: ... - # NOTE: If its a string/``Path``, make it into a tuple. If it is anything - # else just leave it. - values: ( - tuple[Path, ...] - | dict[str, YamlFileConfigDict] - | dict[Path, YamlFileConfigDict] - ) + # NOTE: If its a string/``Path``, make it into a tuple. If dict keys + # are strings make them ``Path``. + values: tuple[Path, ...] | dict[Path, YamlFileConfigDict] if isinstance(found_value, PosixPath): logger.debug(f"`{item}` was a PosixPath.") values = (found_value,) elif isinstance(found_value, str): logger.debug(f"`{item}` was a String.") values = (Path(found_value),) + elif isinstance(found_value, dict) and any( + isinstance(item, str) for item in found_value + ): + values = { + k if isinstance(k, Path) else Path(k): v for k, v in found_value.items() + } else: values = found_value @@ -268,12 +267,7 @@ def validate_files( # NOTE: Create dictionary if the sequence is not a dictionary. files: dict[Path, YamlFileConfigDict] if not isinstance(values, dict): - files = { - ( - k if isinstance(k, Path) else Path(k) - ): DEFAULT_YAML_FILE_CONFIG_DICT.copy() - for k in values - } + files = {k: DEFAULT_YAML_FILE_CONFIG_DICT.copy() for k in values} elif any(not isinstance(v, dict) for v in values.values()): raise ValueError(f"`{item}` values must have type `dict`.") elif not len(values): From f79d1310a9f54a44b7e16436c454f2fa508ed146 Mon Sep 17 00:00:00 2001 From: Adrian Cederberg Date: Thu, 18 Jul 2024 08:40:40 -0600 Subject: [PATCH 2/2] chore(version): Bump version 2.3.1 -> 2.3.2 --- pyproject.toml | 4 ++-- yaml_settings_pydantic/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d88ba53..9bcd6aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ "Helio Chissini de Castro " ] name = "yaml-settings-pydantic" -version = "2.3.1" +version = "2.3.2" description = "A tool to easily load (many) JSON/YAML files as pydantic settings." readme = "README.rst" keywords = [ @@ -197,7 +197,7 @@ pytest-mypy = "^0.10.3" [tool.bumpver] -current_version = "2.3.1" +current_version = "2.3.2" version_pattern = "MAJOR.MINOR.PATCH" commit_message = "chore(version): Bump version {old_version} -> {new_version}" commit = true diff --git a/yaml_settings_pydantic/__init__.py b/yaml_settings_pydantic/__init__.py index ed77a38..425ea45 100644 --- a/yaml_settings_pydantic/__init__.py +++ b/yaml_settings_pydantic/__init__.py @@ -28,7 +28,7 @@ from typing_extensions import Doc, NotRequired, TypedDict from yaml import safe_load -__version__ = "2.3.1" +__version__ = "2.3.2" logger = logging.getLogger("yaml_settings_pydantic") if environ.get("YAML_SETTINGS_PYDANTIC_LOGGER") == "true": logging.basicConfig(level=logging.DEBUG)