From ea182766fc08a620891a97f56a127db9df91495b Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Thu, 11 Apr 2024 22:14:29 +0530 Subject: [PATCH] Expect `for` after `async` instead of `bump` (#10877) Co-authored-by: Micha Reiser --- .../comprehension_missing_for_after_async.py | 2 + .../src/parser/expression.rs | 10 +- ...prehension_missing_for_after_async.py.snap | 114 ++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 crates/ruff_python_parser/resources/inline/err/comprehension_missing_for_after_async.py create mode 100644 crates/ruff_python_parser/tests/snapshots/invalid_syntax@comprehension_missing_for_after_async.py.snap diff --git a/crates/ruff_python_parser/resources/inline/err/comprehension_missing_for_after_async.py b/crates/ruff_python_parser/resources/inline/err/comprehension_missing_for_after_async.py new file mode 100644 index 0000000000000..3c5be71bbd8e3 --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/err/comprehension_missing_for_after_async.py @@ -0,0 +1,2 @@ +(async) +(x async x in iter) diff --git a/crates/ruff_python_parser/src/parser/expression.rs b/crates/ruff_python_parser/src/parser/expression.rs index cbeb3f9656f31..5e4b36afae71b 100644 --- a/crates/ruff_python_parser/src/parser/expression.rs +++ b/crates/ruff_python_parser/src/parser/expression.rs @@ -1934,7 +1934,15 @@ impl<'src> Parser<'src> { let start = self.node_start(); let is_async = self.eat(TokenKind::Async); - self.bump(TokenKind::For); + + if is_async { + // test_err comprehension_missing_for_after_async + // (async) + // (x async x in iter) + self.expect(TokenKind::For); + } else { + self.bump(TokenKind::For); + }; let saved_context = self.set_ctx(ParserCtxFlags::FOR_TARGET); let mut target = self.parse_expression_list(AllowStarredExpression::Yes); diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@comprehension_missing_for_after_async.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@comprehension_missing_for_after_async.py.snap new file mode 100644 index 0000000000000..4297ad0f41fee --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@comprehension_missing_for_after_async.py.snap @@ -0,0 +1,114 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/err/comprehension_missing_for_after_async.py +--- +## AST + +``` +Module( + ModModule { + range: 0..28, + body: [ + Expr( + StmtExpr { + range: 0..7, + value: Generator( + ExprGenerator { + range: 0..7, + elt: Name( + ExprName { + range: 1..1, + id: "", + ctx: Invalid, + }, + ), + generators: [ + Comprehension { + range: 1..6, + target: Name( + ExprName { + range: 6..6, + id: "", + ctx: Store, + }, + ), + iter: Name( + ExprName { + range: 6..6, + id: "", + ctx: Invalid, + }, + ), + ifs: [], + is_async: true, + }, + ], + parenthesized: true, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 8..27, + value: Generator( + ExprGenerator { + range: 8..27, + elt: Name( + ExprName { + range: 9..10, + id: "x", + ctx: Load, + }, + ), + generators: [ + Comprehension { + range: 11..26, + target: Name( + ExprName { + range: 17..18, + id: "x", + ctx: Store, + }, + ), + iter: Name( + ExprName { + range: 22..26, + id: "iter", + ctx: Load, + }, + ), + ifs: [], + is_async: true, + }, + ], + parenthesized: true, + }, + ), + }, + ), + ], + }, +) +``` +## Errors + + | +1 | (async) + | ^^^^^ Syntax Error: Expected an expression +2 | (x async x in iter) + | + + + | +1 | (async) + | ^ Syntax Error: Expected 'for', found ')' +2 | (x async x in iter) + | + + + | +1 | (async) +2 | (x async x in iter) + | ^ Syntax Error: Expected 'for', found name + |