Skip to content

Commit

Permalink
Fix fstrings not properly displaying when stringifying
Browse files Browse the repository at this point in the history
  • Loading branch information
dosisod committed Feb 24, 2024
1 parent 12b7f84 commit 900f6b4
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
61 changes: 61 additions & 0 deletions refurb/checks/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,49 @@ def is_type_none_call(node: Expression) -> bool:
return False


def get_fstring_parts(expr: Expression) -> list[tuple[bool, Expression, str]]:
match expr:
case CallExpr(
callee=MemberExpr(
expr=StrExpr(value="{:{}}"),
name="format",
),
args=[arg, StrExpr(value=format_arg)],
arg_kinds=[ArgKind.ARG_POS, ArgKind.ARG_POS],
):
return [(True, arg, format_arg)]

case CallExpr(
callee=MemberExpr(
expr=StrExpr(value=""),
name="join",
),
args=[ListExpr(items=items)],
arg_kinds=[ArgKind.ARG_POS],
):
exprs: list[tuple[bool, Expression, str]] = []

had_at_least_one_fstring_part = False

for item in items:
if isinstance(item, StrExpr):
exprs.append((False, item, ""))

elif tmp := get_fstring_parts(item):
had_at_least_one_fstring_part = True
exprs.extend(tmp)

else:
return []

if not had_at_least_one_fstring_part:
return []

return exprs

return []


def stringify(node: Node) -> str:
try:
return _stringify(node)
Expand Down Expand Up @@ -352,6 +395,24 @@ def _stringify(node: Node) -> str:
return f"({inner})"

case CallExpr(arg_names=arg_names, arg_kinds=arg_kinds, args=args):
if fstring_parts := get_fstring_parts(node):
output = 'f"'

for is_format_arg, arg, fmt in fstring_parts:
if not is_format_arg:
assert isinstance(arg, StrExpr)

output += arg.value

elif fmt:
output += f"{{{_stringify(arg)}:{fmt}}}"

else:
output += f"{{{_stringify(arg)}}}"

output += '"'
return output

call_args: list[str] = []

for arg_name, kind, arg in zip(arg_names, arg_kinds, args):
Expand Down
11 changes: 11 additions & 0 deletions test/data/stringify.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@
lambda x: x[:2:]
lambda x: x[::]
lambda x: x[:]

# test fstring formatting
_ = str(f"{123}") # noqa: FURB183
_ = str(f"{123:x}")
_ = str(f"x{123}y")
_ = str(f"x{123}y{456}z")
_ = str(f"{'abc'}") # noqa: FURB183

# wont trigger string formatting
_ = str("".join([""]))
_ = str("".join(["", 1])) # type: ignore
7 changes: 7 additions & 0 deletions test/data/stringify.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ test/data/stringify.py:17:1 [FURB118]: Replace `lambda x: x[::3]` with `operator
test/data/stringify.py:18:1 [FURB118]: Replace `lambda x: x[:2]` with `operator.itemgetter(slice(None, 2))`
test/data/stringify.py:19:1 [FURB118]: Replace `lambda x: x[:]` with `operator.itemgetter(slice(None, None))`
test/data/stringify.py:20:1 [FURB118]: Replace `lambda x: x[:]` with `operator.itemgetter(slice(None, None))`
test/data/stringify.py:23:5 [FURB123]: Replace `str(f"{123}")` with `f"{123}"`
test/data/stringify.py:24:5 [FURB123]: Replace `str(f"{123:x}")` with `f"{123:x}"`
test/data/stringify.py:25:5 [FURB123]: Replace `str(f"x{123}y")` with `f"x{123}y"`
test/data/stringify.py:26:5 [FURB123]: Replace `str(f"x{123}y{456}z")` with `f"x{123}y{456}z"`
test/data/stringify.py:27:5 [FURB123]: Replace `str(f"{"abc"}")` with `f"{"abc"}"`
test/data/stringify.py:30:5 [FURB123]: Replace `str("".join([""]))` with `"".join([""])`
test/data/stringify.py:31:5 [FURB123]: Replace `str("".join(["", 1]))` with `"".join(["", 1])`

0 comments on commit 900f6b4

Please sign in to comment.