mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	Merge branch 'release/4.29.0' into master
This commit is contained in:
		
						commit
						f1a3ad0b82
					
				
							
								
								
									
										2
									
								
								.github/workflows/tests-and-linters.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/tests-and-linters.yml
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -6,7 +6,7 @@ jobs:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test-on-different-versions:
 | 
					  test-on-different-versions:
 | 
				
			||||||
    name: Run tests
 | 
					    name: Run tests
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-18.04
 | 
				
			||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, pypy2, pypy3]
 | 
					        python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, pypy2, pypy3]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,14 @@ Method ``.reset_singletons()`` also resets singletons in sub-containers: ``provi
 | 
				
			||||||
   :lines: 3-
 | 
					   :lines: 3-
 | 
				
			||||||
   :emphasize-lines: 21
 | 
					   :emphasize-lines: 21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can use ``.reset_singletons()`` method with a context manager. Singletons will be reset on
 | 
				
			||||||
 | 
					both entering and exiting a context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/reset_singletons_with.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :lines: 3-
 | 
				
			||||||
 | 
					   :emphasize-lines: 14-15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
See also: :ref:`singleton-provider`.
 | 
					See also: :ref:`singleton-provider`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. disqus::
 | 
					.. disqus::
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,15 @@ that were made in every particular version.
 | 
				
			||||||
From version 0.7.6 *Dependency Injector* framework strictly 
 | 
					From version 0.7.6 *Dependency Injector* framework strictly 
 | 
				
			||||||
follows `Semantic versioning`_
 | 
					follows `Semantic versioning`_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4.29.0
 | 
				
			||||||
 | 
					------
 | 
				
			||||||
 | 
					- Implement context manager interface for resetting a singleton provider.
 | 
				
			||||||
 | 
					  See issue: `#413 <https://github.com/ets-labs/python-dependency-injector/issues/413>`_.
 | 
				
			||||||
 | 
					  Thanks to `@Arrowana <https://github.com/Arrowana>`_ for suggesting the improvement.
 | 
				
			||||||
 | 
					- Implement overriding interface to container provider.
 | 
				
			||||||
 | 
					  See issue: `#415 <https://github.com/ets-labs/python-dependency-injector/issues/415>`_.
 | 
				
			||||||
 | 
					  Thanks to `@wackazong <https://github.com/wackazong>`_ for bringing up the use case.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
4.28.1
 | 
					4.28.1
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
- Fix async mode mode exception handling issue in ``Dependency`` provider.
 | 
					- Fix async mode mode exception handling issue in ``Dependency`` provider.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,13 +20,12 @@ returns it on the rest of the calls.
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
   :lines: 3-
 | 
					   :lines: 3-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``Singleton`` provider handles an injection of the dependencies the same way like a
 | 
					``Singleton`` provider handles dependencies injection the same way like a :ref:`factory-provider`.
 | 
				
			||||||
:ref:`factory-provider`.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. note::
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ``Singleton`` provider does dependencies injection only when creates the object. When the object
 | 
					   ``Singleton`` provider makes dependencies injection only when creates an object. When an object
 | 
				
			||||||
   is created and memorized ``Singleton`` provider just returns it without applying the injections.
 | 
					   is created and memorized ``Singleton`` provider just returns it without applying injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Specialization of the provided type and abstract singletons work the same like like for the
 | 
					Specialization of the provided type and abstract singletons work the same like like for the
 | 
				
			||||||
factories:
 | 
					factories:
 | 
				
			||||||
| 
						 | 
					@ -56,6 +55,21 @@ provider.
 | 
				
			||||||
   Resetting of the memorized object clears the reference to it. Further object's lifecycle is
 | 
					   Resetting of the memorized object clears the reference to it. Further object's lifecycle is
 | 
				
			||||||
   managed by the garbage collector.
 | 
					   managed by the garbage collector.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can use ``.reset()`` method with a context manager. Memorized instance will be reset on
 | 
				
			||||||
 | 
					both entering and exiting a context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/providers/singleton_resetting_with.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :lines: 3-
 | 
				
			||||||
 | 
					   :emphasize-lines: 18-19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context manager ``.reset()`` returns resetting singleton provider. You can use it for aliasing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   with container.user_service.reset() as user_service:
 | 
				
			||||||
 | 
					       ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Method ``.reset()`` resets only current provider. To reset all dependent singleton providers
 | 
					Method ``.reset()`` resets only current provider. To reset all dependent singleton providers
 | 
				
			||||||
call ``.full_reset()`` method.
 | 
					call ``.full_reset()`` method.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +78,13 @@ call ``.full_reset()`` method.
 | 
				
			||||||
   :lines: 3-
 | 
					   :lines: 3-
 | 
				
			||||||
   :emphasize-lines: 25
 | 
					   :emphasize-lines: 25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Method ``.full_reset()`` supports context manager interface like ``.reset()`` does.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   with container.user_service.full_reset() as user_service:
 | 
				
			||||||
 | 
					       ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
See also: :ref:`reset-container-singletons`.
 | 
					See also: :ref:`reset-container-singletons`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Using singleton with multiple threads
 | 
					Using singleton with multiple threads
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										23
									
								
								examples/containers/reset_singletons_with.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								examples/containers/reset_singletons_with.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					"""Container reset singletons context manager example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import containers, providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service = providers.Singleton(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    container = Container()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service1 = container.service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with container.reset_singletons():
 | 
				
			||||||
 | 
					        service2 = container.service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service3 = container.service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert service1 is not service2
 | 
				
			||||||
 | 
					    assert service2 is not service3
 | 
				
			||||||
 | 
					    assert service3 is not service1
 | 
				
			||||||
							
								
								
									
										27
									
								
								examples/providers/singleton_resetting_with.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/providers/singleton_resetting_with.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					"""`Singleton` provider resetting context manager example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import containers, providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserService:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_service = providers.Singleton(UserService)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    container = Container()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_service1 = container.user_service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with container.user_service.reset():
 | 
				
			||||||
 | 
					        user_service2 = container.user_service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_service3 = container.user_service()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert user_service1 is not user_service2
 | 
				
			||||||
 | 
					    assert user_service2 is not user_service3
 | 
				
			||||||
 | 
					    assert user_service3 is not user_service1
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
"""Top-level package."""
 | 
					"""Top-level package."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__version__ = '4.28.1'
 | 
					__version__ = '4.29.0'
 | 
				
			||||||
"""Version number.
 | 
					"""Version number.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:type: str
 | 
					:type: str
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
 | 
					    Generic,
 | 
				
			||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
    Dict,
 | 
					    Dict,
 | 
				
			||||||
    Tuple,
 | 
					    Tuple,
 | 
				
			||||||
| 
						 | 
					@ -20,6 +21,7 @@ from .providers import Provider, Self, ProviderParent
 | 
				
			||||||
C_Base = TypeVar('C_Base', bound='Container')
 | 
					C_Base = TypeVar('C_Base', bound='Container')
 | 
				
			||||||
C = TypeVar('C', bound='DeclarativeContainer')
 | 
					C = TypeVar('C', bound='DeclarativeContainer')
 | 
				
			||||||
C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
 | 
					C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
 | 
				
			||||||
 | 
					T = TypeVar('T')
 | 
				
			||||||
TT = TypeVar('TT')
 | 
					TT = TypeVar('TT')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +46,7 @@ class Container:
 | 
				
			||||||
    def init_resources(self) -> Optional[Awaitable]: ...
 | 
					    def init_resources(self) -> Optional[Awaitable]: ...
 | 
				
			||||||
    def shutdown_resources(self) -> Optional[Awaitable]: ...
 | 
					    def shutdown_resources(self) -> Optional[Awaitable]: ...
 | 
				
			||||||
    def apply_container_providers_overridings(self) -> None: ...
 | 
					    def apply_container_providers_overridings(self) -> None: ...
 | 
				
			||||||
    def reset_singletons(self) -> None: ...
 | 
					    def reset_singletons(self) -> SingletonResetContext[C_Base]: ...
 | 
				
			||||||
    def check_dependencies(self) -> None: ...
 | 
					    def check_dependencies(self) -> None: ...
 | 
				
			||||||
    @overload
 | 
					    @overload
 | 
				
			||||||
    def resolve_provider_name(self, provider: Provider) -> str: ...
 | 
					    def resolve_provider_name(self, provider: Provider) -> str: ...
 | 
				
			||||||
| 
						 | 
					@ -72,6 +74,11 @@ class DeclarativeContainer(Container):
 | 
				
			||||||
    def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
 | 
					    def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SingletonResetContext(Generic[T]):
 | 
				
			||||||
 | 
					    def __init__(self, container: T): ...
 | 
				
			||||||
 | 
					    def __enter__(self) -> T: ...
 | 
				
			||||||
 | 
					    def __exit__(self, *_: Any) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def override(container: Type[C]) -> _Callable[[Type[C_Overriding]], Type[C_Overriding]]: ...
 | 
					def override(container: Type[C]) -> _Callable[[Type[C_Overriding]], Type[C_Overriding]]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -304,6 +304,7 @@ class DynamicContainer(Container):
 | 
				
			||||||
        """Reset container singletons."""
 | 
					        """Reset container singletons."""
 | 
				
			||||||
        for provider in self.traverse(types=[providers.BaseSingleton]):
 | 
					        for provider in self.traverse(types=[providers.BaseSingleton]):
 | 
				
			||||||
            provider.reset()
 | 
					            provider.reset()
 | 
				
			||||||
 | 
					        return SingletonResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def check_dependencies(self):
 | 
					    def check_dependencies(self):
 | 
				
			||||||
        """Check if container dependencies are defined.
 | 
					        """Check if container dependencies are defined.
 | 
				
			||||||
| 
						 | 
					@ -639,6 +640,18 @@ class DeclarativeContainer(Container):
 | 
				
			||||||
            provider.reset_override()
 | 
					            provider.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SingletonResetContext:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, container):
 | 
				
			||||||
 | 
					        self._container = container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __enter__(self):
 | 
				
			||||||
 | 
					        return self._container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __exit__(self, *_):
 | 
				
			||||||
 | 
					        self._container.reset_singletons()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def override(object container):
 | 
					def override(object container):
 | 
				
			||||||
    """:py:class:`DeclarativeContainer` overriding decorator.
 | 
					    """:py:class:`DeclarativeContainer` overriding decorator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -54,11 +54,6 @@ cdef class DependenciesContainer(Object):
 | 
				
			||||||
    cpdef object _override_providers(self, object container)
 | 
					    cpdef object _override_providers(self, object container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class OverridingContext(object):
 | 
					 | 
				
			||||||
    cdef Provider __overridden
 | 
					 | 
				
			||||||
    cdef Provider __overriding
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Callable providers
 | 
					# Callable providers
 | 
				
			||||||
cdef class Callable(Provider):
 | 
					cdef class Callable(Provider):
 | 
				
			||||||
    cdef object __provides
 | 
					    cdef object __provides
 | 
				
			||||||
| 
						 | 
					@ -292,6 +287,23 @@ cpdef tuple parse_named_injections(dict kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Utils
 | 
					# 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
 | 
					cdef object CLASS_TYPES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,12 +38,8 @@ Injection = Any
 | 
				
			||||||
ProviderParent = Union['Provider', Any]
 | 
					ProviderParent = Union['Provider', Any]
 | 
				
			||||||
T = TypeVar('T')
 | 
					T = TypeVar('T')
 | 
				
			||||||
TT = TypeVar('TT')
 | 
					TT = TypeVar('TT')
 | 
				
			||||||
 | 
					P = TypeVar('P', bound='Provider')
 | 
				
			||||||
 | 
					BS = TypeVar('BS', bound='BaseSingleton')
 | 
				
			||||||
class OverridingContext:
 | 
					 | 
				
			||||||
    def __init__(self, overridden: Provider, overriding: Provider): ...
 | 
					 | 
				
			||||||
    def __enter__(self) -> Provider: ...
 | 
					 | 
				
			||||||
    def __exit__(self, *_: Any) -> None: ...
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Provider(Generic[T]):
 | 
					class Provider(Generic[T]):
 | 
				
			||||||
| 
						 | 
					@ -62,7 +58,7 @@ class Provider(Generic[T]):
 | 
				
			||||||
    def overridden(self) -> Tuple[Provider]: ...
 | 
					    def overridden(self) -> Tuple[Provider]: ...
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def last_overriding(self) -> Optional[Provider]: ...
 | 
					    def last_overriding(self) -> Optional[Provider]: ...
 | 
				
			||||||
    def override(self, provider: Union[Provider, Any]) -> OverridingContext: ...
 | 
					    def override(self, provider: Union[Provider, Any]) -> OverridingContext[P]: ...
 | 
				
			||||||
    def reset_last_overriding(self) -> None: ...
 | 
					    def reset_last_overriding(self) -> None: ...
 | 
				
			||||||
    def reset_override(self) -> None: ...
 | 
					    def reset_override(self) -> None: ...
 | 
				
			||||||
    def delegate(self) -> Provider: ...
 | 
					    def delegate(self) -> Provider: ...
 | 
				
			||||||
| 
						 | 
					@ -109,7 +105,7 @@ class Dependency(Provider[T]):
 | 
				
			||||||
    def default(self) -> Provider[T]: ...
 | 
					    def default(self) -> Provider[T]: ...
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_defined(self) -> bool: ...
 | 
					    def is_defined(self) -> bool: ...
 | 
				
			||||||
    def provided_by(self, provider: Provider) -> OverridingContext: ...
 | 
					    def provided_by(self, provider: Provider) -> OverridingContext[P]: ...
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def parent(self) -> Optional[ProviderParent]: ...
 | 
					    def parent(self) -> Optional[ProviderParent]: ...
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
| 
						 | 
					@ -153,7 +149,7 @@ class DelegatedCallable(Callable[T]): ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractCallable(Callable[T]):
 | 
					class AbstractCallable(Callable[T]):
 | 
				
			||||||
    def override(self, provider: Callable) -> OverridingContext: ...
 | 
					    def override(self, provider: Callable) -> OverridingContext[P]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CallableDelegate(Delegate):
 | 
					class CallableDelegate(Delegate):
 | 
				
			||||||
| 
						 | 
					@ -167,7 +163,7 @@ class DelegatedCoroutine(Coroutine[T]): ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractCoroutine(Coroutine[T]):
 | 
					class AbstractCoroutine(Coroutine[T]):
 | 
				
			||||||
    def override(self, provider: Coroutine) -> OverridingContext: ...
 | 
					    def override(self, provider: Coroutine) -> OverridingContext[P]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CoroutineDelegate(Delegate):
 | 
					class CoroutineDelegate(Delegate):
 | 
				
			||||||
| 
						 | 
					@ -212,7 +208,7 @@ class Configuration(Object[Any]):
 | 
				
			||||||
    def __getitem__(self, item: Union[str, Provider]) -> ConfigurationOption: ...
 | 
					    def __getitem__(self, item: Union[str, Provider]) -> ConfigurationOption: ...
 | 
				
			||||||
    def get_name(self) -> str: ...
 | 
					    def get_name(self) -> str: ...
 | 
				
			||||||
    def get(self, selector: str) -> Any: ...
 | 
					    def get(self, selector: str) -> Any: ...
 | 
				
			||||||
    def set(self, selector: str, value: Any) -> OverridingContext: ...
 | 
					    def set(self, selector: str, value: Any) -> OverridingContext[P]: ...
 | 
				
			||||||
    def reset_cache(self) -> None: ...
 | 
					    def reset_cache(self) -> None: ...
 | 
				
			||||||
    def update(self, value: Any) -> None: ...
 | 
					    def update(self, value: Any) -> None: ...
 | 
				
			||||||
    def from_ini(self, filepath: Union[Path, str], required: bool = False) -> None: ...
 | 
					    def from_ini(self, filepath: Union[Path, str], required: bool = False) -> None: ...
 | 
				
			||||||
| 
						 | 
					@ -250,7 +246,7 @@ class DelegatedFactory(Factory[T]): ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractFactory(Factory[T]):
 | 
					class AbstractFactory(Factory[T]):
 | 
				
			||||||
    def override(self, provider: Factory) -> OverridingContext: ...
 | 
					    def override(self, provider: Factory) -> OverridingContext[P]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FactoryDelegate(Delegate):
 | 
					class FactoryDelegate(Delegate):
 | 
				
			||||||
| 
						 | 
					@ -293,8 +289,8 @@ class BaseSingleton(Provider[T]):
 | 
				
			||||||
    def add_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
 | 
					    def add_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
 | 
				
			||||||
    def set_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
 | 
					    def set_attributes(self, **kwargs: Injection) -> BaseSingleton[T]: ...
 | 
				
			||||||
    def clear_attributes(self) -> BaseSingleton[T]: ...
 | 
					    def clear_attributes(self) -> BaseSingleton[T]: ...
 | 
				
			||||||
    def reset(self) -> None: ...
 | 
					    def reset(self) -> SingletonResetContext[BS]: ...
 | 
				
			||||||
    def full_reset(self) -> None: ...
 | 
					    def full_reset(self) -> SingletonFullResetContext[BS]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Singleton(BaseSingleton[T]): ...
 | 
					class Singleton(BaseSingleton[T]): ...
 | 
				
			||||||
| 
						 | 
					@ -316,7 +312,7 @@ class DelegatedThreadLocalSingleton(ThreadLocalSingleton[T]): ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractSingleton(BaseSingleton[T]):
 | 
					class AbstractSingleton(BaseSingleton[T]):
 | 
				
			||||||
    def override(self, provider: BaseSingleton) -> OverridingContext: ...
 | 
					    def override(self, provider: BaseSingleton) -> OverridingContext[P]: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SingletonDelegate(Delegate):
 | 
					class SingletonDelegate(Delegate):
 | 
				
			||||||
| 
						 | 
					@ -414,6 +410,29 @@ class MethodCaller(Provider, ProvidedInstanceFluentInterface):
 | 
				
			||||||
    def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
 | 
					    def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OverridingContext(Generic[T]):
 | 
				
			||||||
 | 
					    def __init__(self, overridden: Provider, overriding: Provider): ...
 | 
				
			||||||
 | 
					    def __enter__(self) -> T: ...
 | 
				
			||||||
 | 
					    def __exit__(self, *_: Any) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseSingletonResetContext(Generic[T]):
 | 
				
			||||||
 | 
					    def __init__(self, provider: T): ...
 | 
				
			||||||
 | 
					    def __enter__(self) -> T: ...
 | 
				
			||||||
 | 
					    def __exit__(self, *_: Any) -> None: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SingletonResetContext(BaseSingletonResetContext):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SingletonFullResetContext(BaseSingletonResetContext):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CHILD_PROVIDERS: Tuple[Provider]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_provider(instance: Any) -> bool: ...
 | 
					def is_provider(instance: Any) -> bool: ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,6 +463,3 @@ if pydantic:
 | 
				
			||||||
    PydanticSettings = pydantic.BaseSettings
 | 
					    PydanticSettings = pydantic.BaseSettings
 | 
				
			||||||
else:
 | 
					else:
 | 
				
			||||||
    PydanticSettings = Any
 | 
					    PydanticSettings = Any
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CHILD_PROVIDERS: Tuple[Provider]
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -990,42 +990,6 @@ cdef class DependenciesContainer(Object):
 | 
				
			||||||
            provider.override(dependency_provider)
 | 
					            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):
 | 
					cdef class Callable(Provider):
 | 
				
			||||||
    r"""Callable provider calls wrapped callable on every call.
 | 
					    r"""Callable provider calls wrapped callable on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2632,11 +2596,12 @@ cdef class BaseSingleton(Provider):
 | 
				
			||||||
    def full_reset(self):
 | 
					    def full_reset(self):
 | 
				
			||||||
        """Reset cached instance in current and all underlying singletons, if any.
 | 
					        """Reset cached instance in current and all underlying singletons, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: :py:class:`SingletonFullResetContext`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.reset()
 | 
					        self.reset()
 | 
				
			||||||
        for provider in self.traverse(types=[BaseSingleton]):
 | 
					        for provider in self.traverse(types=[BaseSingleton]):
 | 
				
			||||||
            provider.reset()
 | 
					            provider.reset()
 | 
				
			||||||
 | 
					        return SingletonFullResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def related(self):
 | 
					    def related(self):
 | 
				
			||||||
| 
						 | 
					@ -2707,6 +2672,7 @@ cdef class Singleton(BaseSingleton):
 | 
				
			||||||
        if __is_future_or_coroutine(self.__storage):
 | 
					        if __is_future_or_coroutine(self.__storage):
 | 
				
			||||||
            asyncio.ensure_future(self.__storage).cancel()
 | 
					            asyncio.ensure_future(self.__storage).cancel()
 | 
				
			||||||
        self.__storage = None
 | 
					        self.__storage = None
 | 
				
			||||||
 | 
					        return SingletonResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
        """Return single instance."""
 | 
					        """Return single instance."""
 | 
				
			||||||
| 
						 | 
					@ -2775,7 +2741,7 @@ cdef class ThreadSafeSingleton(BaseSingleton):
 | 
				
			||||||
            if __is_future_or_coroutine(self.__storage):
 | 
					            if __is_future_or_coroutine(self.__storage):
 | 
				
			||||||
                asyncio.ensure_future(self.__storage).cancel()
 | 
					                asyncio.ensure_future(self.__storage).cancel()
 | 
				
			||||||
            self.__storage = None
 | 
					            self.__storage = None
 | 
				
			||||||
 | 
					        return SingletonResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
        """Return single instance."""
 | 
					        """Return single instance."""
 | 
				
			||||||
| 
						 | 
					@ -2853,10 +2819,18 @@ cdef class ThreadLocalSingleton(BaseSingleton):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if __is_future_or_coroutine(self.__storage.instance):
 | 
					        try:
 | 
				
			||||||
            asyncio.ensure_future(self.__storage.instance).cancel()
 | 
					            instance = self.__storage.instance
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            return SingletonResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if __is_future_or_coroutine(instance):
 | 
				
			||||||
 | 
					            asyncio.ensure_future(instance).cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        del self.__storage.instance
 | 
					        del self.__storage.instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return SingletonResetContext(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
        """Return single instance."""
 | 
					        """Return single instance."""
 | 
				
			||||||
        cdef object instance
 | 
					        cdef object instance
 | 
				
			||||||
| 
						 | 
					@ -3604,7 +3578,32 @@ cdef class Container(Provider):
 | 
				
			||||||
            raise Error('Container provider {0} can be overridden only by providers container'.format(self))
 | 
					            raise Error('Container provider {0} can be overridden only by providers container'.format(self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.__container.override_providers(**provider.providers)
 | 
					        self.__container.override_providers(**provider.providers)
 | 
				
			||||||
        super().override(provider)
 | 
					        return super().override(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
 | 
					        """Reset last overriding provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :raise: :py:exc:`dependency_injector.errors.Error` if provider is not
 | 
				
			||||||
 | 
					                overridden.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        super().reset_last_overriding()
 | 
				
			||||||
 | 
					        for provider in self.__container.providers.values():
 | 
				
			||||||
 | 
					            if not provider.overridden:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            provider.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_override(self):
 | 
				
			||||||
 | 
					        """Reset all overriding providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        super().reset_override()
 | 
				
			||||||
 | 
					        for provider in self.__container.providers.values():
 | 
				
			||||||
 | 
					            if not provider.overridden:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            provider.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def apply_overridings(self):
 | 
					    def apply_overridings(self):
 | 
				
			||||||
        """Apply container overriding.
 | 
					        """Apply container overriding.
 | 
				
			||||||
| 
						 | 
					@ -4188,6 +4187,67 @@ cpdef tuple parse_named_injections(dict kwargs):
 | 
				
			||||||
    return tuple(injections)
 | 
					    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)
 | 
					CHILD_PROVIDERS = (Dependency, DependenciesContainer, Container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -336,6 +336,36 @@ class DeclarativeContainerInstanceTests(unittest.TestCase):
 | 
				
			||||||
        self.assertIs(obj32, obj42)
 | 
					        self.assertIs(obj32, obj42)
 | 
				
			||||||
        self.assertIs(obj33, obj43)
 | 
					        self.assertIs(obj33, obj43)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_singletons_context_manager(self):
 | 
				
			||||||
 | 
					        class Item:
 | 
				
			||||||
 | 
					            def __init__(self, dependency):
 | 
				
			||||||
 | 
					                self.dependency = dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					            dependent = providers.Singleton(object)
 | 
				
			||||||
 | 
					            singleton = providers.Singleton(Item, dependency=dependent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        container = Container()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = container.singleton()
 | 
				
			||||||
 | 
					        with container.reset_singletons():
 | 
				
			||||||
 | 
					            instance2 = container.singleton()
 | 
				
			||||||
 | 
					        instance3 = container.singleton()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(len({instance1, instance2, instance3}), 3)
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            len({instance1.dependency, instance2.dependency, instance3.dependency}),
 | 
				
			||||||
 | 
					            3,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_singletons_context_manager_as_attribute(self):
 | 
				
			||||||
 | 
					        container = containers.DeclarativeContainer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with container.reset_singletons() as alias:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(container, alias)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_check_dependencies(self):
 | 
					    def test_check_dependencies(self):
 | 
				
			||||||
        class SubContainer(containers.DeclarativeContainer):
 | 
					        class SubContainer(containers.DeclarativeContainer):
 | 
				
			||||||
            dependency = providers.Dependency()
 | 
					            dependency = providers.Dependency()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,6 +176,48 @@ class ContainerTests(unittest.TestCase):
 | 
				
			||||||
        result = b.a().c().bar()
 | 
					        result = b.a().c().bar()
 | 
				
			||||||
        self.assertEqual(result, 'foo++')
 | 
					        self.assertEqual(result, 'foo++')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_last_overriding(self):
 | 
				
			||||||
 | 
					        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
				
			||||||
 | 
					        application.core.override(TestCore(config=_copied(TEST_CONFIG_2['core'])))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        application.core.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_last_overriding_only_overridden(self):
 | 
				
			||||||
 | 
					        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
				
			||||||
 | 
					        application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2['core'])))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        application.core.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_override_context_manager(self):
 | 
				
			||||||
 | 
					        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
				
			||||||
 | 
					        overriding_core = TestCore(config=_copied(TEST_CONFIG_2['core']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with application.core.override(overriding_core) as context_core:
 | 
				
			||||||
 | 
					            self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_2})
 | 
				
			||||||
 | 
					            self.assertIs(context_core(), overriding_core)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_override(self):
 | 
				
			||||||
 | 
					        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
				
			||||||
 | 
					        application.core.override(TestCore(config=_copied(TEST_CONFIG_2['core'])))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        application.core.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(application.dict_factory(), {'value': None})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_override_only_overridden(self):
 | 
				
			||||||
 | 
					        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
				
			||||||
 | 
					        application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2['core'])))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        application.core.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(application.dict_factory(), {'value': None})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_assign_parent(self):
 | 
					    def test_assign_parent(self):
 | 
				
			||||||
        parent = providers.DependenciesContainer()
 | 
					        parent = providers.DependenciesContainer()
 | 
				
			||||||
        provider = providers.Container(TestCore)
 | 
					        provider = providers.Container(TestCore)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -370,6 +370,23 @@ class _BaseSingletonTestCase(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_context_manager(self):
 | 
				
			||||||
 | 
					        singleton = self.singleton_cls(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = singleton()
 | 
				
			||||||
 | 
					        with singleton.reset():
 | 
				
			||||||
 | 
					            instance2 = singleton()
 | 
				
			||||||
 | 
					        instance3 = singleton()
 | 
				
			||||||
 | 
					        self.assertEqual(len({instance1, instance2, instance3}), 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_context_manager_as_attribute(self):
 | 
				
			||||||
 | 
					        singleton = self.singleton_cls(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with singleton.reset() as alias:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(singleton, alias)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_full_reset(self):
 | 
					    def test_full_reset(self):
 | 
				
			||||||
        dependent_singleton = providers.Singleton(object)
 | 
					        dependent_singleton = providers.Singleton(object)
 | 
				
			||||||
        provider = self.singleton_cls(dict, dependency=dependent_singleton)
 | 
					        provider = self.singleton_cls(dict, dependency=dependent_singleton)
 | 
				
			||||||
| 
						 | 
					@ -386,6 +403,33 @@ class _BaseSingletonTestCase(object):
 | 
				
			||||||
        self.assertIsNot(dependent_instance1, dependent_instance2)
 | 
					        self.assertIsNot(dependent_instance1, dependent_instance2)
 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_full_reset_context_manager(self):
 | 
				
			||||||
 | 
					        class Item:
 | 
				
			||||||
 | 
					            def __init__(self, dependency):
 | 
				
			||||||
 | 
					                self.dependency = dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dependent_singleton = providers.Singleton(object)
 | 
				
			||||||
 | 
					        singleton = self.singleton_cls(Item, dependency=dependent_singleton)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance1 = singleton()
 | 
				
			||||||
 | 
					        with singleton.full_reset():
 | 
				
			||||||
 | 
					            instance2 = singleton()
 | 
				
			||||||
 | 
					        instance3 = singleton()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(len({instance1, instance2, instance3}), 3)
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            len({instance1.dependency, instance2.dependency, instance3.dependency}),
 | 
				
			||||||
 | 
					            3,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_full_reset_context_manager_as_attribute(self):
 | 
				
			||||||
 | 
					        singleton = self.singleton_cls(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with singleton.full_reset() as alias:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertIs(singleton, alias)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
					class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,6 +489,16 @@ class ThreadLocalSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertIsNot(instance1, instance2)
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reset_clean(self):
 | 
				
			||||||
 | 
					        provider = providers.ThreadLocalSingleton(Example)
 | 
				
			||||||
 | 
					        instance1 = provider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        provider.reset()
 | 
				
			||||||
 | 
					        provider.reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instance2 = provider()
 | 
				
			||||||
 | 
					        self.assertIsNot(instance1, instance2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DelegatedThreadLocalSingletonTests(_BaseSingletonTestCase,
 | 
					class DelegatedThreadLocalSingletonTests(_BaseSingletonTestCase,
 | 
				
			||||||
                                         unittest.TestCase):
 | 
					                                         unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user