diff --git a/Lib/inspect.py b/Lib/inspect.py index dc5a6e3be883bb0..0dbd596db160236 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2720,6 +2720,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 84c1b9541367363..27660379ec43a37 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 000000000000000..d08a1220cbe5efc --- /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`.