How to make ruff to use f-string instead str.format?

I’m trying ruff but when I do ruff check . on my example:

print("%s" % "hello")

it shows:

UP031 Use format specifiers instead of percent format

and if I do ruff check . --fix or ruff format . they don’t change anything.

My pyproject.toml snipped:

[tool.ruff]
target-version = "py39"
line-length = 120
extend-select = ["E501", "UP", "RUF"]

  • 1

    Can you try ruff check . --fix --unsafe-fixes?

    – 

You should always post the versions of the tools you are using and when asking for help with errors/outputs you should always post the whole output.

Running your example with ruff 0.1.2 (ruff check .) outputs:

main.py:1:7: UP031 Use format specifiers instead of percent format
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).

The error message clearly states that there aren’t fixes available unless you run the command with the option --unsafe-fixes. If you want ruff to fix it then you need to run the command ruff check . --fix --unsafe-fixes

$ ruff check . --fix --unsafe-fixes
Found 1 error (1 fixed, 0 remaining).

and it will fix the line to print("{}".format("hello"))

It is an unsafe fix as explained by the documentation, the value you are trying to print could change the way its printed if you change the formatting.

I got to understand better my problem and designed a better example.

pyupgrade:

cat <<EOF >|test.py
a=1
b=2
ab = "%s %s" % (a, b)
c = "%s %s"  % (ab, ab)
print("%s" % ab)
EOF
pyupgrade --py36-plus test.py
cat test.py
pyupgrade --py36-plus test.py
cat test.py

Rewriting test.py
a=1
b=2
ab = "{} {}".format(a, b)
c = "%s %s"  % (ab, ab)
print("%s" % ab)
Rewriting test.py
a=1
b=2
ab = f"{a} {b}"
c = "%s %s"  % (ab, ab)
print("%s" % ab)

So pyupgrade needs two runs and the final result is not great.

ruff:

cat <<EOF >|test.py
a=1
b=2
ab = "%s %s" % (a, b)
c = "%s %s"  % (ab, ab)
print("%s" % ab)
EOF
ruff check --fix --unsafe-fixes test.py
cat test.py

Found 4 errors (4 fixed, 0 remaining).
a=1
b=2
ab = f"{a} {b}"
c = f"{ab} {ab}"
print("%s" % ab)

ruff clearly does better: just one run and better results. Yet, I wonder why print("%s" % ab) is not converted to `print(f”{ab}”).

Leave a Comment