Skip to content

Commit

Permalink
Merge branch 'release/4.19.0' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
rmk135 committed Feb 5, 2021
2 parents 78f623c + 398d502 commit ce6d3df
Show file tree
Hide file tree
Showing 14 changed files with 2,971 additions and 2,681 deletions.
8 changes: 8 additions & 0 deletions docs/main/changelog.rst
Expand Up @@ -7,6 +7,14 @@ that were made in every particular version.
From version 0.7.6 *Dependency Injector* framework strictly
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
------
- Add ``container.reset_singleton()`` method to reset container singletons.
Expand Down
5 changes: 4 additions & 1 deletion docs/providers/custom.rst
Expand Up @@ -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
``Provider._copy_overriding()`` method to copy all overriding providers. See the example
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__()``.
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
:language: python
Expand Down
8 changes: 8 additions & 0 deletions docs/providers/singleton.rst
Expand Up @@ -54,6 +54,14 @@ provider.
Resetting of the memorized object clears the reference to it. Further object's lifecycle is
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
-------------------------------------

Expand Down
6 changes: 6 additions & 0 deletions examples/providers/custom_factory.py
Expand Up @@ -25,6 +25,12 @@ def __deepcopy__(self, memo):

return copied

@property
def related(self):
"""Return related providers generator."""
yield from [self._factory]
yield from super().related

def _provide(self, args, kwargs):
return self._factory(*args, **kwargs)

Expand Down
31 changes: 31 additions & 0 deletions examples/providers/singleton_full_resetting.py
@@ -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
8 changes: 4 additions & 4 deletions examples/providers/singleton_resetting.py
Expand Up @@ -9,15 +9,15 @@ class UserService:

class Container(containers.DeclarativeContainer):

user_service_provider = providers.Singleton(UserService)
user_service = providers.Singleton(UserService)


if __name__ == '__main__':
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
2 changes: 1 addition & 1 deletion src/dependency_injector/__init__.py
@@ -1,6 +1,6 @@
"""Top-level package."""

__version__ = '4.18.0'
__version__ = '4.19.0'
"""Version number.
:type: str
Expand Down
38 changes: 19 additions & 19 deletions src/dependency_injector/containers.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/dependency_injector/containers.pyi
Expand Up @@ -21,6 +21,7 @@ from .providers import Provider
C_Base = TypeVar('C_Base', bound='Container')
C = TypeVar('C', bound='DeclarativeContainer')
C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
TT = TypeVar('TT')


class Container:
Expand All @@ -46,10 +47,10 @@ class Container:
def apply_container_providers_overridings(self) -> None: ...
def reset_singletons(self) -> None: ...
@overload
def traverse(self, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
def traverse(self, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...
@classmethod
@overload
def traverse(cls, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
def traverse(cls, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...


class DynamicContainer(Container): ...
Expand Down
4 changes: 2 additions & 2 deletions src/dependency_injector/containers.pyx
Expand Up @@ -272,8 +272,8 @@ class DynamicContainer(Container):
provider.apply_overridings()

def reset_singletons(self):
"""Reset all container singletons."""
for provider in self.traverse(types=[providers.Singleton]):
"""Reset container singletons."""
for provider in self.traverse(types=[providers.BaseSingleton]):
provider.reset()


Expand Down

0 comments on commit ce6d3df

Please sign in to comment.