From 5f4e7ab4403e3b0fba8d8f818496f2d68147546a Mon Sep 17 00:00:00 2001 From: Alexis Janon <98706738+ajanon@users.noreply.github.com> Date: Wed, 6 Jul 2022 09:45:23 +0200 Subject: [PATCH] Extend "optional" flag for ConfZFileSource to ignore more exceptions See PR #50 and issue #52. "optional" now makes it possible to ignore if a command line argument is not set (through "file_from_cl") or if an environment variable is not present ("file_from_env"). If set, this also ignores errors if the file format is invalid. --- confz/confz_source.py | 5 +++-- confz/loaders/file_loader.py | 17 ++++++++--------- tests/loaders/test_file_loader.py | 12 ++++++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/confz/confz_source.py b/confz/confz_source.py index aa27e91..1b135fe 100644 --- a/confz/confz_source.py +++ b/confz/confz_source.py @@ -41,8 +41,9 @@ class ConfZFileSource(ConfZSource): encoding: str = "utf-8" """The encoding of the file. Default is UTF-8.""" optional: bool = False - """True if this config file is only optional. If set to True no error is thrown - when the file was not found.""" + """True if this config file is only optional. If set to True no error is + thrown when the file was not found, when the environment variable or the command + line argument was not set, or when the file format is invalid.""" @dataclass diff --git a/confz/loaders/file_loader.py b/confz/loaders/file_loader.py index 58368e5..8e9ff4c 100644 --- a/confz/loaders/file_loader.py +++ b/confz/loaders/file_loader.py @@ -87,7 +87,6 @@ def _read_file( file_path: Path, file_format: FileFormat, file_encoding: str, - optional: bool, ) -> dict: try: with file_path.open(encoding=file_encoding) as f: @@ -98,9 +97,6 @@ def _read_file( elif file_format == FileFormat.TOML: file_content = toml.load(f) except OSError as e: - if optional: - return {} - raise ConfZFileException( f"Could not open config file '{file_path}'." ) from e @@ -109,9 +105,12 @@ def _read_file( @classmethod def populate_config(cls, config: dict, confz_source: ConfZFileSource): - file_path = cls._get_filename(confz_source) - file_format = cls._get_format(file_path, confz_source.format) - file_content = cls._read_file( - file_path, file_format, confz_source.encoding, confz_source.optional - ) + try: + file_path = cls._get_filename(confz_source) + file_format = cls._get_format(file_path, confz_source.format) + file_content = cls._read_file(file_path, file_format, confz_source.encoding) + except ConfZFileException as e: + if confz_source.optional: + return + raise e cls.update_dict_recursively(config, file_content) diff --git a/tests/loaders/test_file_loader.py b/tests/loaders/test_file_loader.py index 32e75cb..b4a401d 100644 --- a/tests/loaders/test_file_loader.py +++ b/tests/loaders/test_file_loader.py @@ -170,3 +170,15 @@ def test_from_cl_arg_name(monkeypatch): ) assert config.inner.attr1 == "1 🎉" assert config.attr2 == "2" + + +def test_from_cl_arg_optional(): + # if not set, should load the config file without errors + config = OuterConfig( + config_sources=[ + ConfZFileSource(file_from_cl="--my_config_file", optional=True), + ConfZFileSource(file=ASSET_FOLDER / "config.yml"), + ] + ) + assert config.inner.attr1 == "1 🎉" + assert config.attr2 == "2"