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
13 changes: 12 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3493,13 +3493,24 @@ def is_type_ref(self, rv: Expression, bare: bool = False) -> bool:
else:
valid_refs = type_constructors

if isinstance(rv.node, TypeAlias) or rv.fullname in valid_refs:
if isinstance(rv.node, TypeAlias):
# Fix for #20308: Reassignment of a generic TypeAliasType (PEP 695)
# should be evaluated as a variable assignment, not a type expression.
# This allows usage like `B = A` where `type A[T] = ...` without
# triggering "Missing type parameters" error.
if bare and rv.node.python_3_12_type_alias and rv.node.alias_tvars:
return False
return True

if rv.fullname in valid_refs:
return True

if isinstance(rv.node, TypeInfo):
if bare:
return True
# Assignment color = Color['RED'] defines a variable, not an alias.
return not rv.node.is_enum

if isinstance(rv.node, Var):
return rv.node.fullname in NEVER_NAMES

Expand Down
11 changes: 11 additions & 0 deletions test-data/unit/check-python312.test
Original file line number Diff line number Diff line change
Expand Up @@ -2237,3 +2237,14 @@ class D[*Ts](Generic[Unpack[Us]]): # E: Generic[...] base class is redundant \
# E: Can only use one type var tuple in a class def
pass
[builtins fixtures/tuple.pyi]

[case testPep695GenericTypeAliasReassignment]
from typing import reveal_type

type A[T] = T | str
B = A
reveal_type(B)
[out]
main:5: note: Revealed type is "typing.TypeAliasType"
[builtins fixtures/tuple.pyi]
[typing fixtures/typing-full.pyi]