Add tests for .from_ini() for config and config option

This commit is contained in:
Roman Mogylatov 2021-06-21 21:00:14 -04:00
parent 534b9691fa
commit f77c8b13e9
4 changed files with 8210 additions and 7830 deletions

File diff suppressed because it is too large Load Diff

View File

@ -200,7 +200,7 @@ class ConfigurationOption(Provider[Any]):
def required(self) -> ConfigurationOption: ...
def is_required(self) -> bool: ...
def update(self, value: Any) -> None: ...
def from_ini(self, filepath: Union[Path, str], required: bool = False) -> None: ...
def from_ini(self, filepath: Union[Path, str], required: bool = False, envs_required: bool = False) -> None: ...
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any] = None, envs_required: bool = False) -> None: ...
def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ...
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...
@ -237,7 +237,7 @@ class Configuration(Object[Any]):
def set(self, selector: str, value: Any) -> OverridingContext[P]: ...
def reset_cache(self) -> None: ...
def update(self, value: Any) -> None: ...
def from_ini(self, filepath: Union[Path, str], required: bool = False) -> None: ...
def from_ini(self, filepath: Union[Path, str], required: bool = False, envs_required: bool = False) -> None: ...
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any] = None, envs_required: bool = False) -> None: ...
def from_pydantic(self, settings: PydanticSettings, required: bool = False, **kwargs: Any) -> None: ...
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...

View File

@ -88,19 +88,25 @@ def _resolve_config_env_markers(config_content, envs_required=False):
if sys.version_info[0] == 3:
def _parse_ini_file(filepath):
def _parse_ini_file(filepath, envs_required=False):
parser = iniconfigparser.ConfigParser()
with open(filepath) as config_file:
config_string = _resolve_config_env_markers(config_file.read())
config_string = _resolve_config_env_markers(
config_file.read(),
envs_required=envs_required,
)
parser.read_string(config_string)
return parser
else:
import StringIO
def _parse_ini_file(filepath):
def _parse_ini_file(filepath, envs_required=False):
parser = iniconfigparser.ConfigParser()
with open(filepath) as config_file:
config_string = _resolve_config_env_markers(config_file.read())
config_string = _resolve_config_env_markers(
config_file.read(),
envs_required=envs_required,
)
parser.readfp(StringIO.StringIO(config_string))
return parser
@ -1521,7 +1527,7 @@ cdef class ConfigurationOption(Provider):
"""
self.override(value)
def from_ini(self, filepath, required=UNDEFINED):
def from_ini(self, filepath, required=UNDEFINED, envs_required=False):
"""Load configuration from the ini file.
Loaded configuration is merged recursively over existing configuration.
@ -1532,10 +1538,16 @@ cdef class ConfigurationOption(Provider):
:param required: When required is True, raise an exception if file does not exist.
:type required: bool
:param envs_required: When True, raises an error on undefined environment variable.
:type envs_required: bool
:rtype: None
"""
try:
parser = _parse_ini_file(filepath)
parser = _parse_ini_file(
filepath,
envs_required=envs_required or self._is_strict_mode_enabled(),
)
except IOError as exception:
if required is not False \
and (self._is_strict_mode_enabled() or required is True) \
@ -1951,7 +1963,7 @@ cdef class Configuration(Object):
"""
self.override(value)
def from_ini(self, filepath, required=UNDEFINED):
def from_ini(self, filepath, required=UNDEFINED, envs_required=False):
"""Load configuration from the ini file.
Loaded configuration is merged recursively over existing configuration.
@ -1962,10 +1974,16 @@ cdef class Configuration(Object):
:param required: When required is True, raise an exception if file does not exist.
:type required: bool
:param envs_required: When True, raises an error on undefined environment variable.
:type envs_required: bool
:rtype: None
"""
try:
parser = _parse_ini_file(filepath)
parser = _parse_ini_file(
filepath,
envs_required=envs_required or self._is_strict_mode_enabled(),
)
except IOError as exception:
if required is not False \
and (self._is_strict_mode_enabled() or required is True) \

View File

@ -629,7 +629,7 @@ class ConfigFromIniWithEnvInterpolationTests(unittest.TestCase):
self.assertEqual(self.config.section1.value1(), 'test-value')
self.assertEqual(self.config.section1.value2(), 'test-path/path')
def test_missing_envs(self):
def test_missing_envs_not_required(self):
del os.environ['CONFIG_TEST_ENV']
del os.environ['CONFIG_TEST_PATH']
@ -654,7 +654,38 @@ class ConfigFromIniWithEnvInterpolationTests(unittest.TestCase):
self.assertEqual(self.config.section1.value1(), '')
self.assertEqual(self.config.section1.value2(), '/path')
def test_option_missing_envs(self):
def test_missing_envs_required(self):
with open(self.config_file, 'w') as config_file:
config_file.write(
'[section]\n'
'undefined=${UNDEFINED}\n'
)
with self.assertRaises(ValueError) as context:
self.config.from_ini(self.config_file, envs_required=True)
self.assertEqual(
str(context.exception),
'Missing required environment variable "UNDEFINED"',
)
def test_missing_envs_strict_mode(self):
with open(self.config_file, 'w') as config_file:
config_file.write(
'[section]\n'
'undefined=${UNDEFINED}\n'
)
self.config.set_strict(True)
with self.assertRaises(ValueError) as context:
self.config.from_ini(self.config_file)
self.assertEqual(
str(context.exception),
'Missing required environment variable "UNDEFINED"',
)
def test_option_missing_envs_not_required(self):
del os.environ['CONFIG_TEST_ENV']
del os.environ['CONFIG_TEST_PATH']
@ -679,6 +710,37 @@ class ConfigFromIniWithEnvInterpolationTests(unittest.TestCase):
self.assertEqual(self.config.option.section1.value1(), '')
self.assertEqual(self.config.option.section1.value2(), '/path')
def test_option_missing_envs_required(self):
with open(self.config_file, 'w') as config_file:
config_file.write(
'[section]\n'
'undefined=${UNDEFINED}\n'
)
with self.assertRaises(ValueError) as context:
self.config.option.from_ini(self.config_file, envs_required=True)
self.assertEqual(
str(context.exception),
'Missing required environment variable "UNDEFINED"',
)
def test_option_missing_envs_strict_mode(self):
with open(self.config_file, 'w') as config_file:
config_file.write(
'[section]\n'
'undefined=${UNDEFINED}\n'
)
self.config.set_strict(True)
with self.assertRaises(ValueError) as context:
self.config.option.from_ini(self.config_file)
self.assertEqual(
str(context.exception),
'Missing required environment variable "UNDEFINED"',
)
def test_default_values(self):
os.environ['DEFINED'] = 'defined'
self.addCleanup(os.environ.pop, 'DEFINED')
@ -964,7 +1026,7 @@ class ConfigFromYamlWithEnvInterpolationTests(unittest.TestCase):
)
@unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
def test_option_missing_envs(self):
def test_option_missing_envs_not_required(self):
del os.environ['CONFIG_TEST_ENV']
del os.environ['CONFIG_TEST_PATH']