From 52c1faa568b883f16d2e5075c3ecca983c9eac4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Perceval=20Wajsb=C3=BCrt?= Date: Fri, 15 Dec 2023 12:49:02 +0100 Subject: [PATCH] Support casting config values as dict with pydantic (#54) --- confection/__init__.py | 2 +- confection/tests/test_config.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/confection/__init__.py b/confection/__init__.py index 9c6922c..23d0672 100644 --- a/confection/__init__.py +++ b/confection/__init__.py @@ -960,7 +960,7 @@ def _update_from_parsed( filled[key] = value if key not in final: final[key] = value - if isinstance(value, dict): + if isinstance(value, dict) and isinstance(final[key], dict): filled[key], final[key] = cls._update_from_parsed( value, filled[key], final[key] ) diff --git a/confection/tests/test_config.py b/confection/tests/test_config.py index 5873eb2..662462c 100644 --- a/confection/tests/test_config.py +++ b/confection/tests/test_config.py @@ -1431,3 +1431,29 @@ def test_parse_strings_interpretable_as_ints(): ) assert cfg["a"]["foo"] == [3, "003", "y"] assert cfg["b"]["bar"] == 3 + + +def test_dict_casting(): + class CastStrAsDict: + @classmethod + def validate(cls, value): + if isinstance(value, str): + return {value: True} + return value + + @classmethod + def __get_validators__(cls): + yield cls.validate + + class SectionSchema(BaseModel): + key: CastStrAsDict + + class MainSchema(BaseModel): + section: SectionSchema + + cfg = Config().from_str(""" + [section] + key = 1 + """) + + assert my_registry.fill(cfg, schema=MainSchema) == {'section': {'key': 1}}