Changelog

0.15.2

Released on 2026-02-19.

Preview features

Bug fixes

  • [flake8-async] Fix in_async_context logic (#23426)
  • [ruff] Fix for RUF102 should delete entire comment (#23380)
  • [ruff] Suppress diagnostic for strings with backslashes in interpolations before Python 3.12 (RUF027) (#21069)
  • [flake8-bugbear] Fix B023 false positive for immediately-invoked lambdas (#23294)
  • [parser] Fix false syntax error for match-like annotated assignments (#23297)
  • [parser] Fix indentation tracking after line continuations (#23417)

Rule changes

  • [flake8-executable] Allow global flags in uv shebangs (EXE003) (#22582)
  • [pyupgrade] Fix handling of typing.{io,re} (UP035) (#23131)
  • [ruff] Detect PLC0207 on chained str.split() calls (#23275)

CLI

  • Remove invalid inline noqa warning (#23270)

Configuration

  • Add extension mapping to configuration file options (#23384)

Documentation

  • Add Q004 to the list of conflicting rules (#23340)
  • [ruff] Expand lint.external docs and add sub-diagnostic (RUF100, RUF102) (#23268)

Contributors

0.15.1

Released on 2026-02-12.

Preview features

  • [airflow] Add ruff rules to catch deprecated Airflow imports for Airflow 3.1 (AIR321) (#22376)
  • [airflow] Third positional parameter not named ti_key should be flagged for BaseOperatorLink.get_link (AIR303) (#22828)
  • [flake8-gettext] Fix false negatives for plural argument of ngettext (INT001, INT002, INT003) (#21078)
  • [pyflakes] Fix infinite loop in preview fix for unused-import (F401) (#23038)
  • [pygrep-hooks] Detect non-existent mock methods in standalone expressions (PGH005) (#22830)
  • [pylint] Allow dunder submodules and improve diagnostic range (PLC2701) (#22804)
  • [pyupgrade] Improve diagnostic range for tuples (UP024) (#23013)
  • [refurb] Check subscripts in tuple do not use lambda parameters in reimplemented-operator (FURB118) (#23079)
  • [ruff] Detect mutable defaults in field calls (RUF008) (#23046)
  • [ruff] Ignore std cmath.inf (RUF069) (#23120)
  • [ruff] New rule float-equality-comparison (RUF069) (#20585)
  • Don't format unlabeled Markdown code blocks (#23106)
  • Markdown formatting support in LSP (#23063)
  • Support Quarto Markdown language markers (#22947)
  • Support formatting pycon Markdown code blocks (#23112)
  • Use extension mapping to select Markdown code block language (#22934)

Bug fixes

  • Avoid false positive for undefined variables in FAST001 (#23224)
  • Avoid introducing syntax errors for FAST003 autofix (#23227)
  • Avoid suggesting InitVar for __post_init__ that references PEP 695 type parameters (#23226)
  • Deduplicate type variables in generic functions (#23225)
  • Fix exception handler parenthesis removal for Python 3.14+ (#23126)
  • Fix f-string middle panic when parsing t-strings (#23232)
  • Wrap RUF020 target for multiline fixes (#23210)
  • Wrap UP007 target for multiline fixes (#23208)
  • Fix missing diagnostics for last range suppression in file (#23242)
  • [pyupgrade] Fix syntax error on string with newline escape and comment (UP037) (#22968)

Rule changes

  • Use ruff instead of Ruff as the program name in GitHub output format (#23240)
  • [PT006] Fix syntax error when unpacking nested tuples in parametrize fixes (#22441) (#22464)
  • [airflow] Catch deprecated attribute access from context key for Airflow 3.0 (AIR301) (#22850)
  • [airflow] Capture deprecated arguments and a decorator (AIR301) (#23170)
  • [flake8-boolean-trap] Add multiprocessing.Value to excluded functions for FBT003 (#23010)
  • [flake8-bugbear] Add a secondary annotation showing the previous occurrence (B033) (#22634)
  • [flake8-type-checking] Add sub-diagnostic showing the runtime use of an annotation (TC004) (#23091)
  • [isort] Support configurable import section heading comments (#23151)
  • [ruff] Improve the diagnostic for RUF012 (#23202)

Formatter

  • Suppress diagnostic output for format --check --silent (#17736)

Documentation

  • Add tabbed shell completion documentation (#23169)
  • Explain how to enable Markdown formatting for pre-commit hook (#23077)
  • Fixed import in runtime-evaluated-decorators example (#23187)
  • Update ruff server contributing guide (#23060)

Other changes

  • Exclude WASM artifacts from GitHub releases (#23221)

Contributors

0.15.0

Released on 2026-02-03.

Check out the blog post for a migration guide and overview of the changes!

Breaking changes

  • Ruff now formats your code according to the 2026 style guide. See the formatter section below or in the blog post for a detailed list of changes.

  • The linter now supports block suppression comments. For example, to suppress N803 for all parameters in this function:

    # ruff: disable[N803]
    def foo(
        legacyArg1,
        legacyArg2,
        legacyArg3,
        legacyArg4,
    ): ...
    # ruff: enable[N803]
    

    See the documentation for more details.

  • The ruff:alpine Docker image is now based on Alpine 3.23 (up from 3.21).

  • The ruff:debian and ruff:debian-slim Docker images are now based on Debian 13 “Trixie” instead of Debian 12 “Bookworm.”

  • Binaries for the ppc64 (64-bit big-endian PowerPC) architecture are no longer included in our releases. It should still be possible to build Ruff manually for this platform, if needed.

  • Ruff now resolves all extended configuration files before falling back on a default Python version.

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

  • The --output-format flag is now respected when running Ruff in --watch mode, and the full output format is now used by default, matching the regular CLI output.
  • builtin-attribute-shadowing (A003) now detects the use of shadowed built-in names in additional contexts like decorators, default arguments, and other attribute definitions.
  • duplicate-union-member (PYI016) now considers typing.Optional when searching for duplicate union members.
  • split-static-string (SIM905) now offers an autofix when the maxsplit argument is provided, even without a sep argument.
  • dict-get-with-none-default (SIM910) now applies to more types of key expressions.
  • super-call-with-parameters (UP008) now has a safe fix when it will not delete comments.
  • unnecessary-default-type-args (UP043) now applies to stub (.pyi) files on Python versions before 3.13.

Formatter

This release introduces the new 2026 style guide, with the following changes:

  • Lambda parameters are now kept on the same line and lambda bodies will be parenthesized to let them break across multiple lines (#21385)
  • Parentheses around tuples of exceptions in except clauses will now be removed on Python 3.14 and later (#20768)
  • A single empty line is now permitted at the beginning of function bodies (#21110)
  • Parentheses are avoided for long as captures in match statements (#21176)
  • Extra spaces between escaped quotes and ending triple quotes can now be omitted (#17216)
  • Blank lines are now enforced before classes with decorators in stub files (#18888)

Preview features

Bug fixes

  • Fix suppression indentation matching (#22903)

Rule changes

  • Customize where the fix_title sub-diagnostic appears (#23044)
  • [FastAPI] Add sub-diagnostic explaining why a fix was unavailable (FAST002) (#22565)
  • [flake8-annotations] Don't suggest NoReturn for functions raising NotImplementedError (ANN201, ANN202, ANN205, ANN206) (#21311)
  • [pyupgrade] Make fix unsafe if it deletes comments (UP017) (#22873)
  • [pyupgrade] Make fix unsafe if it deletes comments (UP020) (#22872)
  • [pyupgrade] Make fix unsafe if it deletes comments (UP033) (#22871)
  • [refurb] Do not add abc.ABC if already present (FURB180) (#22234)
  • [refurb] Make fix unsafe if it deletes comments (FURB110) (#22768)
  • [ruff] Add sub-diagnostics with permissions (RUF064) (#22972)

Server

  • Identify notebooks by LSP didOpen instead of .ipynb file extension (#22810)

CLI

  • Add --color CLI option to force colored output (#22806)

Documentation

  • Document - stdin convention in CLI help text (#22817)
  • [refurb] Change example to re.search with ^ anchor (FURB167) (#22984)
  • Fix link to Sphinx code block directives (#23041)
  • [pydocstyle] Clarify which quote styles are allowed (D300) (#22825)
  • [flake8-bugbear] Improve docs for no-explicit-stacklevel (B028) (#22538)

Other changes

Contributors

0.14.x

See changelogs/0.14.x

0.13.x

See changelogs/0.13.x

0.12.x

See changelogs/0.12.x

0.11.x

See changelogs/0.11.x

0.10.x

See changelogs/0.10.x

0.9.x

See changelogs/0.9.x

0.8.x

See changelogs/0.8.x

0.7.x

See changelogs/0.7.x

0.6.x

See changelogs/0.6.x

0.5.x

See changelogs/0.5.x

0.4.x

See changelogs/0.4.x

0.3.x

See changelogs/0.3.x

0.2.x

See changelogs/0.2.x

0.1.x

See changelogs/0.1.x