mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-17 03:18:38 +00:00
Merge 25f753bd9e into 665f68036c
This commit is contained in:
commit
28aaaed2c2
4 changed files with 127 additions and 2 deletions
|
|
@ -64,3 +64,12 @@ import logging
|
|||
|
||||
x = 1
|
||||
logging.error(f"{x} -> %s", x)
|
||||
|
||||
# Test cases for control characters in f-strings
|
||||
bar = "bar"
|
||||
logging.getLogger().error(f"Lorem ipsum \n {bar}")
|
||||
|
||||
value = "test"
|
||||
logging.info(f"Tab\t{value}")
|
||||
|
||||
logging.info(f"CR\r{value}")
|
||||
|
|
|
|||
|
|
@ -14,6 +14,26 @@ use crate::rules::flake8_logging_format::violations::{
|
|||
};
|
||||
use crate::{Edit, Fix};
|
||||
|
||||
/// Escape control characters and quotes for use in a Python string literal.
|
||||
/// Escapes newlines, tabs, carriage returns, backslashes, and quotes that match the quote style.
|
||||
fn escape_string_for_literal(text: &str, quote_char: char) -> String {
|
||||
let mut escaped = String::with_capacity(text.len() * 2);
|
||||
for ch in text.chars() {
|
||||
match ch {
|
||||
'\n' => escaped.push_str("\\n"),
|
||||
'\t' => escaped.push_str("\\t"),
|
||||
'\r' => escaped.push_str("\\r"),
|
||||
'\\' => escaped.push_str("\\\\"),
|
||||
ch if ch == quote_char => {
|
||||
escaped.push('\\');
|
||||
escaped.push(ch);
|
||||
}
|
||||
_ => escaped.push(ch),
|
||||
}
|
||||
}
|
||||
escaped
|
||||
}
|
||||
|
||||
fn logging_f_string(
|
||||
checker: &Checker,
|
||||
msg: &Expr,
|
||||
|
|
@ -50,6 +70,9 @@ fn logging_f_string(
|
|||
.next()
|
||||
.unwrap_or("\"");
|
||||
|
||||
// Extract the quote character for escaping
|
||||
let quote_char = quote_str.chars().next().unwrap_or('"');
|
||||
|
||||
for part in &f_string.value {
|
||||
match part {
|
||||
ast::FStringPart::Literal(literal) => {
|
||||
|
|
@ -57,7 +80,7 @@ fn logging_f_string(
|
|||
if literal_text.contains('%') {
|
||||
return;
|
||||
}
|
||||
format_string.push_str(literal_text);
|
||||
format_string.push_str(&escape_string_for_literal(literal_text, quote_char));
|
||||
}
|
||||
ast::FStringPart::FString(f) => {
|
||||
for element in &f.elements {
|
||||
|
|
@ -69,7 +92,10 @@ fn logging_f_string(
|
|||
if lit.value.as_ref().contains('%') {
|
||||
return;
|
||||
}
|
||||
format_string.push_str(lit.value.as_ref());
|
||||
format_string.push_str(&escape_string_for_literal(
|
||||
lit.value.as_ref(),
|
||||
quote_char,
|
||||
));
|
||||
}
|
||||
InterpolatedStringElement::Interpolation(interpolated) => {
|
||||
if interpolated.format_spec.is_some()
|
||||
|
|
|
|||
|
|
@ -217,5 +217,40 @@ G004 Logging statement uses f-string
|
|||
65 | x = 1
|
||||
66 | logging.error(f"{x} -> %s", x)
|
||||
| ^^^^^^^^^^^^
|
||||
67 |
|
||||
68 | # Test cases for control characters in f-strings
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
|
||||
G004 Logging statement uses f-string
|
||||
--> G004.py:70:27
|
||||
|
|
||||
68 | # Test cases for control characters in f-strings
|
||||
69 | bar = "bar"
|
||||
70 | logging.getLogger().error(f"Lorem ipsum \n {bar}")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
71 |
|
||||
72 | value = "test"
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
|
||||
G004 Logging statement uses f-string
|
||||
--> G004.py:73:14
|
||||
|
|
||||
72 | value = "test"
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
| ^^^^^^^^^^^^^^^
|
||||
74 |
|
||||
75 | logging.info(f"CR\r{value}")
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
|
||||
G004 Logging statement uses f-string
|
||||
--> G004.py:75:14
|
||||
|
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
74 |
|
||||
75 | logging.info(f"CR\r{value}")
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
|
|
|
|||
|
|
@ -273,5 +273,60 @@ G004 Logging statement uses f-string
|
|||
65 | x = 1
|
||||
66 | logging.error(f"{x} -> %s", x)
|
||||
| ^^^^^^^^^^^^
|
||||
67 |
|
||||
68 | # Test cases for control characters in f-strings
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
|
||||
G004 [*] Logging statement uses f-string
|
||||
--> G004.py:70:27
|
||||
|
|
||||
68 | # Test cases for control characters in f-strings
|
||||
69 | bar = "bar"
|
||||
70 | logging.getLogger().error(f"Lorem ipsum \n {bar}")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
71 |
|
||||
72 | value = "test"
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
67 |
|
||||
68 | # Test cases for control characters in f-strings
|
||||
69 | bar = "bar"
|
||||
- logging.getLogger().error(f"Lorem ipsum \n {bar}")
|
||||
70 + logging.getLogger().error("Lorem ipsum \n %s", bar)
|
||||
71 |
|
||||
72 | value = "test"
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
|
||||
G004 [*] Logging statement uses f-string
|
||||
--> G004.py:73:14
|
||||
|
|
||||
72 | value = "test"
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
| ^^^^^^^^^^^^^^^
|
||||
74 |
|
||||
75 | logging.info(f"CR\r{value}")
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
70 | logging.getLogger().error(f"Lorem ipsum \n {bar}")
|
||||
71 |
|
||||
72 | value = "test"
|
||||
- logging.info(f"Tab\t{value}")
|
||||
73 + logging.info("Tab\t%s", value)
|
||||
74 |
|
||||
75 | logging.info(f"CR\r{value}")
|
||||
|
||||
G004 [*] Logging statement uses f-string
|
||||
--> G004.py:75:14
|
||||
|
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
74 |
|
||||
75 | logging.info(f"CR\r{value}")
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: Convert to lazy `%` formatting
|
||||
72 | value = "test"
|
||||
73 | logging.info(f"Tab\t{value}")
|
||||
74 |
|
||||
- logging.info(f"CR\r{value}")
|
||||
75 + logging.info("CR\r%s", value)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue