mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-07-23 14:29:53 +03:00
Add full test coverage + bugfix
This commit is contained in:
parent
1005c51bd0
commit
24ea8acc7c
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,11 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
yaml = None
|
yaml = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pydantic
|
||||||
|
except ImportError:
|
||||||
|
pydantic = None
|
||||||
|
|
||||||
from . import resources
|
from . import resources
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,6 +167,7 @@ class ConfigurationOption(Provider[Any]):
|
||||||
def update(self, value: Any) -> 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) -> None: ...
|
||||||
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any]=None) -> None: ...
|
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any]=None) -> 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: ...
|
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...
|
||||||
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
|
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
|
||||||
|
|
||||||
|
@ -183,6 +189,7 @@ class Configuration(Object[Any]):
|
||||||
def update(self, value: Any) -> 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) -> None: ...
|
||||||
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any]=None) -> None: ...
|
def from_yaml(self, filepath: Union[Path, str], required: bool = False, loader: Optional[Any]=None) -> 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: ...
|
def from_dict(self, options: _Dict[str, Any], required: bool = False) -> None: ...
|
||||||
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
|
def from_env(self, name: str, default: Optional[Any] = None, required: bool = False) -> None: ...
|
||||||
|
|
||||||
|
@ -397,3 +404,8 @@ if yaml:
|
||||||
class YamlLoader(yaml.SafeLoader): ...
|
class YamlLoader(yaml.SafeLoader): ...
|
||||||
else:
|
else:
|
||||||
class YamlLoader: ...
|
class YamlLoader: ...
|
||||||
|
|
||||||
|
if pydantic:
|
||||||
|
PydanticSettings = pydantic.BaseSettings
|
||||||
|
else:
|
||||||
|
PydanticSettings = Any
|
||||||
|
|
|
@ -1460,6 +1460,12 @@ cdef class ConfigurationOption(Provider):
|
||||||
'"pip install dependency-injector[pydantic]"'
|
'"pip install dependency-injector[pydantic]"'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic.BaseSettings):
|
||||||
|
raise Error(
|
||||||
|
'Got settings class, but expect instance: '
|
||||||
|
'instead "{0}" use "{0}()"'.format(settings.__name__)
|
||||||
|
)
|
||||||
|
|
||||||
if not isinstance(settings, pydantic.BaseSettings):
|
if not isinstance(settings, pydantic.BaseSettings):
|
||||||
raise Error(
|
raise Error(
|
||||||
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
||||||
|
@ -1824,6 +1830,12 @@ cdef class Configuration(Object):
|
||||||
'"pip install dependency-injector[pydantic]"'
|
'"pip install dependency-injector[pydantic]"'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic.BaseSettings):
|
||||||
|
raise Error(
|
||||||
|
'Got settings class, but expect instance: '
|
||||||
|
'instead "{0}" use "{0}()"'.format(settings.__name__)
|
||||||
|
)
|
||||||
|
|
||||||
if not isinstance(settings, pydantic.BaseSettings):
|
if not isinstance(settings, pydantic.BaseSettings):
|
||||||
raise Error(
|
raise Error(
|
||||||
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
||||||
|
|
|
@ -754,7 +754,7 @@ class ConfigFromPydanticTests(unittest.TestCase):
|
||||||
|
|
||||||
class Settings2(pydantic.BaseSettings):
|
class Settings2(pydantic.BaseSettings):
|
||||||
section1 = Section21()
|
section1 = Section21()
|
||||||
section2 = Section3()
|
section3 = Section3()
|
||||||
|
|
||||||
self.Settings2 = Settings2
|
self.Settings2 = Settings2
|
||||||
|
|
||||||
|
@ -767,78 +767,109 @@ class ConfigFromPydanticTests(unittest.TestCase):
|
||||||
self.assertEqual(self.config.section2(), {'value2': 2})
|
self.assertEqual(self.config.section2(), {'value2': 2})
|
||||||
self.assertEqual(self.config.section2.value2(), 2)
|
self.assertEqual(self.config.section2.value2(), 2)
|
||||||
|
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
def test_merge(self):
|
||||||
# def test_merge(self):
|
self.config.from_pydantic(self.Settings1())
|
||||||
# self.config.from_yaml(self.config_file_1)
|
self.config.from_pydantic(self.Settings2())
|
||||||
# self.config.from_yaml(self.config_file_2)
|
|
||||||
#
|
self.assertEqual(
|
||||||
# self.assertEqual(
|
self.config(),
|
||||||
# self.config(),
|
{
|
||||||
# {
|
'section1': {
|
||||||
# 'section1': {
|
'value1': 11,
|
||||||
# 'value1': 11,
|
'value11': 11,
|
||||||
# 'value11': 11,
|
},
|
||||||
# },
|
'section2': {
|
||||||
# 'section2': {
|
'value2': 2,
|
||||||
# 'value2': 2,
|
},
|
||||||
# },
|
'section3': {
|
||||||
# 'section3': {
|
'value3': 3,
|
||||||
# 'value3': 3,
|
},
|
||||||
# },
|
},
|
||||||
# },
|
)
|
||||||
# )
|
self.assertEqual(self.config.section1(), {'value1': 11, 'value11': 11})
|
||||||
# self.assertEqual(self.config.section1(), {'value1': 11, 'value11': 11})
|
self.assertEqual(self.config.section1.value1(), 11)
|
||||||
# self.assertEqual(self.config.section1.value1(), 11)
|
self.assertEqual(self.config.section1.value11(), 11)
|
||||||
# self.assertEqual(self.config.section1.value11(), 11)
|
self.assertEqual(self.config.section2(), {'value2': 2})
|
||||||
# self.assertEqual(self.config.section2(), {'value2': 2})
|
self.assertEqual(self.config.section2.value2(), 2)
|
||||||
# self.assertEqual(self.config.section2.value2(), 2)
|
self.assertEqual(self.config.section3(), {'value3': 3})
|
||||||
# self.assertEqual(self.config.section3(), {'value3': 3})
|
self.assertEqual(self.config.section3.value3(), 3)
|
||||||
# self.assertEqual(self.config.section3.value3(), 3)
|
|
||||||
#
|
def test_empty_settings(self):
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
self.config.from_pydantic(pydantic.BaseSettings())
|
||||||
# def test_file_does_not_exist(self):
|
self.assertEqual(self.config(), {})
|
||||||
# self.config.from_yaml('./does_not_exist.yml')
|
|
||||||
# self.assertEqual(self.config(), {})
|
def test_empty_settings_strict_mode(self):
|
||||||
#
|
self.config = providers.Configuration(strict=True)
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
with self.assertRaises(ValueError):
|
||||||
# def test_file_does_not_exist_strict_mode(self):
|
self.config.from_pydantic(pydantic.BaseSettings())
|
||||||
# self.config = providers.Configuration(strict=True)
|
|
||||||
# with self.assertRaises(IOError):
|
def test_option_empty_settings(self):
|
||||||
# self.config.from_yaml('./does_not_exist.yml')
|
self.config.option.from_pydantic(pydantic.BaseSettings())
|
||||||
#
|
self.assertEqual(self.config.option(), {})
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
|
||||||
# def test_option_file_does_not_exist(self):
|
def test_option_empty_settings_strict_mode(self):
|
||||||
# self.config.option.from_yaml('./does_not_exist.yml')
|
self.config = providers.Configuration(strict=True)
|
||||||
# self.assertIsNone(self.config.option())
|
with self.assertRaises(ValueError):
|
||||||
#
|
self.config.option.from_pydantic(pydantic.BaseSettings())
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
|
||||||
# def test_option_file_does_not_exist_strict_mode(self):
|
def test_required_empty_settings(self):
|
||||||
# self.config = providers.Configuration(strict=True)
|
with self.assertRaises(ValueError):
|
||||||
# with self.assertRaises(IOError):
|
self.config.from_pydantic(pydantic.BaseSettings(), required=True)
|
||||||
# self.config.option.from_yaml('./does_not_exist.yml')
|
|
||||||
#
|
def test_required_option_empty_settings(self):
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
with self.assertRaises(ValueError):
|
||||||
# def test_required_file_does_not_exist(self):
|
self.config.option.from_pydantic(pydantic.BaseSettings(), required=True)
|
||||||
# with self.assertRaises(IOError):
|
|
||||||
# self.config.from_yaml('./does_not_exist.yml', required=True)
|
def test_not_required_empty_settings_strict_mode(self):
|
||||||
#
|
self.config = providers.Configuration(strict=True)
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
self.config.from_pydantic(pydantic.BaseSettings(), required=False)
|
||||||
# def test_required_option_file_does_not_exist(self):
|
self.assertEqual(self.config(), {})
|
||||||
# with self.assertRaises(IOError):
|
|
||||||
# self.config.option.from_yaml('./does_not_exist.yml', required=True)
|
def test_not_required_option_empty_settings_strict_mode(self):
|
||||||
#
|
self.config = providers.Configuration(strict=True)
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
self.config.option.from_pydantic(pydantic.BaseSettings(), required=False)
|
||||||
# def test_not_required_file_does_not_exist_strict_mode(self):
|
self.assertEqual(self.config.option(), {})
|
||||||
# self.config = providers.Configuration(strict=True)
|
self.assertEqual(self.config(), {'option': {}})
|
||||||
# self.config.from_yaml('./does_not_exist.yml', required=False)
|
|
||||||
# self.assertEqual(self.config(), {})
|
def test_not_instance_of_settings(self):
|
||||||
#
|
with self.assertRaises(errors.Error) as error:
|
||||||
# @unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
self.config.from_pydantic({})
|
||||||
# def test_not_required_option_file_does_not_exist_strict_mode(self):
|
|
||||||
# self.config = providers.Configuration(strict=True)
|
self.assertEqual(
|
||||||
# self.config.option.from_yaml('./does_not_exist.yml', required=False)
|
error.exception.args[0],
|
||||||
# with self.assertRaises(errors.Error):
|
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
||||||
# self.config.option()
|
'got {0} instead'.format({})
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_option_not_instance_of_settings(self):
|
||||||
|
with self.assertRaises(errors.Error) as error:
|
||||||
|
self.config.option.from_pydantic({})
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
error.exception.args[0],
|
||||||
|
'Unable to recognize settings instance, expect "pydantic.BaseSettings", '
|
||||||
|
'got {0} instead'.format({})
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_subclass_instead_of_instance(self):
|
||||||
|
with self.assertRaises(errors.Error) as error:
|
||||||
|
self.config.from_pydantic(self.Settings1)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
error.exception.args[0],
|
||||||
|
'Got settings class, but expect instance: '
|
||||||
|
'instead "Settings1" use "Settings1()"'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_option_subclass_instead_of_instance(self):
|
||||||
|
with self.assertRaises(errors.Error) as error:
|
||||||
|
self.config.option.from_pydantic(self.Settings1)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
error.exception.args[0],
|
||||||
|
'Got settings class, but expect instance: '
|
||||||
|
'instead "Settings1" use "Settings1()"'
|
||||||
|
)
|
||||||
|
|
||||||
def test_no_pydantic_installed(self):
|
def test_no_pydantic_installed(self):
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
@ -861,6 +892,27 @@ class ConfigFromPydanticTests(unittest.TestCase):
|
||||||
'"pip install dependency-injector[pydantic]"',
|
'"pip install dependency-injector[pydantic]"',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_option_no_pydantic_installed(self):
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def no_pydantic_module():
|
||||||
|
pydantic = providers.pydantic
|
||||||
|
providers.pydantic = None
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
providers.pydantic = pydantic
|
||||||
|
|
||||||
|
with no_pydantic_module():
|
||||||
|
with self.assertRaises(errors.Error) as error:
|
||||||
|
self.config.option.from_pydantic(self.Settings1())
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
error.exception.args[0],
|
||||||
|
'Unable to load pydantic configuration - pydantic is not installed. '
|
||||||
|
'Install pydantic or install Dependency Injector with pydantic extras: '
|
||||||
|
'"pip install dependency-injector[pydantic]"',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConfigFromDict(unittest.TestCase):
|
class ConfigFromDict(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user