[ruff] Fix syntax error introduced for an empty string followed by a u-prefixed string (UP025) (#18899)

## Summary
/closes #18895
## Test Plan

---------

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
Илья Любавский 2025-07-01 16:34:08 +03:00 committed by GitHub
parent dac4e356eb
commit 667dc62038
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 111 additions and 5 deletions

View file

@ -26,3 +26,9 @@ def hello():
f"foo"u"bar" # OK
f"foo" u"bar" # OK
# https://github.com/astral-sh/ruff/issues/18895
""u""
""u"hi"
""""""""""""""""""""u"hi"
""U"helloooo"

View file

@ -42,9 +42,28 @@ impl AlwaysFixableViolation for UnicodeKindPrefix {
pub(crate) fn unicode_kind_prefix(checker: &Checker, string: &StringLiteral) {
if string.flags.prefix().is_unicode() {
let mut diagnostic = checker.report_diagnostic(UnicodeKindPrefix, string.range);
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at(
string.start(),
TextSize::from(1),
))));
let prefix_range = TextRange::at(string.start(), TextSize::new(1));
let locator = checker.locator();
let content = locator
.slice(TextRange::new(prefix_range.end(), string.end()))
.to_owned();
// If the preceding character is equivalent to the quote character, insert a space to avoid a
// syntax error. For example, when removing the `u` prefix in `""u""`, rewrite to `"" ""`
// instead of `""""`.
// see https://github.com/astral-sh/ruff/issues/18895
let edit = if locator
.slice(TextRange::up_to(prefix_range.start()))
.chars()
.last()
.is_some_and(|char| content.starts_with(char))
{
Edit::range_replacement(" ".to_string(), prefix_range)
} else {
Edit::range_deletion(prefix_range)
};
diagnostic.set_fix(Fix::safe_edit(edit));
}
}

View file

@ -281,14 +281,18 @@ UP025.py:27:7: UP025 [*] Remove unicode literals from strings
25 25 | return"Hello" # OK
26 26 |
27 |-f"foo"u"bar" # OK
27 |+f"foo""bar" # OK
27 |+f"foo" "bar" # OK
28 28 | f"foo" u"bar" # OK
29 29 |
30 30 | # https://github.com/astral-sh/ruff/issues/18895
UP025.py:28:8: UP025 [*] Remove unicode literals from strings
|
27 | f"foo"u"bar" # OK
28 | f"foo" u"bar" # OK
| ^^^^^^ UP025
29 |
30 | # https://github.com/astral-sh/ruff/issues/18895
|
= help: Remove unicode prefix
@ -298,3 +302,80 @@ UP025.py:28:8: UP025 [*] Remove unicode literals from strings
27 27 | f"foo"u"bar" # OK
28 |-f"foo" u"bar" # OK
28 |+f"foo" "bar" # OK
29 29 |
30 30 | # https://github.com/astral-sh/ruff/issues/18895
31 31 | ""u""
UP025.py:31:3: UP025 [*] Remove unicode literals from strings
|
30 | # https://github.com/astral-sh/ruff/issues/18895
31 | ""u""
| ^^^ UP025
32 | ""u"hi"
33 | """"""""""""""""""""u"hi"
|
= help: Remove unicode prefix
Safe fix
28 28 | f"foo" u"bar" # OK
29 29 |
30 30 | # https://github.com/astral-sh/ruff/issues/18895
31 |-""u""
31 |+"" ""
32 32 | ""u"hi"
33 33 | """"""""""""""""""""u"hi"
34 34 | ""U"helloooo"
UP025.py:32:3: UP025 [*] Remove unicode literals from strings
|
30 | # https://github.com/astral-sh/ruff/issues/18895
31 | ""u""
32 | ""u"hi"
| ^^^^^ UP025
33 | """"""""""""""""""""u"hi"
34 | ""U"helloooo"
|
= help: Remove unicode prefix
Safe fix
29 29 |
30 30 | # https://github.com/astral-sh/ruff/issues/18895
31 31 | ""u""
32 |-""u"hi"
32 |+"" "hi"
33 33 | """"""""""""""""""""u"hi"
34 34 | ""U"helloooo"
UP025.py:33:21: UP025 [*] Remove unicode literals from strings
|
31 | ""u""
32 | ""u"hi"
33 | """"""""""""""""""""u"hi"
| ^^^^^ UP025
34 | ""U"helloooo"
|
= help: Remove unicode prefix
Safe fix
30 30 | # https://github.com/astral-sh/ruff/issues/18895
31 31 | ""u""
32 32 | ""u"hi"
33 |-""""""""""""""""""""u"hi"
33 |+"""""""""""""""""""" "hi"
34 34 | ""U"helloooo"
UP025.py:34:3: UP025 [*] Remove unicode literals from strings
|
32 | ""u"hi"
33 | """"""""""""""""""""u"hi"
34 | ""U"helloooo"
| ^^^^^^^^^^^ UP025
|
= help: Remove unicode prefix
Safe fix
31 31 | ""u""
32 32 | ""u"hi"
33 33 | """"""""""""""""""""u"hi"
34 |-""U"helloooo"
34 |+"" "helloooo"