mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-23 10:03:56 +03:00
Implement POC
This commit is contained in:
parent
08ea99759d
commit
a485228fa2
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,7 @@ class Container:
|
|||
providers: Dict[str, Provider]
|
||||
dependencies: Dict[str, Provider]
|
||||
overridden: Tuple[Provider]
|
||||
wiring_config: Dict[str, Any]
|
||||
__self__: Self
|
||||
def __init__(self) -> None: ...
|
||||
def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
|
||||
|
@ -43,6 +44,7 @@ class Container:
|
|||
def override_providers(self, **overriding_providers: Union[Provider, Any]) -> None: ...
|
||||
def reset_last_overriding(self) -> None: ...
|
||||
def reset_override(self) -> None: ...
|
||||
def is_auto_wiring_enabled(self) -> bool: ...
|
||||
def wire(self, modules: Optional[Iterable[Any]] = None, packages: Optional[Iterable[Any]] = None, from_package: Optional[str] = None) -> None: ...
|
||||
def unwire(self) -> None: ...
|
||||
def init_resources(self) -> Optional[Awaitable]: ...
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Containers module."""
|
||||
|
||||
import contextlib
|
||||
import copy as copy_module
|
||||
import json
|
||||
import sys
|
||||
import importlib
|
||||
|
@ -77,6 +78,7 @@ class DynamicContainer(Container):
|
|||
self.overridden = tuple()
|
||||
self.parent = None
|
||||
self.declarative_parent = None
|
||||
self.wiring_config = {}
|
||||
self.wired_to_modules = []
|
||||
self.wired_to_packages = []
|
||||
self.__self__ = providers.Self(self)
|
||||
|
@ -97,6 +99,7 @@ class DynamicContainer(Container):
|
|||
|
||||
copied.provider_type = providers.Provider
|
||||
copied.overridden = providers.deepcopy(self.overridden, memo)
|
||||
copied.wiring_config = copy_module.deepcopy(self.wiring_config, memo)
|
||||
copied.declarative_parent = self.declarative_parent
|
||||
|
||||
for name, provider in providers.deepcopy(self.providers, memo).items():
|
||||
|
@ -251,18 +254,35 @@ class DynamicContainer(Container):
|
|||
for provider in six.itervalues(self.providers):
|
||||
provider.reset_override()
|
||||
|
||||
def is_auto_wiring_enabled(self):
|
||||
"""Check if auto wiring is enabled."""
|
||||
return self.wiring_config.get("auto_wire") is True
|
||||
|
||||
def wire(self, modules=None, packages=None, from_package=None):
|
||||
"""Wire container providers with provided packages and modules.
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
if modules is None and "modules" in self.wiring_config:
|
||||
modules = self.wiring_config["modules"]
|
||||
if packages is None and "packages" in self.wiring_config:
|
||||
packages = self.wiring_config["packages"]
|
||||
|
||||
modules = [*modules] if modules else []
|
||||
packages = [*packages] if packages else []
|
||||
|
||||
if _any_relative_string_imports_in(modules) or _any_relative_string_imports_in(packages):
|
||||
if from_package is None:
|
||||
with contextlib.suppress(Exception):
|
||||
from_package = _resolve_calling_package_name()
|
||||
if "from_package" in self.wiring_config:
|
||||
from_package = self.wiring_config["from_package"]
|
||||
elif self.declarative_parent is not None \
|
||||
and ("modules" in self.wiring_config
|
||||
or "packages" in self.wiring_config):
|
||||
with contextlib.suppress(Exception):
|
||||
from_package = _resolve_package_name_from_cls(self.declarative_parent)
|
||||
else:
|
||||
with contextlib.suppress(Exception):
|
||||
from_package = _resolve_calling_package_name()
|
||||
|
||||
modules = _resolve_string_imports(modules, from_package)
|
||||
packages = _resolve_string_imports(packages, from_package)
|
||||
|
@ -467,6 +487,7 @@ class DeclarativeContainerMetaClass(type):
|
|||
attributes['inherited_providers'] = inherited_providers
|
||||
attributes['cls_providers'] = cls_providers
|
||||
attributes['providers'] = all_providers
|
||||
attributes['wiring_config'] = attributes.get('wiring_config', {})
|
||||
|
||||
cls = <type>type.__new__(mcs, class_name, bases, attributes)
|
||||
|
||||
|
@ -617,6 +638,12 @@ class DeclarativeContainer(Container):
|
|||
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
|
||||
"""
|
||||
|
||||
wiring_config = dict()
|
||||
"""Dictionary of wiring configuration.
|
||||
|
||||
:type: dict[str, Any]
|
||||
"""
|
||||
|
||||
cls_providers = dict()
|
||||
"""Read-only dictionary of current container providers.
|
||||
|
||||
|
@ -649,6 +676,7 @@ class DeclarativeContainer(Container):
|
|||
"""
|
||||
container = cls.instance_type()
|
||||
container.provider_type = cls.provider_type
|
||||
container.wiring_config = copy_module.deepcopy(cls.wiring_config)
|
||||
container.declarative_parent = cls
|
||||
|
||||
copied_providers = providers.deepcopy({ **cls.providers, **{'@@self@@': cls.__self__}})
|
||||
|
@ -665,6 +693,9 @@ class DeclarativeContainer(Container):
|
|||
container.override_providers(**overriding_providers)
|
||||
container.apply_container_providers_overridings()
|
||||
|
||||
if container.is_auto_wiring_enabled():
|
||||
container.wire()
|
||||
|
||||
return container
|
||||
|
||||
@classmethod
|
||||
|
@ -826,3 +857,8 @@ cpdef object _resolve_calling_package_name():
|
|||
pre_last_frame = stack[0]
|
||||
module = inspect.getmodule(pre_last_frame[0])
|
||||
return module.__package__
|
||||
|
||||
|
||||
cpdef object _resolve_package_name_from_cls(cls):
|
||||
module = importlib.import_module(cls.__module__)
|
||||
return module.__package__
|
||||
|
|
|
@ -30,6 +30,7 @@ _SAMPLES_DIR = os.path.abspath(
|
|||
import sys
|
||||
sys.path.append(_TOP_DIR)
|
||||
sys.path.append(_SAMPLES_DIR)
|
||||
import copy
|
||||
|
||||
from asyncutils import AsyncTestCase
|
||||
|
||||
|
@ -361,6 +362,74 @@ class WiringWithStringModuleAndPackageNamesTest(unittest.TestCase):
|
|||
self.assertIsInstance(service, Service)
|
||||
|
||||
|
||||
class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
|
||||
|
||||
container: Container
|
||||
original_wiring_config = copy.deepcopy(Container.wiring_config)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
Container.wiring_config = copy.deepcopy(self.original_wiring_config)
|
||||
self.container.unwire()
|
||||
|
||||
def test_absolute_names(self):
|
||||
Container.wiring_config = {
|
||||
"modules": ["wiringsamples.module"],
|
||||
"packages": ["wiringsamples.package"],
|
||||
}
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
from wiringsamples.package.subpackage.submodule import test_function
|
||||
service = test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_relative_names_with_explicit_package(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"packages": [".package"],
|
||||
"from_package": "wiringsamples",
|
||||
}
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
from wiringsamples.package.subpackage.submodule import test_function
|
||||
service = test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_relative_names_with_auto_package(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"packages": [".package"],
|
||||
}
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
from wiringsamples.package.subpackage.submodule import test_function
|
||||
service = test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_auto_wire(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"auto_wire": True,
|
||||
}
|
||||
self.container = Container()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
self.assertTrue(self.container.is_auto_wiring_enabled())
|
||||
|
||||
|
||||
class ModuleAsPackageTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user