Handle `.encode` calls on parenthesized expressions (#4338)

This commit is contained in:
Charlie Marsh 2023-05-09 22:57:10 -04:00 committed by GitHub
parent 045449ab12
commit 5e46dcbf21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 19 deletions

View File

@ -59,3 +59,14 @@ u"foo".encode("utf-8") # b"foo"
R"foo\o".encode("utf-8") # br"foo\o"
U"foo".encode("utf-8") # b"foo"
print("foo".encode()) # print(b"foo")
# `encode` on parenthesized strings.
(
"abc"
"def"
).encode()
((
"abc"
"def"
)).encode()

View File

@ -107,27 +107,27 @@ fn match_encoding_arg<'a>(args: &'a [Expr], kwargs: &'a [Keyword]) -> Option<Enc
}
/// Return a [`Fix`] replacing the call to encode with a byte string.
fn replace_with_bytes_literal(locator: &Locator, expr: &Expr, constant: &Expr) -> Fix {
fn replace_with_bytes_literal(locator: &Locator, expr: &Expr) -> Fix {
// Build up a replacement string by prefixing all string tokens with `b`.
let contents = locator.slice(constant.range());
let contents = locator.slice(expr.range());
let mut replacement = String::with_capacity(contents.len() + 1);
let mut prev = None;
for (tok, range) in lexer::lex_located(contents, Mode::Module, constant.start()).flatten() {
if matches!(tok, Tok::String { .. }) {
if let Some(prev) = prev {
let mut prev = expr.start();
for (tok, range) in lexer::lex_located(contents, Mode::Module, expr.start()).flatten() {
match tok {
Tok::Dot => break,
Tok::String { .. } => {
replacement.push_str(locator.slice(TextRange::new(prev, range.start())));
}
let string = locator.slice(range);
replacement.push_str(&format!(
"b{}",
&string.trim_start_matches('u').trim_start_matches('U')
));
} else {
if let Some(prev) = prev {
}
_ => {
replacement.push_str(locator.slice(TextRange::new(prev, range.end())));
}
}
prev = Some(range.end());
prev = range.end();
}
Fix::unspecified(Edit::range_replacement(replacement, expr.range()))
}
@ -159,11 +159,7 @@ pub fn unnecessary_encode_utf8(
expr.range(),
);
if checker.patch(Rule::UnnecessaryEncodeUTF8) {
diagnostic.set_fix(replace_with_bytes_literal(
checker.locator,
expr,
variable,
));
diagnostic.set_fix(replace_with_bytes_literal(checker.locator, expr));
}
checker.diagnostics.push(diagnostic);
} else if let EncodingArg::Keyword(kwarg) = encoding_arg {

View File

@ -373,6 +373,7 @@ UP012.py:59:1: UP012 [*] Unnecessary call to `encode` as UTF-8
59 |+bR"foo\o" # br"foo\o"
60 60 | U"foo".encode("utf-8") # b"foo"
61 61 | print("foo".encode()) # print(b"foo")
62 62 |
UP012.py:60:1: UP012 [*] Unnecessary call to `encode` as UTF-8
|
@ -391,6 +392,8 @@ UP012.py:60:1: UP012 [*] Unnecessary call to `encode` as UTF-8
60 |-U"foo".encode("utf-8") # b"foo"
60 |+b"foo" # b"foo"
61 61 | print("foo".encode()) # print(b"foo")
62 62 |
63 63 | # `encode` on parenthesized strings.
UP012.py:61:7: UP012 [*] Unnecessary call to `encode` as UTF-8
|
@ -398,6 +401,8 @@ UP012.py:61:7: UP012 [*] Unnecessary call to `encode` as UTF-8
62 | U"foo".encode("utf-8") # b"foo"
63 | print("foo".encode()) # print(b"foo")
| ^^^^^^^^^^^^^^ UP012
64 |
65 | # `encode` on parenthesized strings.
|
= help: Rewrite as bytes literal
@ -407,5 +412,58 @@ UP012.py:61:7: UP012 [*] Unnecessary call to `encode` as UTF-8
60 60 | U"foo".encode("utf-8") # b"foo"
61 |-print("foo".encode()) # print(b"foo")
61 |+print(b"foo") # print(b"foo")
62 62 |
63 63 | # `encode` on parenthesized strings.
64 64 | (
UP012.py:64:1: UP012 [*] Unnecessary call to `encode` as UTF-8
|
64 | # `encode` on parenthesized strings.
65 | / (
66 | | "abc"
67 | | "def"
68 | | ).encode()
| |__________^ UP012
69 |
70 | ((
|
= help: Rewrite as bytes literal
Suggested fix
62 62 |
63 63 | # `encode` on parenthesized strings.
64 64 | (
65 |- "abc"
66 |- "def"
67 |-).encode()
65 |+ b"abc"
66 |+ b"def"
67 |+)
68 68 |
69 69 | ((
70 70 | "abc"
UP012.py:69:1: UP012 [*] Unnecessary call to `encode` as UTF-8
|
69 | ).encode()
70 |
71 | / ((
72 | | "abc"
73 | | "def"
74 | | )).encode()
| |___________^ UP012
|
= help: Rewrite as bytes literal
Suggested fix
67 67 | ).encode()
68 68 |
69 69 | ((
70 |- "abc"
71 |- "def"
72 |-)).encode()
70 |+ b"abc"
71 |+ b"def"
72 |+))