Skip to content

Commit ce6d3df

Browse files
committed
Merge branch 'release/4.19.0' into master
2 parents 78f623c + 398d502 commit ce6d3df

File tree

14 files changed

+2971
-2681
lines changed

14 files changed

+2971
-2681
lines changed

docs/main/changelog.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ that were made in every particular version.
77
From version 0.7.6 *Dependency Injector* framework strictly
88
follows `Semantic versioning`_
99

10+
4.19.0
11+
------
12+
- Add ``singleton.full_reset()`` method to reset all underlying singleton providers.
13+
- Fix ``container.reset_singleton()`` to reset all provider types, not only ``Singleton``.
14+
- Improve ``container.traverse(types=[...])`` and ``provider.traverse(types=[...])`` typing stubs
15+
to return ``types`` -typed iterator.
16+
- Update docs on creating custom providers with a requirement to specify ``.related`` property.
17+
1018
4.18.0
1119
------
1220
- Add ``container.reset_singleton()`` method to reset container singletons.

docs/providers/custom.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ To create a custom provider you need to follow these rules:
2020
from the ``providers`` module. After the a new provider object is created use
2121
``Provider._copy_overriding()`` method to copy all overriding providers. See the example
2222
below.
23-
4. If the new provider has a ``__init__()`` method, it should call the parent
23+
4. If new provider has a ``__init__()`` method, it should call the parent
2424
``Provider.__init__()``.
25+
5. If new provider stores any other providers, these providers should be listed in
26+
``.related`` property. Property ``.related`` also should yield providers from parent
27+
``.related`` property.
2528

2629
.. literalinclude:: ../../examples/providers/custom_factory.py
2730
:language: python

docs/providers/singleton.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ provider.
5454
Resetting of the memorized object clears the reference to it. Further object's lifecycle is
5555
managed by the garbage collector.
5656

57+
Method ``.reset()`` resets only current provider. To reset all dependent singleton providers
58+
call ``.full_reset()`` method.
59+
60+
.. literalinclude:: ../../examples/providers/singleton_full_resetting.py
61+
:language: python
62+
:lines: 3-
63+
:emphasize-lines: 25
64+
5765
Using singleton with multiple threads
5866
-------------------------------------
5967

examples/providers/custom_factory.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ def __deepcopy__(self, memo):
2525

2626
return copied
2727

28+
@property
29+
def related(self):
30+
"""Return related providers generator."""
31+
yield from [self._factory]
32+
yield from super().related
33+
2834
def _provide(self, args, kwargs):
2935
return self._factory(*args, **kwargs)
3036

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""`Singleton` provider full resetting example."""
2+
3+
from dependency_injector import containers, providers
4+
5+
6+
class Database:
7+
...
8+
9+
10+
class UserService:
11+
def __init__(self, db: Database):
12+
self.db = db
13+
14+
15+
class Container(containers.DeclarativeContainer):
16+
17+
database = providers.Singleton(Database)
18+
19+
user_service = providers.Singleton(UserService, db=database)
20+
21+
22+
if __name__ == '__main__':
23+
container = Container()
24+
25+
user_service1 = container.user_service()
26+
27+
container.user_service.full_reset()
28+
29+
user_service2 = container.user_service()
30+
assert user_service2 is not user_service1
31+
assert user_service2.db is not user_service1.db

examples/providers/singleton_resetting.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ class UserService:
99

1010
class Container(containers.DeclarativeContainer):
1111

12-
user_service_provider = providers.Singleton(UserService)
12+
user_service = providers.Singleton(UserService)
1313

1414

1515
if __name__ == '__main__':
1616
container = Container()
1717

18-
user_service1 = container.user_service_provider()
18+
user_service1 = container.user_service()
1919

20-
container.user_service_provider.reset()
20+
container.user_service.reset()
2121

22-
user_service2 = container.user_service_provider()
22+
user_service2 = container.user_service()
2323
assert user_service2 is not user_service1

src/dependency_injector/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Top-level package."""
22

3-
__version__ = '4.18.0'
3+
__version__ = '4.19.0'
44
"""Version number.
55
66
:type: str

src/dependency_injector/containers.c

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dependency_injector/containers.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ from .providers import Provider
2121
C_Base = TypeVar('C_Base', bound='Container')
2222
C = TypeVar('C', bound='DeclarativeContainer')
2323
C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
24+
TT = TypeVar('TT')
2425

2526

2627
class Container:
@@ -46,10 +47,10 @@ class Container:
4647
def apply_container_providers_overridings(self) -> None: ...
4748
def reset_singletons(self) -> None: ...
4849
@overload
49-
def traverse(self, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
50+
def traverse(self, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...
5051
@classmethod
5152
@overload
52-
def traverse(cls, types: Optional[Sequence[Type]] = None) -> Iterator[Provider]: ...
53+
def traverse(cls, types: Optional[Sequence[TT]] = None) -> Iterator[TT]: ...
5354

5455

5556
class DynamicContainer(Container): ...

src/dependency_injector/containers.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ class DynamicContainer(Container):
272272
provider.apply_overridings()
273273

274274
def reset_singletons(self):
275-
"""Reset all container singletons."""
276-
for provider in self.traverse(types=[providers.Singleton]):
275+
"""Reset container singletons."""
276+
for provider in self.traverse(types=[providers.BaseSingleton]):
277277
provider.reset()
278278

279279

0 commit comments

Comments
 (0)