Skip to content

Commit af742b9

Browse files
committed
Merge branch 'release/4.3.8' into master
2 parents 26a89d6 + cdce524 commit af742b9

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

docs/main/changelog.rst

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

10+
4.3.8
11+
-----
12+
- Add a hotfix to support wiring for ``FastAPI`` endpoints.
13+
1014
4.3.7
1115
-----
1216
- Fix race in ``ThreadSafeSingleton``. Many thanks to

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.3.7'
3+
__version__ = '4.3.8'
44
"""Version number.
55
66
:type: str

src/dependency_injector/wiring.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,15 @@ def _get_patched(fn, injections, closing):
316316
def _patched(*args, **kwargs):
317317
to_inject = kwargs.copy()
318318
for injection, provider in injections.items():
319-
if injection not in kwargs:
319+
if injection not in kwargs \
320+
or _is_fastapi_default_arg_injection(injection, kwargs):
320321
to_inject[injection] = provider()
321322

322323
result = fn(*args, **to_inject)
323324

324325
for injection, provider in closing.items():
325-
if injection in kwargs:
326+
if injection in kwargs \
327+
and not _is_fastapi_default_arg_injection(injection, kwargs):
326328
continue
327329
if not isinstance(provider, providers.Resource):
328330
continue
@@ -337,13 +339,15 @@ def _get_async_patched(fn, injections, closing):
337339
async def _patched(*args, **kwargs):
338340
to_inject = kwargs.copy()
339341
for injection, provider in injections.items():
340-
if injection not in kwargs:
342+
if injection not in kwargs \
343+
or _is_fastapi_default_arg_injection(injection, kwargs):
341344
to_inject[injection] = provider()
342345

343346
result = await fn(*args, **to_inject)
344347

345348
for injection, provider in closing.items():
346-
if injection in kwargs:
349+
if injection in kwargs \
350+
and not _is_fastapi_default_arg_injection(injection, kwargs):
347351
continue
348352
if not isinstance(provider, providers.Resource):
349353
continue
@@ -353,6 +357,11 @@ async def _patched(*args, **kwargs):
353357
return _patched
354358

355359

360+
def _is_fastapi_default_arg_injection(injection, kwargs):
361+
"""Check if injection is FastAPI injection of the default argument."""
362+
return injection in kwargs and isinstance(kwargs[injection], _Marker)
363+
364+
356365
def _is_patched(fn):
357366
return getattr(fn, '__wired__', False) is True
358367

tests/unit/wiring/test_wiring_py36.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from decimal import Decimal
22
import unittest
33

4-
from dependency_injector.wiring import wire, Provide
4+
from dependency_injector.wiring import wire, Provide, Closing
55

66
# Runtime import to avoid syntax errors in samples on Python < 3.5
77
import os
@@ -225,3 +225,41 @@ def test_closing_resource_context(self):
225225
self.assertIs(result_2, service)
226226
self.assertEqual(result_2.init_counter, 0)
227227
self.assertEqual(result_2.shutdown_counter, 0)
228+
229+
230+
class WiringAndFastAPITest(unittest.TestCase):
231+
232+
container: Container
233+
234+
def test_bypass_marker_injection(self):
235+
container = Container()
236+
container.wire(modules=[module])
237+
self.addCleanup(container.unwire)
238+
239+
service = module.test_function(service=Provide[Container.service])
240+
self.assertIsInstance(service, Service)
241+
242+
def test_closing_resource_bypass_marker_injection(self):
243+
from wiringsamples import resourceclosing
244+
245+
resourceclosing.Service.reset_counter()
246+
247+
container = resourceclosing.Container()
248+
container.wire(modules=[resourceclosing])
249+
self.addCleanup(container.unwire)
250+
251+
result_1 = resourceclosing.test_function(
252+
service=Closing[Provide[resourceclosing.Container.service]],
253+
)
254+
self.assertIsInstance(result_1, resourceclosing.Service)
255+
self.assertEqual(result_1.init_counter, 1)
256+
self.assertEqual(result_1.shutdown_counter, 1)
257+
258+
result_2 = resourceclosing.test_function(
259+
service=Closing[Provide[resourceclosing.Container.service]],
260+
)
261+
self.assertIsInstance(result_2, resourceclosing.Service)
262+
self.assertEqual(result_2.init_counter, 2)
263+
self.assertEqual(result_2.shutdown_counter, 2)
264+
265+
self.assertIsNot(result_1, result_2)

0 commit comments

Comments
 (0)