mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-17 22:07:42 +00:00
[syntax-errors] Limit except*
range to *
(#16473)
Summary -- This is a follow-up to #16446 to fix the diagnostic range to point to the `*` like `pyright` does (https://github.com/astral-sh/ruff/pull/16446#discussion_r1976900643). Storing the range in the `ExceptClauseKind::Star` variant feels slightly awkward, but we don't store the star itself anywhere on the `ExceptHandler`. And we can't just take `ExceptHandler.start() + "except".text_len()` because this code appears to be valid: ```python try: ... except * Error: ... ``` Test Plan -- Existing tests.
This commit is contained in:
parent
1977dda079
commit
c8a06a9be8
3 changed files with 94 additions and 16 deletions
|
@ -1,3 +1,5 @@
|
||||||
# parse_options: {"target-version": "3.10"}
|
# parse_options: {"target-version": "3.10"}
|
||||||
try: ...
|
try: ...
|
||||||
except* ValueError: ...
|
except* ValueError: ...
|
||||||
|
except* KeyError: ...
|
||||||
|
except * Error: ...
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ruff_python_ast::name::Name;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast, ExceptHandler, Expr, ExprContext, IpyEscapeKind, Operator, Stmt, WithItem,
|
self as ast, ExceptHandler, Expr, ExprContext, IpyEscapeKind, Operator, Stmt, WithItem,
|
||||||
};
|
};
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::parser::expression::{ParsedExpr, EXPR_SET};
|
use crate::parser::expression::{ParsedExpr, EXPR_SET};
|
||||||
use crate::parser::progress::ParserProgress;
|
use crate::parser::progress::ParserProgress;
|
||||||
|
@ -1377,6 +1377,9 @@ impl<'src> Parser<'src> {
|
||||||
let mut mixed_except_ranges = Vec::new();
|
let mut mixed_except_ranges = Vec::new();
|
||||||
let handlers = self.parse_clauses(Clause::Except, |p| {
|
let handlers = self.parse_clauses(Clause::Except, |p| {
|
||||||
let (handler, kind) = p.parse_except_clause();
|
let (handler, kind) = p.parse_except_clause();
|
||||||
|
if let ExceptClauseKind::Star(range) = kind {
|
||||||
|
p.add_unsupported_syntax_error(UnsupportedSyntaxErrorKind::ExceptStar, range);
|
||||||
|
}
|
||||||
if is_star.is_none() {
|
if is_star.is_none() {
|
||||||
is_star = Some(kind.is_star());
|
is_star = Some(kind.is_star());
|
||||||
} else if is_star != Some(kind.is_star()) {
|
} else if is_star != Some(kind.is_star()) {
|
||||||
|
@ -1466,11 +1469,8 @@ impl<'src> Parser<'src> {
|
||||||
// # parse_options: {"target-version": "3.10"}
|
// # parse_options: {"target-version": "3.10"}
|
||||||
// try: ...
|
// try: ...
|
||||||
// except* ValueError: ...
|
// except* ValueError: ...
|
||||||
|
// except* KeyError: ...
|
||||||
let range = self.node_range(try_start);
|
// except * Error: ...
|
||||||
if is_star {
|
|
||||||
self.add_unsupported_syntax_error(UnsupportedSyntaxErrorKind::ExceptStar, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::StmtTry {
|
ast::StmtTry {
|
||||||
body: try_body,
|
body: try_body,
|
||||||
|
@ -1478,7 +1478,7 @@ impl<'src> Parser<'src> {
|
||||||
orelse,
|
orelse,
|
||||||
finalbody,
|
finalbody,
|
||||||
is_star,
|
is_star,
|
||||||
range,
|
range: self.node_range(try_start),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,8 +1491,9 @@ impl<'src> Parser<'src> {
|
||||||
let start = self.node_start();
|
let start = self.node_start();
|
||||||
self.bump(TokenKind::Except);
|
self.bump(TokenKind::Except);
|
||||||
|
|
||||||
|
let star_token_range = self.current_token_range();
|
||||||
let block_kind = if self.eat(TokenKind::Star) {
|
let block_kind = if self.eat(TokenKind::Star) {
|
||||||
ExceptClauseKind::Star
|
ExceptClauseKind::Star(star_token_range)
|
||||||
} else {
|
} else {
|
||||||
ExceptClauseKind::Normal
|
ExceptClauseKind::Normal
|
||||||
};
|
};
|
||||||
|
@ -3650,12 +3651,14 @@ enum ExceptClauseKind {
|
||||||
/// A normal except clause e.g., `except Exception as e: ...`.
|
/// A normal except clause e.g., `except Exception as e: ...`.
|
||||||
Normal,
|
Normal,
|
||||||
/// An except clause with a star e.g., `except *: ...`.
|
/// An except clause with a star e.g., `except *: ...`.
|
||||||
Star,
|
///
|
||||||
|
/// Contains the star's [`TextRange`] for error reporting.
|
||||||
|
Star(TextRange),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExceptClauseKind {
|
impl ExceptClauseKind {
|
||||||
const fn is_star(self) -> bool {
|
const fn is_star(self) -> bool {
|
||||||
matches!(self, ExceptClauseKind::Star)
|
matches!(self, ExceptClauseKind::Star(..))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ input_file: crates/ruff_python_parser/resources/inline/err/except_star_py310.py
|
||||||
```
|
```
|
||||||
Module(
|
Module(
|
||||||
ModModule {
|
ModModule {
|
||||||
range: 0..77,
|
range: 0..126,
|
||||||
body: [
|
body: [
|
||||||
Try(
|
Try(
|
||||||
StmtTry {
|
StmtTry {
|
||||||
range: 44..76,
|
range: 44..125,
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
|
@ -52,6 +52,60 @@ Module(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ExceptHandler(
|
||||||
|
ExceptHandlerExceptHandler {
|
||||||
|
range: 77..98,
|
||||||
|
type_: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 85..93,
|
||||||
|
id: Name("KeyError"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
name: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 95..98,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 95..98,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ExceptHandler(
|
||||||
|
ExceptHandlerExceptHandler {
|
||||||
|
range: 99..125,
|
||||||
|
type_: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 115..120,
|
||||||
|
id: Name("Error"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
name: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 122..125,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 122..125,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
orelse: [],
|
orelse: [],
|
||||||
finalbody: [],
|
finalbody: [],
|
||||||
|
@ -65,8 +119,27 @@ Module(
|
||||||
## Unsupported Syntax Errors
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
|
||||||
1 | # parse_options: {"target-version": "3.10"}
|
1 | # parse_options: {"target-version": "3.10"}
|
||||||
2 | / try: ...
|
2 | try: ...
|
||||||
3 | | except* ValueError: ...
|
3 | except* ValueError: ...
|
||||||
| |_______________________^ Syntax Error: Cannot use `except*` on Python 3.10 (syntax was added in Python 3.11)
|
| ^ Syntax Error: Cannot use `except*` on Python 3.10 (syntax was added in Python 3.11)
|
||||||
|
4 | except* KeyError: ...
|
||||||
|
5 | except * Error: ...
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | try: ...
|
||||||
|
3 | except* ValueError: ...
|
||||||
|
4 | except* KeyError: ...
|
||||||
|
| ^ Syntax Error: Cannot use `except*` on Python 3.10 (syntax was added in Python 3.11)
|
||||||
|
5 | except * Error: ...
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
3 | except* ValueError: ...
|
||||||
|
4 | except* KeyError: ...
|
||||||
|
5 | except * Error: ...
|
||||||
|
| ^ Syntax Error: Cannot use `except*` on Python 3.10 (syntax was added in Python 3.11)
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue