mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Make some refactoring and add tests
This commit is contained in:
		
							parent
							
								
									a948ff37b7
								
							
						
					
					
						commit
						8eb7501ec1
					
				| 
						 | 
				
			
			@ -3606,7 +3606,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_20DeclarativeContai
 | 
			
		|||
static PyObject *__pyx_pf_19dependency_injector_10containers_20DeclarativeContainer_4reset_last_overriding(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_cls); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_20DeclarativeContainer_6reset_override(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_cls); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_container); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext_2__enter__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext_2__enter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext_4__exit__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v__); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_8override__decorator(PyObject *__pyx_self, PyObject *__pyx_v_overriding_container); /* proto */
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_4override(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_container); /* proto */
 | 
			
		||||
| 
						 | 
				
			
			@ -14649,7 +14649,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetCon
 | 
			
		|||
 *         self._container = container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __enter__(self):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14667,20 +14667,50 @@ static PyObject *__pyx_pw_19dependency_injector_10containers_21SingletonResetCon
 | 
			
		|||
  return __pyx_r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext_2__enter__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self) {
 | 
			
		||||
static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetContext_2__enter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
 | 
			
		||||
  PyObject *__pyx_r = NULL;
 | 
			
		||||
  __Pyx_RefNannyDeclarations
 | 
			
		||||
  PyObject *__pyx_t_1 = NULL;
 | 
			
		||||
  int __pyx_lineno = 0;
 | 
			
		||||
  const char *__pyx_filename = NULL;
 | 
			
		||||
  int __pyx_clineno = 0;
 | 
			
		||||
  __Pyx_RefNannySetupContext("__enter__", 0);
 | 
			
		||||
 | 
			
		||||
  /* "dependency_injector/containers.pyx":649
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __enter__(self):
 | 
			
		||||
 *         return self._container             # <<<<<<<<<<<<<<
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __exit__(self, *_):
 | 
			
		||||
 */
 | 
			
		||||
  __Pyx_XDECREF(__pyx_r);
 | 
			
		||||
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_container_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 649, __pyx_L1_error)
 | 
			
		||||
  __Pyx_GOTREF(__pyx_t_1);
 | 
			
		||||
  __pyx_r = __pyx_t_1;
 | 
			
		||||
  __pyx_t_1 = 0;
 | 
			
		||||
  goto __pyx_L0;
 | 
			
		||||
 | 
			
		||||
  /* "dependency_injector/containers.pyx":648
 | 
			
		||||
 *         self._container = container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __enter__(self):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
  /* function exit code */
 | 
			
		||||
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
 | 
			
		||||
  __pyx_L1_error:;
 | 
			
		||||
  __Pyx_XDECREF(__pyx_t_1);
 | 
			
		||||
  __Pyx_AddTraceback("dependency_injector.containers.SingletonResetContext.__enter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
 | 
			
		||||
  __pyx_r = NULL;
 | 
			
		||||
  __pyx_L0:;
 | 
			
		||||
  __Pyx_XGIVEREF(__pyx_r);
 | 
			
		||||
  __Pyx_RefNannyFinishContext();
 | 
			
		||||
  return __pyx_r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* "dependency_injector/containers.pyx":651
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __exit__(self, *_):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         self._container.reset_singletons()
 | 
			
		||||
| 
						 | 
				
			
			@ -14796,7 +14826,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_21SingletonResetCon
 | 
			
		|||
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 | 
			
		||||
 | 
			
		||||
  /* "dependency_injector/containers.pyx":651
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __exit__(self, *_):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         self._container.reset_singletons()
 | 
			
		||||
| 
						 | 
				
			
			@ -23499,7 +23529,7 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
 | 
			
		|||
 *         self._container = container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __enter__(self):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
  __pyx_tuple__101 = PyTuple_Pack(1, __pyx_n_s_self_2); if (unlikely(!__pyx_tuple__101)) __PYX_ERR(0, 648, __pyx_L1_error)
 | 
			
		||||
| 
						 | 
				
			
			@ -23508,7 +23538,7 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
 | 
			
		|||
  __pyx_codeobj__102 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__101, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_dependency_injector_containe, __pyx_n_s_enter, 648, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__102)) __PYX_ERR(0, 648, __pyx_L1_error)
 | 
			
		||||
 | 
			
		||||
  /* "dependency_injector/containers.pyx":651
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __exit__(self, *_):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         self._container.reset_singletons()
 | 
			
		||||
| 
						 | 
				
			
			@ -25115,7 +25145,7 @@ if (!__Pyx_RefNanny) {
 | 
			
		|||
 *         self._container = container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __enter__(self):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_19dependency_injector_10containers_21SingletonResetContext_3__enter__, 0, __pyx_n_s_SingletonResetContext___enter, NULL, __pyx_n_s_dependency_injector_containers, __pyx_d, ((PyObject *)__pyx_codeobj__102)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 648, __pyx_L1_error)
 | 
			
		||||
| 
						 | 
				
			
			@ -25124,7 +25154,7 @@ if (!__Pyx_RefNanny) {
 | 
			
		|||
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 | 
			
		||||
 | 
			
		||||
  /* "dependency_injector/containers.pyx":651
 | 
			
		||||
 *         ...
 | 
			
		||||
 *         return self._container
 | 
			
		||||
 * 
 | 
			
		||||
 *     def __exit__(self, *_):             # <<<<<<<<<<<<<<
 | 
			
		||||
 *         self._container.reset_singletons()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
from typing import (
 | 
			
		||||
    Generic,
 | 
			
		||||
    Type,
 | 
			
		||||
    Dict,
 | 
			
		||||
    Tuple,
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,7 @@ from .providers import Provider, Self, ProviderParent
 | 
			
		|||
C_Base = TypeVar('C_Base', bound='Container')
 | 
			
		||||
C = TypeVar('C', bound='DeclarativeContainer')
 | 
			
		||||
C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
 | 
			
		||||
T = TypeVar('T')
 | 
			
		||||
TT = TypeVar('TT')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +46,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) -> SingletonResettingContext: ...
 | 
			
		||||
    def reset_singletons(self) -> SingletonResetContext[C_Base]: ...
 | 
			
		||||
    def check_dependencies(self) -> None: ...
 | 
			
		||||
    @overload
 | 
			
		||||
    def resolve_provider_name(self, provider: Provider) -> str: ...
 | 
			
		||||
| 
						 | 
				
			
			@ -72,9 +74,9 @@ class DeclarativeContainer(Container):
 | 
			
		|||
    def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SingletonResettingContext:
 | 
			
		||||
    def __init__(self, container: Container): ...
 | 
			
		||||
    def __enter__(self) -> None: ...
 | 
			
		||||
class SingletonResetContext(Generic[T]):
 | 
			
		||||
    def __init__(self, container: T): ...
 | 
			
		||||
    def __enter__(self) -> T: ...
 | 
			
		||||
    def __exit__(self, *_: Any) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -646,7 +646,7 @@ class SingletonResetContext:
 | 
			
		|||
        self._container = container
 | 
			
		||||
 | 
			
		||||
    def __enter__(self):
 | 
			
		||||
        ...
 | 
			
		||||
        return self._container
 | 
			
		||||
 | 
			
		||||
    def __exit__(self, *_):
 | 
			
		||||
        self._container.reset_singletons()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -38,6 +38,8 @@ Injection = Any
 | 
			
		|||
ProviderParent = Union['Provider', Any]
 | 
			
		||||
T = TypeVar('T')
 | 
			
		||||
TT = TypeVar('TT')
 | 
			
		||||
P = TypeVar('P', bound='Provider')
 | 
			
		||||
BS = TypeVar('BS', bound='BaseSingleton')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Provider(Generic[T]):
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +58,7 @@ class Provider(Generic[T]):
 | 
			
		|||
    def overridden(self) -> Tuple[Provider]: ...
 | 
			
		||||
    @property
 | 
			
		||||
    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_override(self) -> None: ...
 | 
			
		||||
    def delegate(self) -> Provider: ...
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +105,7 @@ class Dependency(Provider[T]):
 | 
			
		|||
    def default(self) -> Provider[T]: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def is_defined(self) -> bool: ...
 | 
			
		||||
    def provided_by(self, provider: Provider) -> OverridingContext: ...
 | 
			
		||||
    def provided_by(self, provider: Provider) -> OverridingContext[P]: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def parent(self) -> Optional[ProviderParent]: ...
 | 
			
		||||
    @property
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +149,7 @@ class DelegatedCallable(Callable[T]): ...
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class AbstractCallable(Callable[T]):
 | 
			
		||||
    def override(self, provider: Callable) -> OverridingContext: ...
 | 
			
		||||
    def override(self, provider: Callable) -> OverridingContext[P]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CallableDelegate(Delegate):
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +163,7 @@ class DelegatedCoroutine(Coroutine[T]): ...
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class AbstractCoroutine(Coroutine[T]):
 | 
			
		||||
    def override(self, provider: Coroutine) -> OverridingContext: ...
 | 
			
		||||
    def override(self, provider: Coroutine) -> OverridingContext[P]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CoroutineDelegate(Delegate):
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +208,7 @@ class Configuration(Object[Any]):
 | 
			
		|||
    def __getitem__(self, item: Union[str, Provider]) -> ConfigurationOption: ...
 | 
			
		||||
    def get_name(self) -> str: ...
 | 
			
		||||
    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 update(self, value: Any) -> None: ...
 | 
			
		||||
    def from_ini(self, filepath: Union[Path, str], required: bool = False) -> None: ...
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +246,7 @@ class DelegatedFactory(Factory[T]): ...
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class AbstractFactory(Factory[T]):
 | 
			
		||||
    def override(self, provider: Factory) -> OverridingContext: ...
 | 
			
		||||
    def override(self, provider: Factory) -> OverridingContext[P]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FactoryDelegate(Delegate):
 | 
			
		||||
| 
						 | 
				
			
			@ -287,8 +289,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) -> SingletonResetContext: ...
 | 
			
		||||
    def full_reset(self) -> SingletonFullResetContext: ...
 | 
			
		||||
    def reset(self) -> SingletonResetContext[BS]: ...
 | 
			
		||||
    def full_reset(self) -> SingletonFullResetContext[BS]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Singleton(BaseSingleton[T]): ...
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +312,7 @@ class DelegatedThreadLocalSingleton(ThreadLocalSingleton[T]): ...
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class AbstractSingleton(BaseSingleton[T]):
 | 
			
		||||
    def override(self, provider: BaseSingleton) -> OverridingContext: ...
 | 
			
		||||
    def override(self, provider: BaseSingleton) -> OverridingContext[P]: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SingletonDelegate(Delegate):
 | 
			
		||||
| 
						 | 
				
			
			@ -408,15 +410,15 @@ class MethodCaller(Provider, ProvidedInstanceFluentInterface):
 | 
			
		|||
    def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OverridingContext:
 | 
			
		||||
class OverridingContext(Generic[T]):
 | 
			
		||||
    def __init__(self, overridden: Provider, overriding: Provider): ...
 | 
			
		||||
    def __enter__(self) -> Provider: ...
 | 
			
		||||
    def __enter__(self) -> T: ...
 | 
			
		||||
    def __exit__(self, *_: Any) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseSingletonResetContext:
 | 
			
		||||
    def __init__(self, provider: Provider): ...
 | 
			
		||||
    def __enter__(self) -> None: ...
 | 
			
		||||
class BaseSingletonResetContext(Generic[T]):
 | 
			
		||||
    def __init__(self, provider: T): ...
 | 
			
		||||
    def __enter__(self) -> T: ...
 | 
			
		||||
    def __exit__(self, *_: Any) -> None: ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2743,7 +2743,6 @@ cdef class ThreadSafeSingleton(BaseSingleton):
 | 
			
		|||
            self.__storage = None
 | 
			
		||||
        return SingletonResetContext(self)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
			
		||||
        """Return single instance."""
 | 
			
		||||
        instance = self.__storage
 | 
			
		||||
| 
						 | 
				
			
			@ -2820,9 +2819,16 @@ cdef class ThreadLocalSingleton(BaseSingleton):
 | 
			
		|||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if __is_future_or_coroutine(self.__storage.instance):
 | 
			
		||||
            asyncio.ensure_future(self.__storage.instance).cancel()
 | 
			
		||||
        try:
 | 
			
		||||
            instance = self.__storage.instance
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            return SingletonResetContext(self)
 | 
			
		||||
 | 
			
		||||
        if __is_future_or_coroutine(instance):
 | 
			
		||||
            asyncio.ensure_future(instance).cancel()
 | 
			
		||||
 | 
			
		||||
        del self.__storage.instance
 | 
			
		||||
 | 
			
		||||
        return SingletonResetContext(self)
 | 
			
		||||
 | 
			
		||||
    cpdef object _provide(self, tuple args, dict kwargs):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,6 +336,36 @@ class DeclarativeContainerInstanceTests(unittest.TestCase):
 | 
			
		|||
        self.assertIs(obj32, obj42)
 | 
			
		||||
        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):
 | 
			
		||||
        class SubContainer(containers.DeclarativeContainer):
 | 
			
		||||
            dependency = providers.Dependency()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -370,6 +370,23 @@ class _BaseSingletonTestCase(object):
 | 
			
		|||
 | 
			
		||||
        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):
 | 
			
		||||
        dependent_singleton = providers.Singleton(object)
 | 
			
		||||
        provider = self.singleton_cls(dict, dependency=dependent_singleton)
 | 
			
		||||
| 
						 | 
				
			
			@ -386,6 +403,33 @@ class _BaseSingletonTestCase(object):
 | 
			
		|||
        self.assertIsNot(dependent_instance1, dependent_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):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -445,6 +489,16 @@ class ThreadLocalSingletonTests(_BaseSingletonTestCase, unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
        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,
 | 
			
		||||
                                         unittest.TestCase):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user