1717 ARG_POS ,
1818 ARG_STAR ,
1919 ARG_STAR2 ,
20+ PARAM_SPEC_KIND ,
21+ TYPE_VAR_KIND ,
22+ TYPE_VAR_TUPLE_KIND ,
2023 ArgKind ,
2124 Argument ,
2225 AssertStmt ,
7982 TempNode ,
8083 TryStmt ,
8184 TupleExpr ,
85+ TypeAliasStmt ,
86+ TypeParam ,
8287 UnaryExpr ,
8388 Var ,
8489 WhileStmt ,
8792 YieldFromExpr ,
8893 check_arg_names ,
8994)
90- from mypy .options import Options
95+ from mypy .options import NEW_GENERIC_SYNTAX , Options
9196from mypy .patterns import (
9297 AsPattern ,
9398 ClassPattern ,
@@ -144,11 +149,6 @@ def ast3_parse(
144149NamedExpr = ast3 .NamedExpr
145150Constant = ast3 .Constant
146151
147- if sys .version_info >= (3 , 12 ):
148- ast_TypeAlias = ast3 .TypeAlias
149- else :
150- ast_TypeAlias = Any
151-
152152if sys .version_info >= (3 , 10 ):
153153 Match = ast3 .Match
154154 MatchValue = ast3 .MatchValue
@@ -171,11 +171,21 @@ def ast3_parse(
171171 MatchAs = Any
172172 MatchOr = Any
173173 AstNode = Union [ast3 .expr , ast3 .stmt , ast3 .ExceptHandler ]
174+
174175if sys .version_info >= (3 , 11 ):
175176 TryStar = ast3 .TryStar
176177else :
177178 TryStar = Any
178179
180+ if sys .version_info >= (3 , 12 ):
181+ ast_TypeAlias = ast3 .TypeAlias
182+ ast_ParamSpec = ast3 .ParamSpec
183+ ast_TypeVarTuple = ast3 .TypeVarTuple
184+ else :
185+ ast_TypeAlias = Any
186+ ast_ParamSpec = Any
187+ ast_TypeVarTuple = Any
188+
179189N = TypeVar ("N" , bound = Node )
180190
181191# There is no way to create reasonable fallbacks at this stage,
@@ -884,6 +894,8 @@ def do_func_def(
884894
885895 arg_kinds = [arg .kind for arg in args ]
886896 arg_names = [None if arg .pos_only else arg .variable .name for arg in args ]
897+ # Type parameters, if using new syntax for generics (PEP 695)
898+ explicit_type_params : list [TypeParam ] | None = None
887899
888900 arg_types : list [Type | None ] = []
889901 if no_type_check :
@@ -937,12 +949,17 @@ def do_func_def(
937949 return_type = AnyType (TypeOfAny .from_error )
938950 else :
939951 if sys .version_info >= (3 , 12 ) and n .type_params :
940- self .fail (
941- ErrorMessage ("PEP 695 generics are not yet supported" , code = codes .VALID_TYPE ),
942- n .type_params [0 ].lineno ,
943- n .type_params [0 ].col_offset ,
944- blocker = False ,
945- )
952+ if NEW_GENERIC_SYNTAX in self .options .enable_incomplete_feature :
953+ explicit_type_params = self .translate_type_params (n .type_params )
954+ else :
955+ self .fail (
956+ ErrorMessage (
957+ "PEP 695 generics are not yet supported" , code = codes .VALID_TYPE
958+ ),
959+ n .type_params [0 ].lineno ,
960+ n .type_params [0 ].col_offset ,
961+ blocker = False ,
962+ )
946963
947964 arg_types = [a .type_annotation for a in args ]
948965 return_type = TypeConverter (
@@ -986,7 +1003,7 @@ def do_func_def(
9861003 self .class_and_function_stack .pop ()
9871004 self .class_and_function_stack .append ("F" )
9881005 body = self .as_required_block (n .body , can_strip = True , is_coroutine = is_coroutine )
989- func_def = FuncDef (n .name , args , body , func_type )
1006+ func_def = FuncDef (n .name , args , body , func_type , explicit_type_params )
9901007 if isinstance (func_def .type , CallableType ):
9911008 # semanal.py does some in-place modifications we want to avoid
9921009 func_def .unanalyzed_type = func_def .type .copy_modified ()
@@ -1120,13 +1137,19 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef:
11201137 self .class_and_function_stack .append ("C" )
11211138 keywords = [(kw .arg , self .visit (kw .value )) for kw in n .keywords if kw .arg ]
11221139
1140+ # Type parameters, if using new syntax for generics (PEP 695)
1141+ explicit_type_params : list [TypeParam ] | None = None
1142+
11231143 if sys .version_info >= (3 , 12 ) and n .type_params :
1124- self .fail (
1125- ErrorMessage ("PEP 695 generics are not yet supported" , code = codes .VALID_TYPE ),
1126- n .type_params [0 ].lineno ,
1127- n .type_params [0 ].col_offset ,
1128- blocker = False ,
1129- )
1144+ if NEW_GENERIC_SYNTAX in self .options .enable_incomplete_feature :
1145+ explicit_type_params = self .translate_type_params (n .type_params )
1146+ else :
1147+ self .fail (
1148+ ErrorMessage ("PEP 695 generics are not yet supported" , code = codes .VALID_TYPE ),
1149+ n .type_params [0 ].lineno ,
1150+ n .type_params [0 ].col_offset ,
1151+ blocker = False ,
1152+ )
11301153
11311154 cdef = ClassDef (
11321155 n .name ,
@@ -1135,6 +1158,7 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef:
11351158 self .translate_expr_list (n .bases ),
11361159 metaclass = dict (keywords ).get ("metaclass" ),
11371160 keywords = keywords ,
1161+ type_args = explicit_type_params ,
11381162 )
11391163 cdef .decorators = self .translate_expr_list (n .decorator_list )
11401164 # Set lines to match the old mypy 0.700 lines, in order to keep
@@ -1150,6 +1174,24 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef:
11501174 self .class_and_function_stack .pop ()
11511175 return cdef
11521176
1177+ def translate_type_params (self , type_params : list [Any ]) -> list [TypeParam ]:
1178+ explicit_type_params = []
1179+ for p in type_params :
1180+ bound = None
1181+ values : list [Type ] = []
1182+ if isinstance (p , ast_ParamSpec ): # type: ignore[misc]
1183+ explicit_type_params .append (TypeParam (p .name , PARAM_SPEC_KIND , None , []))
1184+ elif isinstance (p , ast_TypeVarTuple ): # type: ignore[misc]
1185+ explicit_type_params .append (TypeParam (p .name , TYPE_VAR_TUPLE_KIND , None , []))
1186+ else :
1187+ if isinstance (p .bound , ast3 .Tuple ):
1188+ conv = TypeConverter (self .errors , line = p .lineno )
1189+ values = [conv .visit (t ) for t in p .bound .elts ]
1190+ elif p .bound is not None :
1191+ bound = TypeConverter (self .errors , line = p .lineno ).visit (p .bound )
1192+ explicit_type_params .append (TypeParam (p .name , TYPE_VAR_KIND , bound , values ))
1193+ return explicit_type_params
1194+
11531195 # Return(expr? value)
11541196 def visit_Return (self , n : ast3 .Return ) -> ReturnStmt :
11551197 node = ReturnStmt (self .visit (n .value ))
@@ -1735,15 +1777,23 @@ def visit_MatchOr(self, n: MatchOr) -> OrPattern:
17351777 node = OrPattern ([self .visit (pattern ) for pattern in n .patterns ])
17361778 return self .set_line (node , n )
17371779
1738- def visit_TypeAlias (self , n : ast_TypeAlias ) -> AssignmentStmt :
1739- self .fail (
1740- ErrorMessage ("PEP 695 type aliases are not yet supported" , code = codes .VALID_TYPE ),
1741- n .lineno ,
1742- n .col_offset ,
1743- blocker = False ,
1744- )
1745- node = AssignmentStmt ([NameExpr (n .name .id )], self .visit (n .value ))
1746- return self .set_line (node , n )
1780+ # TypeAlias(identifier name, type_param* type_params, expr value)
1781+ def visit_TypeAlias (self , n : ast_TypeAlias ) -> TypeAliasStmt | AssignmentStmt :
1782+ node : TypeAliasStmt | AssignmentStmt
1783+ if NEW_GENERIC_SYNTAX in self .options .enable_incomplete_feature :
1784+ type_params = self .translate_type_params (n .type_params )
1785+ value = self .visit (n .value )
1786+ node = TypeAliasStmt (self .visit_Name (n .name ), type_params , value )
1787+ return self .set_line (node , n )
1788+ else :
1789+ self .fail (
1790+ ErrorMessage ("PEP 695 type aliases are not yet supported" , code = codes .VALID_TYPE ),
1791+ n .lineno ,
1792+ n .col_offset ,
1793+ blocker = False ,
1794+ )
1795+ node = AssignmentStmt ([NameExpr (n .name .id )], self .visit (n .value ))
1796+ return self .set_line (node , n )
17471797
17481798
17491799class TypeConverter :
0 commit comments