Add implementation and typing stubs

This commit is contained in:
Roman Mogylatov 2021-03-01 10:11:09 -05:00
parent e0b0a1e968
commit a948ff37b7
7 changed files with 12692 additions and 9105 deletions

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@ class Container:
def init_resources(self) -> Optional[Awaitable]: ...
def shutdown_resources(self) -> Optional[Awaitable]: ...
def apply_container_providers_overridings(self) -> None: ...
def reset_singletons(self) -> None: ...
def reset_singletons(self) -> SingletonResettingContext: ...
def check_dependencies(self) -> None: ...
@overload
def resolve_provider_name(self, provider: Provider) -> str: ...
@ -72,6 +72,11 @@ class DeclarativeContainer(Container):
def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
class SingletonResettingContext:
def __init__(self, container: Container): ...
def __enter__(self) -> None: ...
def __exit__(self, *_: Any) -> None: ...
def override(container: Type[C]) -> _Callable[[Type[C_Overriding]], Type[C_Overriding]]: ...

View File

@ -304,6 +304,7 @@ class DynamicContainer(Container):
"""Reset container singletons."""
for provider in self.traverse(types=[providers.BaseSingleton]):
provider.reset()
return SingletonResetContext(self)
def check_dependencies(self):
"""Check if container dependencies are defined.
@ -639,6 +640,18 @@ class DeclarativeContainer(Container):
provider.reset_override()
class SingletonResetContext:
def __init__(self, container):
self._container = container
def __enter__(self):
...
def __exit__(self, *_):
self._container.reset_singletons()
def override(object container):
""":py:class:`DeclarativeContainer` overriding decorator.

File diff suppressed because it is too large Load Diff

View File

@ -54,11 +54,6 @@ cdef class DependenciesContainer(Object):
cpdef object _override_providers(self, object container)
cdef class OverridingContext(object):
cdef Provider __overridden
cdef Provider __overriding
# Callable providers
cdef class Callable(Provider):
cdef object __provides
@ -292,6 +287,23 @@ cpdef tuple parse_named_injections(dict kwargs)
# Utils
cdef class OverridingContext(object):
cdef Provider __overridden
cdef Provider __overriding
cdef class BaseSingletonResetContext(object):
cdef object __singleton
cdef class SingletonResetContext(BaseSingletonResetContext):
pass
cdef class SingletonFullResetContext(BaseSingletonResetContext):
pass
cdef object CLASS_TYPES

View File

@ -40,12 +40,6 @@ T = TypeVar('T')
TT = TypeVar('TT')
class OverridingContext:
def __init__(self, overridden: Provider, overriding: Provider): ...
def __enter__(self) -> Provider: ...
def __exit__(self, *_: Any) -> None: ...
class Provider(Generic[T]):
def __init__(self) -> None: ...
@ -293,8 +287,8 @@ class BaseSingleton(Provider[T]):
def add_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
def set_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
def clear_attributes(self) -> BaseSingleton[T]: ...
def reset(self) -> None: ...
def full_reset(self) -> None: ...
def reset(self) -> SingletonResetContext: ...
def full_reset(self) -> SingletonFullResetContext: ...
class Singleton(BaseSingleton[T]): ...
@ -414,6 +408,29 @@ class MethodCaller(Provider, ProvidedInstanceFluentInterface):
def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
class OverridingContext:
def __init__(self, overridden: Provider, overriding: Provider): ...
def __enter__(self) -> Provider: ...
def __exit__(self, *_: Any) -> None: ...
class BaseSingletonResetContext:
def __init__(self, provider: Provider): ...
def __enter__(self) -> None: ...
def __exit__(self, *_: Any) -> None: ...
class SingletonResetContext(BaseSingletonResetContext):
...
class SingletonFullResetContext(BaseSingletonResetContext):
...
CHILD_PROVIDERS: Tuple[Provider]
def is_provider(instance: Any) -> bool: ...
@ -444,6 +461,3 @@ if pydantic:
PydanticSettings = pydantic.BaseSettings
else:
PydanticSettings = Any
CHILD_PROVIDERS: Tuple[Provider]

View File

@ -990,42 +990,6 @@ cdef class DependenciesContainer(Object):
provider.override(dependency_provider)
cdef class OverridingContext(object):
"""Provider overriding context.
:py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
implementing ``with`` contexts. When :py:class:`OverridingContext` is
closed, overriding that was created in this context is dropped also.
.. code-block:: python
with provider.override(another_provider):
assert provider.overridden
assert not provider.overridden
"""
def __init__(self, Provider overridden, Provider overriding):
"""Initializer.
:param overridden: Overridden provider.
:type overridden: :py:class:`Provider`
:param overriding: Overriding provider.
:type overriding: :py:class:`Provider`
"""
self.__overridden = overridden
self.__overriding = overriding
super(OverridingContext, self).__init__()
def __enter__(self):
"""Do nothing."""
return self.__overriding
def __exit__(self, *_):
"""Exit overriding context."""
self.__overridden.reset_last_overriding()
cdef class Callable(Provider):
r"""Callable provider calls wrapped callable on every call.
@ -2632,11 +2596,12 @@ cdef class BaseSingleton(Provider):
def full_reset(self):
"""Reset cached instance in current and all underlying singletons, if any.
:rtype: None
:rtype: :py:class:`SingletonFullResetContext`
"""
self.reset()
for provider in self.traverse(types=[BaseSingleton]):
provider.reset()
return SingletonFullResetContext(self)
@property
def related(self):
@ -2707,6 +2672,7 @@ cdef class Singleton(BaseSingleton):
if __is_future_or_coroutine(self.__storage):
asyncio.ensure_future(self.__storage).cancel()
self.__storage = None
return SingletonResetContext(self)
cpdef object _provide(self, tuple args, dict kwargs):
"""Return single instance."""
@ -2775,6 +2741,7 @@ cdef class ThreadSafeSingleton(BaseSingleton):
if __is_future_or_coroutine(self.__storage):
asyncio.ensure_future(self.__storage).cancel()
self.__storage = None
return SingletonResetContext(self)
cpdef object _provide(self, tuple args, dict kwargs):
@ -2856,6 +2823,7 @@ cdef class ThreadLocalSingleton(BaseSingleton):
if __is_future_or_coroutine(self.__storage.instance):
asyncio.ensure_future(self.__storage.instance).cancel()
del self.__storage.instance
return SingletonResetContext(self)
cpdef object _provide(self, tuple args, dict kwargs):
"""Return single instance."""
@ -4188,6 +4156,67 @@ cpdef tuple parse_named_injections(dict kwargs):
return tuple(injections)
cdef class OverridingContext(object):
"""Provider overriding context.
:py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
implementing ``with`` contexts. When :py:class:`OverridingContext` is
closed, overriding that was created in this context is dropped also.
.. code-block:: python
with provider.override(another_provider):
assert provider.overridden
assert not provider.overridden
"""
def __init__(self, Provider overridden, Provider overriding):
"""Initializer.
:param overridden: Overridden provider.
:type overridden: :py:class:`Provider`
:param overriding: Overriding provider.
:type overriding: :py:class:`Provider`
"""
self.__overridden = overridden
self.__overriding = overriding
super(OverridingContext, self).__init__()
def __enter__(self):
"""Do nothing."""
return self.__overriding
def __exit__(self, *_):
"""Exit overriding context."""
self.__overridden.reset_last_overriding()
cdef class BaseSingletonResetContext(object):
def __init__(self, Provider provider):
self.__singleton = provider
super().__init__()
def __enter__(self):
return self.__singleton
def __exit__(self, *_):
raise NotImplementedError()
cdef class SingletonResetContext(BaseSingletonResetContext):
def __exit__(self, *_):
return self.__singleton.reset()
cdef class SingletonFullResetContext(BaseSingletonResetContext):
def __exit__(self, *_):
return self.__singleton.full_reset()
CHILD_PROVIDERS = (Dependency, DependenciesContainer, Container)