Skip to content

Commit 6c81831

Browse files
Moved consider-using-f-string to RecommendationChecker (#4957)
Based on discussion in #4787 Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent baaa81a commit 6c81831

File tree

3 files changed

+108
-101
lines changed

3 files changed

+108
-101
lines changed

pylint/checkers/refactoring/recommendation_checker.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ class RecommendationChecker(checkers.BaseChecker):
5050
"When iterating over values, sequence types (e.g., ``lists``, ``tuples``, ``ranges``) "
5151
"are more efficient than ``sets``.",
5252
),
53+
"C0209": (
54+
"Formatting a regular string which could be a f-string",
55+
"consider-using-f-string",
56+
"Used when we detect a string that is being formatted with format() or % "
57+
"which could potentially be a f-string. The use of f-strings is preferred.",
58+
),
5359
}
5460

5561
@staticmethod
@@ -313,3 +319,75 @@ def _check_use_sequence_for_iteration(
313319
"""Check if code iterates over an in-place defined set."""
314320
if isinstance(node.iter, nodes.Set):
315321
self.add_message("use-sequence-for-iteration", node=node.iter)
322+
323+
@utils.check_messages("consider-using-f-string")
324+
def visit_const(self, node: nodes.Const) -> None:
325+
if node.pytype() == "builtins.str" and not isinstance(
326+
node.parent, nodes.JoinedStr
327+
):
328+
self._detect_replacable_format_call(node)
329+
330+
def _detect_replacable_format_call(self, node: nodes.Const) -> None:
331+
"""Check whether a string is used in a call to format() or '%' and whether it
332+
can be replaced by a f-string"""
333+
if (
334+
isinstance(node.parent, nodes.Attribute)
335+
and node.parent.attrname == "format"
336+
):
337+
# Allow assigning .format to a variable
338+
if isinstance(node.parent.parent, nodes.Assign):
339+
return
340+
341+
if node.parent.parent.args:
342+
for arg in node.parent.parent.args:
343+
# If star expressions with more than 1 element are being used
344+
if isinstance(arg, nodes.Starred):
345+
inferred = utils.safe_infer(arg.value)
346+
if (
347+
isinstance(inferred, astroid.List)
348+
and len(inferred.elts) > 1
349+
):
350+
return
351+
352+
elif node.parent.parent.keywords:
353+
keyword_args = [
354+
i[0] for i in utils.parse_format_method_string(node.value)[0]
355+
]
356+
for keyword in node.parent.parent.keywords:
357+
# If keyword is used multiple times
358+
if keyword_args.count(keyword.arg) > 1:
359+
return
360+
361+
keyword = utils.safe_infer(keyword.value)
362+
363+
# If lists of more than one element are being unpacked
364+
if isinstance(keyword, nodes.Dict):
365+
if len(keyword.items) > 1 and len(keyword_args) > 1:
366+
return
367+
368+
# If all tests pass, then raise message
369+
self.add_message(
370+
"consider-using-f-string",
371+
node=node,
372+
line=node.lineno,
373+
col_offset=node.col_offset,
374+
)
375+
376+
elif isinstance(node.parent, nodes.BinOp) and node.parent.op == "%":
377+
inferred_right = utils.safe_infer(node.parent.right)
378+
379+
# If dicts or lists of length > 1 are used
380+
if isinstance(inferred_right, nodes.Dict):
381+
if len(inferred_right.items) > 1:
382+
return
383+
elif isinstance(inferred_right, nodes.List):
384+
if len(inferred_right.elts) > 1:
385+
return
386+
387+
# If all tests pass, then raise message
388+
self.add_message(
389+
"consider-using-f-string",
390+
node=node,
391+
line=node.lineno,
392+
col_offset=node.col_offset,
393+
)

pylint/checkers/strings.py

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -671,12 +671,6 @@ class StringConstantChecker(BaseTokenChecker):
671671
"in Python 2 to indicate a string was Unicode, but since Python 3.0 strings "
672672
"are Unicode by default.",
673673
),
674-
"C1407": (
675-
"Formatting a regular string which could be a f-string",
676-
"consider-using-f-string",
677-
"Used when we detect a string that is being formatted with format() or % "
678-
"which could potentially be a f-string. The use of f-strings is preferred.",
679-
),
680674
}
681675
options = (
682676
(
@@ -914,13 +908,11 @@ def process_non_raw_string_token(
914908
index += 2
915909

916910
@check_messages("redundant-u-string-prefix")
917-
@check_messages("consider-using-f-string")
918911
def visit_const(self, node: nodes.Const) -> None:
919912
if node.pytype() == "builtins.str" and not isinstance(
920913
node.parent, nodes.JoinedStr
921914
):
922915
self._detect_u_string_prefix(node)
923-
self._detect_replacable_format_call(node)
924916

925917
def _detect_u_string_prefix(self, node: nodes.Const):
926918
"""Check whether strings include a 'u' prefix like u'String'"""
@@ -931,69 +923,6 @@ def _detect_u_string_prefix(self, node: nodes.Const):
931923
col_offset=node.col_offset,
932924
)
933925

934-
def _detect_replacable_format_call(self, node: nodes.Const) -> None:
935-
"""Check whether a string is used in a call to format() or '%' and whether it
936-
can be replaced by a f-string"""
937-
if (
938-
isinstance(node.parent, nodes.Attribute)
939-
and node.parent.attrname == "format"
940-
):
941-
# Allow assigning .format to a variable
942-
if isinstance(node.parent.parent, nodes.Assign):
943-
return
944-
945-
if node.parent.parent.args:
946-
for arg in node.parent.parent.args:
947-
# If star expressions with more than 1 element are being used
948-
if isinstance(arg, nodes.Starred):
949-
inferred = utils.safe_infer(arg.value)
950-
if (
951-
isinstance(inferred, astroid.List)
952-
and len(inferred.elts) > 1
953-
):
954-
return
955-
956-
elif node.parent.parent.keywords:
957-
keyword_args = [
958-
i[0] for i in utils.parse_format_method_string(node.value)[0]
959-
]
960-
for keyword in node.parent.parent.keywords:
961-
# If keyword is used multiple times
962-
if keyword_args.count(keyword.arg) > 1:
963-
return
964-
965-
keyword = utils.safe_infer(keyword.value)
966-
967-
# If lists of more than one element are being unpacked
968-
if isinstance(keyword, nodes.Dict):
969-
if len(keyword.items) > 1 and len(keyword_args) > 1:
970-
return
971-
972-
# If all tests pass, then raise message
973-
self.add_message(
974-
"consider-using-f-string",
975-
line=node.lineno,
976-
col_offset=node.col_offset,
977-
)
978-
979-
elif isinstance(node.parent, nodes.BinOp) and node.parent.op == "%":
980-
inferred_right = utils.safe_infer(node.parent.right)
981-
982-
# If dicts or lists of length > 1 are used
983-
if isinstance(inferred_right, nodes.Dict):
984-
if len(inferred_right.items) > 1:
985-
return
986-
elif isinstance(inferred_right, nodes.List):
987-
if len(inferred_right.elts) > 1:
988-
return
989-
990-
# If all tests pass, then raise message
991-
self.add_message(
992-
"consider-using-f-string",
993-
line=node.lineno,
994-
col_offset=node.col_offset,
995-
)
996-
997926

998927
def register(linter):
999928
"""required method to auto register this checker"""
Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
consider-using-f-string:40:10::"Formatting a regular string which could be a f-string":HIGH
2-
consider-using-f-string:41:10::"Formatting a regular string which could be a f-string":HIGH
3-
consider-using-f-string:42:10::"Formatting a regular string which could be a f-string":HIGH
4-
consider-using-f-string:43:10::"Formatting a regular string which could be a f-string":HIGH
5-
consider-using-f-string:44:10::"Formatting a regular string which could be a f-string":HIGH
6-
consider-using-f-string:45:10::"Formatting a regular string which could be a f-string":HIGH
7-
consider-using-f-string:46:10::"Formatting a regular string which could be a f-string":HIGH
8-
consider-using-f-string:47:10::"Formatting a regular string which could be a f-string":HIGH
9-
consider-using-f-string:48:10::"Formatting a regular string which could be a f-string":HIGH
10-
consider-using-f-string:49:10::"Formatting a regular string which could be a f-string":HIGH
11-
consider-using-f-string:68:4::"Formatting a regular string which could be a f-string":HIGH
12-
consider-using-f-string:69:4::"Formatting a regular string which could be a f-string":HIGH
13-
consider-using-f-string:70:4::"Formatting a regular string which could be a f-string":HIGH
14-
consider-using-f-string:71:4::"Formatting a regular string which could be a f-string":HIGH
15-
consider-using-f-string:72:4::"Formatting a regular string which could be a f-string":HIGH
16-
consider-using-f-string:73:4::"Formatting a regular string which could be a f-string":HIGH
17-
consider-using-f-string:74:4::"Formatting a regular string which could be a f-string":HIGH
18-
consider-using-f-string:75:4::"Formatting a regular string which could be a f-string":HIGH
19-
consider-using-f-string:76:4::"Formatting a regular string which could be a f-string":HIGH
20-
consider-using-f-string:77:4::"Formatting a regular string which could be a f-string":HIGH
21-
consider-using-f-string:98:8::"Formatting a regular string which could be a f-string":HIGH
22-
consider-using-f-string:99:8::"Formatting a regular string which could be a f-string":HIGH
23-
consider-using-f-string:100:8::"Formatting a regular string which could be a f-string":HIGH
24-
consider-using-f-string:101:8::"Formatting a regular string which could be a f-string":HIGH
25-
consider-using-f-string:102:8::"Formatting a regular string which could be a f-string":HIGH
26-
consider-using-f-string:103:8::"Formatting a regular string which could be a f-string":HIGH
27-
consider-using-f-string:104:8::"Formatting a regular string which could be a f-string":HIGH
28-
consider-using-f-string:105:8::"Formatting a regular string which could be a f-string":HIGH
29-
consider-using-f-string:106:8::"Formatting a regular string which could be a f-string":HIGH
30-
consider-using-f-string:107:8::"Formatting a regular string which could be a f-string":HIGH
1+
consider-using-f-string:40:10:print_bad:Formatting a regular string which could be a f-string:HIGH
2+
consider-using-f-string:41:10:print_bad:Formatting a regular string which could be a f-string:HIGH
3+
consider-using-f-string:42:10:print_bad:Formatting a regular string which could be a f-string:HIGH
4+
consider-using-f-string:43:10:print_bad:Formatting a regular string which could be a f-string:HIGH
5+
consider-using-f-string:44:10:print_bad:Formatting a regular string which could be a f-string:HIGH
6+
consider-using-f-string:45:10:print_bad:Formatting a regular string which could be a f-string:HIGH
7+
consider-using-f-string:46:10:print_bad:Formatting a regular string which could be a f-string:HIGH
8+
consider-using-f-string:47:10:print_bad:Formatting a regular string which could be a f-string:HIGH
9+
consider-using-f-string:48:10:print_bad:Formatting a regular string which could be a f-string:HIGH
10+
consider-using-f-string:49:10:print_bad:Formatting a regular string which could be a f-string:HIGH
11+
consider-using-f-string:68:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
12+
consider-using-f-string:69:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
13+
consider-using-f-string:70:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
14+
consider-using-f-string:71:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
15+
consider-using-f-string:72:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
16+
consider-using-f-string:73:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
17+
consider-using-f-string:74:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
18+
consider-using-f-string:75:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
19+
consider-using-f-string:76:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
20+
consider-using-f-string:77:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
21+
consider-using-f-string:98:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
22+
consider-using-f-string:99:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
23+
consider-using-f-string:100:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
24+
consider-using-f-string:101:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
25+
consider-using-f-string:102:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
26+
consider-using-f-string:103:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
27+
consider-using-f-string:104:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
28+
consider-using-f-string:105:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
29+
consider-using-f-string:106:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
30+
consider-using-f-string:107:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH

0 commit comments

Comments
 (0)