mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-19 02:55:20 +00:00
Disallow f-strings in match pattern literal (#7857)
## Summary This PR fixes a bug to disallow f-strings in match pattern literal. ``` literal_pattern ::= signed_number | signed_number "+" NUMBER | signed_number "-" NUMBER | strings | "None" | "True" | "False" | signed_number: NUMBER | "-" NUMBER ``` Source: https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-literal_pattern Also, ```console $ python /tmp/t.py File "/tmp/t.py", line 4 case "hello " f"{name}": ^^^^^^^^^^^^^^^^^^ SyntaxError: patterns may only match literals and attribute lookups ``` ## Test Plan Update existing test case and accordingly the snapshots. Also, add a new test case to verify that the parser does raise an error.
This commit is contained in:
parent
38f512d588
commit
43883b7a15
4 changed files with 13901 additions and 13810 deletions
|
@ -1143,6 +1143,24 @@ match x:
|
|||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_match_pattern_fstring_literal() {
|
||||
// F-string literal is not allowed in match pattern.
|
||||
let parse_error = parse_suite(
|
||||
r#"
|
||||
match x:
|
||||
case f"{y}":
|
||||
pass
|
||||
"#,
|
||||
"<test>",
|
||||
)
|
||||
.err();
|
||||
assert!(
|
||||
parse_error.is_some(),
|
||||
"expected parse error when f-string literal is used in match pattern"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_variadic_generics() {
|
||||
let parse_ast = parse_suite(
|
||||
|
@ -1285,7 +1303,9 @@ f'{f"{3.1415=:.1f}":*^20}'
|
|||
|
||||
{"foo " f"bar {x + y} " "baz": 10}
|
||||
match foo:
|
||||
case "foo " f"bar {x + y} " "baz":
|
||||
case "one":
|
||||
pass
|
||||
case "implicitly " "concatenated":
|
||||
pass
|
||||
|
||||
f"\{foo}\{bar:\}"
|
||||
|
|
|
@ -668,7 +668,7 @@ LiteralPattern: ast::Pattern = {
|
|||
value: Box::new(value.into()),
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
<location:@L> <strings:StringLiteralOrFString+> <end_location:@R> =>? Ok(ast::PatternMatchValue {
|
||||
<location:@L> <strings:StringLiteral+> <end_location:@R> =>? Ok(ast::PatternMatchValue {
|
||||
value: Box::new(concatenate_strings(strings, (location..end_location).into())?),
|
||||
range: (location..end_location).into()
|
||||
}.into()),
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -644,7 +644,7 @@ expression: parse_ast
|
|||
),
|
||||
Match(
|
||||
StmtMatch {
|
||||
range: 207..269,
|
||||
range: 207..298,
|
||||
subject: Name(
|
||||
ExprName {
|
||||
range: 213..216,
|
||||
|
@ -654,68 +654,20 @@ expression: parse_ast
|
|||
),
|
||||
cases: [
|
||||
MatchCase {
|
||||
range: 222..269,
|
||||
range: 222..246,
|
||||
pattern: MatchValue(
|
||||
PatternMatchValue {
|
||||
range: 227..255,
|
||||
value: FString(
|
||||
ExprFString {
|
||||
range: 227..255,
|
||||
values: [
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 228..240,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "foo bar ",
|
||||
unicode: false,
|
||||
implicit_concatenated: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
FormattedValue(
|
||||
ExprFormattedValue {
|
||||
range: 240..247,
|
||||
value: BinOp(
|
||||
ExprBinOp {
|
||||
range: 241..246,
|
||||
left: Name(
|
||||
ExprName {
|
||||
range: 241..242,
|
||||
id: "x",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
op: Add,
|
||||
right: Name(
|
||||
ExprName {
|
||||
range: 245..246,
|
||||
id: "y",
|
||||
ctx: Load,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
debug_text: None,
|
||||
conversion: None,
|
||||
format_spec: None,
|
||||
},
|
||||
),
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 247..254,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: " baz",
|
||||
unicode: false,
|
||||
implicit_concatenated: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
implicit_concatenated: true,
|
||||
range: 227..232,
|
||||
value: Constant(
|
||||
ExprConstant {
|
||||
range: 227..232,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "one",
|
||||
unicode: false,
|
||||
implicit_concatenated: false,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
@ -724,7 +676,35 @@ expression: parse_ast
|
|||
body: [
|
||||
Pass(
|
||||
StmtPass {
|
||||
range: 265..269,
|
||||
range: 242..246,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
MatchCase {
|
||||
range: 251..298,
|
||||
pattern: MatchValue(
|
||||
PatternMatchValue {
|
||||
range: 256..284,
|
||||
value: Constant(
|
||||
ExprConstant {
|
||||
range: 256..284,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "implicitly concatenated",
|
||||
unicode: false,
|
||||
implicit_concatenated: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
guard: None,
|
||||
body: [
|
||||
Pass(
|
||||
StmtPass {
|
||||
range: 294..298,
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -734,14 +714,14 @@ expression: parse_ast
|
|||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 271..288,
|
||||
range: 300..317,
|
||||
value: FString(
|
||||
ExprFString {
|
||||
range: 271..288,
|
||||
range: 300..317,
|
||||
values: [
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 273..274,
|
||||
range: 302..303,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "\\",
|
||||
|
@ -753,10 +733,10 @@ expression: parse_ast
|
|||
),
|
||||
FormattedValue(
|
||||
ExprFormattedValue {
|
||||
range: 274..279,
|
||||
range: 303..308,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 275..278,
|
||||
range: 304..307,
|
||||
id: "foo",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -768,7 +748,7 @@ expression: parse_ast
|
|||
),
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 279..280,
|
||||
range: 308..309,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "\\",
|
||||
|
@ -780,10 +760,10 @@ expression: parse_ast
|
|||
),
|
||||
FormattedValue(
|
||||
ExprFormattedValue {
|
||||
range: 280..287,
|
||||
range: 309..316,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 281..284,
|
||||
range: 310..313,
|
||||
id: "bar",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -793,11 +773,11 @@ expression: parse_ast
|
|||
format_spec: Some(
|
||||
FString(
|
||||
ExprFString {
|
||||
range: 285..286,
|
||||
range: 314..315,
|
||||
values: [
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 285..286,
|
||||
range: 314..315,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "\\",
|
||||
|
@ -822,14 +802,14 @@ expression: parse_ast
|
|||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 289..303,
|
||||
range: 318..332,
|
||||
value: FString(
|
||||
ExprFString {
|
||||
range: 289..303,
|
||||
range: 318..332,
|
||||
values: [
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 291..302,
|
||||
range: 320..331,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "\\{foo\\}",
|
||||
|
@ -847,17 +827,17 @@ expression: parse_ast
|
|||
),
|
||||
Expr(
|
||||
StmtExpr {
|
||||
range: 304..344,
|
||||
range: 333..373,
|
||||
value: FString(
|
||||
ExprFString {
|
||||
range: 304..344,
|
||||
range: 333..373,
|
||||
values: [
|
||||
FormattedValue(
|
||||
ExprFormattedValue {
|
||||
range: 308..341,
|
||||
range: 337..370,
|
||||
value: Name(
|
||||
ExprName {
|
||||
range: 314..317,
|
||||
range: 343..346,
|
||||
id: "foo",
|
||||
ctx: Load,
|
||||
},
|
||||
|
@ -867,11 +847,11 @@ expression: parse_ast
|
|||
format_spec: Some(
|
||||
FString(
|
||||
ExprFString {
|
||||
range: 318..340,
|
||||
range: 347..369,
|
||||
values: [
|
||||
Constant(
|
||||
ExprConstant {
|
||||
range: 318..340,
|
||||
range: 347..369,
|
||||
value: Str(
|
||||
StringConstant {
|
||||
value: "x\n y\n z\n",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue