mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	Add implementation
This commit is contained in:
		
							parent
							
								
									ce6d3df72c
								
							
						
					
					
						commit
						41f8009811
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -35,6 +35,7 @@ class Container:
 | 
				
			||||||
    def __setattr__(self, name: str, value: Union[Provider, Any]) -> None: ...
 | 
					    def __setattr__(self, name: str, value: Union[Provider, Any]) -> None: ...
 | 
				
			||||||
    def __delattr__(self, name: str) -> None: ...
 | 
					    def __delattr__(self, name: str) -> None: ...
 | 
				
			||||||
    def set_providers(self, **providers: Provider): ...
 | 
					    def set_providers(self, **providers: Provider): ...
 | 
				
			||||||
 | 
					    def set_provider(self, name: str, provider: Provider) -> None: ...
 | 
				
			||||||
    def override(self, overriding: C_Base) -> None: ...
 | 
					    def override(self, overriding: C_Base) -> None: ...
 | 
				
			||||||
    def override_providers(self, **overriding_providers: Provider) -> None: ...
 | 
					    def override_providers(self, **overriding_providers: Provider) -> None: ...
 | 
				
			||||||
    def reset_last_overriding(self) -> None: ...
 | 
					    def reset_last_overriding(self) -> None: ...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ class DynamicContainer(Container):
 | 
				
			||||||
        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__ = providers.Object(self)
 | 
					        self.__self__ = providers.Self(self)
 | 
				
			||||||
        super(DynamicContainer, self).__init__()
 | 
					        super(DynamicContainer, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __deepcopy__(self, memo):
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ class DynamicContainer(Container):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if isinstance(value, providers.Provider) and name != '__self__':
 | 
					        if isinstance(value, providers.Provider) and not isinstance(value, providers.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)
 | 
				
			||||||
| 
						 | 
					@ -154,6 +154,19 @@ class DynamicContainer(Container):
 | 
				
			||||||
        for name, provider in six.iteritems(providers):
 | 
					        for name, provider in six.iteritems(providers):
 | 
				
			||||||
            setattr(self, name, provider)
 | 
					            setattr(self, name, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_provider(self, name, provider):
 | 
				
			||||||
 | 
					        """Set container provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Provider name
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param provider: Provider
 | 
				
			||||||
 | 
					        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        setattr(self, name, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def override(self, object overriding):
 | 
					    def override(self, object overriding):
 | 
				
			||||||
        """Override current container by overriding container.
 | 
					        """Override current container by overriding container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -282,6 +295,10 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __new__(type mcs, str class_name, tuple bases, dict attributes):
 | 
					    def __new__(type mcs, str class_name, tuple bases, dict attributes):
 | 
				
			||||||
        """Declarative container class factory."""
 | 
					        """Declarative container class factory."""
 | 
				
			||||||
 | 
					        self = mcs.__fetch_self(attributes)
 | 
				
			||||||
 | 
					        if self is None:
 | 
				
			||||||
 | 
					            self = providers.Self()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        containers = {
 | 
					        containers = {
 | 
				
			||||||
            name: container
 | 
					            name: container
 | 
				
			||||||
            for name, container in six.iteritems(attributes)
 | 
					            for name, container in six.iteritems(attributes)
 | 
				
			||||||
| 
						 | 
					@ -291,7 +308,7 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
        cls_providers = {
 | 
					        cls_providers = {
 | 
				
			||||||
            name: provider
 | 
					            name: provider
 | 
				
			||||||
            for name, provider in six.iteritems(attributes)
 | 
					            for name, provider in six.iteritems(attributes)
 | 
				
			||||||
            if isinstance(provider, providers.Provider)
 | 
					            if isinstance(provider, providers.Provider) and not isinstance(provider, providers.Self)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        inherited_providers = {
 | 
					        inherited_providers = {
 | 
				
			||||||
| 
						 | 
					@ -312,7 +329,8 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cls = <type>type.__new__(mcs, class_name, bases, attributes)
 | 
					        cls = <type>type.__new__(mcs, class_name, bases, attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cls.__self__ = providers.Object(cls)
 | 
					        self.set_container(cls)
 | 
				
			||||||
 | 
					        cls.__self__ = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for provider in six.itervalues(cls.providers):
 | 
					        for provider in six.itervalues(cls.providers):
 | 
				
			||||||
            _check_provider_type(cls, provider)
 | 
					            _check_provider_type(cls, provider)
 | 
				
			||||||
| 
						 | 
					@ -375,6 +393,28 @@ class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
        """Return providers traversal generator."""
 | 
					        """Return providers traversal generator."""
 | 
				
			||||||
        yield from providers.traverse(*cls.providers.values(), types=types)
 | 
					        yield from providers.traverse(*cls.providers.values(), types=types)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def __fetch_self(attributes):
 | 
				
			||||||
 | 
					        self = None
 | 
				
			||||||
 | 
					        alt_names = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for name, value in attributes.items():
 | 
				
			||||||
 | 
					            if not isinstance(value, providers.Self):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if self is not None and value is not self:
 | 
				
			||||||
 | 
					                raise errors.Error('Container can have only one "Self" provider')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if name != '__self__':
 | 
				
			||||||
 | 
					                alt_names.append(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self:
 | 
				
			||||||
 | 
					            self.set_alt_names(alt_names)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.add_metaclass(DeclarativeContainerMetaClass)
 | 
					@six.add_metaclass(DeclarativeContainerMetaClass)
 | 
				
			||||||
class DeclarativeContainer(Container):
 | 
					class DeclarativeContainer(Container):
 | 
				
			||||||
| 
						 | 
					@ -448,9 +488,21 @@ class DeclarativeContainer(Container):
 | 
				
			||||||
        container = cls.instance_type()
 | 
					        container = cls.instance_type()
 | 
				
			||||||
        container.provider_type = cls.provider_type
 | 
					        container.provider_type = cls.provider_type
 | 
				
			||||||
        container.declarative_parent = cls
 | 
					        container.declarative_parent = cls
 | 
				
			||||||
        container.set_providers(**providers.deepcopy(cls.providers))
 | 
					
 | 
				
			||||||
 | 
					        copied_providers = providers.deepcopy({ **cls.providers, **{'@@self@@': cls.__self__}})
 | 
				
			||||||
 | 
					        copied_self = copied_providers.pop('@@self@@')
 | 
				
			||||||
 | 
					        copied_self.set_container(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        container.__self__ = copied_self
 | 
				
			||||||
 | 
					        for name in copied_self.alt_names:
 | 
				
			||||||
 | 
					            container.set_provider(name, copied_self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for name, provider in copied_providers.items():
 | 
				
			||||||
 | 
					            container.set_provider(name, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container.override_providers(**overriding_providers)
 | 
					        container.override_providers(**overriding_providers)
 | 
				
			||||||
        container.apply_container_providers_overridings()
 | 
					        container.apply_container_providers_overridings()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return container
 | 
					        return container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -27,6 +27,11 @@ cdef class Object(Provider):
 | 
				
			||||||
    cpdef object _provide(self, tuple args, dict kwargs)
 | 
					    cpdef object _provide(self, tuple args, dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Self(Provider):
 | 
				
			||||||
 | 
					    cdef object __container
 | 
				
			||||||
 | 
					    cdef tuple __alt_names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Delegate(Provider):
 | 
					cdef class Delegate(Provider):
 | 
				
			||||||
    cdef object __provides
 | 
					    cdef object __provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,14 @@ class Object(Provider[T]):
 | 
				
			||||||
    def __init__(self, provides: T) -> None: ...
 | 
					    def __init__(self, provides: T) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Self(Provider[T]):
 | 
				
			||||||
 | 
					    def __init__(self, container: Optional[T] = None) -> None: ...
 | 
				
			||||||
 | 
					    def set_container(self, container: T) -> None: ...
 | 
				
			||||||
 | 
					    def set_alt_names(self, alt_names: _Iterable[Any]) -> None: ...
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def alt_names(self) -> Tuple[Any]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Delegate(Provider[Provider]):
 | 
					class Delegate(Provider[Provider]):
 | 
				
			||||||
    def __init__(self, provides: Provider) -> None: ...
 | 
					    def __init__(self, provides: Provider) -> None: ...
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -458,6 +458,62 @@ cdef class Object(Provider):
 | 
				
			||||||
        return self.__provides
 | 
					        return self.__provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class Self(Provider):
 | 
				
			||||||
 | 
					    """Self provider returns own container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, container=None):
 | 
				
			||||||
 | 
					        """Initialize provider."""
 | 
				
			||||||
 | 
					        self.__container = container
 | 
				
			||||||
 | 
					        self.__alt_names = tuple()
 | 
				
			||||||
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__()
 | 
				
			||||||
 | 
					        copied.set_container(deepcopy(self.__container, memo))
 | 
				
			||||||
 | 
					        copied.set_alt_names(self.__alt_names)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._copy_overridings(copied, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return represent_provider(provider=self, provides=self.__container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        """Return string representation of provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: str
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self.__str__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_container(self, container):
 | 
				
			||||||
 | 
					        self.__container = container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_alt_names(self, alt_names):
 | 
				
			||||||
 | 
					        self.__alt_names = tuple(set(alt_names))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def alt_names(self):
 | 
				
			||||||
 | 
					        return self.__alt_names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def related(self):
 | 
				
			||||||
 | 
					        """Return related providers generator."""
 | 
				
			||||||
 | 
					        yield from super().related
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
 | 
					        return self.__container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Delegate(Provider):
 | 
					cdef class Delegate(Provider):
 | 
				
			||||||
    """Delegate provider returns provider "as is".
 | 
					    """Delegate provider returns provider "as is".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user