gh-144361: Fix NameError when type parameter default refers to a forward name#152208
gh-144361: Fix NameError when type parameter default refers to a forward name#152208tangyuan0821 wants to merge 3 commits into
Conversation
JelleZijlstra
left a comment
There was a problem hiding this comment.
Thanks, please add tests covering the new behavior.
| args = prepare(cls, args) | ||
| try: | ||
| args = prepare(cls, args) | ||
| except NameError: |
There was a problem hiding this comment.
I don't understand this part, why do we have to add default here?
There was a problem hiding this comment.
The C implementation of TypeVar.typing_prepare_subst doesn't catch NameError
when the default is a forward ref — it just raises and returns NULL, so it never
gets a chance to add the default to args. I do both in the except block.
For TypeVarTuple/ParamSpec, their C code delegates to the Python prepare
functions which already handle this themselves, so the outer catch is redundant
for those but harmless.
There was a problem hiding this comment.
hm, is that always the right solution? Should we fix the C code instead?
There was a problem hiding this comment.
I think we should merge this for now. The Python fallback only activates when __default__ raises NameError, so existing behavior stays intact. I'll follow up with a C fix for Objects/typetype.c under the same issue(#144361). Bundling both changes here makes the PR harder to review.
There was a problem hiding this comment.
No, let's fix it in one PR. The change here risks introducing new bugs.
There was a problem hiding this comment.
Fixed in typevar_typing_prepare_subst_impl. Removed the outer try/except.
TypeVarTuple and ParamSpec delegate to Python functions that already catch this. Worth moving to C too?
Instead of catching NameError in Python's _generic_class_getitem, fix the C implementation of TypeVar.__typing_prepare_subst__ to fall back to FORWARDREF format when typevar_default() raises NameError. Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Fix #144361: PEP 696 + PEP 749 — delayed evaluation of type parameter defaults.
Three call sites in Lib/typing.py eagerly evaluate default (Format.VALUE),
which fails when the default references a name defined later in the module.
Catch NameError and fall back to annotationlib.call_evaluate_function
with Format.FORWARDREF.