Fix issue with explicit providing of envs_required=False for configuration from_*()

This commit is contained in:
Roman Mogylatov 2021-10-22 21:08:24 -04:00
parent f51a946973
commit 8a31384b18
6 changed files with 848 additions and 749 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1527,7 +1527,7 @@ cdef class ConfigurationOption(Provider):
""" """
self.override(value) self.override(value)
def from_ini(self, filepath, required=UNDEFINED, envs_required=False): def from_ini(self, filepath, required=UNDEFINED, envs_required=UNDEFINED):
"""Load configuration from the ini file. """Load configuration from the ini file.
Loaded configuration is merged recursively over existing configuration. Loaded configuration is merged recursively over existing configuration.
@ -1546,7 +1546,7 @@ cdef class ConfigurationOption(Provider):
try: try:
parser = _parse_ini_file( parser = _parse_ini_file(
filepath, filepath,
envs_required=envs_required or self._is_strict_mode_enabled(), envs_required=envs_required if envs_required is not UNDEFINED else self._is_strict_mode_enabled(),
) )
except IOError as exception: except IOError as exception:
if required is not False \ if required is not False \
@ -1565,7 +1565,7 @@ cdef class ConfigurationOption(Provider):
current_config = {} current_config = {}
self.override(merge_dicts(current_config, config)) self.override(merge_dicts(current_config, config))
def from_yaml(self, filepath, required=UNDEFINED, loader=None, envs_required=False): def from_yaml(self, filepath, required=UNDEFINED, loader=None, envs_required=UNDEFINED):
"""Load configuration from the yaml file. """Load configuration from the yaml file.
Loaded configuration is merged recursively over existing configuration. Loaded configuration is merged recursively over existing configuration.
@ -1607,7 +1607,7 @@ cdef class ConfigurationOption(Provider):
config_content = _resolve_config_env_markers( config_content = _resolve_config_env_markers(
config_content, config_content,
envs_required=envs_required or self._is_strict_mode_enabled(), envs_required=envs_required if envs_required is not UNDEFINED else self._is_strict_mode_enabled(),
) )
config = yaml.load(config_content, loader) config = yaml.load(config_content, loader)
@ -1861,7 +1861,7 @@ cdef class Configuration(Object):
self.__yaml_files = list(files) self.__yaml_files = list(files)
return self return self
def load(self, required=UNDEFINED, envs_required=False): def load(self, required=UNDEFINED, envs_required=UNDEFINED):
"""Load configuration. """Load configuration.
This method loads configuration from configuration files or pydantic settings that This method loads configuration from configuration files or pydantic settings that
@ -1998,7 +1998,7 @@ cdef class Configuration(Object):
""" """
self.override(value) self.override(value)
def from_ini(self, filepath, required=UNDEFINED, envs_required=False): def from_ini(self, filepath, required=UNDEFINED, envs_required=UNDEFINED):
"""Load configuration from the ini file. """Load configuration from the ini file.
Loaded configuration is merged recursively over existing configuration. Loaded configuration is merged recursively over existing configuration.
@ -2017,7 +2017,7 @@ cdef class Configuration(Object):
try: try:
parser = _parse_ini_file( parser = _parse_ini_file(
filepath, filepath,
envs_required=envs_required or self._is_strict_mode_enabled(), envs_required=envs_required if envs_required is not UNDEFINED else self._is_strict_mode_enabled(),
) )
except IOError as exception: except IOError as exception:
if required is not False \ if required is not False \
@ -2036,7 +2036,7 @@ cdef class Configuration(Object):
current_config = {} current_config = {}
self.override(merge_dicts(current_config, config)) self.override(merge_dicts(current_config, config))
def from_yaml(self, filepath, required=UNDEFINED, loader=None, envs_required=False): def from_yaml(self, filepath, required=UNDEFINED, loader=None, envs_required=UNDEFINED):
"""Load configuration from the yaml file. """Load configuration from the yaml file.
Loaded configuration is merged recursively over existing configuration. Loaded configuration is merged recursively over existing configuration.
@ -2078,7 +2078,7 @@ cdef class Configuration(Object):
config_content = _resolve_config_env_markers( config_content = _resolve_config_env_markers(
config_content, config_content,
envs_required=envs_required or self._is_strict_mode_enabled(), envs_required=envs_required if envs_required is not UNDEFINED else self._is_strict_mode_enabled(),
) )
config = yaml.load(config_content, loader) config = yaml.load(config_content, loader)

View File

@ -3,7 +3,7 @@
import os import os
from dependency_injector import providers from dependency_injector import providers
from pytest import fixture from pytest import fixture, mark
@fixture @fixture
@ -51,7 +51,7 @@ def ini_config_file_2(tmp_path):
@fixture @fixture
def ini_config_file_3(tmp_path): def ini_config_file_3(tmp_path):
ini_config_file_3 = str(tmp_path / "config_1.ini") ini_config_file_3 = str(tmp_path / "config_3.ini")
with open(ini_config_file_3, "w") as file: with open(ini_config_file_3, "w") as file:
file.write( file.write(
"[section1]\n" "[section1]\n"
@ -91,7 +91,7 @@ def yaml_config_file_2(tmp_path):
@fixture @fixture
def yaml_config_file_3(tmp_path): def yaml_config_file_3(tmp_path):
yaml_config_file_3 = str(tmp_path / "config_1.yml") yaml_config_file_3 = str(tmp_path / "config_3.yml")
with open(yaml_config_file_3, "w") as file: with open(yaml_config_file_3, "w") as file:
file.write( file.write(
"section1:\n" "section1:\n"

View File

@ -63,6 +63,17 @@ def test_missing_envs_strict_mode(config, ini_config_file_3):
config.from_ini(ini_config_file_3) config.from_ini(ini_config_file_3)
@mark.parametrize("config_type", ["strict"])
def test_missing_envs_not_required_in_strict_mode(config, ini_config_file_3):
with open(ini_config_file_3, "w") as file:
file.write(
"[section]\n"
"undefined=${UNDEFINED}\n"
)
config.from_ini(ini_config_file_3, envs_required=False)
assert config.section.undefined() == ""
def test_option_missing_envs_not_required(config, ini_config_file_3): def test_option_missing_envs_not_required(config, ini_config_file_3):
del os.environ["CONFIG_TEST_ENV"] del os.environ["CONFIG_TEST_ENV"]
del os.environ["CONFIG_TEST_PATH"] del os.environ["CONFIG_TEST_PATH"]
@ -93,6 +104,18 @@ def test_option_missing_envs_required(config, ini_config_file_3):
config.option.from_ini(ini_config_file_3, envs_required=True) config.option.from_ini(ini_config_file_3, envs_required=True)
@mark.parametrize("config_type", ["strict"])
def test_option_missing_envs_not_required_in_strict_mode(config, ini_config_file_3):
config.override({"option": {}})
with open(ini_config_file_3, "w") as file:
file.write(
"[section]\n"
"undefined=${UNDEFINED}\n"
)
config.option.from_ini(ini_config_file_3, envs_required=False)
assert config.option.section.undefined() == ""
@mark.parametrize("config_type", ["strict"]) @mark.parametrize("config_type", ["strict"])
def test_option_missing_envs_strict_mode(config, ini_config_file_3): def test_option_missing_envs_strict_mode(config, ini_config_file_3):
with open(ini_config_file_3, "w") as file: with open(ini_config_file_3, "w") as file:

View File

@ -64,6 +64,17 @@ def test_missing_envs_strict_mode(config, yaml_config_file_3):
config.from_yaml(yaml_config_file_3) config.from_yaml(yaml_config_file_3)
@mark.parametrize("config_type", ["strict"])
def test_missing_envs_not_required_in_strict_mode(config, yaml_config_file_3):
with open(yaml_config_file_3, "w") as file:
file.write(
"section:\n"
" undefined: ${UNDEFINED}\n"
)
config.from_yaml(yaml_config_file_3, envs_required=False)
assert config.section.undefined() is None
def test_option_missing_envs_not_required(config, yaml_config_file_3): def test_option_missing_envs_not_required(config, yaml_config_file_3):
del os.environ["CONFIG_TEST_ENV"] del os.environ["CONFIG_TEST_ENV"]
del os.environ["CONFIG_TEST_PATH"] del os.environ["CONFIG_TEST_PATH"]
@ -94,6 +105,18 @@ def test_option_missing_envs_required(config, yaml_config_file_3):
config.option.from_yaml(yaml_config_file_3, envs_required=True) config.option.from_yaml(yaml_config_file_3, envs_required=True)
@mark.parametrize("config_type", ["strict"])
def test_option_missing_envs_not_required_in_strict_mode(config, yaml_config_file_3):
config.override({"option": {}})
with open(yaml_config_file_3, "w") as file:
file.write(
"section:\n"
" undefined: ${UNDEFINED}\n"
)
config.option.from_yaml(yaml_config_file_3, envs_required=False)
assert config.option.section.undefined() is None
@mark.parametrize("config_type", ["strict"]) @mark.parametrize("config_type", ["strict"])
def test_option_missing_envs_strict_mode(config, yaml_config_file_3): def test_option_missing_envs_strict_mode(config, yaml_config_file_3):
with open(yaml_config_file_3, "w") as file: with open(yaml_config_file_3, "w") as file:

View File

@ -72,3 +72,26 @@ def test_not_required_file_does_not_exist_strict_mode(config):
config.set_yaml_files(["./does_not_exist.yml"]) config.set_yaml_files(["./does_not_exist.yml"])
config.load(required=False) config.load(required=False)
assert config() == {} assert config() == {}
def test_missing_envs_required(config, yaml_config_file_3):
with open(yaml_config_file_3, "w") as file:
file.write(
"section:\n"
" undefined: ${UNDEFINED}\n"
)
config.set_yaml_files([yaml_config_file_3])
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
config.load(envs_required=True)
@mark.parametrize("config_type", ["strict"])
def test_missing_envs_not_required_in_strict_mode(config, yaml_config_file_3):
with open(yaml_config_file_3, "w") as file:
file.write(
"section:\n"
" undefined: ${UNDEFINED}\n"
)
config.set_yaml_files([yaml_config_file_3])
config.load(envs_required=False)
assert config.section.undefined() is None