Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pyflakes/F50x.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@
# ok: ternary/binop where one branch could be a tuple → Unknown
'%s %s' % (a if cond else b)
'%s %s' % (a + b)

# F507: zero placeholders with literal non-tuple RHS
'hello' % 42 # F507
'' % 42 # F507
'hello' % (1,) # F507
# F507: zero placeholders with variable RHS (intentional use is very unlikely)
banana = 42
'hello' % banana # F507
'' % banana # F507
'hello' % unknown_var # F507
'hello' % get_value() # F507
'hello' % obj.attr # F507
# ok: zero placeholders with empty tuple
'hello' % ()
8 changes: 8 additions & 0 deletions crates/ruff_linter/src/rules/pyflakes/rules/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,14 @@ pub(crate) fn percent_format_positional_count_mismatch(
location,
);
}
} else if summary.num_positional == 0 {
// When the format string has no placeholders, only `()` or `{}` would
// succeed at runtime. The chance that this is intentional is very low,
// so flag any RHS that isn't an empty tuple or empty dict literal.
checker.report_diagnostic(
PercentFormatPositionalCountMismatch { wanted: 0, got: 1 },
location,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
assertion_line: 192
---
F507 `%`-format string has 2 placeholder(s) but 1 substitution(s)
--> F50x.py:5:1
Expand Down Expand Up @@ -187,3 +186,90 @@ F507 `%`-format string has 2 placeholder(s) but 1 substitution(s)
43 | # ok: single placeholder with literal RHS
44 | '%s' % 42
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:57:1
|
56 | # F507: zero placeholders with literal non-tuple RHS
57 | 'hello' % 42 # F507
| ^^^^^^^^^^^^
58 | '' % 42 # F507
59 | 'hello' % (1,) # F507
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:58:1
|
56 | # F507: zero placeholders with literal non-tuple RHS
57 | 'hello' % 42 # F507
58 | '' % 42 # F507
| ^^^^^^^
59 | 'hello' % (1,) # F507
60 | # F507: zero placeholders with variable RHS (intentional use is very unlikely)
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:59:1
|
57 | 'hello' % 42 # F507
58 | '' % 42 # F507
59 | 'hello' % (1,) # F507
| ^^^^^^^^^^^^^^
60 | # F507: zero placeholders with variable RHS (intentional use is very unlikely)
61 | banana = 42
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:62:1
|
60 | # F507: zero placeholders with variable RHS (intentional use is very unlikely)
61 | banana = 42
62 | 'hello' % banana # F507
| ^^^^^^^^^^^^^^^^
63 | '' % banana # F507
64 | 'hello' % unknown_var # F507
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:63:1
|
61 | banana = 42
62 | 'hello' % banana # F507
63 | '' % banana # F507
| ^^^^^^^^^^^
64 | 'hello' % unknown_var # F507
65 | 'hello' % get_value() # F507
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:64:1
|
62 | 'hello' % banana # F507
63 | '' % banana # F507
64 | 'hello' % unknown_var # F507
| ^^^^^^^^^^^^^^^^^^^^^
65 | 'hello' % get_value() # F507
66 | 'hello' % obj.attr # F507
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:65:1
|
63 | '' % banana # F507
64 | 'hello' % unknown_var # F507
65 | 'hello' % get_value() # F507
| ^^^^^^^^^^^^^^^^^^^^^
66 | 'hello' % obj.attr # F507
67 | # ok: zero placeholders with empty tuple
|

F507 `%`-format string has 0 placeholder(s) but 1 substitution(s)
--> F50x.py:66:1
|
64 | 'hello' % unknown_var # F507
65 | 'hello' % get_value() # F507
66 | 'hello' % obj.attr # F507
| ^^^^^^^^^^^^^^^^^^
67 | # ok: zero placeholders with empty tuple
68 | 'hello' % ()
|
Loading