mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Add container injections to wiring
This commit is contained in:
		
							parent
							
								
									6e77a95909
								
							
						
					
					
						commit
						f3a54040e8
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -13,6 +13,7 @@ import six
 | 
				
			||||||
from .errors import Error
 | 
					from .errors import Error
 | 
				
			||||||
from .providers cimport (
 | 
					from .providers cimport (
 | 
				
			||||||
    Provider,
 | 
					    Provider,
 | 
				
			||||||
 | 
					    Object,
 | 
				
			||||||
    Resource,
 | 
					    Resource,
 | 
				
			||||||
    deepcopy,
 | 
					    deepcopy,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -70,6 +71,7 @@ class DynamicContainer(object):
 | 
				
			||||||
        self.declarative_parent = None
 | 
					        self.declarative_parent = None
 | 
				
			||||||
        self.wired_to_modules = []
 | 
					        self.wired_to_modules = []
 | 
				
			||||||
        self.wired_to_packages = []
 | 
					        self.wired_to_packages = []
 | 
				
			||||||
 | 
					        self.__self__ = Object(self)
 | 
				
			||||||
        super(DynamicContainer, self).__init__()
 | 
					        super(DynamicContainer, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __deepcopy__(self, memo):
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
| 
						 | 
					@ -102,7 +104,7 @@ class DynamicContainer(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if isinstance(value, Provider):
 | 
					        if isinstance(value, Provider) and name != '__self__':
 | 
				
			||||||
            _check_provider_type(self, value)
 | 
					            _check_provider_type(self, value)
 | 
				
			||||||
            self.providers[name] = value
 | 
					            self.providers[name] = value
 | 
				
			||||||
        super(DynamicContainer, self).__setattr__(name, value)
 | 
					        super(DynamicContainer, self).__setattr__(name, value)
 | 
				
			||||||
| 
						 | 
					@ -282,6 +284,8 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cls = <type>type.__new__(mcs, class_name, bases, attributes)
 | 
					        cls = <type>type.__new__(mcs, class_name, bases, attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cls.__self__ = Object(cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for provider in six.itervalues(cls.providers):
 | 
					        for provider in six.itervalues(cls.providers):
 | 
				
			||||||
            _check_provider_type(cls, provider)
 | 
					            _check_provider_type(cls, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,7 +305,7 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if isinstance(value, Provider):
 | 
					        if isinstance(value, Provider) and name != '__self__':
 | 
				
			||||||
            _check_provider_type(cls, value)
 | 
					            _check_provider_type(cls, value)
 | 
				
			||||||
            cls.providers[name] = value
 | 
					            cls.providers[name] = value
 | 
				
			||||||
            cls.cls_providers[name] = value
 | 
					            cls.cls_providers[name] = value
 | 
				
			||||||
| 
						 | 
					@ -381,6 +385,12 @@ class DeclarativeContainer(object):
 | 
				
			||||||
    :type: tuple[:py:class:`DeclarativeContainer`]
 | 
					    :type: tuple[:py:class:`DeclarativeContainer`]
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __self__ = None
 | 
				
			||||||
 | 
					    """Provider that provides current container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :type: :py:class:`dependency_injector.providers.Provider`
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __new__(cls, **overriding_providers):
 | 
					    def __new__(cls, **overriding_providers):
 | 
				
			||||||
        """Constructor.
 | 
					        """Constructor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ from typing import (
 | 
				
			||||||
    Generic,
 | 
					    Generic,
 | 
				
			||||||
    TypeVar,
 | 
					    TypeVar,
 | 
				
			||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
 | 
					    Union,
 | 
				
			||||||
    cast,
 | 
					    cast,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,8 +76,8 @@ class ProvidersMap:
 | 
				
			||||||
    def __init__(self, container):
 | 
					    def __init__(self, container):
 | 
				
			||||||
        self._container = container
 | 
					        self._container = container
 | 
				
			||||||
        self._map = self._create_providers_map(
 | 
					        self._map = self._create_providers_map(
 | 
				
			||||||
            current_providers=container.providers,
 | 
					            current_container=container,
 | 
				
			||||||
            original_providers=container.declarative_parent.providers,
 | 
					            original_container=container.declarative_parent,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_provider(
 | 
					    def resolve_provider(
 | 
				
			||||||
| 
						 | 
					@ -173,9 +174,15 @@ class ProvidersMap:
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def _create_providers_map(
 | 
					    def _create_providers_map(
 | 
				
			||||||
            cls,
 | 
					            cls,
 | 
				
			||||||
            current_providers: Dict[str, providers.Provider],
 | 
					            current_container: Container,
 | 
				
			||||||
            original_providers: Dict[str, providers.Provider],
 | 
					            original_container: Container,
 | 
				
			||||||
    ) -> Dict[providers.Provider, providers.Provider]:
 | 
					    ) -> Dict[providers.Provider, providers.Provider]:
 | 
				
			||||||
 | 
					        current_providers = current_container.providers
 | 
				
			||||||
 | 
					        current_providers['__self__'] = current_container.__self__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        original_providers = original_container.providers
 | 
				
			||||||
 | 
					        original_providers['__self__'] = original_container.__self__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        providers_map = {}
 | 
					        providers_map = {}
 | 
				
			||||||
        for provider_name, current_provider in current_providers.items():
 | 
					        for provider_name, current_provider in current_providers.items():
 | 
				
			||||||
            original_provider = original_providers[provider_name]
 | 
					            original_provider = original_providers[provider_name]
 | 
				
			||||||
| 
						 | 
					@ -184,8 +191,8 @@ class ProvidersMap:
 | 
				
			||||||
            if isinstance(current_provider, providers.Container) \
 | 
					            if isinstance(current_provider, providers.Container) \
 | 
				
			||||||
                    and isinstance(original_provider, providers.Container):
 | 
					                    and isinstance(original_provider, providers.Container):
 | 
				
			||||||
                subcontainer_map = cls._create_providers_map(
 | 
					                subcontainer_map = cls._create_providers_map(
 | 
				
			||||||
                    current_providers=current_provider.container.providers,
 | 
					                    current_container=current_provider.container,
 | 
				
			||||||
                    original_providers=original_provider.container.providers,
 | 
					                    original_container=original_provider.container,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                providers_map.update(subcontainer_map)
 | 
					                providers_map.update(subcontainer_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -479,6 +486,12 @@ def _is_declarative_container_instance(instance: Any) -> bool:
 | 
				
			||||||
            and getattr(instance, 'declarative_parent', None) is not None)
 | 
					            and getattr(instance, 'declarative_parent', None) is not None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _is_declarative_container(instance: Any) -> bool:
 | 
				
			||||||
 | 
					    return (isinstance(instance, type)
 | 
				
			||||||
 | 
					            and getattr(instance, '__IS_CONTAINER__', False) is True
 | 
				
			||||||
 | 
					            and getattr(instance, 'declarative_parent', None) is None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClassGetItemMeta(GenericMeta):
 | 
					class ClassGetItemMeta(GenericMeta):
 | 
				
			||||||
    def __getitem__(cls, item):
 | 
					    def __getitem__(cls, item):
 | 
				
			||||||
        # Spike for Python 3.6
 | 
					        # Spike for Python 3.6
 | 
				
			||||||
| 
						 | 
					@ -487,8 +500,10 @@ class ClassGetItemMeta(GenericMeta):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _Marker(Generic[T], metaclass=ClassGetItemMeta):
 | 
					class _Marker(Generic[T], metaclass=ClassGetItemMeta):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, provider: providers.Provider) -> None:
 | 
					    def __init__(self, provider: Union[providers.Provider, Any]) -> None:
 | 
				
			||||||
        self.provider = provider
 | 
					        if _is_declarative_container(provider):
 | 
				
			||||||
 | 
					            provider = provider.__self__
 | 
				
			||||||
 | 
					        self.provider: providers.Provider = provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __class_getitem__(cls, item) -> T:
 | 
					    def __class_getitem__(cls, item) -> T:
 | 
				
			||||||
        return cls(item)
 | 
					        return cls(item)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,3 +91,7 @@ class ClassDecorator:
 | 
				
			||||||
@inject
 | 
					@inject
 | 
				
			||||||
def test_class_decorator(service: Service = Provide[Container.service]):
 | 
					def test_class_decorator(service: Service = Provide[Container.service]):
 | 
				
			||||||
    return service
 | 
					    return service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_container(container: Container = Provide[Container]):
 | 
				
			||||||
 | 
					    return container.service()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,6 +239,10 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        service = module.test_class_decorator()
 | 
					        service = module.test_class_decorator()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_container(self):
 | 
				
			||||||
 | 
					        service = module.test_container()
 | 
				
			||||||
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WiringAndFastAPITest(unittest.TestCase):
 | 
					class WiringAndFastAPITest(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user