summaryrefslogtreecommitdiff
path: root/django/utils/inspect.py
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2025-11-29 18:45:39 -0500
committerJacob Walls <jacobtylerwalls@gmail.com>2025-12-01 20:49:53 -0500
commitec7327453d266d31a00060aeb5b9f19e5adfb0a4 (patch)
tree991b15a8439d4d768ae6256e378b8e2036c2f51e /django/utils/inspect.py
parent2e3953f0a2de7bb702d393279d9dbbe2581a21a5 (diff)
[6.0.x] Fixed #36712 -- Evaluated type annotations lazily in template tag registration.
Ideally, this will be reverted when an upstream solution is available for https://github.com/python/cpython/issues/141560. Thanks Patrick Rauscher for the report and Augusto Pontes for the first iteration and test. Backport of 34186e731ca20a2344b1f88fd543a854d6b13a00 from main.
Diffstat (limited to 'django/utils/inspect.py')
-rw-r--r--django/utils/inspect.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/django/utils/inspect.py b/django/utils/inspect.py
index ac5e82ca14..f0f43ae17e 100644
--- a/django/utils/inspect.py
+++ b/django/utils/inspect.py
@@ -1,11 +1,19 @@
import functools
import inspect
+import threading
+from contextlib import contextmanager
from django.utils.version import PY314
if PY314:
import annotationlib
+ lock = threading.Lock()
+ safe_signature_from_callable = functools.partial(
+ inspect._signature_from_callable,
+ annotation_format=annotationlib.Format.FORWARDREF,
+ )
+
@functools.lru_cache(maxsize=512)
def _get_func_parameters(func, remove_first):
@@ -98,3 +106,27 @@ def is_module_level_function(func):
return False
return True
+
+
+@contextmanager
+def lazy_annotations():
+ """
+ inspect.getfullargspec eagerly evaluates type annotations. To add
+ compatibility with Python 3.14+ deferred evaluation, patch the module-level
+ helper to provide the annotation_format that we are using elsewhere.
+
+ This private helper could be removed when there is an upstream solution for
+ https://github.com/python/cpython/issues/141560.
+
+ This context manager is not reentrant.
+ """
+ if not PY314:
+ yield
+ return
+ with lock:
+ original_helper = inspect._signature_from_callable
+ inspect._signature_from_callable = safe_signature_from_callable
+ try:
+ yield
+ finally:
+ inspect._signature_from_callable = original_helper