Add working prototype, requires deep refactoring

This commit is contained in:
Roman Mogylatov 2021-02-10 08:52:13 -05:00
parent ff3ae95482
commit 5f34c7ce3f
7 changed files with 4758 additions and 3923 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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): ...

View File

@ -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

View File

@ -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)

View File

@ -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]):

View File

@ -3522,23 +3522,38 @@ cdef class Container(Provider):
if container is None:
container = container_cls()
container.set_parent(self)
self.__container = container
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."""