mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Implement concept with WiringConfiguration object
This commit is contained in:
parent
a485228fa2
commit
2a57162d2e
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,7 @@ from typing import (
|
|||
Generic,
|
||||
Type,
|
||||
Dict,
|
||||
List,
|
||||
Tuple,
|
||||
Optional,
|
||||
Any,
|
||||
|
@ -26,12 +27,20 @@ T = TypeVar('T')
|
|||
TT = TypeVar('TT')
|
||||
|
||||
|
||||
class WiringConfiguration:
|
||||
modules: List[Any]
|
||||
packages: List[Any]
|
||||
from_package: Optional[str]
|
||||
auto_wire: bool
|
||||
def __init__(self, modules: Optional[Iterable[Any]] = None, packages: Optional[Iterable[Any]] = None, from_package: Optional[str] = None, auto_wire: bool = True) -> None: ...
|
||||
|
||||
|
||||
class Container:
|
||||
provider_type: Type[Provider] = Provider
|
||||
providers: Dict[str, Provider]
|
||||
dependencies: Dict[str, Provider]
|
||||
overridden: Tuple[Provider]
|
||||
wiring_config: Dict[str, Any]
|
||||
wiring_config: WiringConfiguration
|
||||
__self__: Self
|
||||
def __init__(self) -> None: ...
|
||||
def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
|
||||
|
|
|
@ -33,6 +33,19 @@ else:
|
|||
raise NotImplementedError('Wiring requires Python 3.6 or above')
|
||||
|
||||
|
||||
class WiringConfiguration:
|
||||
"""Container wiring configuration."""
|
||||
|
||||
def __init__(self, modules=None, packages=None, from_package=None, auto_wire=True):
|
||||
self.modules = [*modules] if modules else []
|
||||
self.packages = [*packages] if packages else []
|
||||
self.from_package = from_package
|
||||
self.auto_wire = auto_wire
|
||||
|
||||
def __deepcopy__(self, memo=None):
|
||||
return self.__class__(self.modules, self.packages, self.from_package, self.auto_wire)
|
||||
|
||||
|
||||
class Container(object):
|
||||
"""Abstract container."""
|
||||
|
||||
|
@ -78,7 +91,7 @@ class DynamicContainer(Container):
|
|||
self.overridden = tuple()
|
||||
self.parent = None
|
||||
self.declarative_parent = None
|
||||
self.wiring_config = {}
|
||||
self.wiring_config = WiringConfiguration()
|
||||
self.wired_to_modules = []
|
||||
self.wired_to_packages = []
|
||||
self.__self__ = providers.Self(self)
|
||||
|
@ -255,29 +268,28 @@ class DynamicContainer(Container):
|
|||
provider.reset_override()
|
||||
|
||||
def is_auto_wiring_enabled(self):
|
||||
"""Check if auto wiring is enabled."""
|
||||
return self.wiring_config.get("auto_wire") is True
|
||||
"""Check if auto wiring is needed."""
|
||||
return self.wiring_config.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"]
|
||||
if modules is None and self.wiring_config.modules:
|
||||
modules = self.wiring_config.modules
|
||||
if packages is None and self.wiring_config.packages:
|
||||
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:
|
||||
if "from_package" in self.wiring_config:
|
||||
from_package = self.wiring_config["from_package"]
|
||||
if self.wiring_config.from_package is not None:
|
||||
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):
|
||||
and (self.wiring_config.modules or self.wiring_config.packages):
|
||||
with contextlib.suppress(Exception):
|
||||
from_package = _resolve_package_name_from_cls(self.declarative_parent)
|
||||
else:
|
||||
|
@ -287,6 +299,9 @@ class DynamicContainer(Container):
|
|||
modules = _resolve_string_imports(modules, from_package)
|
||||
packages = _resolve_string_imports(packages, from_package)
|
||||
|
||||
if not modules and not packages:
|
||||
return
|
||||
|
||||
wire(
|
||||
container=self,
|
||||
modules=modules,
|
||||
|
@ -483,11 +498,20 @@ class DeclarativeContainerMetaClass(type):
|
|||
all_providers.update(inherited_providers)
|
||||
all_providers.update(cls_providers)
|
||||
|
||||
wiring_config = attributes.get("wiring_config")
|
||||
if wiring_config is None:
|
||||
wiring_config = WiringConfiguration()
|
||||
if wiring_config is not None and not isinstance(wiring_config, WiringConfiguration):
|
||||
raise errors.Error(
|
||||
"Wiring configuration should be an instance of WiringConfiguration, "
|
||||
"instead got {0}".format(wiring_config)
|
||||
)
|
||||
|
||||
attributes['containers'] = containers
|
||||
attributes['inherited_providers'] = inherited_providers
|
||||
attributes['cls_providers'] = cls_providers
|
||||
attributes['providers'] = all_providers
|
||||
attributes['wiring_config'] = attributes.get('wiring_config', {})
|
||||
attributes['wiring_config'] = wiring_config
|
||||
|
||||
cls = <type>type.__new__(mcs, class_name, bases, attributes)
|
||||
|
||||
|
@ -638,10 +662,10 @@ class DeclarativeContainer(Container):
|
|||
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
|
||||
"""
|
||||
|
||||
wiring_config = dict()
|
||||
"""Dictionary of wiring configuration.
|
||||
wiring_config = WiringConfiguration()
|
||||
"""Wiring configuration.
|
||||
|
||||
:type: dict[str, Any]
|
||||
:type: WiringConfiguration
|
||||
"""
|
||||
|
||||
cls_providers = dict()
|
||||
|
|
|
@ -11,7 +11,7 @@ from dependency_injector.wiring import (
|
|||
register_loader_containers,
|
||||
unregister_loader_containers,
|
||||
)
|
||||
from dependency_injector import errors
|
||||
from dependency_injector import containers, errors
|
||||
|
||||
# Runtime import to avoid syntax errors in samples on Python < 3.5
|
||||
import os
|
||||
|
@ -30,7 +30,6 @@ _SAMPLES_DIR = os.path.abspath(
|
|||
import sys
|
||||
sys.path.append(_TOP_DIR)
|
||||
sys.path.append(_SAMPLES_DIR)
|
||||
import copy
|
||||
|
||||
from asyncutils import AsyncTestCase
|
||||
|
||||
|
@ -365,19 +364,18 @@ class WiringWithStringModuleAndPackageNamesTest(unittest.TestCase):
|
|||
class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
|
||||
|
||||
container: Container
|
||||
original_wiring_config = copy.deepcopy(Container.wiring_config)
|
||||
original_wiring_config = Container.wiring_config
|
||||
|
||||
def tearDown(self) -> None:
|
||||
Container.wiring_config = copy.deepcopy(self.original_wiring_config)
|
||||
Container.wiring_config = self.original_wiring_config
|
||||
self.container.unwire()
|
||||
|
||||
def test_absolute_names(self):
|
||||
Container.wiring_config = {
|
||||
"modules": ["wiringsamples.module"],
|
||||
"packages": ["wiringsamples.package"],
|
||||
}
|
||||
Container.wiring_config = containers.WiringConfiguration(
|
||||
modules=["wiringsamples.module"],
|
||||
packages=["wiringsamples.package"],
|
||||
)
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
@ -387,13 +385,12 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
|
|||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_relative_names_with_explicit_package(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"packages": [".package"],
|
||||
"from_package": "wiringsamples",
|
||||
}
|
||||
Container.wiring_config = containers.WiringConfiguration(
|
||||
modules=[".module"],
|
||||
packages=[".package"],
|
||||
from_package="wiringsamples",
|
||||
)
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
@ -403,12 +400,11 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
|
|||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_relative_names_with_auto_package(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"packages": [".package"],
|
||||
}
|
||||
Container.wiring_config = containers.WiringConfiguration(
|
||||
modules=[".module"],
|
||||
packages=[".package"],
|
||||
)
|
||||
self.container = Container()
|
||||
self.container.wire()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
@ -417,17 +413,19 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
|
|||
service = test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
def test_auto_wire(self):
|
||||
Container.wiring_config = {
|
||||
"modules": [".module"],
|
||||
"auto_wire": True,
|
||||
}
|
||||
def test_auto_wire_disabled(self):
|
||||
Container.wiring_config = containers.WiringConfiguration(
|
||||
modules=[".module"],
|
||||
auto_wire=False,
|
||||
)
|
||||
self.container = Container()
|
||||
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
self.assertIsInstance(service, Provide)
|
||||
|
||||
self.assertTrue(self.container.is_auto_wiring_enabled())
|
||||
self.container.wire()
|
||||
service = module.test_function()
|
||||
self.assertIsInstance(service, Service)
|
||||
|
||||
|
||||
class ModuleAsPackageTest(unittest.TestCase):
|
||||
|
|
Loading…
Reference in New Issue
Block a user