Skip to content

Commit cfed30c

Browse files
committed
Hotfix issue #574, bump version to 4.39.1
1 parent 13cae77 commit cfed30c

File tree

10 files changed

+13543
-4540
lines changed

10 files changed

+13543
-4540
lines changed

docs/main/changelog.rst

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ that were made in every particular version.
77
From version 0.7.6 *Dependency Injector* framework strictly
88
follows `Semantic versioning`_
99

10+
4.39.1
11+
------
12+
- Fix bug `#574 <https://github.com/ets-labs/python-dependency-injector/issues/574>`_:
13+
"``@inject`` breaks ``inspect.iscoroutinefunction``". Thanks to
14+
`@burritoatspoton (Rafał Burczyński) <https://github.com/burritoatspoton>`_ for reporting the issue.
15+
1016
4.39.0
1117
------
1218
- Optimize injections and wiring from x1.5 to x7 times depending on the use case.

src/dependency_injector/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Top-level package."""
22

3-
__version__ = "4.39.0"
3+
__version__ = "4.39.1"
44
"""Version number.
55
66
:type: str

src/dependency_injector/_cwiring.c

+11,759-3,049
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dependency_injector/_cwiring.pyx

+48-48
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,27 @@ import types
99
from . import providers
1010
from .wiring import _Marker
1111

12+
from .providers cimport Provider
13+
1214

1315
def _get_sync_patched(fn):
1416
@functools.wraps(fn)
1517
def _patched(*args, **kwargs):
1618
cdef object result
1719
cdef dict to_inject
20+
cdef object arg_key
21+
cdef Provider provider
1822

1923
to_inject = kwargs.copy()
20-
for injection, provider in _patched.__injections__.items():
21-
if injection not in kwargs or isinstance(kwargs[injection], _Marker):
22-
to_inject[injection] = provider()
24+
for arg_key, provider in _patched.__injections__.items():
25+
if arg_key not in kwargs or isinstance(kwargs[arg_key], _Marker):
26+
to_inject[arg_key] = provider()
2327

2428
result = fn(*args, **to_inject)
2529

2630
if _patched.__closing__:
27-
for injection, provider in _patched.__closing__.items():
28-
if injection in kwargs and not isinstance(kwargs[injection], _Marker):
31+
for arg_key, provider in _patched.__closing__.items():
32+
if arg_key in kwargs and not isinstance(kwargs[arg_key], _Marker):
2933
continue
3034
if not isinstance(provider, providers.Resource):
3135
continue
@@ -35,49 +39,45 @@ def _get_sync_patched(fn):
3539
return _patched
3640

3741

38-
def _get_async_patched(fn):
39-
@functools.wraps(fn)
40-
async def _patched(*args, **kwargs):
41-
cdef object result
42-
cdef dict to_inject
43-
cdef list to_inject_await = []
44-
cdef list to_close_await = []
45-
46-
to_inject = kwargs.copy()
47-
for injection, provider in _patched.__injections__.items():
48-
if injection not in kwargs or isinstance(kwargs[injection], _Marker):
49-
provide = provider()
50-
if _isawaitable(provide):
51-
to_inject_await.append((injection, provide))
52-
else:
53-
to_inject[injection] = provide
54-
55-
if to_inject_await:
56-
async_to_inject = await asyncio.gather(*(provide for _, provide in to_inject_await))
57-
for provide, (injection, _) in zip(async_to_inject, to_inject_await):
58-
to_inject[injection] = provide
59-
60-
result = await fn(*args, **to_inject)
61-
62-
if _patched.__closing__:
63-
for injection, provider in _patched.__closing__.items():
64-
if injection in kwargs \
65-
and isinstance(kwargs[injection], _Marker):
66-
continue
67-
if not isinstance(provider, providers.Resource):
68-
continue
69-
shutdown = provider.shutdown()
70-
if _isawaitable(shutdown):
71-
to_close_await.append(shutdown)
72-
73-
await asyncio.gather(*to_close_await)
74-
75-
return result
76-
77-
# Hotfix for iscoroutinefunction() for Cython < 3.0.0; can be removed after migration to Cython 3.0.0+
78-
_patched._is_coroutine = asyncio.coroutines._is_coroutine
79-
80-
return _patched
42+
async def _async_inject(object fn, tuple args, dict kwargs, dict injections, dict closings):
43+
cdef object result
44+
cdef dict to_inject
45+
cdef list to_inject_await = []
46+
cdef list to_close_await = []
47+
cdef object arg_key
48+
cdef Provider provider
49+
50+
to_inject = kwargs.copy()
51+
for arg_key, provider in injections.items():
52+
if arg_key not in kwargs or isinstance(kwargs[arg_key], _Marker):
53+
provide = provider()
54+
if provider.is_async_mode_enabled():
55+
to_inject_await.append((arg_key, provide))
56+
elif _isawaitable(provide):
57+
to_inject_await.append((arg_key, provide))
58+
else:
59+
to_inject[arg_key] = provide
60+
61+
if to_inject_await:
62+
async_to_inject = await asyncio.gather(*(provide for _, provide in to_inject_await))
63+
for provide, (injection, _) in zip(async_to_inject, to_inject_await):
64+
to_inject[injection] = provide
65+
66+
result = await fn(*args, **to_inject)
67+
68+
if closings:
69+
for arg_key, provider in closings.items():
70+
if arg_key in kwargs and isinstance(kwargs[arg_key], _Marker):
71+
continue
72+
if not isinstance(provider, providers.Resource):
73+
continue
74+
shutdown = provider.shutdown()
75+
if _isawaitable(shutdown):
76+
to_close_await.append(shutdown)
77+
78+
await asyncio.gather(*to_close_await)
79+
80+
return result
8181

8282

8383
cdef bint _isawaitable(object instance):

0 commit comments

Comments
 (0)