Skip to content

Commit 721ceea

Browse files
committed
gh-151665: Fix inspect.signature() on type alias and type parameter evaluators
1 parent 88f7941 commit 721ceea

3 files changed

Lines changed: 31 additions & 0 deletions

File tree

Lib/inspect.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,10 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty):
27202720
raise ValueError(msg)
27212721
self._kind = _POSITIONAL_ONLY
27222722
name = 'implicit{}'.format(name[1:])
2723+
elif name == '.format':
2724+
# gh-151665: Hidden parameter of compiler-generated annotation and type
2725+
# alias/typevar evaluators. Show it as "format".
2726+
name = 'format'
27232727

27242728
# It's possible for C functions to have a positional-only parameter
27252729
# where the name is a keyword, so for compatibility we'll allow it.

Lib/test/test_type_params.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import annotationlib
2+
import inspect
23
import textwrap
34
import types
45
import unittest
@@ -1446,6 +1447,30 @@ def f[T: int = int, **P = int, *Ts = int](): pass
14461447
self.assertIs(annotationlib.call_evaluate_function(case, annotationlib.Format.FORWARDREF), int)
14471448
self.assertEqual(annotationlib.call_evaluate_function(case, annotationlib.Format.STRING), 'int')
14481449

1450+
def test_signature(self):
1451+
# gh-151665: the ".format" parameter of compiler-generated evaluators
1452+
# used to break inspect.signature(). It should show up as "format".
1453+
type Alias = int
1454+
def f[T: int = int, **P = int, *Ts = int](): pass
1455+
T, P, Ts = f.__type_params__
1456+
def g[T: (int, str)](): pass
1457+
T3, = g.__type_params__
1458+
cases = [
1459+
Alias.evaluate_value,
1460+
T.evaluate_bound,
1461+
T.evaluate_default,
1462+
P.evaluate_default,
1463+
Ts.evaluate_default,
1464+
T3.evaluate_constraints,
1465+
]
1466+
for case in cases:
1467+
with self.subTest(case=case):
1468+
sig = inspect.signature(case)
1469+
self.assertEqual(str(sig), '(format=1, /)')
1470+
param, = sig.parameters.values()
1471+
self.assertEqual(param.name, 'format')
1472+
self.assertIs(param.kind, inspect.Parameter.POSITIONAL_ONLY)
1473+
14491474
def test_constraints(self):
14501475
def f[T: (int, str)](): pass
14511476
T, = f.__type_params__
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:func:`inspect.signature` now works on the lazy evaluators of type aliases
2+
and type parameters instead of raising :exc:`ValueError`.

0 commit comments

Comments
 (0)