Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved consider-using-f-string to RecommendationChecker #4957

Merged
merged 2 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 78 additions & 0 deletions pylint/checkers/refactoring/recommendation_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class RecommendationChecker(checkers.BaseChecker):
"When iterating over values, sequence types (e.g., ``lists``, ``tuples``, ``ranges``) "
"are more efficient than ``sets``.",
),
"C0209": (
"Formatting a regular string which could be a f-string",
"consider-using-f-string",
"Used when we detect a string that is being formatted with format() or % "
"which could potentially be a f-string. The use of f-strings is preferred.",
),
}

@staticmethod
Expand Down Expand Up @@ -313,3 +319,75 @@ def _check_use_sequence_for_iteration(
"""Check if code iterates over an in-place defined set."""
if isinstance(node.iter, nodes.Set):
self.add_message("use-sequence-for-iteration", node=node.iter)

@utils.check_messages("consider-using-f-string")
def visit_const(self, node: nodes.Const) -> None:
if node.pytype() == "builtins.str" and not isinstance(
node.parent, nodes.JoinedStr
):
self._detect_replacable_format_call(node)

def _detect_replacable_format_call(self, node: nodes.Const) -> None:
"""Check whether a string is used in a call to format() or '%' and whether it
can be replaced by a f-string"""
if (
isinstance(node.parent, nodes.Attribute)
and node.parent.attrname == "format"
):
# Allow assigning .format to a variable
if isinstance(node.parent.parent, nodes.Assign):
return

if node.parent.parent.args:
for arg in node.parent.parent.args:
# If star expressions with more than 1 element are being used
if isinstance(arg, nodes.Starred):
inferred = utils.safe_infer(arg.value)
if (
isinstance(inferred, astroid.List)
and len(inferred.elts) > 1
):
return

elif node.parent.parent.keywords:
keyword_args = [
i[0] for i in utils.parse_format_method_string(node.value)[0]
]
for keyword in node.parent.parent.keywords:
# If keyword is used multiple times
if keyword_args.count(keyword.arg) > 1:
return

keyword = utils.safe_infer(keyword.value)

# If lists of more than one element are being unpacked
if isinstance(keyword, nodes.Dict):
if len(keyword.items) > 1 and len(keyword_args) > 1:
return

# If all tests pass, then raise message
self.add_message(
"consider-using-f-string",
node=node,
line=node.lineno,
col_offset=node.col_offset,
)

elif isinstance(node.parent, nodes.BinOp) and node.parent.op == "%":
inferred_right = utils.safe_infer(node.parent.right)

# If dicts or lists of length > 1 are used
if isinstance(inferred_right, nodes.Dict):
if len(inferred_right.items) > 1:
return
elif isinstance(inferred_right, nodes.List):
if len(inferred_right.elts) > 1:
return

# If all tests pass, then raise message
self.add_message(
"consider-using-f-string",
node=node,
line=node.lineno,
col_offset=node.col_offset,
)
71 changes: 0 additions & 71 deletions pylint/checkers/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,6 @@ class StringConstantChecker(BaseTokenChecker):
"in Python 2 to indicate a string was Unicode, but since Python 3.0 strings "
"are Unicode by default.",
),
"C1407": (
"Formatting a regular string which could be a f-string",
"consider-using-f-string",
"Used when we detect a string that is being formatted with format() or % "
"which could potentially be a f-string. The use of f-strings is preferred.",
),
}
options = (
(
Expand Down Expand Up @@ -916,13 +910,11 @@ def process_non_raw_string_token(
index += 2

@check_messages("redundant-u-string-prefix")
@check_messages("consider-using-f-string")
def visit_const(self, node: nodes.Const):
if node.pytype() == "builtins.str" and not isinstance(
node.parent, nodes.JoinedStr
):
self._detect_u_string_prefix(node)
self._detect_replacable_format_call(node)

def _detect_u_string_prefix(self, node: nodes.Const):
"""Check whether strings include a 'u' prefix like u'String'"""
Expand All @@ -933,69 +925,6 @@ def _detect_u_string_prefix(self, node: nodes.Const):
col_offset=node.col_offset,
)

def _detect_replacable_format_call(self, node: nodes.Const) -> None:
"""Check whether a string is used in a call to format() or '%' and whether it
can be replaced by a f-string"""
if (
isinstance(node.parent, nodes.Attribute)
and node.parent.attrname == "format"
):
# Allow assigning .format to a variable
if isinstance(node.parent.parent, nodes.Assign):
return

if node.parent.parent.args:
for arg in node.parent.parent.args:
# If star expressions with more than 1 element are being used
if isinstance(arg, nodes.Starred):
inferred = utils.safe_infer(arg.value)
if (
isinstance(inferred, astroid.List)
and len(inferred.elts) > 1
):
return

elif node.parent.parent.keywords:
keyword_args = [
i[0] for i in utils.parse_format_method_string(node.value)[0]
]
for keyword in node.parent.parent.keywords:
# If keyword is used multiple times
if keyword_args.count(keyword.arg) > 1:
return

keyword = utils.safe_infer(keyword.value)

# If lists of more than one element are being unpacked
if isinstance(keyword, nodes.Dict):
if len(keyword.items) > 1 and len(keyword_args) > 1:
return

# If all tests pass, then raise message
self.add_message(
"consider-using-f-string",
line=node.lineno,
col_offset=node.col_offset,
)

elif isinstance(node.parent, nodes.BinOp) and node.parent.op == "%":
inferred_right = utils.safe_infer(node.parent.right)

# If dicts or lists of length > 1 are used
if isinstance(inferred_right, nodes.Dict):
if len(inferred_right.items) > 1:
return
elif isinstance(inferred_right, nodes.List):
if len(inferred_right.elts) > 1:
return

# If all tests pass, then raise message
self.add_message(
"consider-using-f-string",
line=node.lineno,
col_offset=node.col_offset,
)


def register(linter):
"""required method to auto register this checker"""
Expand Down
60 changes: 30 additions & 30 deletions tests/functional/c/consider/consider_using_f_string.txt
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
consider-using-f-string:40:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:41:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:42:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:43:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:44:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:45:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:46:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:47:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:48:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:49:10::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:68:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:69:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:70:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:71:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:72:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:73:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:74:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:75:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:76:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:77:4::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:98:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:99:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:100:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:101:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:102:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:103:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:104:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:105:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:106:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:107:8::"Formatting a regular string which could be a f-string":HIGH
consider-using-f-string:40:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:41:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:42:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:43:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:44:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:45:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:46:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:47:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:48:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:49:10:print_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:68:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:69:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:70:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:71:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:72:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:73:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:74:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:75:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:76:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:77:4:statement_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:98:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:99:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:100:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:101:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:102:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:103:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:104:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:105:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:106:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH
consider-using-f-string:107:8:assignment_bad:Formatting a regular string which could be a f-string:HIGH