mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-16 19:40:59 +03:00
Merge branch 'release/4.19.0' into master
This commit is contained in:
commit
ce6d3df72c
|
@ -7,6 +7,14 @@ 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.19.0
|
||||||
|
------
|
||||||
|
- Add ``singleton.full_reset()`` method to reset all underlying singleton providers.
|
||||||
|
- Fix ``container.reset_singleton()`` to reset all provider types, not only ``Singleton``.
|
||||||
|
- Improve ``container.traverse(types=[...])`` and ``provider.traverse(types=[...])`` typing stubs
|
||||||
|
to return ``types`` -typed iterator.
|
||||||
|
- Update docs on creating custom providers with a requirement to specify ``.related`` property.
|
||||||
|
|
||||||
4.18.0
|
4.18.0
|
||||||
------
|
------
|
||||||
- Add ``container.reset_singleton()`` method to reset container singletons.
|
- Add ``container.reset_singleton()`` method to reset container singletons.
|
||||||
|
|
|
@ -20,8 +20,11 @@ To create a custom provider you need to follow these rules:
|
||||||
from the ``providers`` module. After the a new provider object is created use
|
from the ``providers`` module. After the a new provider object is created use
|
||||||
``Provider._copy_overriding()`` method to copy all overriding providers. See the example
|
``Provider._copy_overriding()`` method to copy all overriding providers. See the example
|
||||||
below.
|
below.
|
||||||
4. If the new provider has a ``__init__()`` method, it should call the parent
|
4. If new provider has a ``__init__()`` method, it should call the parent
|
||||||
``Provider.__init__()``.
|
``Provider.__init__()``.
|
||||||
|
5. If new provider stores any other providers, these providers should be listed in
|
||||||
|
``.related`` property. Property ``.related`` also should yield providers from parent
|
||||||
|
``.related`` property.
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/providers/custom_factory.py
|
.. literalinclude:: ../../examples/providers/custom_factory.py
|
||||||
:language: python
|
:language: python
|
||||||
|
|
|
@ -54,6 +54,14 @@ 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.
|
||||||
|
|
||||||
|
Method ``.reset()`` resets only current provider. To reset all dependent singleton providers
|
||||||
|
call ``.full_reset()`` method.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/providers/singleton_full_resetting.py
|
||||||
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
:emphasize-lines: 25
|
||||||
|
|
||||||
Using singleton with multiple threads
|
Using singleton with multiple threads
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,12 @@ class CustomFactory(providers.Provider):
|
||||||
|
|
||||||
return copied
|
return copied
|
||||||
|
|
||||||
|
@property
|
||||||
|
def related(self):
|
||||||
|
"""Return related providers generator."""
|
||||||
|
yield from [self._factory]
|
||||||
|
yield from super().related
|
||||||
|
|
||||||
def _provide(self, args, kwargs):
|
def _provide(self, args, kwargs):
|
||||||
return self._factory(*args, **kwargs)
|
return self._factory(*args, **kwargs)
|
||||||
|
|
||||||
|
|
31
examples/providers/singleton_full_resetting.py
Normal file
31
examples/providers/singleton_full_resetting.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
"""`Singleton` provider full resetting example."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
|
class Database:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class UserService:
|
||||||
|
def __init__(self, db: Database):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
database = providers.Singleton(Database)
|
||||||
|
|
||||||
|
user_service = providers.Singleton(UserService, db=database)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
user_service1 = container.user_service()
|
||||||
|
|
||||||
|
container.user_service.full_reset()
|
||||||
|
|
||||||
|
user_service2 = container.user_service()
|
||||||
|
assert user_service2 is not user_service1
|
||||||
|
assert user_service2.db is not user_service1.db
|
|
@ -9,15 +9,15 @@ class UserService:
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
user_service_provider = providers.Singleton(UserService)
|
user_service = providers.Singleton(UserService)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
container = Container()
|
container = Container()
|
||||||
|
|
||||||
user_service1 = container.user_service_provider()
|
user_service1 = container.user_service()
|
||||||
|
|
||||||
container.user_service_provider.reset()
|
container.user_service.reset()
|
||||||
|
|
||||||
user_service2 = container.user_service_provider()
|
user_service2 = container.user_service()
|
||||||
assert user_service2 is not user_service1
|
assert user_service2 is not user_service1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Top-level package."""
|
"""Top-level package."""
|
||||||
|
|
||||||
__version__ = '4.18.0'
|
__version__ = '4.19.0'
|
||||||
"""Version number.
|
"""Version number.
|
||||||
|
|
||||||
:type: str
|
:type: str
|
||||||
|
|
|
@ -1620,7 +1620,6 @@ static const char __pyx_k_shutdown[] = "shutdown";
|
||||||
static const char __pyx_k_sub_memo[] = "sub_memo";
|
static const char __pyx_k_sub_memo[] = "sub_memo";
|
||||||
static const char __pyx_k_traverse[] = "traverse";
|
static const char __pyx_k_traverse[] = "traverse";
|
||||||
static const char __pyx_k_Container[] = "Container";
|
static const char __pyx_k_Container[] = "Container";
|
||||||
static const char __pyx_k_Singleton[] = "Singleton";
|
|
||||||
static const char __pyx_k_container[] = "container";
|
static const char __pyx_k_container[] = "container";
|
||||||
static const char __pyx_k_decorator[] = "_decorator";
|
static const char __pyx_k_decorator[] = "_decorator";
|
||||||
static const char __pyx_k_iteritems[] = "iteritems";
|
static const char __pyx_k_iteritems[] = "iteritems";
|
||||||
|
@ -1639,6 +1638,7 @@ static const char __pyx_k_isawaitable[] = "isawaitable";
|
||||||
static const char __pyx_k_IS_CONTAINER[] = "__IS_CONTAINER__";
|
static const char __pyx_k_IS_CONTAINER[] = "__IS_CONTAINER__";
|
||||||
static const char __pyx_k_dependencies[] = "dependencies";
|
static const char __pyx_k_dependencies[] = "dependencies";
|
||||||
static const char __pyx_k_version_info[] = "version_info";
|
static const char __pyx_k_version_info[] = "version_info";
|
||||||
|
static const char __pyx_k_BaseSingleton[] = "BaseSingleton";
|
||||||
static const char __pyx_k_add_metaclass[] = "add_metaclass";
|
static const char __pyx_k_add_metaclass[] = "add_metaclass";
|
||||||
static const char __pyx_k_all_providers[] = "all_providers";
|
static const char __pyx_k_all_providers[] = "all_providers";
|
||||||
static const char __pyx_k_asyncio_tasks[] = "asyncio.tasks";
|
static const char __pyx_k_asyncio_tasks[] = "asyncio.tasks";
|
||||||
|
@ -1724,6 +1724,7 @@ static const char __pyx_k_Declarative_inversion_of_control_2[] = "Declarative in
|
||||||
static PyObject *__pyx_kp_s_0_can_contain_only_1_instances;
|
static PyObject *__pyx_kp_s_0_can_contain_only_1_instances;
|
||||||
static PyObject *__pyx_kp_s_Abstract_container;
|
static PyObject *__pyx_kp_s_Abstract_container;
|
||||||
static PyObject *__pyx_n_s_AttributeError;
|
static PyObject *__pyx_n_s_AttributeError;
|
||||||
|
static PyObject *__pyx_n_s_BaseSingleton;
|
||||||
static PyObject *__pyx_n_s_Container;
|
static PyObject *__pyx_n_s_Container;
|
||||||
static PyObject *__pyx_kp_s_Container_0_could_not_be_overrid;
|
static PyObject *__pyx_kp_s_Container_0_could_not_be_overrid;
|
||||||
static PyObject *__pyx_kp_s_Container_0_could_not_be_overrid_2;
|
static PyObject *__pyx_kp_s_Container_0_could_not_be_overrid_2;
|
||||||
|
@ -1771,7 +1772,6 @@ static PyObject *__pyx_n_s_NotImplementedError;
|
||||||
static PyObject *__pyx_n_s_Object;
|
static PyObject *__pyx_n_s_Object;
|
||||||
static PyObject *__pyx_n_s_Provider;
|
static PyObject *__pyx_n_s_Provider;
|
||||||
static PyObject *__pyx_n_s_Resource;
|
static PyObject *__pyx_n_s_Resource;
|
||||||
static PyObject *__pyx_n_s_Singleton;
|
|
||||||
static PyObject *__pyx_kp_s_Wiring_requires_Python_3_6_or_ab;
|
static PyObject *__pyx_kp_s_Wiring_requires_Python_3_6_or_ab;
|
||||||
static PyObject *__pyx_n_s__11;
|
static PyObject *__pyx_n_s__11;
|
||||||
static PyObject *__pyx_n_s_add_metaclass;
|
static PyObject *__pyx_n_s_add_metaclass;
|
||||||
|
@ -6370,13 +6370,13 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
* provider.apply_overridings()
|
* provider.apply_overridings()
|
||||||
*
|
*
|
||||||
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]):
|
* for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Python wrapper */
|
/* Python wrapper */
|
||||||
static PyObject *__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
|
static PyObject *__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
|
||||||
static char __pyx_doc_19dependency_injector_10containers_16DynamicContainer_33reset_singletons[] = "Reset all container singletons.";
|
static char __pyx_doc_19dependency_injector_10containers_16DynamicContainer_33reset_singletons[] = "Reset container singletons.";
|
||||||
static PyMethodDef __pyx_mdef_19dependency_injector_10containers_16DynamicContainer_34reset_singletons = {"reset_singletons", (PyCFunction)__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons, METH_O, __pyx_doc_19dependency_injector_10containers_16DynamicContainer_33reset_singletons};
|
static PyMethodDef __pyx_mdef_19dependency_injector_10containers_16DynamicContainer_34reset_singletons = {"reset_singletons", (PyCFunction)__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons, METH_O, __pyx_doc_19dependency_injector_10containers_16DynamicContainer_33reset_singletons};
|
||||||
static PyObject *__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons(PyObject *__pyx_self, PyObject *__pyx_v_self) {
|
static PyObject *__pyx_pw_19dependency_injector_10containers_16DynamicContainer_34reset_singletons(PyObject *__pyx_self, PyObject *__pyx_v_self) {
|
||||||
PyObject *__pyx_r = 0;
|
PyObject *__pyx_r = 0;
|
||||||
|
@ -6406,8 +6406,8 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
|
|
||||||
/* "dependency_injector/containers.pyx":276
|
/* "dependency_injector/containers.pyx":276
|
||||||
* def reset_singletons(self):
|
* def reset_singletons(self):
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]): # <<<<<<<<<<<<<<
|
* for provider in self.traverse(types=[providers.BaseSingleton]): # <<<<<<<<<<<<<<
|
||||||
* provider.reset()
|
* provider.reset()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -6417,7 +6417,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
__Pyx_GOTREF(__pyx_t_2);
|
__Pyx_GOTREF(__pyx_t_2);
|
||||||
__Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_providers); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error)
|
__Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_providers); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error)
|
||||||
__Pyx_GOTREF(__pyx_t_3);
|
__Pyx_GOTREF(__pyx_t_3);
|
||||||
__pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_Singleton); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 276, __pyx_L1_error)
|
__pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_BaseSingleton); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 276, __pyx_L1_error)
|
||||||
__Pyx_GOTREF(__pyx_t_4);
|
__Pyx_GOTREF(__pyx_t_4);
|
||||||
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
|
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
|
||||||
__pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error)
|
__pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error)
|
||||||
|
@ -6475,8 +6475,8 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
__pyx_t_3 = 0;
|
__pyx_t_3 = 0;
|
||||||
|
|
||||||
/* "dependency_injector/containers.pyx":277
|
/* "dependency_injector/containers.pyx":277
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]):
|
* for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
* provider.reset() # <<<<<<<<<<<<<<
|
* provider.reset() # <<<<<<<<<<<<<<
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -6502,8 +6502,8 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
|
|
||||||
/* "dependency_injector/containers.pyx":276
|
/* "dependency_injector/containers.pyx":276
|
||||||
* def reset_singletons(self):
|
* def reset_singletons(self):
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]): # <<<<<<<<<<<<<<
|
* for provider in self.traverse(types=[providers.BaseSingleton]): # <<<<<<<<<<<<<<
|
||||||
* provider.reset()
|
* provider.reset()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -6514,8 +6514,8 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_
|
||||||
* provider.apply_overridings()
|
* provider.apply_overridings()
|
||||||
*
|
*
|
||||||
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]):
|
* for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* function exit code */
|
/* function exit code */
|
||||||
|
@ -12153,6 +12153,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
|
||||||
{&__pyx_kp_s_0_can_contain_only_1_instances, __pyx_k_0_can_contain_only_1_instances, sizeof(__pyx_k_0_can_contain_only_1_instances), 0, 0, 1, 0},
|
{&__pyx_kp_s_0_can_contain_only_1_instances, __pyx_k_0_can_contain_only_1_instances, sizeof(__pyx_k_0_can_contain_only_1_instances), 0, 0, 1, 0},
|
||||||
{&__pyx_kp_s_Abstract_container, __pyx_k_Abstract_container, sizeof(__pyx_k_Abstract_container), 0, 0, 1, 0},
|
{&__pyx_kp_s_Abstract_container, __pyx_k_Abstract_container, sizeof(__pyx_k_Abstract_container), 0, 0, 1, 0},
|
||||||
{&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
|
{&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
|
||||||
|
{&__pyx_n_s_BaseSingleton, __pyx_k_BaseSingleton, sizeof(__pyx_k_BaseSingleton), 0, 0, 1, 1},
|
||||||
{&__pyx_n_s_Container, __pyx_k_Container, sizeof(__pyx_k_Container), 0, 0, 1, 1},
|
{&__pyx_n_s_Container, __pyx_k_Container, sizeof(__pyx_k_Container), 0, 0, 1, 1},
|
||||||
{&__pyx_kp_s_Container_0_could_not_be_overrid, __pyx_k_Container_0_could_not_be_overrid, sizeof(__pyx_k_Container_0_could_not_be_overrid), 0, 0, 1, 0},
|
{&__pyx_kp_s_Container_0_could_not_be_overrid, __pyx_k_Container_0_could_not_be_overrid, sizeof(__pyx_k_Container_0_could_not_be_overrid), 0, 0, 1, 0},
|
||||||
{&__pyx_kp_s_Container_0_could_not_be_overrid_2, __pyx_k_Container_0_could_not_be_overrid_2, sizeof(__pyx_k_Container_0_could_not_be_overrid_2), 0, 0, 1, 0},
|
{&__pyx_kp_s_Container_0_could_not_be_overrid_2, __pyx_k_Container_0_could_not_be_overrid_2, sizeof(__pyx_k_Container_0_could_not_be_overrid_2), 0, 0, 1, 0},
|
||||||
|
@ -12200,7 +12201,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
|
||||||
{&__pyx_n_s_Object, __pyx_k_Object, sizeof(__pyx_k_Object), 0, 0, 1, 1},
|
{&__pyx_n_s_Object, __pyx_k_Object, sizeof(__pyx_k_Object), 0, 0, 1, 1},
|
||||||
{&__pyx_n_s_Provider, __pyx_k_Provider, sizeof(__pyx_k_Provider), 0, 0, 1, 1},
|
{&__pyx_n_s_Provider, __pyx_k_Provider, sizeof(__pyx_k_Provider), 0, 0, 1, 1},
|
||||||
{&__pyx_n_s_Resource, __pyx_k_Resource, sizeof(__pyx_k_Resource), 0, 0, 1, 1},
|
{&__pyx_n_s_Resource, __pyx_k_Resource, sizeof(__pyx_k_Resource), 0, 0, 1, 1},
|
||||||
{&__pyx_n_s_Singleton, __pyx_k_Singleton, sizeof(__pyx_k_Singleton), 0, 0, 1, 1},
|
|
||||||
{&__pyx_kp_s_Wiring_requires_Python_3_6_or_ab, __pyx_k_Wiring_requires_Python_3_6_or_ab, sizeof(__pyx_k_Wiring_requires_Python_3_6_or_ab), 0, 0, 1, 0},
|
{&__pyx_kp_s_Wiring_requires_Python_3_6_or_ab, __pyx_k_Wiring_requires_Python_3_6_or_ab, sizeof(__pyx_k_Wiring_requires_Python_3_6_or_ab), 0, 0, 1, 0},
|
||||||
{&__pyx_n_s__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 0, 1, 1},
|
{&__pyx_n_s__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 0, 1, 1},
|
||||||
{&__pyx_n_s_add_metaclass, __pyx_k_add_metaclass, sizeof(__pyx_k_add_metaclass), 0, 0, 1, 1},
|
{&__pyx_n_s_add_metaclass, __pyx_k_add_metaclass, sizeof(__pyx_k_add_metaclass), 0, 0, 1, 1},
|
||||||
|
@ -12648,8 +12648,8 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||||
* provider.apply_overridings()
|
* provider.apply_overridings()
|
||||||
*
|
*
|
||||||
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]):
|
* for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
*/
|
*/
|
||||||
__pyx_tuple__52 = PyTuple_Pack(2, __pyx_n_s_self_2, __pyx_n_s_provider); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 274, __pyx_L1_error)
|
__pyx_tuple__52 = PyTuple_Pack(2, __pyx_n_s_self_2, __pyx_n_s_provider); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 274, __pyx_L1_error)
|
||||||
__Pyx_GOTREF(__pyx_tuple__52);
|
__Pyx_GOTREF(__pyx_tuple__52);
|
||||||
|
@ -13645,8 +13645,8 @@ if (!__Pyx_RefNanny) {
|
||||||
* provider.apply_overridings()
|
* provider.apply_overridings()
|
||||||
*
|
*
|
||||||
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
* def reset_singletons(self): # <<<<<<<<<<<<<<
|
||||||
* """Reset all container singletons."""
|
* """Reset container singletons."""
|
||||||
* for provider in self.traverse(types=[providers.Singleton]):
|
* for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
*/
|
*/
|
||||||
__pyx_t_10 = __Pyx_CyFunction_New(&__pyx_mdef_19dependency_injector_10containers_16DynamicContainer_34reset_singletons, 0, __pyx_n_s_DynamicContainer_reset_singleton, NULL, __pyx_n_s_dependency_injector_containers, __pyx_d, ((PyObject *)__pyx_codeobj__53)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 274, __pyx_L1_error)
|
__pyx_t_10 = __Pyx_CyFunction_New(&__pyx_mdef_19dependency_injector_10containers_16DynamicContainer_34reset_singletons, 0, __pyx_n_s_DynamicContainer_reset_singleton, NULL, __pyx_n_s_dependency_injector_containers, __pyx_d, ((PyObject *)__pyx_codeobj__53)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 274, __pyx_L1_error)
|
||||||
__Pyx_GOTREF(__pyx_t_10);
|
__Pyx_GOTREF(__pyx_t_10);
|
||||||
|
|
|
@ -21,6 +21,7 @@ from .providers import Provider
|
||||||
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')
|
||||||
|
TT = TypeVar('TT')
|
||||||
|
|
||||||
|
|
||||||
class Container:
|
class Container:
|
||||||
|
@ -46,10 +47,10 @@ class Container:
|
||||||
def apply_container_providers_overridings(self) -> None: ...
|
def apply_container_providers_overridings(self) -> None: ...
|
||||||
def reset_singletons(self) -> None: ...
|
def reset_singletons(self) -> None: ...
|
||||||
@overload
|
@overload
|
||||||
def traverse(self, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
|
def traverse(self, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...
|
||||||
@classmethod
|
@classmethod
|
||||||
@overload
|
@overload
|
||||||
def traverse(cls, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
|
def traverse(cls, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...
|
||||||
|
|
||||||
|
|
||||||
class DynamicContainer(Container): ...
|
class DynamicContainer(Container): ...
|
||||||
|
|
|
@ -272,8 +272,8 @@ class DynamicContainer(Container):
|
||||||
provider.apply_overridings()
|
provider.apply_overridings()
|
||||||
|
|
||||||
def reset_singletons(self):
|
def reset_singletons(self):
|
||||||
"""Reset all container singletons."""
|
"""Reset container singletons."""
|
||||||
for provider in self.traverse(types=[providers.Singleton]):
|
for provider in self.traverse(types=[providers.BaseSingleton]):
|
||||||
provider.reset()
|
provider.reset()
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,6 +36,7 @@ from . import resources
|
||||||
|
|
||||||
Injection = Any
|
Injection = Any
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
|
TT = TypeVar('TT')
|
||||||
|
|
||||||
|
|
||||||
class OverridingContext:
|
class OverridingContext:
|
||||||
|
@ -76,7 +77,7 @@ class Provider(Generic[T]):
|
||||||
def is_async_mode_undefined(self) -> bool: ...
|
def is_async_mode_undefined(self) -> bool: ...
|
||||||
@property
|
@property
|
||||||
def related(self) -> _Iterator[Provider]: ...
|
def related(self) -> _Iterator[Provider]: ...
|
||||||
def traverse(self, types: Optional[_Iterable[Type]] = None) -> _Iterator[Provider]: ...
|
def traverse(self, types: Optional[_Iterable[TT]] = None) -> _Iterator[TT]: ...
|
||||||
def _copy_overridings(self, copied: Provider, memo: Optional[_Dict[Any, Any]]) -> None: ...
|
def _copy_overridings(self, copied: Provider, memo: Optional[_Dict[Any, Any]]) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,6 +267,7 @@ class BaseSingleton(Provider[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) -> None: ...
|
||||||
|
def full_reset(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class Singleton(BaseSingleton[T]): ...
|
class Singleton(BaseSingleton[T]): ...
|
||||||
|
|
|
@ -2468,6 +2468,15 @@ cdef class BaseSingleton(Provider):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def full_reset(self):
|
||||||
|
"""Reset cached instance in current and all underlying singletons, if any.
|
||||||
|
|
||||||
|
:rtype: None
|
||||||
|
"""
|
||||||
|
self.reset()
|
||||||
|
for provider in self.traverse(types=[BaseSingleton]):
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def related(self):
|
def related(self):
|
||||||
"""Return related providers generator."""
|
"""Return related providers generator."""
|
||||||
|
|
|
@ -355,6 +355,37 @@ class _BaseSingletonTestCase(object):
|
||||||
|
|
||||||
self.assertIsNot(instance1, instance2)
|
self.assertIsNot(instance1, instance2)
|
||||||
|
|
||||||
|
def test_reset_with_singleton(self):
|
||||||
|
dependent_singleton = providers.Singleton(object)
|
||||||
|
provider = self.singleton_cls(dict, dependency=dependent_singleton)
|
||||||
|
|
||||||
|
dependent_instance = dependent_singleton()
|
||||||
|
instance1 = provider()
|
||||||
|
self.assertIs(instance1['dependency'], dependent_instance)
|
||||||
|
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
instance2 = provider()
|
||||||
|
self.assertIs(instance1['dependency'], dependent_instance)
|
||||||
|
|
||||||
|
self.assertIsNot(instance1, instance2)
|
||||||
|
|
||||||
|
def test_full_reset(self):
|
||||||
|
dependent_singleton = providers.Singleton(object)
|
||||||
|
provider = self.singleton_cls(dict, dependency=dependent_singleton)
|
||||||
|
|
||||||
|
dependent_instance1 = dependent_singleton()
|
||||||
|
instance1 = provider()
|
||||||
|
self.assertIs(instance1['dependency'], dependent_instance1)
|
||||||
|
|
||||||
|
provider.full_reset()
|
||||||
|
|
||||||
|
dependent_instance2 = dependent_singleton()
|
||||||
|
instance2 = provider()
|
||||||
|
self.assertIsNot(instance2['dependency'], dependent_instance1)
|
||||||
|
self.assertIsNot(dependent_instance1, dependent_instance2)
|
||||||
|
self.assertIsNot(instance1, instance2)
|
||||||
|
|
||||||
|
|
||||||
class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
class SingletonTests(_BaseSingletonTestCase, unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user