Released on 2026-02-12.
- [
airflow] Add ruff rules to catch deprecated Airflow imports for Airflow 3.1 (AIR321) (#22376) - [
airflow] Third positional parameter not namedti_keyshould be flagged forBaseOperatorLink.get_link(AIR303) (#22828) - [
flake8-gettext] Fix false negatives for plural argument ofngettext(INT001,INT002,INT003) (#21078) - [
pyflakes] Fix infinite loop in preview fix forunused-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 inreimplemented-operator(FURB118) (#23079) - [
ruff] Detect mutable defaults infieldcalls (RUF008) (#23046) - [
ruff] Ignore stdcmath.inf(RUF069) (#23120) - [
ruff] New rulefloat-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
pyconMarkdown code blocks (#23112) - Use extension mapping to select Markdown code block language (#22934)
- Avoid false positive for undefined variables in
FAST001(#23224) - Avoid introducing syntax errors for
FAST003autofix (#23227) - Avoid suggesting
InitVarfor__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
RUF020target for multiline fixes (#23210) - Wrap
UP007target 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)
- Use
ruffinstead ofRuffas the program name in GitHub output format (#23240) - [
PT006] Fix syntax error when unpacking nested tuples inparametrizefixes (#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] Addmultiprocessing.Valueto excluded functions forFBT003(#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 forRUF012(#23202)
- Suppress diagnostic output for
format --check --silent(#17736)
- Add tabbed shell completion documentation (#23169)
- Explain how to enable Markdown formatting for pre-commit hook (#23077)
- Fixed import in
runtime-evaluated-decoratorsexample (#23187) - Update ruff server contributing guide (#23060)
- Exclude WASM artifacts from GitHub releases (#23221)
- @mkniewallner
- @bxff
- @dylwil3
- @Avasam
- @amyreese
- @charliermarsh
- @Alex-ley-scrub
- @Kalmaegi
- @danparizher
- @AiyionPrime
- @eureka928
- @11happy
- @Jkhall81
- @chirizxc
- @leandrobbraga
- @tvatter
- @anishgirianish
- @shaanmajid
- @ntBre
- @sjyangkevin
Released on 2026-02-03.
Check out the blog post for a migration guide and overview of the 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
N803for 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:alpineDocker image is now based on Alpine 3.23 (up from 3.21). -
The
ruff:debianandruff:debian-slimDocker 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.
The following rules have been stabilized and are no longer in preview:
blocking-http-call-httpx-in-async-function(ASYNC212)blocking-path-method-in-async-function(ASYNC240)blocking-input-in-async-function(ASYNC250)map-without-explicit-strict(B912)if-exp-instead-of-or-operator(FURB110)single-item-membership-test(FURB171)missing-maxsplit-arg(PLC0207)unnecessary-lambda(PLW0108)unnecessary-empty-iterable-within-deque-call(RUF037)in-empty-collection(RUF060)legacy-form-pytest-raises(RUF061)non-octal-permissions(RUF064)invalid-rule-code(RUF102)invalid-suppression-comment(RUF103)unmatched-suppression-comment(RUF104)replace-str-enum(UP042)
The following behaviors have been stabilized:
- The
--output-formatflag is now respected when running Ruff in--watchmode, and thefulloutput 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 considerstyping.Optionalwhen searching for duplicate union members.split-static-string(SIM905) now offers an autofix when themaxsplitargument is provided, even without asepargument.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.
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
exceptclauses 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
ascaptures inmatchstatements (#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)
-
Apply formatting to Markdown code blocks (#22470, #22990, #22996)
See the documentation for more details.
- Fix suppression indentation matching (#22903)
- Customize where the
fix_titlesub-diagnostic appears (#23044) - [
FastAPI] Add sub-diagnostic explaining why a fix was unavailable (FAST002) (#22565) - [
flake8-annotations] Don't suggestNoReturnfor functions raisingNotImplementedError(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 addabc.ABCif already present (FURB180) (#22234) - [
refurb] Make fix unsafe if it deletes comments (FURB110) (#22768) - [
ruff] Add sub-diagnostics with permissions (RUF064) (#22972)
- Identify notebooks by LSP
didOpeninstead of.ipynbfile extension (#22810)
- Add
--colorCLI option to force colored output (#22806)
- Document
-stdin convention in CLI help text (#22817) - [
refurb] Change example tore.searchwith^anchor (FURB167) (#22984) - Fix link to Sphinx code block directives (#23041)
- [
pydocstyle] Clarify which quote styles are allowed (D300) (#22825) - [
flake8-bugbear] Improve docs forno-explicit-stacklevel(B028) (#22538)
- Update MSRV to 1.91 (#22874)
- @danparizher
- @chirizxc
- @amyreese
- @Jkhall81
- @cwkang1998
- @manzt
- @11happy
- @hugovk
- @caiquejjx
- @ntBre
- @akawd
- @konstin
See changelogs/0.9.x
See changelogs/0.8.x
See changelogs/0.7.x
See changelogs/0.6.x
See changelogs/0.5.x
See changelogs/0.4.x
See changelogs/0.3.x
See changelogs/0.2.x
See changelogs/0.1.x