Skip to content

Commit

Permalink
Raise percent-format upgrade rule (UP031) for hanging modulos (#3953)
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh authored Apr 13, 2023
1 parent 9067ae4 commit e160a52
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 43 deletions.
23 changes: 23 additions & 0 deletions crates/ruff/resources/test/fixtures/pyupgrade/UP031_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,26 @@
print('Hello %(arg)s' % bar)
print('Hello %(arg)s' % bar.baz)
print('Hello %(arg)s' % bar['bop'])

# Hanging modulos
(
"foo %s "
"bar %s"
) % (x, y)

(
"foo %(foo)s "
"bar %(bar)s"
) % {"foo": x, "bar": y}

(
"""foo %s"""
% (x,)
)

(
"""
foo %s
"""
% (x,)
)
22 changes: 0 additions & 22 deletions crates/ruff/resources/test/fixtures/pyupgrade/UP031_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,6 @@
"%(and)s" % {"and": 2}

# OK (arguably false negatives)
(
"foo %s "
"bar %s"
) % (x, y)

(
"foo %(foo)s "
"bar %(bar)s"
) % {"foo": x, "bar": y}

(
"""foo %s"""
% (x,)
)

(
"""
foo %s
"""
% (x,)
)

'Hello %s' % bar

'Hello %s' % bar.baz
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3234,7 +3234,7 @@ where
}

if self.settings.rules.enabled(Rule::PrintfStringFormatting) {
pyupgrade::rules::printf_string_formatting(self, expr, left, right);
pyupgrade::rules::printf_string_formatting(self, expr, right);
}
if self.settings.rules.enabled(Rule::BadStringFormatType) {
pylint::rules::bad_string_format_type(self, expr, right);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,17 +296,7 @@ fn convertible(format_string: &CFormatString, params: &Expr) -> bool {
}

/// UP031
pub(crate) fn printf_string_formatting(
checker: &mut Checker,
expr: &Expr,
left: &Expr,
right: &Expr,
) {
// If the modulo symbol is on a separate line, abort.
if right.location.row() != left.end_location.unwrap().row() {
return;
}

pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right: &Expr) {
// Grab each string segment (in case there's an implicit concatenation).
let mut strings: Vec<(Location, Location)> = vec![];
let mut extension = None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ UP031_0.py:83:7: UP031 [*] Use format specifiers instead of percent format
83 |+print('Hello {arg}'.format(**bar))
84 84 | print('Hello %(arg)s' % bar.baz)
85 85 | print('Hello %(arg)s' % bar['bop'])
86 86 |

UP031_0.py:84:7: UP031 [*] Use format specifiers instead of percent format
|
Expand All @@ -768,13 +769,17 @@ UP031_0.py:84:7: UP031 [*] Use format specifiers instead of percent format
84 |-print('Hello %(arg)s' % bar.baz)
84 |+print('Hello {arg}'.format(**bar.baz))
85 85 | print('Hello %(arg)s' % bar['bop'])
86 86 |
87 87 | # Hanging modulos

UP031_0.py:85:7: UP031 [*] Use format specifiers instead of percent format
|
85 | print('Hello %(arg)s' % bar)
86 | print('Hello %(arg)s' % bar.baz)
87 | print('Hello %(arg)s' % bar['bop'])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP031
88 |
89 | # Hanging modulos
|
= help: Replace with format specifiers

Expand All @@ -784,5 +789,109 @@ UP031_0.py:85:7: UP031 [*] Use format specifiers instead of percent format
84 84 | print('Hello %(arg)s' % bar.baz)
85 |-print('Hello %(arg)s' % bar['bop'])
85 |+print('Hello {arg}'.format(**bar['bop']))
86 86 |
87 87 | # Hanging modulos
88 88 | (

UP031_0.py:88:1: UP031 [*] Use format specifiers instead of percent format
|
88 | # Hanging modulos
89 | / (
90 | | "foo %s "
91 | | "bar %s"
92 | | ) % (x, y)
| |__________^ UP031
93 |
94 | (
|
= help: Replace with format specifiers

Suggested fix
86 86 |
87 87 | # Hanging modulos
88 88 | (
89 |- "foo %s "
90 |- "bar %s"
91 |-) % (x, y)
89 |+ "foo {} "
90 |+ "bar {}"
91 |+).format(x, y)
92 92 |
93 93 | (
94 94 | "foo %(foo)s "

UP031_0.py:93:1: UP031 [*] Use format specifiers instead of percent format
|
93 | ) % (x, y)
94 |
95 | / (
96 | | "foo %(foo)s "
97 | | "bar %(bar)s"
98 | | ) % {"foo": x, "bar": y}
| |________________________^ UP031
99 |
100 | (
|
= help: Replace with format specifiers

Suggested fix
91 91 | ) % (x, y)
92 92 |
93 93 | (
94 |- "foo %(foo)s "
95 |- "bar %(bar)s"
96 |-) % {"foo": x, "bar": y}
94 |+ "foo {foo} "
95 |+ "bar {bar}"
96 |+).format(foo=x, bar=y)
97 97 |
98 98 | (
99 99 | """foo %s"""

UP031_0.py:99:5: UP031 [*] Use format specifiers instead of percent format
|
99 | (
100 | """foo %s"""
| _____^
101 | | % (x,)
| |__________^ UP031
102 | )
|
= help: Replace with format specifiers

Suggested fix
96 96 | ) % {"foo": x, "bar": y}
97 97 |
98 98 | (
99 |- """foo %s"""
100 |- % (x,)
99 |+ """foo {}""".format(x)
101 100 | )
102 101 |
103 102 | (

UP031_0.py:104:5: UP031 [*] Use format specifiers instead of percent format
|
104 | (
105 | """
| _____^
106 | | foo %s
107 | | """
108 | | % (x,)
| |__________^ UP031
109 | )
|
= help: Replace with format specifiers

Suggested fix
102 102 |
103 103 | (
104 104 | """
105 |- foo %s
106 |- """
107 |- % (x,)
105 |+ foo {}
106 |+ """.format(x)
108 107 | )


17 changes: 8 additions & 9 deletions scripts/add_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,22 @@ def main(*, name: str, prefix: str, code: str, linter: str) -> None:
# Add the relevant rule function.
with (rules_dir / f"{rule_name_snake}.rs").open("w") as fp:
fp.write(
"""\
f"""\
use ruff_diagnostics::Violation;
use ruff_macros::{derive_message_formats, violation};
use ruff_macros::{{derive_message_formats, violation}};
use crate::checkers::ast::Checker;
#[violation]
pub struct %s;
impl Violation for %s {
pub struct {name};
impl Violation for {name} {{
#[derive_message_formats]
fn message(&self) -> String {
fn message(&self) -> String {{
todo!("implement message");
format!("TODO: write message")
}
}
"""
% (name, name),
}}
}}
""",
)
fp.write(
f"""
Expand Down

0 comments on commit e160a52

Please sign in to comment.