@@ -128,18 +128,29 @@ impl SemanticSyntaxChecker {
128
128
// test_ok valid_annotation_function
129
129
// def f() -> (y := 3): ...
130
130
// def g(arg: (x := 1)): ...
131
+ // def outer():
132
+ // def i(x: (yield 1)): ...
133
+ // def k() -> (yield 1): ...
134
+ // def m(x: (yield from 1)): ...
135
+ // def o() -> (yield from 1): ...
136
+
137
+ // test_err invalid_annotation_function_py314
138
+ // # parse_options: {"target-version": "3.14"}
139
+ // def f() -> (y := 3): ...
140
+ // def g(arg: (x := 1)): ...
141
+ // def outer():
142
+ // def i(x: (yield 1)): ...
143
+ // def k() -> (yield 1): ...
144
+ // def m(x: (yield from 1)): ...
145
+ // def o() -> (yield from 1): ...
131
146
132
147
// test_err invalid_annotation_function
133
148
// def f[T]() -> (y := 3): ...
134
149
// def g[T](arg: (x := 1)): ...
135
150
// def h[T](x: (yield 1)): ...
136
- // def i(x: (yield 1)): ...
137
151
// def j[T]() -> (yield 1): ...
138
- // def k() -> (yield 1): ...
139
152
// def l[T](x: (yield from 1)): ...
140
- // def m(x: (yield from 1)): ...
141
153
// def n[T]() -> (yield from 1): ...
142
- // def o() -> (yield from 1): ...
143
154
// def p[T: (yield 1)](): ... # yield in TypeVar bound
144
155
// def q[T = (yield 1)](): ... # yield in TypeVar default
145
156
// def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default
@@ -148,19 +159,20 @@ impl SemanticSyntaxChecker {
148
159
// def u[T = (x := 1)](): ... # named expr in TypeVar default
149
160
// def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default
150
161
// def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default
151
- let is_generic = type_params. is_some ( ) ;
152
162
let mut visitor = InvalidExpressionVisitor {
153
- allow_named_expr : !is_generic,
154
163
position : InvalidExpressionPosition :: TypeAnnotation ,
155
164
ctx,
156
165
} ;
157
166
if let Some ( type_params) = type_params {
158
167
visitor. visit_type_params ( type_params) ;
159
168
}
160
- if is_generic {
169
+ // the __future__ annotation error takes precedence over the generic error
170
+ if ctx. future_annotations_or_stub ( ) || ctx. python_version ( ) > PythonVersion :: PY313 {
171
+ visitor. position = InvalidExpressionPosition :: TypeAnnotation ;
172
+ } else if type_params. is_some ( ) {
161
173
visitor. position = InvalidExpressionPosition :: GenericDefinition ;
162
174
} else {
163
- visitor . position = InvalidExpressionPosition :: TypeAnnotation ;
175
+ return ;
164
176
}
165
177
for param in parameters
166
178
. iter ( )
@@ -173,36 +185,29 @@ impl SemanticSyntaxChecker {
173
185
}
174
186
}
175
187
Stmt :: ClassDef ( ast:: StmtClassDef {
176
- type_params,
188
+ type_params : Some ( type_params ) ,
177
189
arguments,
178
190
..
179
191
} ) => {
180
192
// test_ok valid_annotation_class
181
193
// class F(y := list): ...
194
+ // def f():
195
+ // class G((yield 1)): ...
196
+ // class H((yield from 1)): ...
182
197
183
198
// test_err invalid_annotation_class
184
199
// class F[T](y := list): ...
185
- // class G((yield 1)): ...
186
- // class H((yield from 1)): ...
187
200
// class I[T]((yield 1)): ...
188
201
// class J[T]((yield from 1)): ...
189
202
// class K[T: (yield 1)]: ... # yield in TypeVar
190
203
// class L[T: (x := 1)]: ... # named expr in TypeVar
191
- let is_generic = type_params. is_some ( ) ;
192
204
let mut visitor = InvalidExpressionVisitor {
193
- allow_named_expr : !is_generic,
194
205
position : InvalidExpressionPosition :: TypeAnnotation ,
195
206
ctx,
196
207
} ;
197
- if let Some ( type_params) = type_params {
198
- visitor. visit_type_params ( type_params) ;
199
- }
200
- if is_generic {
201
- visitor. position = InvalidExpressionPosition :: GenericDefinition ;
202
- } else {
203
- visitor. position = InvalidExpressionPosition :: BaseClass ;
204
- }
208
+ visitor. visit_type_params ( type_params) ;
205
209
if let Some ( arguments) = arguments {
210
+ visitor. position = InvalidExpressionPosition :: GenericDefinition ;
206
211
visitor. visit_arguments ( arguments) ;
207
212
}
208
213
}
@@ -217,7 +222,6 @@ impl SemanticSyntaxChecker {
217
222
// type Y = (yield 1) # yield in value
218
223
// type Y = (x := 1) # named expr in value
219
224
let mut visitor = InvalidExpressionVisitor {
220
- allow_named_expr : false ,
221
225
position : InvalidExpressionPosition :: TypeAlias ,
222
226
ctx,
223
227
} ;
@@ -625,12 +629,6 @@ impl Display for SemanticSyntaxError {
625
629
write ! ( f, "cannot delete `__debug__` on Python {python_version} (syntax was removed in 3.9)" )
626
630
}
627
631
} ,
628
- SemanticSyntaxErrorKind :: InvalidExpression (
629
- kind,
630
- InvalidExpressionPosition :: BaseClass ,
631
- ) => {
632
- write ! ( f, "{kind} cannot be used as a base class" )
633
- }
634
632
SemanticSyntaxErrorKind :: InvalidExpression ( kind, position) => {
635
633
write ! ( f, "{kind} cannot be used within a {position}" )
636
634
}
@@ -858,7 +856,6 @@ pub enum InvalidExpressionPosition {
858
856
TypeVarTupleDefault ,
859
857
ParamSpecDefault ,
860
858
TypeAnnotation ,
861
- BaseClass ,
862
859
GenericDefinition ,
863
860
TypeAlias ,
864
861
}
@@ -872,7 +869,6 @@ impl Display for InvalidExpressionPosition {
872
869
InvalidExpressionPosition :: ParamSpecDefault => "ParamSpec default" ,
873
870
InvalidExpressionPosition :: TypeAnnotation => "type annotation" ,
874
871
InvalidExpressionPosition :: GenericDefinition => "generic definition" ,
875
- InvalidExpressionPosition :: BaseClass => "base class" ,
876
872
InvalidExpressionPosition :: TypeAlias => "type alias" ,
877
873
} )
878
874
}
@@ -1086,16 +1082,6 @@ impl<'a, Ctx: SemanticSyntaxContext> MatchPatternVisitor<'a, Ctx> {
1086
1082
}
1087
1083
1088
1084
struct InvalidExpressionVisitor < ' a , Ctx > {
1089
- /// Allow named expressions (`x := ...`) to appear in annotations.
1090
- ///
1091
- /// These are allowed in non-generic functions, for example:
1092
- ///
1093
- /// ```python
1094
- /// def foo(arg: (x := int)): ... # ok
1095
- /// def foo[T](arg: (x := int)): ... # syntax error
1096
- /// ```
1097
- allow_named_expr : bool ,
1098
-
1099
1085
/// Context used for emitting errors.
1100
1086
ctx : & ' a Ctx ,
1101
1087
@@ -1108,7 +1094,7 @@ where
1108
1094
{
1109
1095
fn visit_expr ( & mut self , expr : & Expr ) {
1110
1096
match expr {
1111
- Expr :: Named ( ast:: ExprNamed { range, .. } ) if ! self . allow_named_expr => {
1097
+ Expr :: Named ( ast:: ExprNamed { range, .. } ) => {
1112
1098
SemanticSyntaxChecker :: add_error (
1113
1099
self . ctx ,
1114
1100
SemanticSyntaxErrorKind :: InvalidExpression (
@@ -1166,6 +1152,9 @@ pub trait SemanticSyntaxContext {
1166
1152
/// Returns `true` if a module's docstring boundary has been passed.
1167
1153
fn seen_docstring_boundary ( & self ) -> bool ;
1168
1154
1155
+ /// Returns `true` if `__future__`-style type annotations are enabled.
1156
+ fn future_annotations_or_stub ( & self ) -> bool ;
1157
+
1169
1158
/// The target Python version for detecting backwards-incompatible syntax changes.
1170
1159
fn python_version ( & self ) -> PythonVersion ;
1171
1160
0 commit comments