mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +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