Ruff v0.6.0 is available now! Install it from PyPI, or your package manager of choice:
pip install --upgrade ruff
As a reminder: Ruff is an extremely fast Python linter and formatter, written in Rust. Ruff can be used to replace Black, Flake8 (plus dozens of plugins), isort, pydocstyle, pyupgrade, and more, all while executing tens or hundreds of times faster than any individual tool.
Migrating to v0.6 #
As with Ruff 0.5, this release contains few breaking changes: most of our users should be able to upgrade to the latest Ruff version without having to make any significant edits to their code or configuration. But with that said, here are a few things to keep in mind when upgrading:
-
Several rules have been deprecated after it was decided that they made recommendations that were either inaccurate or unhelpful:
-
By default, our
isort
rules now search insidesrc/
directories when determining the list of package names that are likely to represent first-party code. This was always configurable, but it was suprising for many users that Ruff didn't understand this common project structure "out of the box".This change may result in some of your imports being reordered or recategorised, as import statements that these rules previously considered to be third-party imports will now be correctly understood as first-party.
-
The
unnecessary-dict-comprehension-for-iterable
rule has been recoded fromRUF025
toC420
, ensuring Ruff's code is consistent with the same rule in theflake8-comprehensions
plugin.
Jupyter notebooks are now linted and formatted by default #
Ruff has supported linting and formatting Jupyter notebooks for a long time. In
previous Ruff versions, however, Ruff would only lint and format notebooks if
you added extend-include = ["*.ipynb"]
to your Ruff configuration file. (Ruff
would also lint any files that you explicitly passed to Ruff on the command
line, including .ipynb
files.)
In Ruff 0.6, this behavior has changed. When passed a directory of files to
lint or format, Ruff will now search for .ipynb
files within that directory
in exactly the same way as it would for .py
or .pyi
files — with no extra
configuration necessary. We added this as a preview-mode feature in Ruff 0.5.6;
this release promotes it to stable.
If you'd rather Ruff left your notebooks alone, you'll still be able to get the
old behavior by setting a custom extend-exclude
setting in your Ruff configuration. For example, in a pyproject.toml
file:
[tool.ruff]
extend-exclude = ["*.ipynb"]
For more fine-grained control over how Ruff handles notebook files, here's how you'd tell Ruff that you'd like your notebooks formatted, but not linted:
[tool.ruff.lint]
exclude = ["*.ipynb"]
Here's how you'd tell Ruff that you'd like your notebooks linted, but not formatted:
[tool.ruff.format]
exclude = ["*.ipynb"]
And to disable specific lint rules on notebooks, you can use Ruff's
per-file-ignores
setting:
[tool.ruff.lint.per-file-ignores]
"*.ipynb" = ["E501"] # disable line-too-long in notebooks
Default behavior changed for flake8-pytest-style
rules #
We've changed the default behaviour for
pytest-fixture-incorrect-parentheses-style
and pytest-incorrect-mark-parentheses-style
(PT001
and PT023
respectively).
Previously, PT001
would by default change @pytest.fixture
decorators to
@pytest.fixture()
, and PT023
would change @pytest.mark.foo
decorators to
@pytest.mark.foo()
. They will now both remove parentheses by default, rather
than adding them. This means that these rules now adhere more closely to the
style recommendations made by the official pytest project.
These rules are both configurable. To revert to Ruff's previous default
behaviors, use the
lint.flake8-pytest-style.mark-parentheses
and lint.flake8-pytest-style.fixture-parentheses
settings in your Ruff configuration file. For example, in a pyproject.toml
file:
[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = true
mark-parentheses = true
These rules also both come with safe autofixes, so you should be able to easily
fix any new violations of these rules caused by this change by running
ruff check . --fix --select=PT001 --select=PT023
.
Rule stabilizations #
This release stabilizes nine rules originally derived from the pylint linter,
all of which were previously only available with --preview
:
singledispatch-method
(PLE1519
)singledispatchmethod-function
(PLE1520
)bad-staticmethod-argument
(PLW0211
)if-stmt-min-max
(PLR1730
)invalid-bytes-return-type
(PLE0308
)invalid-hash-return-type
(PLE0309
)invalid-index-return-type
(PLE0305
)invalid-length-return-type
(E303
)self-or-cls-assignment
(PLW0642
)
Two PYI
rules (originally derived from the flake8-pyi linter), and one RUF
rule,
have also been stabilised:
byte-string-usage
(PYI057
)duplicate-literal-member
(PYI062
)redirected-noqa
(RUF101
)
Other behavior stabilizations #
This release also stabilizes several preview-mode features relating to our
ASYNC
rules. ASYNC100
, ASYNC109
, ASYNC110
, ASYNC115
and ASYNC116
have all had their scope increased so that they detect
antipatterns in asyncio
and anyio
code as well as antipatterns in trio
code:
cancel-scope-no-checkpoint
(ASYNC100
): Supportasyncio
andanyio
context mangers.async-function-with-timeout
(ASYNC109
): Supportasyncio
andanyio
context mangers.async-busy-wait
(ASYNC110
): Supportasyncio
andanyio
context mangers.async-zero-sleep
(ASYNC115
): Supportanyio
context mangers.long-sleep-not-forever
(ASYNC116
): : Supportanyio
context mangers.
Finally, autofixes have been promoted to stable for the following rules in our
flake8-return
category:
superfluous-else-return
(RET505
)superfluous-else-raise
(RET506
)superfluous-else-continue
(RET507
)superfluous-else-break
(RET508
)
View the full changelog on GitHub.
Read more about Astral — the company behind Ruff.