File tree Expand file tree Collapse file tree 2 files changed +50
-3
lines changed Expand file tree Collapse file tree 2 files changed +50
-3
lines changed Original file line number Diff line number Diff line change @@ -1824,6 +1824,8 @@ def analyze_class(self, defn: ClassDef) -> None:
18241824 defn , bases , context = defn
18251825 )
18261826
1827+ self .check_type_alias_bases (bases )
1828+
18271829 for tvd in tvar_defs :
18281830 if isinstance (tvd , TypeVarType ) and any (
18291831 has_placeholder (t ) for t in [tvd .upper_bound ] + tvd .values
@@ -1895,6 +1897,19 @@ def analyze_class(self, defn: ClassDef) -> None:
18951897
18961898 self .analyze_class_body_common (defn )
18971899
1900+ def check_type_alias_bases (self , bases : list [Expression ]) -> None :
1901+ for base in bases :
1902+ if isinstance (base , IndexExpr ):
1903+ base = base .base
1904+ if (
1905+ isinstance (base , RefExpr )
1906+ and isinstance (base .node , TypeAlias )
1907+ and base .node .python_3_12_type_alias
1908+ ):
1909+ self .fail (
1910+ 'Type alias defined using "type" statement not valid as base class' , base
1911+ )
1912+
18981913 def setup_type_vars (self , defn : ClassDef , tvar_defs : list [TypeVarLikeType ]) -> None :
18991914 defn .type_vars = tvar_defs
19001915 defn .info .type_vars = []
Original file line number Diff line number Diff line change @@ -591,6 +591,40 @@ a4: A4
591591reveal_type(a4) # N: Revealed type is "Union[builtins.int, builtins.str]"
592592[builtins fixtures/type.pyi]
593593
594+ [case testPEP695TypeAliasNotValidAsBaseClass]
595+ # flags: --enable-incomplete-feature=NewGenericSyntax
596+ from typing import TypeAlias
597+
598+ import m
599+
600+ type A1 = int
601+ class Bad1(A1): # E: Type alias defined using "type" statement not valid as base class
602+ pass
603+
604+ type A2[T] = list[T]
605+ class Bad2(A2[int]): # E: Type alias defined using "type" statement not valid as base class
606+ pass
607+
608+ class Bad3(m.A1): # E: Type alias defined using "type" statement not valid as base class
609+ pass
610+
611+ class Bad4(m.A2[int]): # E: Type alias defined using "type" statement not valid as base class
612+ pass
613+
614+ B1 = int
615+ B2 = list
616+ B3: TypeAlias = int
617+ class Good1(B1): pass
618+ class Good2(B2[int]): pass
619+ class Good3(list[A1]): pass
620+ class Good4(list[A2[int]]): pass
621+ class Good5(B3): pass
622+
623+ [file m.py]
624+ type A1 = str
625+ type A2[T] = list[T]
626+ [typing fixtures/typing-medium.pyi]
627+
594628[case testPEP695TypeAliasWithUnusedTypeParams]
595629# flags: --enable-incomplete-feature=NewGenericSyntax
596630type A[T] = int
@@ -637,9 +671,7 @@ class D: pass
637671
638672type A = C
639673
640- # Note that this doesn't actually work at runtime, but we currently don't
641- # keep track whether a type alias is valid in various runtime type contexts.
642- class D(A):
674+ class D(A): # E: Type alias defined using "type" statement not valid as base class
643675 pass
644676
645677class C: pass
You can’t perform that action at this time.
0 commit comments