Skip to content

Commit c26b260

Browse files
committed
Merge branch 'release/4.38.0' into master
2 parents 541131e + ad0d430 commit c26b260

40 files changed

+18105
-14970
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Key features of the ``Dependency Injector``:
9090
api_client = providers.Singleton(
9191
ApiClient,
9292
api_key=config.api_key,
93-
timeout=config.timeout.as_int(),
93+
timeout=config.timeout,
9494
)
9595
9696
service = providers.Factory(
@@ -106,8 +106,8 @@ Key features of the ``Dependency Injector``:
106106
107107
if __name__ == "__main__":
108108
container = Container()
109-
container.config.api_key.from_env("API_KEY")
110-
container.config.timeout.from_env("TIMEOUT")
109+
container.config.api_key.from_env("API_KEY", required=True)
110+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
111111
container.wire(modules=[__name__])
112112
113113
main() # <-- dependency is injected automatically

docs/_static/logo.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Key features of the ``Dependency Injector``:
9696
api_client = providers.Singleton(
9797
ApiClient,
9898
api_key=config.api_key,
99-
timeout=config.timeout.as_int(),
99+
timeout=config.timeout,
100100
)
101101
102102
service = providers.Factory(
@@ -112,8 +112,8 @@ Key features of the ``Dependency Injector``:
112112
113113
if __name__ == "__main__":
114114
container = Container()
115-
container.config.api_key.from_env("API_KEY")
116-
container.config.timeout.from_env("TIMEOUT")
115+
container.config.api_key.from_env("API_KEY", required=True)
116+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
117117
container.wire(modules=[__name__])
118118
119119
main() # <-- dependency is injected automatically

docs/introduction/di_in_python.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ What does the Dependency Injector do?
150150
-------------------------------------
151151

152152
With the dependency injection pattern objects loose the responsibility of assembling
153-
the dependencies. The ``Dependency Injector`` absorbs that responsibilities.
153+
the dependencies. The ``Dependency Injector`` absorbs that responsibility.
154154

155155
``Dependency Injector`` helps to assemble and inject the dependencies.
156156

@@ -172,7 +172,7 @@ the dependency.
172172
api_client = providers.Singleton(
173173
ApiClient,
174174
api_key=config.api_key,
175-
timeout=config.timeout.as_int(),
175+
timeout=config.timeout,
176176
)
177177
178178
service = providers.Factory(
@@ -188,8 +188,8 @@ the dependency.
188188
189189
if __name__ == "__main__":
190190
container = Container()
191-
container.config.api_key.from_env("API_KEY")
192-
container.config.timeout.from_env("TIMEOUT")
191+
container.config.api_key.from_env("API_KEY", required=True)
192+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
193193
container.wire(modules=[__name__])
194194
195195
main() # <-- dependency is injected automatically

docs/main/changelog.rst

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

10+
4.38.0
11+
------
12+
- Add new provider ``Aggregate``. It is a generalized version of ``FactoryAggregate`` that
13+
can contain providers of any type, not only ``Factory``. See issue
14+
`#530 <https://github.com/ets-labs/python-dependency-injector/issues/530>`_. Thanks to
15+
`@zerlok (Danil Troshnev) <https://github.com/zerlok>`_ for suggesting the feature.
16+
- Add argument ``as_`` to the ``config.from_env()`` method for the explicit type casting
17+
of an environment variable value, e.g.: ``config.timeout.from_env("TIMEOUT", as_=int)``.
18+
See issue `#533 <https://github.com/ets-labs/python-dependency-injector/issues/533>`_. Thanks to
19+
`@gtors (Andrey Torsunov) <https://github.com/gtors>`_ for suggesting the feature.
20+
- Add ``.providers`` attribute to the ``FactoryAggregate`` provider. It is an alias for
21+
``FactoryAggregate.factories`` attribute.
22+
- Add ``.set_providers()`` method to the ``FactoryAggregate`` provider. It is an alias for
23+
``FactoryAggregate.set_factories()`` method.
24+
- Add string imports for ``Factory``, ``Singleton``, ``Callable``, ``Resource``, and ``Coroutine``
25+
providers, e.g. ``Factory("module.Class")``.
26+
See issue `#531 <https://github.com/ets-labs/python-dependency-injector/issues/531>`_.
27+
Thanks to `@al-stefanitsky-mozdor <https://github.com/al-stefanitsky-mozdor>`_ for suggesting the feature.
28+
- Fix ``Dependency`` provider to don't raise "Dependency is not defined" error when the ``default``
29+
is a falsy value of proper type.
30+
See issue `#550 <https://github.com/ets-labs/python-dependency-injector/issues/550>`_. Thanks to
31+
`@approxit <https://github.com/approxit>`_ for reporting the issue.
32+
- Refactor ``FactoryAggregate`` provider internals.
33+
- Update logo on Github and in docs to support dark themes and remove some imperfections.
34+
1035
4.37.0
1136
------
1237
- Add support of Python 3.10.

docs/providers/aggregate.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.. _aggregate-provider:
2+
3+
Aggregate provider
4+
==================
5+
6+
.. meta::
7+
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Configuration,Injection,
8+
Aggregate,Polymorphism,Environment Variable,Flexibility
9+
:description: Aggregate provider aggregates other providers.
10+
This page demonstrates how to implement the polymorphism and increase the
11+
flexibility of your application using the Aggregate provider.
12+
13+
:py:class:`Aggregate` provider aggregates a group of other providers.
14+
15+
.. currentmodule:: dependency_injector.providers
16+
17+
.. literalinclude:: ../../examples/providers/aggregate.py
18+
:language: python
19+
:lines: 3-
20+
:emphasize-lines: 24-27
21+
22+
Each provider in the ``Aggregate`` is associated with a key. You can call aggregated providers by providing
23+
their key as a first argument. All positional and keyword arguments following the key will be forwarded to
24+
the called provider:
25+
26+
.. code-block:: python
27+
28+
yaml_reader = container.config_readers("yaml", "./config.yml", foo=...)
29+
30+
You can also retrieve an aggregated provider by providing its key as an attribute name:
31+
32+
.. code-block:: python
33+
34+
yaml_reader = container.config_readers.yaml("./config.yml", foo=...)
35+
36+
To retrieve a dictionary of aggregated providers, use ``.providers`` attribute:
37+
38+
.. code-block:: python
39+
40+
container.config_readers.providers == {
41+
"yaml": <YAML provider>,
42+
"json": <JSON provider>,
43+
}
44+
45+
.. note::
46+
You can not override the ``Aggregate`` provider.
47+
48+
.. note::
49+
When you inject the ``Aggregate`` provider, it is passed "as is".
50+
51+
To use non-string keys or string keys with ``.`` and ``-``, provide a dictionary as a positional argument:
52+
53+
.. code-block:: python
54+
55+
aggregate = providers.Aggregate({
56+
SomeClass: providers.Factory(...),
57+
"key.with.periods": providers.Factory(...),
58+
"key-with-dashes": providers.Factory(...),
59+
})
60+
61+
.. seealso::
62+
:ref:`selector-provider` to make injections based on a configuration value, environment variable, or a result of a callable.
63+
64+
``Aggregate`` provider is different from the :ref:`selector-provider`. ``Aggregate`` provider doesn't select which provider
65+
to inject and doesn't have a selector. It is a group of providers and is always injected "as is". The rest of the interface
66+
of both providers is similar.
67+
68+
.. note::
69+
``Aggregate`` provider is a successor of :ref:`factory-aggregate-provider` provider. ``Aggregate`` provider doesn't have
70+
a restriction on the provider type, while ``FactoryAggregate`` aggregates only ``Factory`` providers.
71+
72+
.. disqus::

docs/providers/configuration.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,24 @@ Loading from an environment variable
205205
:lines: 3-
206206
:emphasize-lines: 18-20
207207

208+
You can use ``as_`` argument for the type casting of an environment variable value:
209+
210+
.. code-block:: python
211+
:emphasize-lines: 2,6,10
212+
213+
# API_KEY=secret
214+
container.config.api_key.from_env("API_KEY", as_=str, required=True)
215+
assert container.config.api_key() == "secret"
216+
217+
# SAMPLING_RATIO=0.5
218+
container.config.sampling.from_env("SAMPLING_RATIO", as_=float, required=True)
219+
assert container.config.sampling() == 0.5
220+
221+
# TIMEOUT undefined, default is used
222+
container.config.timeout.from_env("TIMEOUT", as_=int, default=5)
223+
assert container.config.timeout() == 5
224+
225+
208226
Loading a value
209227
---------------
210228

0 commit comments

Comments
 (0)