mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +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,
 | 
					    Generic,
 | 
				
			||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
    Dict,
 | 
					    Dict,
 | 
				
			||||||
 | 
					    List,
 | 
				
			||||||
    Tuple,
 | 
					    Tuple,
 | 
				
			||||||
    Optional,
 | 
					    Optional,
 | 
				
			||||||
    Any,
 | 
					    Any,
 | 
				
			||||||
| 
						 | 
					@ -26,12 +27,20 @@ T = TypeVar('T')
 | 
				
			||||||
TT = TypeVar('TT')
 | 
					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:
 | 
					class Container:
 | 
				
			||||||
    provider_type: Type[Provider] = Provider
 | 
					    provider_type: Type[Provider] = Provider
 | 
				
			||||||
    providers: Dict[str, Provider]
 | 
					    providers: Dict[str, Provider]
 | 
				
			||||||
    dependencies: Dict[str, Provider]
 | 
					    dependencies: Dict[str, Provider]
 | 
				
			||||||
    overridden: Tuple[Provider]
 | 
					    overridden: Tuple[Provider]
 | 
				
			||||||
    wiring_config: Dict[str, Any]
 | 
					    wiring_config: WiringConfiguration
 | 
				
			||||||
    __self__: Self
 | 
					    __self__: Self
 | 
				
			||||||
    def __init__(self) -> None: ...
 | 
					    def __init__(self) -> None: ...
 | 
				
			||||||
    def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
 | 
					    def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,19 @@ else:
 | 
				
			||||||
        raise NotImplementedError('Wiring requires Python 3.6 or above')
 | 
					        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):
 | 
					class Container(object):
 | 
				
			||||||
    """Abstract container."""
 | 
					    """Abstract container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +91,7 @@ class DynamicContainer(Container):
 | 
				
			||||||
        self.overridden = tuple()
 | 
					        self.overridden = tuple()
 | 
				
			||||||
        self.parent = None
 | 
					        self.parent = None
 | 
				
			||||||
        self.declarative_parent = None
 | 
					        self.declarative_parent = None
 | 
				
			||||||
        self.wiring_config = {}
 | 
					        self.wiring_config = WiringConfiguration()
 | 
				
			||||||
        self.wired_to_modules = []
 | 
					        self.wired_to_modules = []
 | 
				
			||||||
        self.wired_to_packages = []
 | 
					        self.wired_to_packages = []
 | 
				
			||||||
        self.__self__ = providers.Self(self)
 | 
					        self.__self__ = providers.Self(self)
 | 
				
			||||||
| 
						 | 
					@ -255,29 +268,28 @@ class DynamicContainer(Container):
 | 
				
			||||||
            provider.reset_override()
 | 
					            provider.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_auto_wiring_enabled(self):
 | 
					    def is_auto_wiring_enabled(self):
 | 
				
			||||||
        """Check if auto wiring is enabled."""
 | 
					        """Check if auto wiring is needed."""
 | 
				
			||||||
        return self.wiring_config.get("auto_wire") is True
 | 
					        return self.wiring_config.auto_wire is True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def wire(self, modules=None, packages=None, from_package=None):
 | 
					    def wire(self, modules=None, packages=None, from_package=None):
 | 
				
			||||||
        """Wire container providers with provided packages and modules.
 | 
					        """Wire container providers with provided packages and modules.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if modules is None and "modules" in self.wiring_config:
 | 
					        if modules is None and self.wiring_config.modules:
 | 
				
			||||||
            modules = self.wiring_config["modules"]
 | 
					            modules = self.wiring_config.modules
 | 
				
			||||||
        if packages is None and "packages" in self.wiring_config:
 | 
					        if packages is None and self.wiring_config.packages:
 | 
				
			||||||
            packages = self.wiring_config["packages"]
 | 
					            packages = self.wiring_config.packages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        modules = [*modules] if modules else []
 | 
					        modules = [*modules] if modules else []
 | 
				
			||||||
        packages = [*packages] if packages else []
 | 
					        packages = [*packages] if packages else []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if _any_relative_string_imports_in(modules) or _any_relative_string_imports_in(packages):
 | 
					        if _any_relative_string_imports_in(modules) or _any_relative_string_imports_in(packages):
 | 
				
			||||||
            if from_package is None:
 | 
					            if from_package is None:
 | 
				
			||||||
                if "from_package" in self.wiring_config:
 | 
					                if self.wiring_config.from_package is not None:
 | 
				
			||||||
                    from_package = self.wiring_config["from_package"]
 | 
					                    from_package = self.wiring_config.from_package
 | 
				
			||||||
                elif self.declarative_parent is not None \
 | 
					                elif self.declarative_parent is not None \
 | 
				
			||||||
                        and ("modules" in self.wiring_config
 | 
					                        and (self.wiring_config.modules or self.wiring_config.packages):
 | 
				
			||||||
                             or "packages" in self.wiring_config):
 | 
					 | 
				
			||||||
                    with contextlib.suppress(Exception):
 | 
					                    with contextlib.suppress(Exception):
 | 
				
			||||||
                        from_package = _resolve_package_name_from_cls(self.declarative_parent)
 | 
					                        from_package = _resolve_package_name_from_cls(self.declarative_parent)
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					@ -287,6 +299,9 @@ class DynamicContainer(Container):
 | 
				
			||||||
        modules = _resolve_string_imports(modules, from_package)
 | 
					        modules = _resolve_string_imports(modules, from_package)
 | 
				
			||||||
        packages = _resolve_string_imports(packages, from_package)
 | 
					        packages = _resolve_string_imports(packages, from_package)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not modules and not packages:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wire(
 | 
					        wire(
 | 
				
			||||||
            container=self,
 | 
					            container=self,
 | 
				
			||||||
            modules=modules,
 | 
					            modules=modules,
 | 
				
			||||||
| 
						 | 
					@ -483,11 +498,20 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
        all_providers.update(inherited_providers)
 | 
					        all_providers.update(inherited_providers)
 | 
				
			||||||
        all_providers.update(cls_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['containers'] = containers
 | 
				
			||||||
        attributes['inherited_providers'] = inherited_providers
 | 
					        attributes['inherited_providers'] = inherited_providers
 | 
				
			||||||
        attributes['cls_providers'] = cls_providers
 | 
					        attributes['cls_providers'] = cls_providers
 | 
				
			||||||
        attributes['providers'] = all_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)
 | 
					        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`]
 | 
					    :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    wiring_config = dict()
 | 
					    wiring_config = WiringConfiguration()
 | 
				
			||||||
    """Dictionary of wiring configuration.
 | 
					    """Wiring configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :type: dict[str, Any]
 | 
					    :type: WiringConfiguration
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cls_providers = dict()
 | 
					    cls_providers = dict()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ from dependency_injector.wiring import (
 | 
				
			||||||
    register_loader_containers,
 | 
					    register_loader_containers,
 | 
				
			||||||
    unregister_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
 | 
					# Runtime import to avoid syntax errors in samples on Python < 3.5
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,6 @@ _SAMPLES_DIR = os.path.abspath(
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
sys.path.append(_TOP_DIR)
 | 
					sys.path.append(_TOP_DIR)
 | 
				
			||||||
sys.path.append(_SAMPLES_DIR)
 | 
					sys.path.append(_SAMPLES_DIR)
 | 
				
			||||||
import copy
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from asyncutils import AsyncTestCase
 | 
					from asyncutils import AsyncTestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,19 +364,18 @@ class WiringWithStringModuleAndPackageNamesTest(unittest.TestCase):
 | 
				
			||||||
class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
 | 
					class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    container: Container
 | 
					    container: Container
 | 
				
			||||||
    original_wiring_config = copy.deepcopy(Container.wiring_config)
 | 
					    original_wiring_config = Container.wiring_config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tearDown(self) -> None:
 | 
					    def tearDown(self) -> None:
 | 
				
			||||||
        Container.wiring_config = copy.deepcopy(self.original_wiring_config)
 | 
					        Container.wiring_config = self.original_wiring_config
 | 
				
			||||||
        self.container.unwire()
 | 
					        self.container.unwire()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_absolute_names(self):
 | 
					    def test_absolute_names(self):
 | 
				
			||||||
        Container.wiring_config = {
 | 
					        Container.wiring_config = containers.WiringConfiguration(
 | 
				
			||||||
            "modules": ["wiringsamples.module"],
 | 
					            modules=["wiringsamples.module"],
 | 
				
			||||||
            "packages": ["wiringsamples.package"],
 | 
					            packages=["wiringsamples.package"],
 | 
				
			||||||
        }
 | 
					        )
 | 
				
			||||||
        self.container = Container()
 | 
					        self.container = Container()
 | 
				
			||||||
        self.container.wire()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        service = module.test_function()
 | 
					        service = module.test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
| 
						 | 
					@ -387,13 +385,12 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_relative_names_with_explicit_package(self):
 | 
					    def test_relative_names_with_explicit_package(self):
 | 
				
			||||||
        Container.wiring_config = {
 | 
					        Container.wiring_config = containers.WiringConfiguration(
 | 
				
			||||||
            "modules": [".module"],
 | 
					            modules=[".module"],
 | 
				
			||||||
            "packages": [".package"],
 | 
					            packages=[".package"],
 | 
				
			||||||
            "from_package": "wiringsamples",
 | 
					            from_package="wiringsamples",
 | 
				
			||||||
        }
 | 
					        )
 | 
				
			||||||
        self.container = Container()
 | 
					        self.container = Container()
 | 
				
			||||||
        self.container.wire()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        service = module.test_function()
 | 
					        service = module.test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
| 
						 | 
					@ -403,12 +400,11 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_relative_names_with_auto_package(self):
 | 
					    def test_relative_names_with_auto_package(self):
 | 
				
			||||||
        Container.wiring_config = {
 | 
					        Container.wiring_config = containers.WiringConfiguration(
 | 
				
			||||||
            "modules": [".module"],
 | 
					            modules=[".module"],
 | 
				
			||||||
            "packages": [".package"],
 | 
					            packages=[".package"],
 | 
				
			||||||
        }
 | 
					        )
 | 
				
			||||||
        self.container = Container()
 | 
					        self.container = Container()
 | 
				
			||||||
        self.container.wire()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        service = module.test_function()
 | 
					        service = module.test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
| 
						 | 
					@ -417,17 +413,19 @@ class WiringWithWiringConfigInTheContainerTest(unittest.TestCase):
 | 
				
			||||||
        service = test_function()
 | 
					        service = test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_auto_wire(self):
 | 
					    def test_auto_wire_disabled(self):
 | 
				
			||||||
        Container.wiring_config = {
 | 
					        Container.wiring_config = containers.WiringConfiguration(
 | 
				
			||||||
            "modules": [".module"],
 | 
					            modules=[".module"],
 | 
				
			||||||
            "auto_wire": True,
 | 
					            auto_wire=False,
 | 
				
			||||||
        }
 | 
					        )
 | 
				
			||||||
        self.container = Container()
 | 
					        self.container = Container()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        service = module.test_function()
 | 
					        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):
 | 
					class ModuleAsPackageTest(unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user