|
6 | 6 | from functools import wraps |
7 | 7 | from importlib import import_module, invalidate_caches as invalidate_import_caches |
8 | 8 | from inspect import ( |
9 | | - CO_ASYNC_GENERATOR, |
10 | | - CO_COROUTINE, |
11 | 9 | Parameter, |
12 | 10 | getmembers, |
13 | 11 | isasyncgenfunction, |
@@ -131,76 +129,15 @@ def is_werkzeug_local_proxy(obj: Any) -> bool: |
131 | 129 |
|
132 | 130 |
|
133 | 131 | def _is_cyfunction(obj: Any) -> bool: |
134 | | - """Return True for Cython-compiled functions/methods. |
135 | | -
|
136 | | - Cython-compiled callables (built with ``binding=True`` and |
137 | | - ``embedsignature=True``) are not recognised by :func:`inspect.isfunction` |
138 | | - because they are instances of ``cython_function_or_method`` rather than |
139 | | - ``types.FunctionType``. They are nevertheless safe targets for wiring: |
140 | | - dep-injector only *reads* ``inspect.signature`` (which works on |
141 | | - cyfunctions with ``embedsignature=True``) and wraps the original via |
142 | | - ``functools.wraps``; no writes are performed on ``__code__``, |
143 | | - ``__defaults__`` or ``__globals__``. |
144 | | -
|
145 | | - Recognises ``cython_function_or_method`` only. Fused-function templates |
146 | | - (``fused_cython_function``) dispatch per call and are intentionally |
147 | | - excluded — wrapping the template would inject before type dispatch, |
148 | | - which has not been validated. Fused support is potential follow-up |
149 | | - work. |
150 | | -
|
151 | | - Cython >= 3.1.0 is the tested floor. Earlier versions may work but |
152 | | - the ``co_flags`` fallbacks in :func:`_iscoroutinefunction_compat` and |
153 | | - :func:`_isasyncgenfunction_compat` exist specifically because |
154 | | - Cython < 3.0 did not surface coroutine / async-generator status via |
155 | | - :mod:`inspect`. |
156 | | - """ |
| 132 | + """Return True for Cython-compiled functions/methods (non-fused).""" |
157 | 133 | return type(obj).__name__ == "cython_function_or_method" |
158 | 134 |
|
159 | 135 |
|
160 | 136 | def _is_function_like(obj: Any) -> bool: |
161 | | - """Return True for pure-Python functions and Cython-compiled functions. |
162 | | -
|
163 | | - Wiring's discovery pass must accept both so that codebases compiled to |
164 | | - ``.so`` extensions (e.g. for source-protected container images) can be |
165 | | - wired transparently. |
166 | | - """ |
| 137 | + """Return True for pure-Python functions and Cython-compiled functions.""" |
167 | 138 | return isfunction(obj) or _is_cyfunction(obj) |
168 | 139 |
|
169 | 140 |
|
170 | | -def _iscoroutinefunction_compat(fn: Any) -> bool: |
171 | | - """Coroutine-function check that also handles Cython-compiled ``async def``. |
172 | | -
|
173 | | - Cython 3.x exposes coroutine cyfunctions correctly via |
174 | | - :func:`inspect.iscoroutinefunction`. Cython < 3.0 did not — for those |
175 | | - versions the underlying ``__code__.co_flags`` still carries the |
176 | | - ``CO_COROUTINE`` bit, so fall back to that. |
177 | | - """ |
178 | | - if iscoroutinefunction(fn): |
179 | | - return True |
180 | | - code = getattr(fn, "__code__", None) |
181 | | - if code is None: |
182 | | - return False |
183 | | - return bool(getattr(code, "co_flags", 0) & CO_COROUTINE) |
184 | | - |
185 | | - |
186 | | -def _isasyncgenfunction_compat(fn: Any) -> bool: |
187 | | - """Async-generator check that also handles Cython-compiled ``async def`` w/ yield. |
188 | | -
|
189 | | - Symmetric to :func:`_iscoroutinefunction_compat`: Cython < 3.0 |
190 | | - async-generator cyfunctions are not recognised by |
191 | | - :func:`inspect.isasyncgenfunction`, but the ``CO_ASYNC_GENERATOR`` bit |
192 | | - is still present in ``__code__.co_flags``. Without this helper, async- |
193 | | - gen cyfunctions would fall through to ``_get_sync_patched`` and break |
194 | | - at first ``await`` / ``async for``. |
195 | | - """ |
196 | | - if isasyncgenfunction(fn): |
197 | | - return True |
198 | | - code = getattr(fn, "__code__", None) |
199 | | - if code is None: |
200 | | - return False |
201 | | - return bool(getattr(code, "co_flags", 0) & CO_ASYNC_GENERATOR) |
202 | | - |
203 | | - |
204 | 141 | from . import providers # noqa: E402 |
205 | 142 |
|
206 | 143 | __all__ = ( |
@@ -895,9 +832,9 @@ def _get_patched( |
895 | 832 | reference_closing=reference_closing, |
896 | 833 | ) |
897 | 834 |
|
898 | | - if _iscoroutinefunction_compat(fn): |
| 835 | + if iscoroutinefunction(fn): |
899 | 836 | patched = _get_async_patched(fn, patched_object) |
900 | | - elif _isasyncgenfunction_compat(fn): |
| 837 | + elif isasyncgenfunction(fn): |
901 | 838 | patched = _get_async_gen_patched(fn, patched_object) |
902 | 839 | else: |
903 | 840 | patched = _get_sync_patched(fn, patched_object) |
|
0 commit comments