File tree 2 files changed +50
-3
lines changed
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:
1824
1824
defn , bases , context = defn
1825
1825
)
1826
1826
1827
+ self .check_type_alias_bases (bases )
1828
+
1827
1829
for tvd in tvar_defs :
1828
1830
if isinstance (tvd , TypeVarType ) and any (
1829
1831
has_placeholder (t ) for t in [tvd .upper_bound ] + tvd .values
@@ -1895,6 +1897,19 @@ def analyze_class(self, defn: ClassDef) -> None:
1895
1897
1896
1898
self .analyze_class_body_common (defn )
1897
1899
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
+
1898
1913
def setup_type_vars (self , defn : ClassDef , tvar_defs : list [TypeVarLikeType ]) -> None :
1899
1914
defn .type_vars = tvar_defs
1900
1915
defn .info .type_vars = []
Original file line number Diff line number Diff line change @@ -591,6 +591,40 @@ a4: A4
591
591
reveal_type(a4) # N: Revealed type is "Union[builtins.int, builtins.str]"
592
592
[builtins fixtures/type.pyi]
593
593
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
+
594
628
[case testPEP695TypeAliasWithUnusedTypeParams]
595
629
# flags: --enable-incomplete-feature=NewGenericSyntax
596
630
type A[T] = int
@@ -637,9 +671,7 @@ class D: pass
637
671
638
672
type A = C
639
673
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
643
675
pass
644
676
645
677
class C: pass
You can’t perform that action at this time.
0 commit comments