mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-12-01 05:53:59 +03:00
Add init implementation and tests
This commit is contained in:
parent
6164b4f45d
commit
ea48fab8d3
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -132,8 +132,9 @@ cdef class Configuration(Object):
|
||||||
cdef str __name
|
cdef str __name
|
||||||
cdef bint __strict
|
cdef bint __strict
|
||||||
cdef dict __children
|
cdef dict __children
|
||||||
cdef list __yaml_files
|
|
||||||
cdef list __ini_files
|
cdef list __ini_files
|
||||||
|
cdef list __yaml_files
|
||||||
|
cdef list __json_files
|
||||||
cdef list __pydantic_settings
|
cdef list __pydantic_settings
|
||||||
cdef object __weakref__
|
cdef object __weakref__
|
||||||
|
|
||||||
|
|
|
@ -238,8 +238,9 @@ class Configuration(Object[Any]):
|
||||||
default: Optional[Any] = None,
|
default: Optional[Any] = None,
|
||||||
*,
|
*,
|
||||||
strict: bool = False,
|
strict: bool = False,
|
||||||
yaml_files: Optional[_Iterable[Union[Path, str]]] = None,
|
|
||||||
ini_files: Optional[_Iterable[Union[Path, str]]] = None,
|
ini_files: Optional[_Iterable[Union[Path, str]]] = None,
|
||||||
|
yaml_files: Optional[_Iterable[Union[Path, str]]] = None,
|
||||||
|
json_files: Optional[_Iterable[Union[Path, str]]] = None,
|
||||||
pydantic_settings: Optional[_Iterable[PydanticSettings]] = None,
|
pydantic_settings: Optional[_Iterable[PydanticSettings]] = None,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def __enter__(self) -> Configuration : ...
|
def __enter__(self) -> Configuration : ...
|
||||||
|
@ -259,11 +260,14 @@ class Configuration(Object[Any]):
|
||||||
def get_children(self) -> _Dict[str, ConfigurationOption]: ...
|
def get_children(self) -> _Dict[str, ConfigurationOption]: ...
|
||||||
def set_children(self, children: _Dict[str, ConfigurationOption]) -> Configuration: ...
|
def set_children(self, children: _Dict[str, ConfigurationOption]) -> Configuration: ...
|
||||||
|
|
||||||
|
def get_ini_files(self) -> _List[Union[Path, str]]: ...
|
||||||
|
def set_ini_files(self, files: _Iterable[Union[Path, str]]) -> Configuration: ...
|
||||||
|
|
||||||
def get_yaml_files(self) -> _List[Union[Path, str]]: ...
|
def get_yaml_files(self) -> _List[Union[Path, str]]: ...
|
||||||
def set_yaml_files(self, files: _Iterable[Union[Path, str]]) -> Configuration: ...
|
def set_yaml_files(self, files: _Iterable[Union[Path, str]]) -> Configuration: ...
|
||||||
|
|
||||||
def get_ini_files(self) -> _List[Union[Path, str]]: ...
|
def get_json_files(self) -> _List[Union[Path, str]]: ...
|
||||||
def set_ini_files(self, files: _Iterable[Union[Path, str]]) -> Configuration: ...
|
def set_json_files(self, files: _Iterable[Union[Path, str]]) -> Configuration: ...
|
||||||
|
|
||||||
def get_pydantic_settings(self) -> _List[PydanticSettings]: ...
|
def get_pydantic_settings(self) -> _List[PydanticSettings]: ...
|
||||||
def set_pydantic_settings(self, settings: _Iterable[PydanticSettings]) -> Configuration: ...
|
def set_pydantic_settings(self, settings: _Iterable[PydanticSettings]) -> Configuration: ...
|
||||||
|
|
|
@ -1925,24 +1925,29 @@ cdef class Configuration(Object):
|
||||||
|
|
||||||
DEFAULT_NAME = "config"
|
DEFAULT_NAME = "config"
|
||||||
|
|
||||||
def __init__(self, name=DEFAULT_NAME, default=None, strict=False, yaml_files=None, ini_files=None, pydantic_settings=None):
|
def __init__(self, name=DEFAULT_NAME, default=None, strict=False, ini_files=None, yaml_files=None, json_files=None, pydantic_settings=None):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__strict = strict
|
self.__strict = strict
|
||||||
self.__children = {}
|
self.__children = {}
|
||||||
self.__yaml_files = []
|
|
||||||
self.__ini_files = []
|
self.__ini_files = []
|
||||||
|
self.__yaml_files = []
|
||||||
|
self.__json_files = []
|
||||||
self.__pydantic_settings = []
|
self.__pydantic_settings = []
|
||||||
|
|
||||||
super().__init__(provides={})
|
super().__init__(provides={})
|
||||||
self.set_default(default)
|
self.set_default(default)
|
||||||
|
|
||||||
|
if ini_files is None:
|
||||||
|
ini_files = []
|
||||||
|
self.set_ini_files(ini_files)
|
||||||
|
|
||||||
if yaml_files is None:
|
if yaml_files is None:
|
||||||
yaml_files = []
|
yaml_files = []
|
||||||
self.set_yaml_files(yaml_files)
|
self.set_yaml_files(yaml_files)
|
||||||
|
|
||||||
if ini_files is None:
|
if json_files is None:
|
||||||
ini_files = []
|
json_files = []
|
||||||
self.set_ini_files(ini_files)
|
self.set_json_files(json_files)
|
||||||
|
|
||||||
if pydantic_settings is None:
|
if pydantic_settings is None:
|
||||||
pydantic_settings = []
|
pydantic_settings = []
|
||||||
|
@ -1958,8 +1963,9 @@ cdef class Configuration(Object):
|
||||||
copied.set_default(self.get_default())
|
copied.set_default(self.get_default())
|
||||||
copied.set_strict(self.get_strict())
|
copied.set_strict(self.get_strict())
|
||||||
copied.set_children(deepcopy(self.get_children(), memo))
|
copied.set_children(deepcopy(self.get_children(), memo))
|
||||||
copied.set_yaml_files(self.get_yaml_files())
|
|
||||||
copied.set_ini_files(self.get_ini_files())
|
copied.set_ini_files(self.get_ini_files())
|
||||||
|
copied.set_yaml_files(self.get_yaml_files())
|
||||||
|
copied.set_json_files(self.get_json_files())
|
||||||
copied.set_pydantic_settings(self.get_pydantic_settings())
|
copied.set_pydantic_settings(self.get_pydantic_settings())
|
||||||
|
|
||||||
self._copy_overridings(copied, memo)
|
self._copy_overridings(copied, memo)
|
||||||
|
@ -2052,6 +2058,15 @@ cdef class Configuration(Object):
|
||||||
self.__yaml_files = list(files)
|
self.__yaml_files = list(files)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def get_json_files(self):
|
||||||
|
"""Return list of JSON files."""
|
||||||
|
return list(self.__json_files)
|
||||||
|
|
||||||
|
def set_json_files(self, files):
|
||||||
|
"""Set list of JSON files."""
|
||||||
|
self.__json_files = list(files)
|
||||||
|
return self
|
||||||
|
|
||||||
def get_pydantic_settings(self):
|
def get_pydantic_settings(self):
|
||||||
"""Return list of Pydantic settings."""
|
"""Return list of Pydantic settings."""
|
||||||
return list(self.__pydantic_settings)
|
return list(self.__pydantic_settings)
|
||||||
|
@ -2078,11 +2093,14 @@ cdef class Configuration(Object):
|
||||||
:param envs_required: When True, raises an error on undefined environment variable.
|
:param envs_required: When True, raises an error on undefined environment variable.
|
||||||
:type envs_required: bool
|
:type envs_required: bool
|
||||||
"""
|
"""
|
||||||
|
for file in self.get_ini_files():
|
||||||
|
self.from_ini(file, required=required, envs_required=envs_required)
|
||||||
|
|
||||||
for file in self.get_yaml_files():
|
for file in self.get_yaml_files():
|
||||||
self.from_yaml(file, required=required, envs_required=envs_required)
|
self.from_yaml(file, required=required, envs_required=envs_required)
|
||||||
|
|
||||||
for file in self.get_ini_files():
|
for file in self.get_json_files():
|
||||||
self.from_ini(file, required=required, envs_required=envs_required)
|
self.from_json(file, required=required, envs_required=envs_required)
|
||||||
|
|
||||||
for settings in self.get_pydantic_settings():
|
for settings in self.get_pydantic_settings():
|
||||||
self.from_pydantic(settings, required=required)
|
self.from_pydantic(settings, required=required)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from dependency_injector import providers
|
from dependency_injector import providers
|
||||||
|
from pydantic import BaseSettings as PydanticSettings
|
||||||
|
|
||||||
|
|
||||||
# Test 1: to check the getattr
|
# Test 1: to check the getattr
|
||||||
|
@ -8,7 +10,19 @@ provider1 = providers.Factory(dict, a=config1.a)
|
||||||
|
|
||||||
# Test 2: to check the from_*() method
|
# Test 2: to check the from_*() method
|
||||||
config2 = providers.Configuration()
|
config2 = providers.Configuration()
|
||||||
|
config2_init_args = providers.Configuration(
|
||||||
|
name="config",
|
||||||
|
strict=True,
|
||||||
|
default={},
|
||||||
|
ini_files=["config.ini", Path("config.ini")],
|
||||||
|
yaml_files=["config.yml", Path("config.yml")],
|
||||||
|
json_files=["config.json", Path("config.json")],
|
||||||
|
pydantic_settings=[PydanticSettings()],
|
||||||
|
)
|
||||||
|
|
||||||
config2.from_dict({})
|
config2.from_dict({})
|
||||||
|
config2.from_value({})
|
||||||
|
|
||||||
config2.from_ini("config.ini")
|
config2.from_ini("config.ini")
|
||||||
config2.from_ini(Path("config.ini"))
|
config2.from_ini(Path("config.ini"))
|
||||||
|
|
||||||
|
@ -23,6 +37,8 @@ config2.from_env("ENV", as_=int, default=123)
|
||||||
config2.from_env("ENV", as_=float, required=True)
|
config2.from_env("ENV", as_=float, required=True)
|
||||||
config2.from_env("ENV", as_=lambda env: str(env))
|
config2.from_env("ENV", as_=lambda env: str(env))
|
||||||
|
|
||||||
|
config2.from_pydantic(PydanticSettings())
|
||||||
|
|
||||||
# Test 3: to check as_*() methods
|
# Test 3: to check as_*() methods
|
||||||
config3 = providers.Configuration()
|
config3 = providers.Configuration()
|
||||||
int3: providers.Callable[int] = config3.option.as_int()
|
int3: providers.Callable[int] = config3.option.as_int()
|
||||||
|
|
|
@ -47,6 +47,11 @@ def test_set_files(config):
|
||||||
assert config.get_ini_files() == ["file1.ini", "file2.ini"]
|
assert config.get_ini_files() == ["file1.ini", "file2.ini"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy(config, ini_config_file_1, ini_config_file_2):
|
||||||
|
config_copy = providers.deepcopy(config)
|
||||||
|
assert config_copy.get_ini_files() == [ini_config_file_1, ini_config_file_2]
|
||||||
|
|
||||||
|
|
||||||
def test_file_does_not_exist(config):
|
def test_file_does_not_exist(config):
|
||||||
config.set_ini_files(["./does_not_exist.ini"])
|
config.set_ini_files(["./does_not_exist.ini"])
|
||||||
config.load()
|
config.load()
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
"""Configuration(json_files=[...]) tests."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config(config_type, json_config_file_1, json_config_file_2):
|
||||||
|
if config_type == "strict":
|
||||||
|
return providers.Configuration(strict=True)
|
||||||
|
elif config_type == "default":
|
||||||
|
return providers.Configuration(json_files=[json_config_file_1, json_config_file_2])
|
||||||
|
else:
|
||||||
|
raise ValueError("Undefined config type \"{0}\"".format(config_type))
|
||||||
|
|
||||||
|
|
||||||
|
def test_load(config):
|
||||||
|
config.load()
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": 11,
|
||||||
|
"value11": 11,
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": 2,
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {"value1": 11, "value11": 11}
|
||||||
|
assert config.section1.value1() == 11
|
||||||
|
assert config.section1.value11() == 11
|
||||||
|
assert config.section2() == {"value2": 2}
|
||||||
|
assert config.section2.value2() == 2
|
||||||
|
assert config.section3() == {"value3": 3}
|
||||||
|
assert config.section3.value3() == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_files(config, json_config_file_1, json_config_file_2):
|
||||||
|
assert config.get_json_files() == [json_config_file_1, json_config_file_2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_files(config):
|
||||||
|
config.set_json_files(["file1.json", "file2.json"])
|
||||||
|
assert config.get_json_files() == ["file1.json", "file2.json"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy(config, json_config_file_1, json_config_file_2):
|
||||||
|
config_copy = providers.deepcopy(config)
|
||||||
|
assert config_copy.get_json_files() == [json_config_file_1, json_config_file_2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_does_not_exist(config):
|
||||||
|
config.set_json_files(["./does_not_exist.json"])
|
||||||
|
config.load()
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_file_does_not_exist_strict_mode(config):
|
||||||
|
config.set_json_files(["./does_not_exist.json"])
|
||||||
|
with raises(IOError):
|
||||||
|
config.load()
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_file_does_not_exist(config):
|
||||||
|
config.set_json_files(["./does_not_exist.json"])
|
||||||
|
with raises(IOError):
|
||||||
|
config.load(required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_file_does_not_exist_strict_mode(config):
|
||||||
|
config.set_json_files(["./does_not_exist.json"])
|
||||||
|
config.load(required=False)
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_envs_required(config, json_config_file_3):
|
||||||
|
with open(json_config_file_3, "w") as file:
|
||||||
|
file.write(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"section": {
|
||||||
|
"undefined": "${UNDEFINED}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
config.set_json_files([json_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, json_config_file_3):
|
||||||
|
with open(json_config_file_3, "w") as file:
|
||||||
|
file.write(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"section": {
|
||||||
|
"undefined": "${UNDEFINED}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
config.set_json_files([json_config_file_3])
|
||||||
|
config.load(envs_required=False)
|
||||||
|
assert config.section.undefined() == ""
|
|
@ -80,6 +80,11 @@ def test_get_pydantic_settings(config, pydantic_settings_1, pydantic_settings_2)
|
||||||
assert config.get_pydantic_settings() == [pydantic_settings_1, pydantic_settings_2]
|
assert config.get_pydantic_settings() == [pydantic_settings_1, pydantic_settings_2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy(config, pydantic_settings_1, pydantic_settings_2):
|
||||||
|
config_copy = providers.deepcopy(config)
|
||||||
|
assert config_copy.get_pydantic_settings() == [pydantic_settings_1, pydantic_settings_2]
|
||||||
|
|
||||||
|
|
||||||
def test_set_pydantic_settings(config):
|
def test_set_pydantic_settings(config):
|
||||||
class Settings3(pydantic.BaseSettings):
|
class Settings3(pydantic.BaseSettings):
|
||||||
...
|
...
|
||||||
|
|
|
@ -47,6 +47,11 @@ def test_set_files(config):
|
||||||
assert config.get_yaml_files() == ["file1.yml", "file2.yml"]
|
assert config.get_yaml_files() == ["file1.yml", "file2.yml"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy(config, yaml_config_file_1, yaml_config_file_2):
|
||||||
|
config_copy = providers.deepcopy(config)
|
||||||
|
assert config_copy.get_yaml_files() == [yaml_config_file_1, yaml_config_file_2]
|
||||||
|
|
||||||
|
|
||||||
def test_file_does_not_exist(config):
|
def test_file_does_not_exist(config):
|
||||||
config.set_yaml_files(["./does_not_exist.yml"])
|
config.set_yaml_files(["./does_not_exist.yml"])
|
||||||
config.load()
|
config.load()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user