Skip to content

Commit

Permalink
Avoid panics for f-string rewrites at start-of-file (#4291)
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh authored May 8, 2023
1 parent b913e99 commit c54e48d
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 31 deletions.
1 change: 1 addition & 0 deletions crates/ruff/resources/test/fixtures/pyupgrade/UP032_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"{} {}".format(a, b) # Intentionally at start-of-file, to ensure graceful handling.
3 changes: 2 additions & 1 deletion crates/ruff/src/rules/pyupgrade/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ mod tests {
#[test_case(Rule::FormatLiterals, Path::new("UP030_2.py"); "UP030_2")]
#[test_case(Rule::PrintfStringFormatting, Path::new("UP031_0.py"); "UP031_0")]
#[test_case(Rule::PrintfStringFormatting, Path::new("UP031_1.py"); "UP031_1")]
#[test_case(Rule::FString, Path::new("UP032.py"); "UP032")]
#[test_case(Rule::FString, Path::new("UP032_0.py"); "UP032_0")]
#[test_case(Rule::FString, Path::new("UP032_1.py"); "UP032_1")]
#[test_case(Rule::LRUCacheWithMaxsizeNone, Path::new("UP033_0.py"); "UP033_0")]
#[test_case(Rule::LRUCacheWithMaxsizeNone, Path::new("UP033_1.py"); "UP033_1")]
#[test_case(Rule::ExtraneousParentheses, Path::new("UP034.py"); "UP034")]
Expand Down
6 changes: 5 additions & 1 deletion crates/ruff/src/rules/pyupgrade/rules/f_strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,11 @@ pub(crate) fn f_strings(checker: &mut Checker, summary: &FormatSummary, expr: &E
// If necessary, add a space between any leading keyword (`return`, `yield`, `assert`, etc.)
// and the string. For example, `return"foo"` is valid, but `returnf"foo"` is not.
let existing = checker.locator.slice(TextRange::up_to(expr.start()));
if existing.chars().last().unwrap().is_ascii_alphabetic() {
if existing
.chars()
.last()
.map_or(false, |char| char.is_ascii_alphabetic())
{
contents.insert(0, ' ');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
source: crates/ruff/src/rules/pyupgrade/mod.rs
---
UP032.py:5:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:5:1: UP032 [*] Use f-string instead of `format` call
|
5 | ###
6 |
Expand All @@ -22,7 +22,7 @@ UP032.py:5:1: UP032 [*] Use f-string instead of `format` call
7 7 | "{1} {0}".format(a, b)
8 8 |

UP032.py:7:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:7:1: UP032 [*] Use f-string instead of `format` call
|
7 | "{} {}".format(a, b)
8 |
Expand All @@ -43,7 +43,7 @@ UP032.py:7:1: UP032 [*] Use f-string instead of `format` call
9 9 | "{x.y}".format(x=z)
10 10 |

UP032.py:9:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:9:1: UP032 [*] Use f-string instead of `format` call
|
9 | "{1} {0}".format(a, b)
10 |
Expand All @@ -64,7 +64,7 @@ UP032.py:9:1: UP032 [*] Use f-string instead of `format` call
11 11 | "{.x} {.y}".format(a, b)
12 12 |

UP032.py:11:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:11:1: UP032 [*] Use f-string instead of `format` call
|
11 | "{x.y}".format(x=z)
12 |
Expand All @@ -85,7 +85,7 @@ UP032.py:11:1: UP032 [*] Use f-string instead of `format` call
13 13 | "{} {}".format(a.b, c.d)
14 14 |

UP032.py:13:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:13:1: UP032 [*] Use f-string instead of `format` call
|
13 | "{.x} {.y}".format(a, b)
14 |
Expand All @@ -106,7 +106,7 @@ UP032.py:13:1: UP032 [*] Use f-string instead of `format` call
15 15 | "{}".format(a())
16 16 |

UP032.py:15:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:15:1: UP032 [*] Use f-string instead of `format` call
|
15 | "{} {}".format(a.b, c.d)
16 |
Expand All @@ -127,7 +127,7 @@ UP032.py:15:1: UP032 [*] Use f-string instead of `format` call
17 17 | "{}".format(a.b())
18 18 |

UP032.py:17:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:17:1: UP032 [*] Use f-string instead of `format` call
|
17 | "{}".format(a())
18 |
Expand All @@ -148,7 +148,7 @@ UP032.py:17:1: UP032 [*] Use f-string instead of `format` call
19 19 | "{}".format(a.b().c())
20 20 |

UP032.py:19:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:19:1: UP032 [*] Use f-string instead of `format` call
|
19 | "{}".format(a.b())
20 |
Expand All @@ -169,7 +169,7 @@ UP032.py:19:1: UP032 [*] Use f-string instead of `format` call
21 21 | "hello {}!".format(name)
22 22 |

UP032.py:21:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:21:1: UP032 [*] Use f-string instead of `format` call
|
21 | "{}".format(a.b().c())
22 |
Expand All @@ -190,7 +190,7 @@ UP032.py:21:1: UP032 [*] Use f-string instead of `format` call
23 23 | "{}{b}{}".format(a, c, b=b)
24 24 |

UP032.py:23:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:23:1: UP032 [*] Use f-string instead of `format` call
|
23 | "hello {}!".format(name)
24 |
Expand All @@ -211,7 +211,7 @@ UP032.py:23:1: UP032 [*] Use f-string instead of `format` call
25 25 | "{}".format(0x0)
26 26 |

UP032.py:25:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:25:1: UP032 [*] Use f-string instead of `format` call
|
25 | "{}{b}{}".format(a, c, b=b)
26 |
Expand All @@ -232,7 +232,7 @@ UP032.py:25:1: UP032 [*] Use f-string instead of `format` call
27 27 | "{} {}".format(a, b)
28 28 |

UP032.py:27:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:27:1: UP032 [*] Use f-string instead of `format` call
|
27 | "{}".format(0x0)
28 |
Expand All @@ -253,7 +253,7 @@ UP032.py:27:1: UP032 [*] Use f-string instead of `format` call
29 29 | """{} {}""".format(a, b)
30 30 |

UP032.py:29:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:29:1: UP032 [*] Use f-string instead of `format` call
|
29 | "{} {}".format(a, b)
30 |
Expand All @@ -274,7 +274,7 @@ UP032.py:29:1: UP032 [*] Use f-string instead of `format` call
31 31 | "foo{}".format(1)
32 32 |

UP032.py:31:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:31:1: UP032 [*] Use f-string instead of `format` call
|
31 | """{} {}""".format(a, b)
32 |
Expand All @@ -295,7 +295,7 @@ UP032.py:31:1: UP032 [*] Use f-string instead of `format` call
33 33 | r"foo{}".format(1)
34 34 |

UP032.py:33:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:33:1: UP032 [*] Use f-string instead of `format` call
|
33 | "foo{}".format(1)
34 |
Expand All @@ -316,7 +316,7 @@ UP032.py:33:1: UP032 [*] Use f-string instead of `format` call
35 35 | x = "{a}".format(a=1)
36 36 |

UP032.py:35:5: UP032 [*] Use f-string instead of `format` call
UP032_0.py:35:5: UP032 [*] Use f-string instead of `format` call
|
35 | r"foo{}".format(1)
36 |
Expand All @@ -337,7 +337,7 @@ UP032.py:35:5: UP032 [*] Use f-string instead of `format` call
37 37 | print("foo {} ".format(x))
38 38 |

UP032.py:37:7: UP032 [*] Use f-string instead of `format` call
UP032_0.py:37:7: UP032 [*] Use f-string instead of `format` call
|
37 | x = "{a}".format(a=1)
38 |
Expand All @@ -358,7 +358,7 @@ UP032.py:37:7: UP032 [*] Use f-string instead of `format` call
39 39 | "{a[b]}".format(a=a)
40 40 |

UP032.py:39:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:39:1: UP032 [*] Use f-string instead of `format` call
|
39 | print("foo {} ".format(x))
40 |
Expand All @@ -379,7 +379,7 @@ UP032.py:39:1: UP032 [*] Use f-string instead of `format` call
41 41 | "{a.a[b]}".format(a=a)
42 42 |

UP032.py:41:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:41:1: UP032 [*] Use f-string instead of `format` call
|
41 | "{a[b]}".format(a=a)
42 |
Expand All @@ -400,7 +400,7 @@ UP032.py:41:1: UP032 [*] Use f-string instead of `format` call
43 43 | "{}{{}}{}".format(escaped, y)
44 44 |

UP032.py:43:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:43:1: UP032 [*] Use f-string instead of `format` call
|
43 | "{a.a[b]}".format(a=a)
44 |
Expand All @@ -421,7 +421,7 @@ UP032.py:43:1: UP032 [*] Use f-string instead of `format` call
45 45 | "{}".format(a)
46 46 |

UP032.py:45:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:45:1: UP032 [*] Use f-string instead of `format` call
|
45 | "{}{{}}{}".format(escaped, y)
46 |
Expand All @@ -442,7 +442,7 @@ UP032.py:45:1: UP032 [*] Use f-string instead of `format` call
47 47 | '({}={{0!e}})'.format(a)
48 48 |

UP032.py:47:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:47:1: UP032 [*] Use f-string instead of `format` call
|
47 | "{}".format(a)
48 |
Expand All @@ -463,7 +463,7 @@ UP032.py:47:1: UP032 [*] Use f-string instead of `format` call
49 49 | "{[b]}".format(a)
50 50 |

UP032.py:49:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:49:1: UP032 [*] Use f-string instead of `format` call
|
49 | '({}={{0!e}})'.format(a)
50 |
Expand All @@ -484,7 +484,7 @@ UP032.py:49:1: UP032 [*] Use f-string instead of `format` call
51 51 | '{[b]}'.format(a)
52 52 |

UP032.py:51:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:51:1: UP032 [*] Use f-string instead of `format` call
|
51 | "{[b]}".format(a)
52 |
Expand All @@ -505,7 +505,7 @@ UP032.py:51:1: UP032 [*] Use f-string instead of `format` call
53 53 | """{[b]}""".format(a)
54 54 |

UP032.py:53:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:53:1: UP032 [*] Use f-string instead of `format` call
|
53 | '{[b]}'.format(a)
54 |
Expand All @@ -526,7 +526,7 @@ UP032.py:53:1: UP032 [*] Use f-string instead of `format` call
55 55 | '''{[b]}'''.format(a)
56 56 |

UP032.py:55:1: UP032 [*] Use f-string instead of `format` call
UP032_0.py:55:1: UP032 [*] Use f-string instead of `format` call
|
55 | """{[b]}""".format(a)
56 |
Expand All @@ -547,7 +547,7 @@ UP032.py:55:1: UP032 [*] Use f-string instead of `format` call
57 57 | ###
58 58 | # Non-errors

UP032.py:100:11: UP032 [*] Use f-string instead of `format` call
UP032_0.py:100:11: UP032 [*] Use f-string instead of `format` call
|
100 | def d(osname, version, release):
101 | return"{}-{}.{}".format(osname, version, release)
Expand All @@ -565,7 +565,7 @@ UP032.py:100:11: UP032 [*] Use f-string instead of `format` call
102 102 |
103 103 | def e():

UP032.py:104:10: UP032 [*] Use f-string instead of `format` call
UP032_0.py:104:10: UP032 [*] Use f-string instead of `format` call
|
104 | def e():
105 | yield"{}".format(1)
Expand All @@ -583,7 +583,7 @@ UP032.py:104:10: UP032 [*] Use f-string instead of `format` call
106 106 |
107 107 | assert"{}".format(1)

UP032.py:107:7: UP032 [*] Use f-string instead of `format` call
UP032_0.py:107:7: UP032 [*] Use f-string instead of `format` call
|
107 | assert"{}".format(1)
| ^^^^^^^^^^^^^^ UP032
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: crates/ruff/src/rules/pyupgrade/mod.rs
---
UP032_1.py:1:1: UP032 [*] Use f-string instead of `format` call
|
1 | "{} {}".format(a, b) # Intentionally at start-of-file, to ensure graceful handling.
| ^^^^^^^^^^^^^^^^^^^^ UP032
|
= help: Convert to f-string

Suggested fix
1 |-"{} {}".format(a, b) # Intentionally at start-of-file, to ensure graceful handling.
1 |+f"{a} {b}" # Intentionally at start-of-file, to ensure graceful handling.


0 comments on commit c54e48d

Please sign in to comment.