https://github.com/python/cpython/commit/6d6b0c50be370bce5ad65d7a312cd3cedf8139ca
commit: 6d6b0c50be370bce5ad65d7a312cd3cedf8139ca
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-06-21T22:35:40Z
summary:

[3.14] gh-151665: Fix inspect.signature() on type alias and type parameter 
evaluators (GH-151787) (#151880)

[3.15] gh-151665: Fix inspect.signature() on type alias and type parameter 
evaluators (GH-151787)
(cherry picked from commit 453714a2dc0d16e6e6b8cff70801dfc1284bf74d)

Co-authored-by: Timofei <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-06-20-14-47-55.gh-issue-151665.82fmzx.rst
M Lib/inspect.py
M Lib/test/test_type_params.py

diff --git a/Lib/inspect.py b/Lib/inspect.py
index d3e406cae7d228..f3020bbaa0f196 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2712,6 +2712,10 @@ def __init__(self, name, kind, *, default=_empty, 
annotation=_empty):
                 raise ValueError(msg)
             self._kind = _POSITIONAL_ONLY
             name = 'implicit{}'.format(name[1:])
+        elif name == '.format':
+            # gh-151665: Hidden parameter of compiler-generated annotation and 
type
+            # alias/typevar evaluators. Show it as "format".
+            name = 'format'
 
         # It's possible for C functions to have a positional-only parameter
         # where the name is a keyword, so for compatibility we'll allow it.
diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py
index 84c1b954136736..27660379ec43a3 100644
--- a/Lib/test/test_type_params.py
+++ b/Lib/test/test_type_params.py
@@ -1,4 +1,5 @@
 import annotationlib
+import inspect
 import textwrap
 import types
 import unittest
@@ -1446,6 +1447,30 @@ def f[T: int = int, **P = int, *Ts = int](): pass
                 self.assertIs(annotationlib.call_evaluate_function(case, 
annotationlib.Format.FORWARDREF), int)
                 self.assertEqual(annotationlib.call_evaluate_function(case, 
annotationlib.Format.STRING), 'int')
 
+    def test_signature(self):
+        # gh-151665: the ".format" parameter of compiler-generated evaluators
+        # used to break inspect.signature(). It should show up as "format".
+        type Alias = int
+        def f[T: int = int, **P = int, *Ts = int](): pass
+        T, P, Ts = f.__type_params__
+        def g[T: (int, str)](): pass
+        T3, = g.__type_params__
+        cases = [
+            Alias.evaluate_value,
+            T.evaluate_bound,
+            T.evaluate_default,
+            P.evaluate_default,
+            Ts.evaluate_default,
+            T3.evaluate_constraints,
+        ]
+        for case in cases:
+            with self.subTest(case=case):
+                sig = inspect.signature(case)
+                self.assertEqual(str(sig), '(format=1, /)')
+                param, = sig.parameters.values()
+                self.assertEqual(param.name, 'format')
+                self.assertIs(param.kind, inspect.Parameter.POSITIONAL_ONLY)
+
     def test_constraints(self):
         def f[T: (int, str)](): pass
         T, = f.__type_params__
diff --git 
a/Misc/NEWS.d/next/Library/2026-06-20-14-47-55.gh-issue-151665.82fmzx.rst 
b/Misc/NEWS.d/next/Library/2026-06-20-14-47-55.gh-issue-151665.82fmzx.rst
new file mode 100644
index 00000000000000..d08a1220cbe5ef
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-06-20-14-47-55.gh-issue-151665.82fmzx.rst
@@ -0,0 +1,2 @@
+:func:`inspect.signature` now works on the lazy evaluators of type aliases
+and type parameters instead of raising :exc:`ValueError`.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to