Ruff v0.16.0
Get Started
Back to blog
July<br>23,<br>2026
Brent Westbrook<br>@ntBre
Ruff v0.16.0 is available now! Install it from<br>PyPI, or with your package manager of choice:
uv tool install ruff@latest
As a reminder: Ruff is an extremely fast Python linter and formatter, written in Rust. Ruff can<br>be used to replace Black, Flake8 (plus dozens of plugins), isort, pydocstyle, pyupgrade, and more,<br>all while executing tens or hundreds of times faster than any individual tool.
Migrating to v0.16 #
Ruff v0.16 has a small number of breaking changes, allowing most users to update without significant<br>changes to code or configuration. The main exception is described below.
Better default rule set #
Ruff now enables 413 rules by default, up from 59 in previous versions.
Since Ruff's default rule set was last modified in<br>v0.1.0, the<br>number of rules in Ruff has grown from 708 to 968. Many of these rules catch severe issues,<br>including syntax errors and<br>immediate runtime errors but were not previously<br>enabled by default. With the new rule set, Ruff will bring these issues and many others to your<br>attention without any Ruff configuration. Even if you're already using<br>select or<br>extend-select, we hope that this will<br>draw your attention to helpful rules that you previously hadn't discovered.
The full listing of enabled rules is too long to include here, but you can find it on our new<br>Default Rules page in the documentation. A few of the<br>highlights include rules from the popular flake8-bugbear (B) and pyupgrade (UP) linters, as well<br>as rules from our own RUF category.
If you want to revert to the old default set, you can easily select the old rules with this<br>configuration:
[lint]<br>select = ["E4", "E7", "E9", "F"]
We view this work as closely tied to our longstanding goal of<br>rule recategorization, so look forward to upcoming<br>developments in this area.
New features in v0.16 #
Ruff v0.16 also includes several newly stabilized features that are highlighted below.
Markdown code block formatting #
Ruff can now format Python code blocks embedded in Markdown files.
In these files, Ruff v0.16 will format<br>fenced code blocks with a python, py,<br>python3, py3, pyi, or pycon info string.<br>pyi blocks are formatted like stub files, pycon blocks as REPL sessions, and the others use<br>normal Python file formatting. For example:
# README
Here's an example:
```py<br>import ruff
ruff_binary = (<br>ruff.find_ruff_bin()<br>```
will be reformatted when running ruff format:
This can also be used to format Quarto notebooks because Ruff still<br>recognizes the language when surrounded by curly braces (e.g. ```{python}). Note that you may<br>need to configure your extension mapping if<br>your Quarto files use the .qmd extension.
If you need to suppress formatting, you have several options. If you want the suppression comments<br>to appear in the code block, you can use normal fmt: off and fmt: on comments within the code<br>block itself, or you can use similar HTML comments to disable formatting for a whole region of the<br>document:
# README
```py<br>x = "this will be suppressed"<br>```
To suppress Markdown formatting entirely, you can use the normal<br>extend-exclude setting to exclude all<br>Markdown files with a glob like *.md.
See the full documentation for<br>more details.
ruff: ignore comments offer new suppression features #
Ruff now has its own suppression comment format that can be used on its own line.
In v0.15, the Ruff linter gained a range suppression mechanism through paired ruff: disable and<br>ruff: enable comments, much like the fmt: off and fmt: on pair described above:
# ruff: disable[N803]<br>def foo(<br>legacyArg1,<br>legacyArg2,<br>legacyArg3,<br>legacyArg4,<br>): ...<br># ruff: enable[N803]
Ruff v0.16 builds on this to add two additional ruff suppression comments. ruff: ignore can be<br>used to suppress a diagnostic on the same line, like noqa, or on the following logical line:
import math # ruff: ignore[F401]
# ruff: ignore[N803]<br>def foo(<br>legacyArg1,<br>legacyArg2,<br>legacyArg3,<br>legacyArg4,<br>): ...
In this case, the logical line spans the whole function header (from def to the colon), so the<br>ruff: ignore suppresses all of the same<br>N803 diagnostics as the<br>disable/enable pair above.
ruff: file-ignore comments can be used to suppress diagnostics for the entire file, just like<br>ruff: noqa comments:
# ruff: file-ignore[F401] Allow unused imports in this file
import foo<br>import bar<br>import baz
As this example also shows, each of these comment kinds can have an associated "reason" explaining<br>why they were added, in this case Allow unused imports in this file.
ruff: ignore comments can be added automatically with the new --add-ignore CLI flag, and in<br>preview, all of these ruff suppression comments support rule names instead of codes:
❯ echo 'import math' > try.py<br>❯ uvx ruff@latest check --preview --add-ignore try.py<br>Added 1 ignore comment.<br>❯ cat try.py<br>import math # ruff: ignore[unused-import]
You can find the full specification for all of these comments in...