Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 25 additions & 0 deletions Lib/test/test_type_params.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import annotationlib
import inspect
import textwrap
import types
import unittest
Expand Down Expand Up @@ -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__
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:func:`inspect.signature` now works on the lazy evaluators of type aliases
and type parameters instead of raising :exc:`ValueError`.
Loading