Skip to content

Ruff 0.16.0 Enables 7x More Rules by Default

July 24, 2026·Tim Hopper · Markdown

Upgrade Ruff to 0.16.0 and your next ruff check may flag hundreds of new violations. Your code didn’t change; Ruff enabled 354 additional rules by default.

Since v0.1.0 in October 2023, the out-of-the-box selection stayed ["E4", "E7", "E9", "F"]: pyflakes detections and a narrow slice of pycodestyle. Those conservative defaults are why the handbook’s guide to recommended Ruff defaults covers enabling bugbear, simplify, pyupgrade, and the rest via extend-select. With 0.16.0, many of those rules are on by default.

Which categories are now on by default

The new default set runs 413 rules across 34 categories. The ones that fire most often in real codebases:

  • B (flake8-bugbear): 29 rules. Mutable default arguments, function calls in defaults, loop variable capture, unsafe setattr/getattr usage.
  • UP (pyupgrade): 42 rules. Optional[X] to X | None, deprecated typing.List/Dict/Tuple to built-in equivalents, unnecessary __future__ imports.
  • SIM (flake8-simplify): 21 rules. Nested with statements, redundant boolean comparisons.
  • PL (pylint): 67 rules covering conventions, errors, refactoring suggestions, and warnings.
  • C4 (flake8-comprehensions): 17 rules. Unnecessary generator-to-list wrapping, redundant collection constructors.
  • DTZ (flake8-datetimez): 10 rules. datetime.now() without timezone, utcnow() usage.
  • I (isort): import sorting.
  • ASYNC (flake8-async): 10 rules. Blocking calls inside async functions, missing checkpoints in async loops.
  • FURB (refurb): 17 rules. sorted()[0] instead of min(), bitwise operations over set operations, redundant type conversion.
  • RUF (Ruff-specific): 36 rules. Mutable class variable defaults, implicit optional, ambiguous class-variable annotations.
  • TRY (tryceratops): 5 rules. Verbose raise in except blocks, redefining the caught exception variable.
  • YTT (flake8-2020), PYI (stub file checks), PT (pytest style), FA (future annotations), and more.

The full list is on Astral’s Default Rules page.

Freeze the old defaults

If you want zero behavior change, pin the previous selection in pyproject.toml:

[tool.ruff.lint]
select = ["E4", "E7", "E9", "F"]

This restores exactly what 0.15.x ran.

Triage the new violations

For codebases willing to adopt the new defaults, triage one category at a time:

ruff check --select B .
ruff check --select UP .
ruff check --select SIM .

Most UP violations have auto-fixes:

ruff check --fix --select UP .

For categories with more judgment calls, such as PL or TRY, run ruff check --select PL . to see which codes fire in your codebase, then add the ones you want to silence to ignore:

[tool.ruff.lint]
ignore = ["PL..."]  # pin specific codes after reviewing what fires

Audit any extend-select entries before removing them. The new defaults enable only a subset of each category (42 of the available UP rules, 21 SIM, 17 C4), not every stable rule under the prefix. A broad extend-select = ["UP"] adds every stable UP rule, so dropping it would silently disable the ones outside the defaults. Check what your extend-select adds beyond the default set on Astral’s Default Rules page first.

See what else 0.16.0 changed

  • Markdown formatting. ruff format now reformats Python code blocks inside Markdown files by default, so ruff format . on a docs repo will touch .md files. To opt out, add "*.md" to the exclude list or wrap a block in fmt: off/fmt: on comments.

  • New suppression syntax. Two new comment forms join # noqa:

    import math  # ruff: ignore[F401]
    
    # ruff: ignore[F401]
    import os

    # ruff: file-ignore[F401] suppresses a rule for the entire file. The existing # noqa syntax still works; the new forms are an alternative. For block-level suppression, see how to disable Ruff rules for a block of code.

  • Inline fix diffs. check and format --check now print a diff of the available fix beside each diagnostic, so CI shows what would change without a separate --fix --diff pass.

  • CI output formats. ruff format --check now supports --output-format github and --output-format gitlab, rendering inline PR annotations for format violations the same way the linter already did.

  • JSON output. The filename, location, and end_location fields in JSON output may now be null for diagnostics without a file location, rather than defaulting to empty strings or row 1, column 1. Tooling that reads Ruff’s JSON output should handle null in those fields.

Learn More

Last updated on