mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Add working prototype, requires deep refactoring
This commit is contained in:
		
							parent
							
								
									ff3ae95482
								
							
						
					
					
						commit
						5f34c7ce3f
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -8,12 +8,13 @@ from typing import (
 | 
			
		|||
    ClassVar,
 | 
			
		||||
    Callable as _Callable,
 | 
			
		||||
    Iterable,
 | 
			
		||||
    Iterator,
 | 
			
		||||
    TypeVar,
 | 
			
		||||
    Awaitable,
 | 
			
		||||
    overload,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from .providers import Provider, Self
 | 
			
		||||
from .providers import Provider, Self, ProviderParent
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
C_Base = TypeVar('C_Base', bound='Container')
 | 
			
		||||
| 
						 | 
				
			
			@ -47,11 +48,14 @@ class Container:
 | 
			
		|||
    def resolve_provider_name(self, provider: Provider) -> str: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def parent_name(self) -> str: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def parent(self) -> ProviderParent: ...
 | 
			
		||||
    def set_parent(self, parent: ProviderParent) -> None: ...
 | 
			
		||||
    @overload
 | 
			
		||||
    def traverse(self, types: Optional[Iterable[Type[TT]]] = None) -> _Iterator[TT]: ...
 | 
			
		||||
    def traverse(self, types: Optional[Iterable[Type[TT]]] = None) -> Iterator[TT]: ...
 | 
			
		||||
    @classmethod
 | 
			
		||||
    @overload
 | 
			
		||||
    def traverse(self, types: Optional[Iterable[Type[TT]]] = None) -> _Iterator[TT]: ...
 | 
			
		||||
    def traverse(cls, types: Optional[Iterable[Type[TT]]] = None) -> Iterator[TT]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DynamicContainer(Container): ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,7 @@ class DynamicContainer(Container):
 | 
			
		|||
        self.provider_type = providers.Provider
 | 
			
		||||
        self.providers = {}
 | 
			
		||||
        self.overridden = tuple()
 | 
			
		||||
        self.parent = None
 | 
			
		||||
        self.declarative_parent = None
 | 
			
		||||
        self.wired_to_modules = []
 | 
			
		||||
        self.wired_to_packages = []
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +84,7 @@ class DynamicContainer(Container):
 | 
			
		|||
 | 
			
		||||
        copied.provider_type = providers.Provider
 | 
			
		||||
        copied.overridden = providers.deepcopy(self.overridden, memo)
 | 
			
		||||
        copied.parent = providers.deepcopy(self.parent, memo)
 | 
			
		||||
        copied.declarative_parent = self.declarative_parent
 | 
			
		||||
 | 
			
		||||
        copied.__self__ = providers.deepcopy(self.__self__, memo)
 | 
			
		||||
| 
						 | 
				
			
			@ -108,12 +110,14 @@ class DynamicContainer(Container):
 | 
			
		|||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if isinstance(value, providers.Provider) and not isinstance(value, providers.Self):
 | 
			
		||||
        if isinstance(value, providers.Provider) \
 | 
			
		||||
                and not isinstance(value, providers.Self) \
 | 
			
		||||
                and name != 'parent':
 | 
			
		||||
            _check_provider_type(self, value)
 | 
			
		||||
 | 
			
		||||
            self.providers[name] = value
 | 
			
		||||
 | 
			
		||||
            if isinstance(value, (providers.Dependency, providers.DependenciesContainer)):
 | 
			
		||||
            if isinstance(value, (providers.Dependency, providers.DependenciesContainer, providers.Container)):
 | 
			
		||||
                value.set_parent(self)
 | 
			
		||||
 | 
			
		||||
        super(DynamicContainer, self).__setattr__(name, value)
 | 
			
		||||
| 
						 | 
				
			
			@ -303,8 +307,15 @@ class DynamicContainer(Container):
 | 
			
		|||
    @property
 | 
			
		||||
    def parent_name(self):
 | 
			
		||||
        """Return parent name."""
 | 
			
		||||
        if self.parent:
 | 
			
		||||
            return self.parent.parent_name
 | 
			
		||||
 | 
			
		||||
        return self.declarative_parent.__name__
 | 
			
		||||
 | 
			
		||||
    def set_parent(self, parent):
 | 
			
		||||
        """Set parent."""
 | 
			
		||||
        self.parent = parent
 | 
			
		||||
 | 
			
		||||
    def resolve_provider_name(self, provider):
 | 
			
		||||
        """Try to resolve provider name."""
 | 
			
		||||
        # TODO: add tests
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -227,6 +227,7 @@ cdef class Container(Provider):
 | 
			
		|||
    cdef object __container_cls
 | 
			
		||||
    cdef dict __overriding_providers
 | 
			
		||||
    cdef object __container
 | 
			
		||||
    cdef object __parent
 | 
			
		||||
 | 
			
		||||
    cpdef object _provide(self, tuple args, dict kwargs)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -368,6 +368,11 @@ class Container(Provider[T]):
 | 
			
		|||
    def __getattr__(self, name: str) -> Provider: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def container(self) -> T: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def parent_name(self) -> str: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def parent(self) -> ProviderParent: ...
 | 
			
		||||
    def set_parent(self, parent: ProviderParent) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Selector(Provider[Any]):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3522,23 +3522,38 @@ cdef class Container(Provider):
 | 
			
		|||
 | 
			
		||||
        if container is None:
 | 
			
		||||
            container = container_cls()
 | 
			
		||||
            container.set_parent(self)
 | 
			
		||||
        self.__container = container
 | 
			
		||||
 | 
			
		||||
        self.apply_overridings()
 | 
			
		||||
        if self.__container and self.__overriding_providers:
 | 
			
		||||
            self.apply_overridings()
 | 
			
		||||
 | 
			
		||||
        self.__parent = None
 | 
			
		||||
 | 
			
		||||
        super(Container, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def __deepcopy__(self, memo):
 | 
			
		||||
        """Create and return full copy of provider."""
 | 
			
		||||
        cdef Container copied
 | 
			
		||||
 | 
			
		||||
        copied = memo.get(id(self))
 | 
			
		||||
        if copied is not None:
 | 
			
		||||
            return copied
 | 
			
		||||
 | 
			
		||||
        copied = self.__class__(
 | 
			
		||||
            self.__container_cls,
 | 
			
		||||
            deepcopy(self.__container, memo),
 | 
			
		||||
            **deepcopy(self.__overriding_providers, memo),
 | 
			
		||||
        copied = self.__class__(self.__container_cls, UNDEFINED)
 | 
			
		||||
        memo[id(self)] = copied
 | 
			
		||||
 | 
			
		||||
        copied.__container = deepcopy(self.__container, memo)
 | 
			
		||||
        copied.__overriding_providers = deepcopy(self.__overriding_providers, memo)
 | 
			
		||||
        copied.apply_overridings()
 | 
			
		||||
 | 
			
		||||
        # TODO: remove duplication
 | 
			
		||||
        copied_parent = (
 | 
			
		||||
            deepcopy(self.__parent, memo)
 | 
			
		||||
            if is_provider(self.parent) or is_container_instance(self.parent)
 | 
			
		||||
            else self.parent
 | 
			
		||||
        )
 | 
			
		||||
        copied.set_parent(copied_parent)
 | 
			
		||||
 | 
			
		||||
        return copied
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3574,6 +3589,20 @@ cdef class Container(Provider):
 | 
			
		|||
        declarative container initialization."""
 | 
			
		||||
        self.__container.override_providers(**self.__overriding_providers)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def parent_name(self):
 | 
			
		||||
        """Return parent name."""
 | 
			
		||||
        return f'{self.parent.parent_name}.{self.parent.resolve_provider_name(self)}'
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def parent(self):
 | 
			
		||||
        """Return parent."""
 | 
			
		||||
        return self.__parent
 | 
			
		||||
 | 
			
		||||
    def set_parent(self, parent):
 | 
			
		||||
        """Set parent."""
 | 
			
		||||
        self.__parent = parent
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def related(self):
 | 
			
		||||
        """Return related providers generator."""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user