@@ -181,10 +181,12 @@ def ast3_parse(
181
181
if sys .version_info >= (3 , 12 ):
182
182
ast_TypeAlias = ast3 .TypeAlias
183
183
ast_ParamSpec = ast3 .ParamSpec
184
+ ast_TypeVar = ast3 .TypeVar
184
185
ast_TypeVarTuple = ast3 .TypeVarTuple
185
186
else :
186
187
ast_TypeAlias = Any
187
188
ast_ParamSpec = Any
189
+ ast_TypeVar = Any
188
190
ast_TypeVarTuple = Any
189
191
190
192
N = TypeVar ("N" , bound = Node )
@@ -345,6 +347,15 @@ def is_no_type_check_decorator(expr: ast3.expr) -> bool:
345
347
return False
346
348
347
349
350
+ def find_disallowed_expression_in_annotation_scope (expr : ast3 .expr | None ) -> ast3 .expr | None :
351
+ if expr is None :
352
+ return None
353
+ for node in ast3 .walk (expr ):
354
+ if isinstance (node , (ast3 .Yield , ast3 .YieldFrom , ast3 .NamedExpr , ast3 .Await )):
355
+ return node
356
+ return None
357
+
358
+
348
359
class ASTConverter :
349
360
def __init__ (
350
361
self ,
@@ -1180,6 +1191,29 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef:
1180
1191
self .class_and_function_stack .pop ()
1181
1192
return cdef
1182
1193
1194
+ def validate_type_param (self , type_param : ast_TypeVar ) -> None :
1195
+ incorrect_expr = find_disallowed_expression_in_annotation_scope (type_param .bound )
1196
+ if incorrect_expr is None :
1197
+ return
1198
+ if isinstance (incorrect_expr , (ast3 .Yield , ast3 .YieldFrom )):
1199
+ self .fail (
1200
+ message_registry .TYPE_VAR_YIELD_EXPRESSION_IN_BOUND ,
1201
+ type_param .lineno ,
1202
+ type_param .col_offset ,
1203
+ )
1204
+ if isinstance (incorrect_expr , ast3 .NamedExpr ):
1205
+ self .fail (
1206
+ message_registry .TYPE_VAR_NAMED_EXPRESSION_IN_BOUND ,
1207
+ type_param .lineno ,
1208
+ type_param .col_offset ,
1209
+ )
1210
+ if isinstance (incorrect_expr , ast3 .Await ):
1211
+ self .fail (
1212
+ message_registry .TYPE_VAR_AWAIT_EXPRESSION_IN_BOUND ,
1213
+ type_param .lineno ,
1214
+ type_param .col_offset ,
1215
+ )
1216
+
1183
1217
def translate_type_params (self , type_params : list [Any ]) -> list [TypeParam ]:
1184
1218
explicit_type_params = []
1185
1219
for p in type_params :
@@ -1202,6 +1236,7 @@ def translate_type_params(self, type_params: list[Any]) -> list[TypeParam]:
1202
1236
conv = TypeConverter (self .errors , line = p .lineno )
1203
1237
values = [conv .visit (t ) for t in p .bound .elts ]
1204
1238
elif p .bound is not None :
1239
+ self .validate_type_param (p )
1205
1240
bound = TypeConverter (self .errors , line = p .lineno ).visit (p .bound )
1206
1241
explicit_type_params .append (TypeParam (p .name , TYPE_VAR_KIND , bound , values ))
1207
1242
return explicit_type_params
@@ -1791,11 +1826,23 @@ def visit_MatchOr(self, n: MatchOr) -> OrPattern:
1791
1826
node = OrPattern ([self .visit (pattern ) for pattern in n .patterns ])
1792
1827
return self .set_line (node , n )
1793
1828
1829
+ def validate_type_alias (self , n : ast_TypeAlias ) -> None :
1830
+ incorrect_expr = find_disallowed_expression_in_annotation_scope (n .value )
1831
+ if incorrect_expr is None :
1832
+ return
1833
+ if isinstance (incorrect_expr , (ast3 .Yield , ast3 .YieldFrom )):
1834
+ self .fail (message_registry .TYPE_ALIAS_WITH_YIELD_EXPRESSION , n .lineno , n .col_offset )
1835
+ if isinstance (incorrect_expr , ast3 .NamedExpr ):
1836
+ self .fail (message_registry .TYPE_ALIAS_WITH_NAMED_EXPRESSION , n .lineno , n .col_offset )
1837
+ if isinstance (incorrect_expr , ast3 .Await ):
1838
+ self .fail (message_registry .TYPE_ALIAS_WITH_AWAIT_EXPRESSION , n .lineno , n .col_offset )
1839
+
1794
1840
# TypeAlias(identifier name, type_param* type_params, expr value)
1795
1841
def visit_TypeAlias (self , n : ast_TypeAlias ) -> TypeAliasStmt | AssignmentStmt :
1796
1842
node : TypeAliasStmt | AssignmentStmt
1797
1843
if NEW_GENERIC_SYNTAX in self .options .enable_incomplete_feature :
1798
1844
type_params = self .translate_type_params (n .type_params )
1845
+ self .validate_type_alias (n )
1799
1846
value = self .visit (n .value )
1800
1847
# Since the value is evaluated lazily, wrap the value inside a lambda.
1801
1848
# This helps mypyc.
0 commit comments