Skip to content

Commit 44d42b5

Browse files
committed
Use colon rather than dot formatting for integer-only types
1 parent 1fe4a5f commit 44d42b5

File tree

3 files changed

+120
-2
lines changed

3 files changed

+120
-2
lines changed

crates/ruff_linter/resources/test/fixtures/pyupgrade/UP031_0.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,10 @@
129129
# Not a valid type annotation but this test shouldn't result in a panic.
130130
# Refer: https://github.com/astral-sh/ruff/issues/11736
131131
x: "'%s + %s' % (1, 2)"
132+
133+
# See: https://github.com/astral-sh/ruff/issues/12421
134+
print("%.2X" % 1)
135+
print("%.02X" % 1)
136+
print("%02X" % 1)
137+
print("%.00002X" % 1)
138+
print("%.20X" % 1)

crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,19 @@ fn handle_part(part: &CFormatPart<String>) -> Cow<'_, str> {
150150
match precision {
151151
CFormatPrecision::Quantity(quantity) => match quantity {
152152
CFormatQuantity::Amount(amount) => {
153-
format_string.push('.');
154-
format_string.push_str(&amount.to_string());
153+
// Integer-only presentation types.
154+
//
155+
// See: https://docs.python.org/3/library/string.html#format-specification-mini-language
156+
if matches!(
157+
spec.format_char,
158+
'b' | 'c' | 'd' | 'o' | 'x' | 'X' | 'n'
159+
) {
160+
format_string.push('0');
161+
format_string.push_str(&amount.to_string());
162+
} else {
163+
format_string.push('.');
164+
format_string.push_str(&amount.to_string());
165+
}
155166
}
156167
CFormatQuantity::FromValuesTuple => {
157168
unreachable!("Width should be a usize")

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP031_0.py.snap

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,8 @@ UP031_0.py:131:5: UP031 [*] Use format specifiers instead of percent format
10071007
130 | # Refer: https://github.com/astral-sh/ruff/issues/11736
10081008
131 | x: "'%s + %s' % (1, 2)"
10091009
| ^^^^^^^^^^^^^^^^^^ UP031
1010+
132 |
1011+
133 | # See: https://github.com/astral-sh/ruff/issues/12421
10101012
|
10111013
= help: Replace with format specifiers
10121014

@@ -1016,3 +1018,101 @@ UP031_0.py:131:5: UP031 [*] Use format specifiers instead of percent format
10161018
130 130 | # Refer: https://github.com/astral-sh/ruff/issues/11736
10171019
131 |-x: "'%s + %s' % (1, 2)"
10181020
131 |+x: "'{} + {}'.format(1, 2)"
1021+
132 132 |
1022+
133 133 | # See: https://github.com/astral-sh/ruff/issues/12421
1023+
134 134 | print("%.2X" % 1)
1024+
1025+
UP031_0.py:134:7: UP031 [*] Use format specifiers instead of percent format
1026+
|
1027+
133 | # See: https://github.com/astral-sh/ruff/issues/12421
1028+
134 | print("%.2X" % 1)
1029+
| ^^^^^^^^^^ UP031
1030+
135 | print("%.02X" % 1)
1031+
136 | print("%02X" % 1)
1032+
|
1033+
= help: Replace with format specifiers
1034+
1035+
Unsafe fix
1036+
131 131 | x: "'%s + %s' % (1, 2)"
1037+
132 132 |
1038+
133 133 | # See: https://github.com/astral-sh/ruff/issues/12421
1039+
134 |-print("%.2X" % 1)
1040+
134 |+print("{:02X}".format(1))
1041+
135 135 | print("%.02X" % 1)
1042+
136 136 | print("%02X" % 1)
1043+
137 137 | print("%.00002X" % 1)
1044+
1045+
UP031_0.py:135:7: UP031 [*] Use format specifiers instead of percent format
1046+
|
1047+
133 | # See: https://github.com/astral-sh/ruff/issues/12421
1048+
134 | print("%.2X" % 1)
1049+
135 | print("%.02X" % 1)
1050+
| ^^^^^^^^^^^ UP031
1051+
136 | print("%02X" % 1)
1052+
137 | print("%.00002X" % 1)
1053+
|
1054+
= help: Replace with format specifiers
1055+
1056+
Unsafe fix
1057+
132 132 |
1058+
133 133 | # See: https://github.com/astral-sh/ruff/issues/12421
1059+
134 134 | print("%.2X" % 1)
1060+
135 |-print("%.02X" % 1)
1061+
135 |+print("{:02X}".format(1))
1062+
136 136 | print("%02X" % 1)
1063+
137 137 | print("%.00002X" % 1)
1064+
138 138 | print("%.20X" % 1)
1065+
1066+
UP031_0.py:136:7: UP031 [*] Use format specifiers instead of percent format
1067+
|
1068+
134 | print("%.2X" % 1)
1069+
135 | print("%.02X" % 1)
1070+
136 | print("%02X" % 1)
1071+
| ^^^^^^^^^^ UP031
1072+
137 | print("%.00002X" % 1)
1073+
138 | print("%.20X" % 1)
1074+
|
1075+
= help: Replace with format specifiers
1076+
1077+
Unsafe fix
1078+
133 133 | # See: https://github.com/astral-sh/ruff/issues/12421
1079+
134 134 | print("%.2X" % 1)
1080+
135 135 | print("%.02X" % 1)
1081+
136 |-print("%02X" % 1)
1082+
136 |+print("{:02X}".format(1))
1083+
137 137 | print("%.00002X" % 1)
1084+
138 138 | print("%.20X" % 1)
1085+
1086+
UP031_0.py:137:7: UP031 [*] Use format specifiers instead of percent format
1087+
|
1088+
135 | print("%.02X" % 1)
1089+
136 | print("%02X" % 1)
1090+
137 | print("%.00002X" % 1)
1091+
| ^^^^^^^^^^^^^^ UP031
1092+
138 | print("%.20X" % 1)
1093+
|
1094+
= help: Replace with format specifiers
1095+
1096+
Unsafe fix
1097+
134 134 | print("%.2X" % 1)
1098+
135 135 | print("%.02X" % 1)
1099+
136 136 | print("%02X" % 1)
1100+
137 |-print("%.00002X" % 1)
1101+
137 |+print("{:02X}".format(1))
1102+
138 138 | print("%.20X" % 1)
1103+
1104+
UP031_0.py:138:7: UP031 [*] Use format specifiers instead of percent format
1105+
|
1106+
136 | print("%02X" % 1)
1107+
137 | print("%.00002X" % 1)
1108+
138 | print("%.20X" % 1)
1109+
| ^^^^^^^^^^^ UP031
1110+
|
1111+
= help: Replace with format specifiers
1112+
1113+
Unsafe fix
1114+
135 135 | print("%.02X" % 1)
1115+
136 136 | print("%02X" % 1)
1116+
137 137 | print("%.00002X" % 1)
1117+
138 |-print("%.20X" % 1)
1118+
138 |+print("{:020X}".format(1))

0 commit comments

Comments
 (0)