mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-26 11:33:58 +03:00
Implement from_*() methods and add tests
This commit is contained in:
parent
3c3c6def6d
commit
73d9c97c1b
File diff suppressed because it is too large
Load Diff
|
@ -51,8 +51,8 @@ class Container:
|
|||
def reset_singletons(self) -> SingletonResetContext[C_Base]: ...
|
||||
def check_dependencies(self) -> None: ...
|
||||
def from_schema(self, schema: Dict[Any, Any]) -> None: ...
|
||||
def from_yaml_schema(self, filepath: Union[Path, str]) -> None:
|
||||
def from_json_schema(self, filepath: Union[Path, str]) -> None:
|
||||
def from_yaml_schema(self, filepath: Union[Path, str], loader: Optional[Any]=None) -> None: ...
|
||||
def from_json_schema(self, filepath: Union[Path, str]) -> None: ...
|
||||
@overload
|
||||
def resolve_provider_name(self, provider: Provider) -> str: ...
|
||||
@classmethod
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Containers module."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
try:
|
||||
|
@ -7,6 +8,11 @@ try:
|
|||
except ImportError:
|
||||
asyncio = None
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
yaml = None
|
||||
|
||||
import six
|
||||
|
||||
from . import providers, errors
|
||||
|
@ -336,15 +342,32 @@ class DynamicContainer(Container):
|
|||
for name, provider in build_schema(schema).items():
|
||||
self.set_provider(name, provider)
|
||||
|
||||
def from_yaml_schema(self, filepath):
|
||||
"""Build container providers from YAML file schema."""
|
||||
# TODO
|
||||
...
|
||||
def from_yaml_schema(self, filepath, loader=None):
|
||||
"""Build container providers from YAML schema.
|
||||
|
||||
You can specify type of loader as a second argument. By default, method
|
||||
uses ``SafeLoader``.
|
||||
"""
|
||||
if yaml is None:
|
||||
raise errors.Error(
|
||||
'Unable to load yaml schema - PyYAML is not installed. '
|
||||
'Install PyYAML or install Dependency Injector with yaml extras: '
|
||||
'"pip install dependency-injector[yaml]"'
|
||||
)
|
||||
|
||||
if loader is None:
|
||||
loader = yaml.SafeLoader
|
||||
|
||||
with open(filepath) as file:
|
||||
schema = yaml.load(file, loader)
|
||||
|
||||
self.from_schema(schema)
|
||||
|
||||
def from_json_schema(self, filepath):
|
||||
"""Build container providers from JSON file schema."""
|
||||
# TODO
|
||||
...
|
||||
"""Build container providers from JSON schema."""
|
||||
with open(filepath) as file:
|
||||
schema = json.load(file)
|
||||
self.from_schema(schema)
|
||||
|
||||
def resolve_provider_name(self, provider):
|
||||
"""Try to resolve provider name."""
|
||||
|
|
|
@ -59,9 +59,14 @@ def _setup_injections(
|
|||
arg_injections = data.get('args')
|
||||
if arg_injections:
|
||||
for arg in arg_injections:
|
||||
injection = _resolve_provider(container, arg)
|
||||
injection = None
|
||||
|
||||
if isinstance(arg, str):
|
||||
injection = _resolve_provider(container, arg)
|
||||
|
||||
if not injection:
|
||||
injection = arg
|
||||
|
||||
args.append(injection)
|
||||
if args:
|
||||
provider.add_args(*args)
|
||||
|
@ -69,9 +74,14 @@ def _setup_injections(
|
|||
kwarg_injections = data.get('kwargs')
|
||||
if kwarg_injections:
|
||||
for name, arg in kwarg_injections.items():
|
||||
injection = _resolve_provider(container, arg)
|
||||
injection = None
|
||||
|
||||
if isinstance(arg, str):
|
||||
injection = _resolve_provider(container, arg)
|
||||
|
||||
if not injection:
|
||||
injection = arg
|
||||
|
||||
kwargs[name] = injection
|
||||
if kwargs:
|
||||
provider.add_kwargs(**kwargs)
|
||||
|
@ -112,7 +122,7 @@ def _get_provider_cls(provider_cls_name: str) -> Type[providers.Provider]:
|
|||
if custom_provider_type:
|
||||
return custom_provider_type
|
||||
|
||||
raise SchemaError(f'Undefined provider class: "{provider_cls_name}"')
|
||||
raise SchemaError(f'Undefined provider class "{provider_cls_name}"')
|
||||
|
||||
|
||||
def _fetch_provider_cls_from_std(provider_cls_name: str) -> Optional[Type[providers.Provider]]:
|
||||
|
@ -134,7 +144,16 @@ def _import_provider_cls(provider_cls_name: str) -> Optional[Type[providers.Prov
|
|||
|
||||
def _import_string(string_name: str) -> Optional[object]:
|
||||
segments = string_name.split('.')
|
||||
|
||||
if len(segments) == 1:
|
||||
member = __builtins__.get(segments[0])
|
||||
if member:
|
||||
return member
|
||||
|
||||
module_name = '.'.join(segments[:-1])
|
||||
if not module_name:
|
||||
return None
|
||||
|
||||
member = segments[-1]
|
||||
module = importlib.import_module(module_name)
|
||||
return getattr(module, member, None)
|
||||
|
|
162
tests/unit/schema/test_containers_api_py36.py
Normal file
162
tests/unit/schema/test_containers_api_py36.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
import contextlib
|
||||
import json
|
||||
import os.path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import yaml
|
||||
from dependency_injector import containers, providers, errors
|
||||
|
||||
|
||||
class FromSchemaTests(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
container = containers.DynamicContainer()
|
||||
container.from_schema(
|
||||
{
|
||||
'version': '1',
|
||||
'providers': {
|
||||
'provider1': {
|
||||
'provider': 'Factory',
|
||||
'provides': 'list',
|
||||
'args': [1, 2, 3],
|
||||
},
|
||||
'provider2': {
|
||||
'provider': 'Factory',
|
||||
'provides': 'dict',
|
||||
'kwargs': {
|
||||
'one': 'provider1',
|
||||
'two': 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
self.assertIsInstance(container.provider1, providers.Factory)
|
||||
self.assertIs(container.provider1.provides, list)
|
||||
self.assertEqual(container.provider1.args, (1, 2, 3))
|
||||
|
||||
self.assertIsInstance(container.provider2, providers.Factory)
|
||||
self.assertIs(container.provider2.provides, dict)
|
||||
self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2})
|
||||
|
||||
|
||||
class FromYamlSchemaTests(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
container = containers.DynamicContainer()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
schema_path = os.path.join(tmp_dir, 'schema.yml')
|
||||
with open(schema_path, 'w') as file:
|
||||
file.write("""
|
||||
version: "1"
|
||||
providers:
|
||||
provider1:
|
||||
provider: Factory
|
||||
provides: list
|
||||
args:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
provider2:
|
||||
provider: Factory
|
||||
provides: dict
|
||||
kwargs:
|
||||
one: provider1
|
||||
two: 2
|
||||
""")
|
||||
|
||||
container.from_yaml_schema(schema_path)
|
||||
|
||||
self.assertIsInstance(container.provider1, providers.Factory)
|
||||
self.assertIs(container.provider1.provides, list)
|
||||
self.assertEqual(container.provider1.args, (1, 2, 3))
|
||||
|
||||
self.assertIsInstance(container.provider2, providers.Factory)
|
||||
self.assertIs(container.provider2.provides, dict)
|
||||
self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2})
|
||||
|
||||
def test_with_loader(self):
|
||||
container = containers.DynamicContainer()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
schema_path = os.path.join(tmp_dir, 'schema.yml')
|
||||
with open(schema_path, 'w') as file:
|
||||
file.write("""
|
||||
version: "1"
|
||||
providers:
|
||||
provider:
|
||||
provider: Factory
|
||||
provides: list
|
||||
args: [1, 2, 3]
|
||||
""")
|
||||
|
||||
container.from_yaml_schema(schema_path, loader=yaml.Loader)
|
||||
|
||||
self.assertIsInstance(container.provider, providers.Factory)
|
||||
self.assertIs(container.provider.provides, list)
|
||||
self.assertEqual(container.provider.args, (1, 2, 3))
|
||||
|
||||
def test_no_yaml_installed(self):
|
||||
@contextlib.contextmanager
|
||||
def no_yaml_module():
|
||||
containers.yaml = None
|
||||
yield
|
||||
containers.yaml = yaml
|
||||
|
||||
container = containers.DynamicContainer()
|
||||
with no_yaml_module():
|
||||
with self.assertRaises(errors.Error) as error:
|
||||
container.from_yaml_schema('./no-yaml-installed.yml')
|
||||
|
||||
self.assertEqual(
|
||||
error.exception.args[0],
|
||||
'Unable to load yaml schema - PyYAML is not installed. '
|
||||
'Install PyYAML or install Dependency Injector with yaml extras: '
|
||||
'"pip install dependency-injector[yaml]"',
|
||||
)
|
||||
|
||||
|
||||
class FromJsonSchemaTests(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
container = containers.DynamicContainer()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
schema_path = os.path.join(tmp_dir, 'schema.json')
|
||||
with open(schema_path, 'w') as file:
|
||||
file.write(
|
||||
json.dumps(
|
||||
{
|
||||
'version': '1',
|
||||
'providers': {
|
||||
'provider1': {
|
||||
'provider': 'Factory',
|
||||
'provides': 'list',
|
||||
'args': [1, 2, 3],
|
||||
},
|
||||
'provider2': {
|
||||
'provider': 'Factory',
|
||||
'provides': 'dict',
|
||||
'kwargs': {
|
||||
'one': 'provider1',
|
||||
'two': 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
indent=4,
|
||||
),
|
||||
)
|
||||
|
||||
container.from_json_schema(schema_path)
|
||||
|
||||
self.assertIsInstance(container.provider1, providers.Factory)
|
||||
self.assertIs(container.provider1.provides, list)
|
||||
self.assertEqual(container.provider1.args, (1, 2, 3))
|
||||
|
||||
self.assertIsInstance(container.provider2, providers.Factory)
|
||||
self.assertIs(container.provider2.provides, dict)
|
||||
self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2})
|
Loading…
Reference in New Issue
Block a user