Ruff v0.16.0: 413 Default Rules, Markdown Formatting, and New Suppression Comments
Ruff v0.16.0 is out, and it's a big one. The Python linter and formatter written in Rust now enables 413 rules by default, up from 59 in v0.1.0. That's a 7x increase. If you've been using Ruff without any configuration, you'll suddenly see warnings for issues that were previously silent.
Better Default Rule Set
Since the last default rule update in v0.1.0, Ruff's total rule count grew from 708 to 968. Many of those new rules catch severe issues like syntax errors and immediate runtime errors but were never enabled by default. Now they are. Highlights include rules from flake8-bugbear (B) and pyupgrade (UP), plus custom RUF rules.
If you prefer the old defaults, you can revert with:
[lint]
select = ["E4", "E7", "E9", "F"]
Markdown Code Block Formatting
Ruff can now format Python code blocks inside Markdown files. It recognizes fenced blocks with info strings python, py, python3, py3, pyi, or pycon. For example, given:
# README
Here's an example:
```py
import ruff
ruff_binary = (
ruff.find_ruff_bin()
)
```
Running ruff format will reformat the code block. Quarto notebooks with ````{python}syntax also work. To suppress formatting, usefmt: off/fmt: on` comments inside code blocks or HTML comments around them.
New Suppression Comments
Ruff v0.16 introduces two new suppression comment formats:
ruff: ignore– suppresses diagnostics on the same line or the following logical line (likenoqabut more flexible).ruff: file-ignore– suppresses diagnostics for the entire file.
Example:
import math # ruff: ignore[F401]
# ruff: ignore[N803]
def foo(
legacyArg1,
legacyArg2,
legacyArg3,
legacyArg4,
): ...
These comments can include a reason string. The --add-ignore CLI flag automatically adds ruff: ignore comments. In preview mode, rule names can be used instead of codes.
Fix Diffs Shown in Output
Both ruff check and ruff format --check now show the diff of fixes inline with the diagnostic output, not just with --diff. This makes it easier to see what will change before applying fixes. The format --check command also supports all output formats (JSON, GitHub annotations, etc.).
Breaking change: In JSON output, fields like filename, location, end_location, and fix.edits[].location may now be null instead of defaulting to empty string or row 1, column 1.
Rule Stabilizations
Twelve rules graduated from preview to stable:
AIR303(airflow3-incompatible-function-signature)CPY001(missing-copyright-notice)FURB164(unnecessary-from-float)FURB192(sorted-min-max)ISC004(implicit-string-concatenation-in-collection-literal)LOG004(log-exception-outside-except-handler)PLE0304(invalid-bool-return-type)PLR0917(too-many-positional-arguments)PLR1708(stop-iteration-return)RUF036(none-not-at-end-of-union)RUF063(access-annotations-from-class-dict)RUF068(duplicate-entry-in-dunder-all)
Other Behavior Stabilizations
BLE001(blind-except) is now suppressed when exception is logged via methods other thancritical,error, andexception.FA102checks for additional PEP 585-compatible APIs.INT001-INT003now check forbuiltins._assignments.S310resolves local string literal bindings to reduce false positives.S508/S509support newer PySNMP API.UP019recognizestyping_extensions.Text.
Migration Notes
Most users can upgrade without changes. The main breaking change is the JSON null fields. If you rely on those fields being non-null, update your parsing logic.
What's Next
Ruff's default rule set will continue to evolve as part of the rule recategorization effort. Expect more rules to be enabled by default in future releases.
Upgrade now: uv tool install ruff@latest or pip install --upgrade ruff.


