diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index d599ec0f52..15f0d4f08a 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -573,6 +573,7 @@ impl SemanticSyntaxContext for Checker<'_> { | SemanticSyntaxErrorKind::IrrefutableCasePattern(_) | SemanticSyntaxErrorKind::SingleStarredAssignment | SemanticSyntaxErrorKind::WriteToDebug(_) + | SemanticSyntaxErrorKind::InvalidExpression(..) | SemanticSyntaxErrorKind::DuplicateMatchKey(_) | SemanticSyntaxErrorKind::DuplicateMatchClassAttribute(_) | SemanticSyntaxErrorKind::InvalidStarExpression => { diff --git a/crates/ruff_python_parser/resources/inline/err/invalid_annotation_class.py b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_class.py new file mode 100644 index 0000000000..84be61ecc0 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_class.py @@ -0,0 +1,7 @@ +class F[T](y := list): ... +class G((yield 1)): ... +class H((yield from 1)): ... +class I[T]((yield 1)): ... +class J[T]((yield from 1)): ... +class K[T: (yield 1)]: ... # yield in TypeVar +class L[T: (x := 1)]: ... # named expr in TypeVar diff --git a/crates/ruff_python_parser/resources/inline/err/invalid_annotation_function.py b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_function.py new file mode 100644 index 0000000000..9410d84b35 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_function.py @@ -0,0 +1,18 @@ +def f[T]() -> (y := 3): ... +def g[T](arg: (x := 1)): ... +def h[T](x: (yield 1)): ... +def i(x: (yield 1)): ... +def j[T]() -> (yield 1): ... +def k() -> (yield 1): ... +def l[T](x: (yield from 1)): ... +def m(x: (yield from 1)): ... +def n[T]() -> (yield from 1): ... +def o() -> (yield from 1): ... +def p[T: (yield 1)](): ... # yield in TypeVar bound +def q[T = (yield 1)](): ... # yield in TypeVar default +def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default +def s[**Ts = (yield 1)](): ... # yield in ParamSpec default +def t[T: (x := 1)](): ... # named expr in TypeVar bound +def u[T = (x := 1)](): ... # named expr in TypeVar default +def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default +def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default diff --git a/crates/ruff_python_parser/resources/inline/err/invalid_annotation_type_alias.py b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_type_alias.py new file mode 100644 index 0000000000..4e6cc04d11 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/err/invalid_annotation_type_alias.py @@ -0,0 +1,6 @@ +type X[T: (yield 1)] = int # TypeVar bound +type X[T = (yield 1)] = int # TypeVar default +type X[*Ts = (yield 1)] = int # TypeVarTuple default +type X[**Ts = (yield 1)] = int # ParamSpec default +type Y = (yield 1) # yield in value +type Y = (x := 1) # named expr in value diff --git a/crates/ruff_python_parser/resources/inline/ok/function_def_valid_return_expr.py b/crates/ruff_python_parser/resources/inline/ok/function_def_valid_return_expr.py index 7fb5dadfeb..603e510a34 100644 --- a/crates/ruff_python_parser/resources/inline/ok/function_def_valid_return_expr.py +++ b/crates/ruff_python_parser/resources/inline/ok/function_def_valid_return_expr.py @@ -1,4 +1,3 @@ def foo() -> int | str: ... def foo() -> lambda x: x: ... -def foo() -> (yield x): ... def foo() -> int if True else str: ... diff --git a/crates/ruff_python_parser/resources/inline/ok/param_with_annotation.py b/crates/ruff_python_parser/resources/inline/ok/param_with_annotation.py index 404be13e78..e109ecaebc 100644 --- a/crates/ruff_python_parser/resources/inline/ok/param_with_annotation.py +++ b/crates/ruff_python_parser/resources/inline/ok/param_with_annotation.py @@ -1,4 +1,3 @@ def foo(arg: int): ... def foo(arg: lambda x: x): ... -def foo(arg: (yield x)): ... def foo(arg: (x := int)): ... diff --git a/crates/ruff_python_parser/resources/inline/ok/valid_annotation_class.py b/crates/ruff_python_parser/resources/inline/ok/valid_annotation_class.py new file mode 100644 index 0000000000..35bd80e577 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/ok/valid_annotation_class.py @@ -0,0 +1 @@ +class F(y := list): ... diff --git a/crates/ruff_python_parser/resources/inline/ok/valid_annotation_function.py b/crates/ruff_python_parser/resources/inline/ok/valid_annotation_function.py new file mode 100644 index 0000000000..25add3d168 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/ok/valid_annotation_function.py @@ -0,0 +1,2 @@ +def f() -> (y := 3): ... +def g(arg: (x := 1)): ... diff --git a/crates/ruff_python_parser/src/parser/statement.rs b/crates/ruff_python_parser/src/parser/statement.rs index a0fb724a03..86d6fde4c1 100644 --- a/crates/ruff_python_parser/src/parser/statement.rs +++ b/crates/ruff_python_parser/src/parser/statement.rs @@ -1891,7 +1891,6 @@ impl<'src> Parser<'src> { // test_ok function_def_valid_return_expr // def foo() -> int | str: ... // def foo() -> lambda x: x: ... - // def foo() -> (yield x): ... // def foo() -> int if True else str: ... // test_err function_def_invalid_return_expr @@ -2986,7 +2985,6 @@ impl<'src> Parser<'src> { // test_ok param_with_annotation // def foo(arg: int): ... // def foo(arg: lambda x: x): ... - // def foo(arg: (yield x)): ... // def foo(arg: (x := int)): ... // test_err param_with_invalid_annotation diff --git a/crates/ruff_python_parser/src/semantic_errors.rs b/crates/ruff_python_parser/src/semantic_errors.rs index 1e12ce2760..095ae921b9 100644 --- a/crates/ruff_python_parser/src/semantic_errors.rs +++ b/crates/ruff_python_parser/src/semantic_errors.rs @@ -114,6 +114,120 @@ impl SemanticSyntaxChecker { } Self::debug_shadowing(stmt, ctx); + Self::check_annotation(stmt, ctx); + } + + fn check_annotation(stmt: &ast::Stmt, ctx: &Ctx) { + match stmt { + Stmt::FunctionDef(ast::StmtFunctionDef { + type_params, + parameters, + returns, + .. + }) => { + // test_ok valid_annotation_function + // def f() -> (y := 3): ... + // def g(arg: (x := 1)): ... + + // test_err invalid_annotation_function + // def f[T]() -> (y := 3): ... + // def g[T](arg: (x := 1)): ... + // def h[T](x: (yield 1)): ... + // def i(x: (yield 1)): ... + // def j[T]() -> (yield 1): ... + // def k() -> (yield 1): ... + // def l[T](x: (yield from 1)): ... + // def m(x: (yield from 1)): ... + // def n[T]() -> (yield from 1): ... + // def o() -> (yield from 1): ... + // def p[T: (yield 1)](): ... # yield in TypeVar bound + // def q[T = (yield 1)](): ... # yield in TypeVar default + // def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default + // def s[**Ts = (yield 1)](): ... # yield in ParamSpec default + // def t[T: (x := 1)](): ... # named expr in TypeVar bound + // def u[T = (x := 1)](): ... # named expr in TypeVar default + // def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default + // def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default + let is_generic = type_params.is_some(); + let mut visitor = InvalidExpressionVisitor { + allow_named_expr: !is_generic, + position: InvalidExpressionPosition::TypeAnnotation, + ctx, + }; + if let Some(type_params) = type_params { + visitor.visit_type_params(type_params); + } + if is_generic { + visitor.position = InvalidExpressionPosition::GenericDefinition; + } else { + visitor.position = InvalidExpressionPosition::TypeAnnotation; + } + for param in parameters + .iter() + .filter_map(ast::AnyParameterRef::annotation) + { + visitor.visit_expr(param); + } + if let Some(returns) = returns { + visitor.visit_expr(returns); + } + } + Stmt::ClassDef(ast::StmtClassDef { + type_params, + arguments, + .. + }) => { + // test_ok valid_annotation_class + // class F(y := list): ... + + // test_err invalid_annotation_class + // class F[T](y := list): ... + // class G((yield 1)): ... + // class H((yield from 1)): ... + // class I[T]((yield 1)): ... + // class J[T]((yield from 1)): ... + // class K[T: (yield 1)]: ... # yield in TypeVar + // class L[T: (x := 1)]: ... # named expr in TypeVar + let is_generic = type_params.is_some(); + let mut visitor = InvalidExpressionVisitor { + allow_named_expr: !is_generic, + position: InvalidExpressionPosition::TypeAnnotation, + ctx, + }; + if let Some(type_params) = type_params { + visitor.visit_type_params(type_params); + } + if is_generic { + visitor.position = InvalidExpressionPosition::GenericDefinition; + } else { + visitor.position = InvalidExpressionPosition::BaseClass; + } + if let Some(arguments) = arguments { + visitor.visit_arguments(arguments); + } + } + Stmt::TypeAlias(ast::StmtTypeAlias { + type_params, value, .. + }) => { + // test_err invalid_annotation_type_alias + // type X[T: (yield 1)] = int # TypeVar bound + // type X[T = (yield 1)] = int # TypeVar default + // type X[*Ts = (yield 1)] = int # TypeVarTuple default + // type X[**Ts = (yield 1)] = int # ParamSpec default + // type Y = (yield 1) # yield in value + // type Y = (x := 1) # named expr in value + let mut visitor = InvalidExpressionVisitor { + allow_named_expr: false, + position: InvalidExpressionPosition::TypeAlias, + ctx, + }; + visitor.visit_expr(value); + if let Some(type_params) = type_params { + visitor.visit_type_params(type_params); + } + } + _ => {} + } } /// Emit a [`SemanticSyntaxErrorKind::InvalidStarExpression`] if `expr` is starred. @@ -511,6 +625,15 @@ impl Display for SemanticSyntaxError { write!(f, "cannot delete `__debug__` on Python {python_version} (syntax was removed in 3.9)") } }, + SemanticSyntaxErrorKind::InvalidExpression( + kind, + InvalidExpressionPosition::BaseClass, + ) => { + write!(f, "{kind} cannot be used as a base class") + } + SemanticSyntaxErrorKind::InvalidExpression(kind, position) => { + write!(f, "{kind} cannot be used within a {position}") + } SemanticSyntaxErrorKind::DuplicateMatchKey(key) => { write!( f, @@ -641,6 +764,21 @@ pub enum SemanticSyntaxErrorKind { /// [BPO 45000]: https://github.com/python/cpython/issues/89163 WriteToDebug(WriteToDebugKind), + /// Represents the use of an invalid expression kind in one of several locations. + /// + /// The kinds include `yield` and `yield from` expressions and named expressions, and locations + /// include type parameter bounds and defaults, type annotations, type aliases, and base class + /// lists. + /// + /// ## Examples + /// + /// ```python + /// type X[T: (yield 1)] = int + /// type Y = (yield 1) + /// def f[T](x: int) -> (y := 3): return x + /// ``` + InvalidExpression(InvalidExpressionKind, InvalidExpressionPosition), + /// Represents a duplicate key in a `match` mapping pattern. /// /// The [CPython grammar] allows keys in mapping patterns to be literals or attribute accesses: @@ -713,6 +851,48 @@ pub enum SemanticSyntaxErrorKind { InvalidStarExpression, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum InvalidExpressionPosition { + TypeVarBound, + TypeVarDefault, + TypeVarTupleDefault, + ParamSpecDefault, + TypeAnnotation, + BaseClass, + GenericDefinition, + TypeAlias, +} + +impl Display for InvalidExpressionPosition { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + InvalidExpressionPosition::TypeVarBound => "TypeVar bound", + InvalidExpressionPosition::TypeVarDefault => "TypeVar default", + InvalidExpressionPosition::TypeVarTupleDefault => "TypeVarTuple default", + InvalidExpressionPosition::ParamSpecDefault => "ParamSpec default", + InvalidExpressionPosition::TypeAnnotation => "type annotation", + InvalidExpressionPosition::GenericDefinition => "generic definition", + InvalidExpressionPosition::BaseClass => "base class", + InvalidExpressionPosition::TypeAlias => "type alias", + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum InvalidExpressionKind { + Yield, + NamedExpr, +} + +impl Display for InvalidExpressionKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + InvalidExpressionKind::Yield => "yield expression", + InvalidExpressionKind::NamedExpr => "named expression", + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum WriteToDebugKind { Store, @@ -905,6 +1085,83 @@ impl<'a, Ctx: SemanticSyntaxContext> MatchPatternVisitor<'a, Ctx> { } } +struct InvalidExpressionVisitor<'a, Ctx> { + /// Allow named expressions (`x := ...`) to appear in annotations. + /// + /// These are allowed in non-generic functions, for example: + /// + /// ```python + /// def foo(arg: (x := int)): ... # ok + /// def foo[T](arg: (x := int)): ... # syntax error + /// ``` + allow_named_expr: bool, + + /// Context used for emitting errors. + ctx: &'a Ctx, + + position: InvalidExpressionPosition, +} + +impl Visitor<'_> for InvalidExpressionVisitor<'_, Ctx> +where + Ctx: SemanticSyntaxContext, +{ + fn visit_expr(&mut self, expr: &Expr) { + match expr { + Expr::Named(ast::ExprNamed { range, .. }) if !self.allow_named_expr => { + SemanticSyntaxChecker::add_error( + self.ctx, + SemanticSyntaxErrorKind::InvalidExpression( + InvalidExpressionKind::NamedExpr, + self.position, + ), + *range, + ); + } + Expr::Yield(ast::ExprYield { range, .. }) + | Expr::YieldFrom(ast::ExprYieldFrom { range, .. }) => { + SemanticSyntaxChecker::add_error( + self.ctx, + SemanticSyntaxErrorKind::InvalidExpression( + InvalidExpressionKind::Yield, + self.position, + ), + *range, + ); + } + _ => {} + } + ast::visitor::walk_expr(self, expr); + } + + fn visit_type_param(&mut self, type_param: &ast::TypeParam) { + match type_param { + ast::TypeParam::TypeVar(ast::TypeParamTypeVar { bound, default, .. }) => { + if let Some(expr) = bound { + self.position = InvalidExpressionPosition::TypeVarBound; + self.visit_expr(expr); + } + if let Some(expr) = default { + self.position = InvalidExpressionPosition::TypeVarDefault; + self.visit_expr(expr); + } + } + ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { default, .. }) => { + if let Some(expr) = default { + self.position = InvalidExpressionPosition::TypeVarTupleDefault; + self.visit_expr(expr); + } + } + ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { default, .. }) => { + if let Some(expr) = default { + self.position = InvalidExpressionPosition::ParamSpecDefault; + self.visit_expr(expr); + } + } + }; + } +} + pub trait SemanticSyntaxContext { /// Returns `true` if a module's docstring boundary has been passed. fn seen_docstring_boundary(&self) -> bool; diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@function_def_invalid_return_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@function_def_invalid_return_expr.py.snap index 9b30fe8ef2..f1968dedf9 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@function_def_invalid_return_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@function_def_invalid_return_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/function_def_invalid_return_expr.py -snapshot_kind: text --- ## AST @@ -180,3 +179,13 @@ Module( 3 | def foo() -> yield x: ... | ^^^^^^^ Syntax Error: Yield expression cannot be used here | + + +## Semantic Syntax Errors + + | +1 | def foo() -> *int: ... +2 | def foo() -> (*int): ... +3 | def foo() -> yield x: ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_class.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_class.py.snap new file mode 100644 index 0000000000..11cddd2d71 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_class.py.snap @@ -0,0 +1,479 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/err/invalid_annotation_class.py +--- +## AST + +``` +Module( + ModModule { + range: 0..246, + body: [ + ClassDef( + StmtClassDef { + range: 0..26, + decorator_list: [], + name: Identifier { + id: Name("F"), + range: 6..7, + }, + type_params: Some( + TypeParams { + range: 7..10, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 8..9, + name: Identifier { + id: Name("T"), + range: 8..9, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + arguments: Some( + Arguments { + range: 10..21, + args: [ + Named( + ExprNamed { + range: 11..20, + target: Name( + ExprName { + range: 11..12, + id: Name("y"), + ctx: Store, + }, + ), + value: Name( + ExprName { + range: 16..20, + id: Name("list"), + ctx: Load, + }, + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 23..26, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 23..26, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 27..50, + decorator_list: [], + name: Identifier { + id: Name("G"), + range: 33..34, + }, + type_params: None, + arguments: Some( + Arguments { + range: 34..45, + args: [ + Yield( + ExprYield { + range: 36..43, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 42..43, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 47..50, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 47..50, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 51..79, + decorator_list: [], + name: Identifier { + id: Name("H"), + range: 57..58, + }, + type_params: None, + arguments: Some( + Arguments { + range: 58..74, + args: [ + YieldFrom( + ExprYieldFrom { + range: 60..72, + value: NumberLiteral( + ExprNumberLiteral { + range: 71..72, + value: Int( + 1, + ), + }, + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 76..79, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 76..79, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 80..106, + decorator_list: [], + name: Identifier { + id: Name("I"), + range: 86..87, + }, + type_params: Some( + TypeParams { + range: 87..90, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 88..89, + name: Identifier { + id: Name("T"), + range: 88..89, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + arguments: Some( + Arguments { + range: 90..101, + args: [ + Yield( + ExprYield { + range: 92..99, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 98..99, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 103..106, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 103..106, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 107..138, + decorator_list: [], + name: Identifier { + id: Name("J"), + range: 113..114, + }, + type_params: Some( + TypeParams { + range: 114..117, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 115..116, + name: Identifier { + id: Name("T"), + range: 115..116, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + arguments: Some( + Arguments { + range: 117..133, + args: [ + YieldFrom( + ExprYieldFrom { + range: 119..131, + value: NumberLiteral( + ExprNumberLiteral { + range: 130..131, + value: Int( + 1, + ), + }, + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 135..138, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 135..138, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 139..165, + decorator_list: [], + name: Identifier { + id: Name("K"), + range: 145..146, + }, + type_params: Some( + TypeParams { + range: 146..160, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 147..159, + name: Identifier { + id: Name("T"), + range: 147..148, + }, + bound: Some( + Yield( + ExprYield { + range: 151..158, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 157..158, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + default: None, + }, + ), + ], + }, + ), + arguments: None, + body: [ + Expr( + StmtExpr { + range: 162..165, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 162..165, + }, + ), + }, + ), + ], + }, + ), + ClassDef( + StmtClassDef { + range: 190..215, + decorator_list: [], + name: Identifier { + id: Name("L"), + range: 196..197, + }, + type_params: Some( + TypeParams { + range: 197..210, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 198..209, + name: Identifier { + id: Name("T"), + range: 198..199, + }, + bound: Some( + Named( + ExprNamed { + range: 202..208, + target: Name( + ExprName { + range: 202..203, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 207..208, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + default: None, + }, + ), + ], + }, + ), + arguments: None, + body: [ + Expr( + StmtExpr { + range: 212..215, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 212..215, + }, + ), + }, + ), + ], + }, + ), + ], + }, +) +``` +## Semantic Syntax Errors + + | +1 | class F[T](y := list): ... + | ^^^^^^^^^ Syntax Error: named expression cannot be used within a generic definition +2 | class G((yield 1)): ... +3 | class H((yield from 1)): ... + | + + + | +1 | class F[T](y := list): ... +2 | class G((yield 1)): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used as a base class +3 | class H((yield from 1)): ... +4 | class I[T]((yield 1)): ... + | + + + | +1 | class F[T](y := list): ... +2 | class G((yield 1)): ... +3 | class H((yield from 1)): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used as a base class +4 | class I[T]((yield 1)): ... +5 | class J[T]((yield from 1)): ... + | + + + | +2 | class G((yield 1)): ... +3 | class H((yield from 1)): ... +4 | class I[T]((yield 1)): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +5 | class J[T]((yield from 1)): ... +6 | class K[T: (yield 1)]: ... # yield in TypeVar + | + + + | +3 | class H((yield from 1)): ... +4 | class I[T]((yield 1)): ... +5 | class J[T]((yield from 1)): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +6 | class K[T: (yield 1)]: ... # yield in TypeVar +7 | class L[T: (x := 1)]: ... # named expr in TypeVar + | + + + | +4 | class I[T]((yield 1)): ... +5 | class J[T]((yield from 1)): ... +6 | class K[T: (yield 1)]: ... # yield in TypeVar + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar bound +7 | class L[T: (x := 1)]: ... # named expr in TypeVar + | + + + | +5 | class J[T]((yield from 1)): ... +6 | class K[T: (yield 1)]: ... # yield in TypeVar +7 | class L[T: (x := 1)]: ... # named expr in TypeVar + | ^^^^^^ Syntax Error: named expression cannot be used within a TypeVar bound + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_function.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_function.py.snap new file mode 100644 index 0000000000..67dae0e7c1 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_function.py.snap @@ -0,0 +1,1392 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/err/invalid_annotation_function.py +--- +## AST + +``` +Module( + ModModule { + range: 0..795, + body: [ + FunctionDef( + StmtFunctionDef { + range: 0..27, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("f"), + range: 4..5, + }, + type_params: Some( + TypeParams { + range: 5..8, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 6..7, + name: Identifier { + id: Name("T"), + range: 6..7, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 8..10, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + Named( + ExprNamed { + range: 15..21, + target: Name( + ExprName { + range: 15..16, + id: Name("y"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 20..21, + value: Int( + 3, + ), + }, + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 24..27, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 24..27, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 28..56, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("g"), + range: 32..33, + }, + type_params: Some( + TypeParams { + range: 33..36, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 34..35, + name: Identifier { + id: Name("T"), + range: 34..35, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 36..51, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 37..50, + parameter: Parameter { + range: 37..50, + name: Identifier { + id: Name("arg"), + range: 37..40, + }, + annotation: Some( + Named( + ExprNamed { + range: 43..49, + target: Name( + ExprName { + range: 43..44, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 48..49, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 53..56, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 53..56, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 57..84, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("h"), + range: 61..62, + }, + type_params: Some( + TypeParams { + range: 62..65, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 63..64, + name: Identifier { + id: Name("T"), + range: 63..64, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 65..79, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 66..78, + parameter: Parameter { + range: 66..78, + name: Identifier { + id: Name("x"), + range: 66..67, + }, + annotation: Some( + Yield( + ExprYield { + range: 70..77, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 76..77, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 81..84, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 81..84, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 85..109, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("i"), + range: 89..90, + }, + type_params: None, + parameters: Parameters { + range: 90..104, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 91..103, + parameter: Parameter { + range: 91..103, + name: Identifier { + id: Name("x"), + range: 91..92, + }, + annotation: Some( + Yield( + ExprYield { + range: 95..102, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 101..102, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 106..109, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 106..109, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 110..138, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("j"), + range: 114..115, + }, + type_params: Some( + TypeParams { + range: 115..118, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 116..117, + name: Identifier { + id: Name("T"), + range: 116..117, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 118..120, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + Yield( + ExprYield { + range: 125..132, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 131..132, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 135..138, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 135..138, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 139..164, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("k"), + range: 143..144, + }, + type_params: None, + parameters: Parameters { + range: 144..146, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + Yield( + ExprYield { + range: 151..158, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 157..158, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 161..164, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 161..164, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 165..197, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("l"), + range: 169..170, + }, + type_params: Some( + TypeParams { + range: 170..173, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 171..172, + name: Identifier { + id: Name("T"), + range: 171..172, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 173..192, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 174..191, + parameter: Parameter { + range: 174..191, + name: Identifier { + id: Name("x"), + range: 174..175, + }, + annotation: Some( + YieldFrom( + ExprYieldFrom { + range: 178..190, + value: NumberLiteral( + ExprNumberLiteral { + range: 189..190, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 194..197, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 194..197, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 198..227, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("m"), + range: 202..203, + }, + type_params: None, + parameters: Parameters { + range: 203..222, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 204..221, + parameter: Parameter { + range: 204..221, + name: Identifier { + id: Name("x"), + range: 204..205, + }, + annotation: Some( + YieldFrom( + ExprYieldFrom { + range: 208..220, + value: NumberLiteral( + ExprNumberLiteral { + range: 219..220, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 224..227, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 224..227, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 228..261, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("n"), + range: 232..233, + }, + type_params: Some( + TypeParams { + range: 233..236, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 234..235, + name: Identifier { + id: Name("T"), + range: 234..235, + }, + bound: None, + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 236..238, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + YieldFrom( + ExprYieldFrom { + range: 243..255, + value: NumberLiteral( + ExprNumberLiteral { + range: 254..255, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 258..261, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 258..261, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 262..292, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("o"), + range: 266..267, + }, + type_params: None, + parameters: Parameters { + range: 267..269, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + YieldFrom( + ExprYieldFrom { + range: 274..286, + value: NumberLiteral( + ExprNumberLiteral { + range: 285..286, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 289..292, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 289..292, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 293..319, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("p"), + range: 297..298, + }, + type_params: Some( + TypeParams { + range: 298..312, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 299..311, + name: Identifier { + id: Name("T"), + range: 299..300, + }, + bound: Some( + Yield( + ExprYield { + range: 303..310, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 309..310, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 312..314, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 316..319, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 316..319, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 350..377, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("q"), + range: 354..355, + }, + type_params: Some( + TypeParams { + range: 355..370, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 356..369, + name: Identifier { + id: Name("T"), + range: 356..357, + }, + bound: None, + default: Some( + Yield( + ExprYield { + range: 361..368, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 367..368, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 370..372, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 374..377, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 374..377, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 409..438, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("r"), + range: 413..414, + }, + type_params: Some( + TypeParams { + range: 414..431, + type_params: [ + TypeVarTuple( + TypeParamTypeVarTuple { + range: 415..430, + name: Identifier { + id: Name("Ts"), + range: 416..418, + }, + default: Some( + Yield( + ExprYield { + range: 422..429, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 428..429, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 431..433, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 435..438, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 435..438, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 473..503, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("s"), + range: 477..478, + }, + type_params: Some( + TypeParams { + range: 478..496, + type_params: [ + ParamSpec( + TypeParamParamSpec { + range: 479..495, + name: Identifier { + id: Name("Ts"), + range: 481..483, + }, + default: Some( + Yield( + ExprYield { + range: 487..494, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 493..494, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 496..498, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 500..503, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 500..503, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 534..559, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("t"), + range: 538..539, + }, + type_params: Some( + TypeParams { + range: 539..552, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 540..551, + name: Identifier { + id: Name("T"), + range: 540..541, + }, + bound: Some( + Named( + ExprNamed { + range: 544..550, + target: Name( + ExprName { + range: 544..545, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 549..550, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + default: None, + }, + ), + ], + }, + ), + parameters: Parameters { + range: 552..554, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 556..559, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 556..559, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 596..622, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("u"), + range: 600..601, + }, + type_params: Some( + TypeParams { + range: 601..615, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 602..614, + name: Identifier { + id: Name("T"), + range: 602..603, + }, + bound: None, + default: Some( + Named( + ExprNamed { + range: 607..613, + target: Name( + ExprName { + range: 607..608, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 612..613, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 615..617, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 619..622, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 619..622, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 660..688, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("v"), + range: 664..665, + }, + type_params: Some( + TypeParams { + range: 665..681, + type_params: [ + TypeVarTuple( + TypeParamTypeVarTuple { + range: 666..680, + name: Identifier { + id: Name("Ts"), + range: 667..669, + }, + default: Some( + Named( + ExprNamed { + range: 673..679, + target: Name( + ExprName { + range: 673..674, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 678..679, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 681..683, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 685..688, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 685..688, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 729..758, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("w"), + range: 733..734, + }, + type_params: Some( + TypeParams { + range: 734..751, + type_params: [ + ParamSpec( + TypeParamParamSpec { + range: 735..750, + name: Identifier { + id: Name("Ts"), + range: 737..739, + }, + default: Some( + Named( + ExprNamed { + range: 743..749, + target: Name( + ExprName { + range: 743..744, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 748..749, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + ), + ], + }, + ), + parameters: Parameters { + range: 751..753, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 755..758, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 755..758, + }, + ), + }, + ), + ], + }, + ), + ], + }, +) +``` +## Semantic Syntax Errors + + | +1 | def f[T]() -> (y := 3): ... + | ^^^^^^ Syntax Error: named expression cannot be used within a generic definition +2 | def g[T](arg: (x := 1)): ... +3 | def h[T](x: (yield 1)): ... + | + + + | +1 | def f[T]() -> (y := 3): ... +2 | def g[T](arg: (x := 1)): ... + | ^^^^^^ Syntax Error: named expression cannot be used within a generic definition +3 | def h[T](x: (yield 1)): ... +4 | def i(x: (yield 1)): ... + | + + + | +1 | def f[T]() -> (y := 3): ... +2 | def g[T](arg: (x := 1)): ... +3 | def h[T](x: (yield 1)): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +4 | def i(x: (yield 1)): ... +5 | def j[T]() -> (yield 1): ... + | + + + | +2 | def g[T](arg: (x := 1)): ... +3 | def h[T](x: (yield 1)): ... +4 | def i(x: (yield 1)): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation +5 | def j[T]() -> (yield 1): ... +6 | def k() -> (yield 1): ... + | + + + | +3 | def h[T](x: (yield 1)): ... +4 | def i(x: (yield 1)): ... +5 | def j[T]() -> (yield 1): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +6 | def k() -> (yield 1): ... +7 | def l[T](x: (yield from 1)): ... + | + + + | +4 | def i(x: (yield 1)): ... +5 | def j[T]() -> (yield 1): ... +6 | def k() -> (yield 1): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation +7 | def l[T](x: (yield from 1)): ... +8 | def m(x: (yield from 1)): ... + | + + + | +5 | def j[T]() -> (yield 1): ... +6 | def k() -> (yield 1): ... +7 | def l[T](x: (yield from 1)): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +8 | def m(x: (yield from 1)): ... +9 | def n[T]() -> (yield from 1): ... + | + + + | + 6 | def k() -> (yield 1): ... + 7 | def l[T](x: (yield from 1)): ... + 8 | def m(x: (yield from 1)): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation + 9 | def n[T]() -> (yield from 1): ... +10 | def o() -> (yield from 1): ... + | + + + | + 7 | def l[T](x: (yield from 1)): ... + 8 | def m(x: (yield from 1)): ... + 9 | def n[T]() -> (yield from 1): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a generic definition +10 | def o() -> (yield from 1): ... +11 | def p[T: (yield 1)](): ... # yield in TypeVar bound + | + + + | + 8 | def m(x: (yield from 1)): ... + 9 | def n[T]() -> (yield from 1): ... +10 | def o() -> (yield from 1): ... + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation +11 | def p[T: (yield 1)](): ... # yield in TypeVar bound +12 | def q[T = (yield 1)](): ... # yield in TypeVar default + | + + + | + 9 | def n[T]() -> (yield from 1): ... +10 | def o() -> (yield from 1): ... +11 | def p[T: (yield 1)](): ... # yield in TypeVar bound + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar bound +12 | def q[T = (yield 1)](): ... # yield in TypeVar default +13 | def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default + | + + + | +10 | def o() -> (yield from 1): ... +11 | def p[T: (yield 1)](): ... # yield in TypeVar bound +12 | def q[T = (yield 1)](): ... # yield in TypeVar default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar default +13 | def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default +14 | def s[**Ts = (yield 1)](): ... # yield in ParamSpec default + | + + + | +11 | def p[T: (yield 1)](): ... # yield in TypeVar bound +12 | def q[T = (yield 1)](): ... # yield in TypeVar default +13 | def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVarTuple default +14 | def s[**Ts = (yield 1)](): ... # yield in ParamSpec default +15 | def t[T: (x := 1)](): ... # named expr in TypeVar bound + | + + + | +12 | def q[T = (yield 1)](): ... # yield in TypeVar default +13 | def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default +14 | def s[**Ts = (yield 1)](): ... # yield in ParamSpec default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a ParamSpec default +15 | def t[T: (x := 1)](): ... # named expr in TypeVar bound +16 | def u[T = (x := 1)](): ... # named expr in TypeVar default + | + + + | +13 | def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default +14 | def s[**Ts = (yield 1)](): ... # yield in ParamSpec default +15 | def t[T: (x := 1)](): ... # named expr in TypeVar bound + | ^^^^^^ Syntax Error: named expression cannot be used within a TypeVar bound +16 | def u[T = (x := 1)](): ... # named expr in TypeVar default +17 | def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default + | + + + | +14 | def s[**Ts = (yield 1)](): ... # yield in ParamSpec default +15 | def t[T: (x := 1)](): ... # named expr in TypeVar bound +16 | def u[T = (x := 1)](): ... # named expr in TypeVar default + | ^^^^^^ Syntax Error: named expression cannot be used within a TypeVar default +17 | def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default +18 | def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default + | + + + | +15 | def t[T: (x := 1)](): ... # named expr in TypeVar bound +16 | def u[T = (x := 1)](): ... # named expr in TypeVar default +17 | def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default + | ^^^^^^ Syntax Error: named expression cannot be used within a TypeVarTuple default +18 | def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default + | + + + | +16 | def u[T = (x := 1)](): ... # named expr in TypeVar default +17 | def v[*Ts = (x := 1)](): ... # named expr in TypeVarTuple default +18 | def w[**Ts = (x := 1)](): ... # named expr in ParamSpec default + | ^^^^^^ Syntax Error: named expression cannot be used within a ParamSpec default + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_type_alias.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_type_alias.py.snap new file mode 100644 index 0000000000..e820cf9864 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@invalid_annotation_type_alias.py.snap @@ -0,0 +1,340 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/err/invalid_annotation_type_alias.py +--- +## AST + +``` +Module( + ModModule { + range: 0..308, + body: [ + TypeAlias( + StmtTypeAlias { + range: 0..26, + name: Name( + ExprName { + range: 5..6, + id: Name("X"), + ctx: Store, + }, + ), + type_params: Some( + TypeParams { + range: 6..20, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 7..19, + name: Identifier { + id: Name("T"), + range: 7..8, + }, + bound: Some( + Yield( + ExprYield { + range: 11..18, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 17..18, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + default: None, + }, + ), + ], + }, + ), + value: Name( + ExprName { + range: 23..26, + id: Name("int"), + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 48..75, + name: Name( + ExprName { + range: 53..54, + id: Name("X"), + ctx: Store, + }, + ), + type_params: Some( + TypeParams { + range: 54..69, + type_params: [ + TypeVar( + TypeParamTypeVar { + range: 55..68, + name: Identifier { + id: Name("T"), + range: 55..56, + }, + bound: None, + default: Some( + Yield( + ExprYield { + range: 60..67, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 66..67, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + value: Name( + ExprName { + range: 72..75, + id: Name("int"), + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 98..127, + name: Name( + ExprName { + range: 103..104, + id: Name("X"), + ctx: Store, + }, + ), + type_params: Some( + TypeParams { + range: 104..121, + type_params: [ + TypeVarTuple( + TypeParamTypeVarTuple { + range: 105..120, + name: Identifier { + id: Name("Ts"), + range: 106..108, + }, + default: Some( + Yield( + ExprYield { + range: 112..119, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 118..119, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + value: Name( + ExprName { + range: 124..127, + id: Name("int"), + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 153..183, + name: Name( + ExprName { + range: 158..159, + id: Name("X"), + ctx: Store, + }, + ), + type_params: Some( + TypeParams { + range: 159..177, + type_params: [ + ParamSpec( + TypeParamParamSpec { + range: 160..176, + name: Identifier { + id: Name("Ts"), + range: 162..164, + }, + default: Some( + Yield( + ExprYield { + range: 168..175, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 174..175, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + ), + }, + ), + ], + }, + ), + value: Name( + ExprName { + range: 180..183, + id: Name("int"), + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 205..223, + name: Name( + ExprName { + range: 210..211, + id: Name("Y"), + ctx: Store, + }, + ), + type_params: None, + value: Yield( + ExprYield { + range: 215..222, + value: Some( + NumberLiteral( + ExprNumberLiteral { + range: 221..222, + value: Int( + 1, + ), + }, + ), + ), + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 254..271, + name: Name( + ExprName { + range: 259..260, + id: Name("Y"), + ctx: Store, + }, + ), + type_params: None, + value: Named( + ExprNamed { + range: 264..270, + target: Name( + ExprName { + range: 264..265, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 269..270, + value: Int( + 1, + ), + }, + ), + }, + ), + }, + ), + ], + }, +) +``` +## Semantic Syntax Errors + + | +1 | type X[T: (yield 1)] = int # TypeVar bound + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar bound +2 | type X[T = (yield 1)] = int # TypeVar default +3 | type X[*Ts = (yield 1)] = int # TypeVarTuple default + | + + + | +1 | type X[T: (yield 1)] = int # TypeVar bound +2 | type X[T = (yield 1)] = int # TypeVar default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar default +3 | type X[*Ts = (yield 1)] = int # TypeVarTuple default +4 | type X[**Ts = (yield 1)] = int # ParamSpec default + | + + + | +1 | type X[T: (yield 1)] = int # TypeVar bound +2 | type X[T = (yield 1)] = int # TypeVar default +3 | type X[*Ts = (yield 1)] = int # TypeVarTuple default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVarTuple default +4 | type X[**Ts = (yield 1)] = int # ParamSpec default +5 | type Y = (yield 1) # yield in value + | + + + | +2 | type X[T = (yield 1)] = int # TypeVar default +3 | type X[*Ts = (yield 1)] = int # TypeVarTuple default +4 | type X[**Ts = (yield 1)] = int # ParamSpec default + | ^^^^^^^ Syntax Error: yield expression cannot be used within a ParamSpec default +5 | type Y = (yield 1) # yield in value +6 | type Y = (x := 1) # named expr in value + | + + + | +3 | type X[*Ts = (yield 1)] = int # TypeVarTuple default +4 | type X[**Ts = (yield 1)] = int # ParamSpec default +5 | type Y = (yield 1) # yield in value + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type alias +6 | type Y = (x := 1) # named expr in value + | + + + | +4 | type X[**Ts = (yield 1)] = int # ParamSpec default +5 | type Y = (yield 1) # yield in value +6 | type Y = (x := 1) # named expr in value + | ^^^^^^ Syntax Error: named expression cannot be used within a type alias + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_annotation.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_annotation.py.snap index 7315a10a91..d799a78939 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_annotation.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_annotation.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/param_with_invalid_annotation.py -snapshot_kind: text --- ## AST @@ -225,3 +224,13 @@ Module( 3 | def foo(arg: x := int): ... | ^^ Syntax Error: Expected ',', found ':=' | + + +## Semantic Syntax Errors + + | +1 | def foo(arg: *int): ... +2 | def foo(arg: yield int): ... + | ^^^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation +3 | def foo(arg: x := int): ... + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_star_annotation.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_star_annotation.py.snap index ab62d648e7..13eeeed689 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_star_annotation.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@param_with_invalid_star_annotation.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/param_with_invalid_star_annotation.py -snapshot_kind: text --- ## AST @@ -309,3 +308,14 @@ Module( | ^^^^^^^ Syntax Error: Yield expression cannot be used here 5 | # def foo(*args: **int): ... | + + +## Semantic Syntax Errors + + | +2 | def foo(*args: (*tuple[int])): ... +3 | def foo(*args: *int or str): ... +4 | def foo(*args: *yield x): ... + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type annotation +5 | # def foo(*args: **int): ... + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_alias_invalid_value_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_alias_invalid_value_expr.py.snap index e039b7cae9..3b1d5c40ab 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_alias_invalid_value_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_alias_invalid_value_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/type_alias_invalid_value_expr.py -snapshot_kind: text --- ## AST @@ -159,3 +158,23 @@ Module( 4 | type x = x := 1 | ^^ Syntax Error: Expected a statement | + + +## Semantic Syntax Errors + + | +1 | type x = *y +2 | type x = yield y + | ^^^^^^^ Syntax Error: yield expression cannot be used within a type alias +3 | type x = yield from y +4 | type x = x := 1 + | + + + | +1 | type x = *y +2 | type x = yield y +3 | type x = yield from y + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a type alias +4 | type x = x := 1 + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_invalid_bound_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_invalid_bound_expr.py.snap index ccd38751b7..6de003c414 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_invalid_bound_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_invalid_bound_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/type_param_invalid_bound_expr.py -snapshot_kind: text --- ## AST @@ -257,3 +256,23 @@ Module( 4 | type X[T: x := int] = int | ^^ Syntax Error: Expected ',', found ':=' | + + +## Semantic Syntax Errors + + | +1 | type X[T: *int] = int +2 | type X[T: yield x] = int + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar bound +3 | type X[T: yield from x] = int +4 | type X[T: x := int] = int + | + + + | +1 | type X[T: *int] = int +2 | type X[T: yield x] = int +3 | type X[T: yield from x] = int + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar bound +4 | type X[T: x := int] = int + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_param_spec_invalid_default_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_param_spec_invalid_default_expr.py.snap index 8b86b5ee84..757545ca6e 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_param_spec_invalid_default_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_param_spec_invalid_default_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/type_param_param_spec_invalid_default_expr.py -snapshot_kind: text --- ## AST @@ -313,3 +312,24 @@ Module( 5 | type X[**P = *int] = int | ^^^^ Syntax Error: Starred expression cannot be used here | + + +## Semantic Syntax Errors + + | +1 | type X[**P = *int] = int +2 | type X[**P = yield x] = int + | ^^^^^^^ Syntax Error: yield expression cannot be used within a ParamSpec default +3 | type X[**P = yield from x] = int +4 | type X[**P = x := int] = int + | + + + | +1 | type X[**P = *int] = int +2 | type X[**P = yield x] = int +3 | type X[**P = yield from x] = int + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a ParamSpec default +4 | type X[**P = x := int] = int +5 | type X[**P = *int] = int + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_invalid_default_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_invalid_default_expr.py.snap index a7d70ddda2..9d93c799c7 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_invalid_default_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_invalid_default_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/type_param_type_var_invalid_default_expr.py -snapshot_kind: text --- ## AST @@ -378,3 +377,34 @@ Module( 6 | type X[T: int = *int] = int | ^^^^ Syntax Error: Starred expression cannot be used here | + + +## Semantic Syntax Errors + + | +1 | type X[T = *int] = int +2 | type X[T = yield x] = int + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar default +3 | type X[T = (yield x)] = int +4 | type X[T = yield from x] = int + | + + + | +1 | type X[T = *int] = int +2 | type X[T = yield x] = int +3 | type X[T = (yield x)] = int + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar default +4 | type X[T = yield from x] = int +5 | type X[T = x := int] = int + | + + + | +2 | type X[T = yield x] = int +3 | type X[T = (yield x)] = int +4 | type X[T = yield from x] = int + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVar default +5 | type X[T = x := int] = int +6 | type X[T: int = *int] = int + | diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_tuple_invalid_default_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_tuple_invalid_default_expr.py.snap index c509a0e5ef..61860a15ef 100644 --- a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_tuple_invalid_default_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@type_param_type_var_tuple_invalid_default_expr.py.snap @@ -1,7 +1,6 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/err/type_param_type_var_tuple_invalid_default_expr.py -snapshot_kind: text --- ## AST @@ -320,3 +319,24 @@ Module( 5 | type X[*Ts = x := int] = int | ^^ Syntax Error: Expected ',', found ':=' | + + +## Semantic Syntax Errors + + | +1 | type X[*Ts = *int] = int +2 | type X[*Ts = *int or str] = int +3 | type X[*Ts = yield x] = int + | ^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVarTuple default +4 | type X[*Ts = yield from x] = int +5 | type X[*Ts = x := int] = int + | + + + | +2 | type X[*Ts = *int or str] = int +3 | type X[*Ts = yield x] = int +4 | type X[*Ts = yield from x] = int + | ^^^^^^^^^^^^ Syntax Error: yield expression cannot be used within a TypeVarTuple default +5 | type X[*Ts = x := int] = int + | diff --git a/crates/ruff_python_parser/tests/snapshots/valid_syntax@function_def_valid_return_expr.py.snap b/crates/ruff_python_parser/tests/snapshots/valid_syntax@function_def_valid_return_expr.py.snap index 791706860e..f4bd699f74 100644 --- a/crates/ruff_python_parser/tests/snapshots/valid_syntax@function_def_valid_return_expr.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/valid_syntax@function_def_valid_return_expr.py.snap @@ -1,14 +1,13 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/ok/function_def_valid_return_expr.py -snapshot_kind: text --- ## AST ``` Module( ModModule { - range: 0..125, + range: 0..97, body: [ FunctionDef( StmtFunctionDef { @@ -135,7 +134,7 @@ Module( ), FunctionDef( StmtFunctionDef { - range: 58..85, + range: 58..96, is_async: false, decorator_list: [], name: Identifier { @@ -151,74 +150,26 @@ Module( kwonlyargs: [], kwarg: None, }, - returns: Some( - Yield( - ExprYield { - range: 72..79, - value: Some( - Name( - ExprName { - range: 78..79, - id: Name("x"), - ctx: Load, - }, - ), - ), - }, - ), - ), - body: [ - Expr( - StmtExpr { - range: 82..85, - value: EllipsisLiteral( - ExprEllipsisLiteral { - range: 82..85, - }, - ), - }, - ), - ], - }, - ), - FunctionDef( - StmtFunctionDef { - range: 86..124, - is_async: false, - decorator_list: [], - name: Identifier { - id: Name("foo"), - range: 90..93, - }, - type_params: None, - parameters: Parameters { - range: 93..95, - posonlyargs: [], - args: [], - vararg: None, - kwonlyargs: [], - kwarg: None, - }, returns: Some( If( ExprIf { - range: 99..119, + range: 71..91, test: BooleanLiteral( ExprBooleanLiteral { - range: 106..110, + range: 78..82, value: true, }, ), body: Name( ExprName { - range: 99..102, + range: 71..74, id: Name("int"), ctx: Load, }, ), orelse: Name( ExprName { - range: 116..119, + range: 88..91, id: Name("str"), ctx: Load, }, @@ -229,10 +180,10 @@ Module( body: [ Expr( StmtExpr { - range: 121..124, + range: 93..96, value: EllipsisLiteral( ExprEllipsisLiteral { - range: 121..124, + range: 93..96, }, ), }, diff --git a/crates/ruff_python_parser/tests/snapshots/valid_syntax@param_with_annotation.py.snap b/crates/ruff_python_parser/tests/snapshots/valid_syntax@param_with_annotation.py.snap index c351f8dd32..c3d622ebb0 100644 --- a/crates/ruff_python_parser/tests/snapshots/valid_syntax@param_with_annotation.py.snap +++ b/crates/ruff_python_parser/tests/snapshots/valid_syntax@param_with_annotation.py.snap @@ -1,14 +1,13 @@ --- source: crates/ruff_python_parser/tests/fixtures.rs input_file: crates/ruff_python_parser/resources/inline/ok/param_with_annotation.py -snapshot_kind: text --- ## AST ``` Module( ModModule { - range: 0..113, + range: 0..84, body: [ FunctionDef( StmtFunctionDef { @@ -148,7 +147,7 @@ Module( ), FunctionDef( StmtFunctionDef { - range: 54..82, + range: 54..83, is_async: false, decorator_list: [], name: Identifier { @@ -157,92 +156,31 @@ Module( }, type_params: None, parameters: Parameters { - range: 61..77, + range: 61..78, posonlyargs: [], args: [ ParameterWithDefault { - range: 62..76, + range: 62..77, parameter: Parameter { - range: 62..76, + range: 62..77, name: Identifier { id: Name("arg"), range: 62..65, }, - annotation: Some( - Yield( - ExprYield { - range: 68..75, - value: Some( - Name( - ExprName { - range: 74..75, - id: Name("x"), - ctx: Load, - }, - ), - ), - }, - ), - ), - }, - default: None, - }, - ], - vararg: None, - kwonlyargs: [], - kwarg: None, - }, - returns: None, - body: [ - Expr( - StmtExpr { - range: 79..82, - value: EllipsisLiteral( - ExprEllipsisLiteral { - range: 79..82, - }, - ), - }, - ), - ], - }, - ), - FunctionDef( - StmtFunctionDef { - range: 83..112, - is_async: false, - decorator_list: [], - name: Identifier { - id: Name("foo"), - range: 87..90, - }, - type_params: None, - parameters: Parameters { - range: 90..107, - posonlyargs: [], - args: [ - ParameterWithDefault { - range: 91..106, - parameter: Parameter { - range: 91..106, - name: Identifier { - id: Name("arg"), - range: 91..94, - }, annotation: Some( Named( ExprNamed { - range: 97..105, + range: 68..76, target: Name( ExprName { - range: 97..98, + range: 68..69, id: Name("x"), ctx: Store, }, ), value: Name( ExprName { - range: 102..105, + range: 73..76, id: Name("int"), ctx: Load, }, @@ -262,10 +200,10 @@ Module( body: [ Expr( StmtExpr { - range: 109..112, + range: 80..83, value: EllipsisLiteral( ExprEllipsisLiteral { - range: 109..112, + range: 80..83, }, ), }, diff --git a/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_class.py.snap b/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_class.py.snap new file mode 100644 index 0000000000..b94b2b72c8 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_class.py.snap @@ -0,0 +1,65 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/ok/valid_annotation_class.py +--- +## AST + +``` +Module( + ModModule { + range: 0..24, + body: [ + ClassDef( + StmtClassDef { + range: 0..23, + decorator_list: [], + name: Identifier { + id: Name("F"), + range: 6..7, + }, + type_params: None, + arguments: Some( + Arguments { + range: 7..18, + args: [ + Named( + ExprNamed { + range: 8..17, + target: Name( + ExprName { + range: 8..9, + id: Name("y"), + ctx: Store, + }, + ), + value: Name( + ExprName { + range: 13..17, + id: Name("list"), + ctx: Load, + }, + ), + }, + ), + ], + keywords: [], + }, + ), + body: [ + Expr( + StmtExpr { + range: 20..23, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 20..23, + }, + ), + }, + ), + ], + }, + ), + ], + }, +) +``` diff --git a/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_function.py.snap b/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_function.py.snap new file mode 100644 index 0000000000..5be2f67c14 --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/valid_syntax@valid_annotation_function.py.snap @@ -0,0 +1,136 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/ok/valid_annotation_function.py +--- +## AST + +``` +Module( + ModModule { + range: 0..51, + body: [ + FunctionDef( + StmtFunctionDef { + range: 0..24, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("f"), + range: 4..5, + }, + type_params: None, + parameters: Parameters { + range: 5..7, + posonlyargs: [], + args: [], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: Some( + Named( + ExprNamed { + range: 12..18, + target: Name( + ExprName { + range: 12..13, + id: Name("y"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 17..18, + value: Int( + 3, + ), + }, + ), + }, + ), + ), + body: [ + Expr( + StmtExpr { + range: 21..24, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 21..24, + }, + ), + }, + ), + ], + }, + ), + FunctionDef( + StmtFunctionDef { + range: 25..50, + is_async: false, + decorator_list: [], + name: Identifier { + id: Name("g"), + range: 29..30, + }, + type_params: None, + parameters: Parameters { + range: 30..45, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 31..44, + parameter: Parameter { + range: 31..44, + name: Identifier { + id: Name("arg"), + range: 31..34, + }, + annotation: Some( + Named( + ExprNamed { + range: 37..43, + target: Name( + ExprName { + range: 37..38, + id: Name("x"), + ctx: Store, + }, + ), + value: NumberLiteral( + ExprNumberLiteral { + range: 42..43, + value: Int( + 1, + ), + }, + ), + }, + ), + ), + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + returns: None, + body: [ + Expr( + StmtExpr { + range: 47..50, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 47..50, + }, + ), + }, + ), + ], + }, + ), + ], + }, +) +```