-
Notifications
You must be signed in to change notification settings - Fork 10
PIE782: False positive when f-string contains numeric formatting #24
Comments
Yeah we ran into this as well. Turns out the heuristic for checking whether a f-string is necessary wasn't as simple as originally thought. |
Probably not unexpected, but
In this case these were conversions from things like |
I think removing the rule would be easier / simpler than trying to fix the heuristic |
Would the rule be useful if it was something as crude as |
OK, I see now that the ast does not easily give you the literal value. Currently you look at any https://github.com/sbdchd/flake8-pie/blob/v0.2.1/flake8_pie.py#L32 I'm not familiar with the ast module, but think I see where the false positives come from - the format specifiers themselves: >>> import ast
>>> def walk(node, indent=4):
... print(" " * indent, str(node), node.s if hasattr(node, "s") else "-")
... if hasattr(node, "values"):
... for child in node.values:
... walk(child, indent + 4)
...
>>> for node in ast.walk(ast.parse("print(f'Hello {name:d}')")): walk(node)
...
<_ast.Module object at 0x7f89600ccb90> -
<_ast.Expr object at 0x7f89600cca10> -
<_ast.Call object at 0x7f89600cc790> -
<_ast.Name object at 0x7f89600cc650> -
<_ast.JoinedStr object at 0x7f89600cc990> -
<_ast.Str object at 0x7f89600cca50> Hello
<_ast.FormattedValue object at 0x7f89600cc810> -
<_ast.Load object at 0x7f89600bf5d0> -
<_ast.Str object at 0x7f89600cca50> Hello
<_ast.FormattedValue object at 0x7f89600cc810> -
<_ast.Name object at 0x7f89600cc690> -
<_ast.JoinedStr object at 0x7f89600ccc10> -
<_ast.Str object at 0x7f89600cc950> d
<_ast.Load object at 0x7f89600bf5d0> -
<_ast.Str object at 0x7f89600cc950> d
>>> for node in ast.walk(ast.parse("print(f'Hello {name}')")): walk(node)
...
<_ast.Module object at 0x7f89600cc690> -
<_ast.Expr object at 0x7f89600cc810> -
<_ast.Call object at 0x7f89600cca50> -
<_ast.Name object at 0x7f89600cc610> -
<_ast.JoinedStr object at 0x7f89600cc990> -
<_ast.Str object at 0x7f89600cc650> Hello
<_ast.FormattedValue object at 0x7f89600cc790> -
<_ast.Load object at 0x7f89600bf5d0> -
<_ast.Str object at 0x7f89600cc650> Hello
<_ast.FormattedValue object at 0x7f89600cc790> -
<_ast.Name object at 0x7f89600cca10> -
<_ast.Load object at 0x7f89600bf5d0> -
>>> for node in ast.walk(ast.parse("print(f'Hello world')")): walk(node)
...
<_ast.Module object at 0x7f89600cc790> -
<_ast.Expr object at 0x7f89600cc650> -
<_ast.Call object at 0x7f89600ccc10> -
<_ast.Name object at 0x7f89600cc990> -
<_ast.JoinedStr object at 0x7f89600cc610> -
<_ast.Str object at 0x7f89600cca50> Hello world
<_ast.Load object at 0x7f89600bf5d0> -
<_ast.Str object at 0x7f89600cca50> Hello world
>>> for node in ast.walk(ast.parse("print('Hello world')")): walk(node)
...
<_ast.Module object at 0x7f89600cc990> -
<_ast.Expr object at 0x7f89600ccc10> -
<_ast.Call object at 0x7f89600cc650> -
<_ast.Name object at 0x7f89600cc790> -
<_ast.Str object at 0x7f89600cc810> Hello world
<_ast.Load object at 0x7f89600bf5d0> - The f-string insertion points look like The false positives are from the format specifiers themselves (here It looks like any format specifier would trigger the false positive:
Indeed it does: class Client:
def __init__(self, id, polite, casual):
self.polite = polite
self.casual = casual
def __format__(self, format_spec):
if format_spec == "polite":
return self.polite
elif format_spec == "casual":
return self.casual
else:
raise ValueError(f"{format_spec} is not a format defined by Client object")
customer = Client(123, "Peter", "Pete")
print(f"Hello {customer:polite}, may we call you {customer:casual}?")
print(f"Thanks!") # pointless f-string
|
I've spent a while looking into the AST tree, but failed to spot how to solve this. Removing the PIE782 warning may be the pragmatic way forward :( |
Turns out the AST of f-strings was more complicated than the examples I initially imagined. Fixing the rule will is likely more annoying than simply removing it. rel: #24
I've removed this rule in the latest version https://pypi.org/project/flake8-pie/0.5.0/ edit: feel free to let me know if there are any problems |
Slightly on a tangent, but I've started working on a plugin to flag the different Python string formatting styles: https://github.com/peterjc/flake8-sfs I would ideally include pointless f-strings as a special case, and will try to let you know if I do manage to solve it one day (or some kind person contributes a solution). |
Just to note that pointless f-strings (like This is also available in ruff https://docs.astral.sh/ruff/rules/f-string-missing-placeholders/ |
Tested on flake8-pie-0.4.2
test.py
But the
f
is not safe to remove.The text was updated successfully, but these errors were encountered: