diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 881686adc5ed..ba0a3f9dade6 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -920,13 +920,20 @@ def visit_assignment_stmt(self, o: AssignmentStmt) -> None: continue if ( isinstance(lvalue, NameExpr) - and not self.is_private_name(lvalue.name) - # it is never an alias with explicit annotation - and not o.unanalyzed_type and self.is_alias_expression(o.rvalue) + and not self.is_private_name(lvalue.name) ): - self.process_typealias(lvalue, o.rvalue) - continue + is_explicit_type_alias = ( + o.unanalyzed_type and getattr(o.type, "name", None) == "TypeAlias" + ) + if is_explicit_type_alias: + self.process_typealias(lvalue, o.rvalue, is_explicit_type_alias=True) + continue + + if not o.unanalyzed_type: + self.process_typealias(lvalue, o.rvalue) + continue + if isinstance(lvalue, (TupleExpr, ListExpr)): items = lvalue.items if isinstance(o.unanalyzed_type, TupleType): # type: ignore[misc] @@ -1139,9 +1146,15 @@ def is_alias_expression(self, expr: Expression, top_level: bool = True) -> bool: else: return False - def process_typealias(self, lvalue: NameExpr, rvalue: Expression) -> None: + def process_typealias( + self, lvalue: NameExpr, rvalue: Expression, is_explicit_type_alias: bool = False + ) -> None: p = AliasPrinter(self) - self.add(f"{self._indent}{lvalue.name} = {rvalue.accept(p)}\n") + if is_explicit_type_alias: + self.import_tracker.require_name("TypeAlias") + self.add(f"{self._indent}{lvalue.name}: TypeAlias = {rvalue.accept(p)}\n") + else: + self.add(f"{self._indent}{lvalue.name} = {rvalue.accept(p)}\n") self.record_name(lvalue.name) self._vars[-1].append(lvalue.name) diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index bf17c34b99a7..86d33e3af51d 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -1544,6 +1544,19 @@ from typing import TypeVar T = TypeVar('T') alias = Union[T, List[T]] +[case testExplicitTypeAlias] +from typing import TypeAlias + +explicit_alias: TypeAlias = tuple[int, str] +implicit_alias = list[int] + +[out] +from typing import TypeAlias + +explicit_alias: TypeAlias = tuple[int, str] +implicit_alias = list[int] + + [case testEllipsisAliasPreserved] alias = Tuple[int, ...]