NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #96 most downloaded on PyPI
An extremely fast Python linter and code formatter, written in Rust.
Last release 3 days ago
01 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
4 years old
426 releases · first in 2022
One column per quarter.
Add a migration guide for categories
Released on 2026-10-01.
pyupgrade] Add rule for context manager iterator annotations (UP052) (#29000)uv format in untrusted workspaces (#28873)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.10/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.10/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ ruff ] Avoid false positives for overloaded division ( RUF069 )
Released on 2026-09-24.
ruff] Avoid false positives for overloaded division (RUF069) (#28309)flake8-bugbear] Avoid false positives for calls with keyword arguments (B009, B010, B043) (#28776)flake8-tidy-imports] Allow lazy imports to be used in deferred annotations (TID255) (#28767)flake8-pyi] Mention stubs in the diagnostic message (PYI002) (#28542)flake8-annotations] Clarify that ANN401 checks return types in addition to arguments (#28334)flake8-bugbear] Document type-checker interaction (B010) (#28509)flake8-comprehensions] Document map/generator exception behavior (C417) (#27794)ruff] Mention related isort settings (RUF022) (#28719)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.9/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.9/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ pyupgrade ] Stop recommending deprecated ByteString aliases ( UP035 )
Released on 2026-09-16.
TypedDict keyword arguments correctly (#28584)flake8-simplify] Detect nested async with under sync parent (SIM117) (#27821)flake8-simplify] Preserve operand order in SIM109 fix (#27824)pyupgrade] Preserve required parentheses in multiline UP040 fixes (#28164)pyupgrade] Skip TypeVarTuple and ParamSpec conversions with bounds or constraints (UP040, UP046, UP047) (#28505)__lazy_modules__ (#28459)TypedDict class keywords (#28533)typing.TypeForm (#28507)__lazy_modules__ (#28491)flake8-type-checking] Prefer lazy imports over TYPE_CHECKING on Python 3.15 and later (TC001, TC002, TC003) (#28541)pyupgrade] Make the fix for UP040 always unsafe (#28526)pyupgrade] Stop recommending deprecated ByteString aliases (UP035) (#28498)ruff, flake8-use-pathlib] Recognize the parent_mode argument (RUF064, PTH103) (#28528)ruff] Detect \Z in pytest.raises() match patterns (RUF043) (#28598)flake8-tidy-imports] Add extend-banned-api (#28644)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.8/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.8/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ ruff ] Add rule for default values on method receivers ( RUF077 )
Released on 2026-09-10.
ruff] Add rule for default values on method receivers (RUF077) (#26700)ruff] Recognize re.prefixmatch (RUF039, RUF055) (#28311)flake8-implicit-str-concat] Mark fix unsafe when it creates a docstring (ISC003) (#27981)flake8-tidy-imports] Skip fixes for multi-member imports (TID254) (#26584)pylint] Gate ImportCycleError on Python 3.15 (PLW0133) (#28310)D211 and D203 rule conflict diagnostic (#28444)slice and frozendict generics (#28477)__cached__ for Python 3.15 (#28476)pyupgrade] Stop recommending removed typing.no_type_check_decorator (UP035) (#28475)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.7/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.7/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Move pytest-fixture-autouse to the restriction category
Released on 2026-09-03.
pytest-fixture-autouse to the restriction category (#28219)flake8-pytest-style] Add an autofix for PT020 (#27993)flake8-tidy-imports] Prevent fix loop between TID254 and TID255 (#28262)isort] Exclude pragma comments from line length calculation (I001) (#27313)flake8-async, pylint] Recognize builtins.open (ASYNC230, PLW1514) (#28021)flake8-bugbear] Fix panic on match subjects (B031) (#27781)flake8-datetimez] Reject tzinfo=None for datetime bounds (DTZ901) (#28022)flake8-pytest-style] Avoid duplicate PT017 diagnostics (#27918)ruff] Remove lint.external hint for Ruff-specific suppressions (RUF102) (#27923)flake8-use-pathlib] Add display-only fix for os.listdir (PTH208) (#28027)lint.per-file-ignores (#28106)flake8-async] Document thread offloading (ASYNC240) (#28008)pyupgrade] Clarify default encoding argument handling (UP012) (#27315)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.6/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.6/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Update preview default rules and categories
Released on 2026-08-27.
flake8-async] Detect blocking generic HTTP requests (ASYNC210) (#28024)flake8-datetimez] Allow timezone-safe strptime chains (DTZ007) (#28023)flake8-simplify] Respect side effects in lambda defaults (SIM401) (#28000)ClientOptions doc comment (#27978)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.5/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.5/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ flake8-use-pathlib ] Add autofix for PTH116
Released on 2026-08-20.
flake8-use-pathlib] Add autofix for PTH116 (#26460)refurb] Restrict delete-full-slice to lists (FURB131) (#27711)refurb] Skip FURB101 and FURB103 when the open argument is a file descriptor (#27643)InvalidInstruction on Windows CPUs that do not support POPCNT (#27803)pyflakes] Emit semantic syntax errors in string type definitions as F722 (#27835)pylint] Allow os._exit imports in import-private-name (PLC2701) (#27738)ruff] Add ctypes.LittleEndianStructure and related types to existing exception (RUF012) (#27753)nonlocal (#27628)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.4/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.4/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ pylint ] Fix false negatives on negative numbers ( PLR6104 )
Released on 2026-08-13.
pylint] Fix false negatives on negative numbers (PLR6104) (#27251)pyupgrade] Add rule to replace while 1 with while True (UP048) (#27190)flake8-bandit] Also check keyword arguments (S602, S603, S607, S609) (#27687)pylint] Allow continue in finally on Python 3.8 (#27626)pylint] Fix PLE1307 false positive with bools (#27651)pylint] Fix false positives and negatives with %b format character (PLE1300, PLE1307) (#27560)pylint] Improve handling of concatenated strings (PLE1300) (#27659)numpy] Make np.chararray autofix backwards-compatible (NPY201) (#27527)Expr size to 64 bytes (#27591)ruff check --statistics output (#27646)ruff] Also suggest asyncio.TaskGroup (RUF006) (#27461)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.3/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.3/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ flake8-pyi ] Avoid false positives on singledispatch functions ( PYI041 )
Released on 2026-08-06.
flake8-pyi] Avoid false positives on singledispatch functions (PYI041) (#27335)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.2/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.2/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Add an option to opt out of human-readable names
Released on 2026-07-30.
flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)ruff] Fix false positive with unpacked arguments (RUF065) (#26959)gen-lsp-types to gracefully handle unknown enumeration values in LSP messages (#27230)flake8-bugbear] Mark range as immutable (B008) (#27247)flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)flake8-return] Fix false positive when variable is read in finally clause (RET504) (#25441)pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)refurb] Parenthesize yield arguments in the FURB192 fix (#27192)flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)pycon Markdown formatting (#27153)flake8-bandit] Document TYPE_CHECKING exception (S101) (#27004)flake8-import-conventions] Document that extend-aliases can override default aliases (#27191)pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.1/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.1/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Check out the blog post for a migration guide and overview of the changes!
Released on 2026-07-23.
Check out the blog post for a migration guide and overview of the changes!
Ruff now enables a much larger set of rules by default (413, up from 59). See the blog post for more details and the new Default Rules page for a full listing of the enabled rules. Note that this is primarily an expansion, but 18 of the more opinionated pycodestyle (E) and pyflakes (F) rules have been removed from the default set: E401, E402, E701, E702, E703, E711, E712, E713, E714, E721, E731, E741, E742, E743, F403, F405, F406, and F722.
Ruff can now format Python code blocks in Markdown files and will do this by default. See the documentation for more details.
Ruff now supports ruff: ignore comments at the ends of lines, like noqa comments, or on the line preceding a diagnostic. For example, these both suppress an unused-import (F401) diagnostic:
import math # ruff: ignore[F401]
# ruff: ignore[F401]
import osFixes are now shown in check and format --check output:
❯ ruff format --check .
unformatted: File would be reformatted
--> try.md:1:1
|
1 | ```python
- import math
2 + import math
3 | ```
|
1 file would be reformattedThis example also shows off the Markdown formatting.
format --check now supports the same output formats as the linter, including the github and gitlab outputs for rendering annotations in CI:
❯ ruff format --check --output-format github .
::error title=ruff (unformatted),file=try.md,line=2,col=8,endLine=2,endColumn=10::try.md:2:8: unformatted: File would be reformattedSee the CLI help or documentation for the full list of supported formats.
The filename, location, end_location, fix.edits[].location, and fix.edits[].end_location fields in the JSON output format may now be null rather than defaulting to the empty string and row 1, column 1, respectively.
The following rules have been stabilized and are no longer in preview:
airflow3-incompatible-function-signature (AIR303)missing-copyright-notice (CPY001)unnecessary-from-float (FURB164)sorted-min-max (FURB192)implicit-string-concatenation-in-collection-literal (ISC004)log-exception-outside-except-handler (LOG004)invalid-bool-return-type (PLE0304)too-many-positional-arguments (PLR0917)stop-iteration-return (PLR1708)none-not-at-end-of-union (RUF036)access-annotations-from-class-dict (RUF063)duplicate-entry-in-dunder-all (RUF068)The following behaviors have been stabilized:
blind-except (BLE001) is now suppressed when the exception is logged via logging methods other than critical, error and exception.future-required-type-annotation (FA102) now checks for additional PEP 585-compatible APIs, such as those from collections.abc.f-string-in-get-text-func-call (INT001), format-in-get-text-func-call (INT002), and printf-in-get-text-func-call (INT003) now check for additional common ways of using the gettext module, such as assigning it to builtins._.suspicious-url-open-usage (S310) now resolves local string literal bindings to avoid more false positives.snmp-insecure-version (S508) and snmp-weak-cryptography (S509) now support the recommended API from newer versions of PySNMP.typing-text-str-alias (UP019) now recognizes typing_extensions.Text in addition to typing.Text.pyupgrade] Fix false positive with TypeVar default before Python 3.13 (UP040) (#26888)ruff] Fix missing check on unrecognized early bound (RUF016) (#26986)pyupgrade] Speed up unnecessary-future-import (UP010) (#27047)ruff] Add missing period in "Why is this bad?" section (RUF200) (#26930)flake8-simplify] Clarify os.environ behavior on Windows (SIM112) (#26972)pydocstyle] Document fix safety (D400) (#26971)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.16.0/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.16.0/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ pycodestyle ] Add an autofix for E402
Released on 2026-07-16.
pycodestyle] Add an autofix for E402 (#22212)refurb] Allow subclassing builtins in stub files (FURB189) (#26812)ruff] Add rule to replace noqa comments with ruff:ignore (RUF105) (#26423)ruff] Add rule to use human-readable names in ruff:ignore comments (RUF106) (#26682)ruff] Add rule to use human-readable names in configuration selectors (RUF201) (#26772)flake8-pyi] Fix false positive in __all__ (PYI053) (#26872)pylint] Ignore mutable type updates in redefined-loop-name (PLW2901) (#25733)flake8-datetimez] Clarify naming guidance for datetime.today (DTZ002) (#26658)pycodestyle] Document E731 fix safety (#26847)ruff] Clarify intentional async contexts for unused-async (RUF029) (#26641)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.22/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.22/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>[ pyupgrade ] Lint and fix use of deprecated abc decorators ( UP051 )
Released on 2026-07-09.
--add-ignore for adding ruff:ignore comments (#26346)flake8-comprehensions] Drop C409 tuple comprehension preview behavior (#25707)pyupgrade] Lint and fix use of deprecated abc decorators (UP051) (#26417)flake8-implicit-str-concat] Fix ISC003 autofix incorrectly stripping + from comments (#26554)flake8-executable] Mark EXE004 fix as unsafe (#26033)flake8-pyi] Mark PYI061 fixes as unsafe in Python files (#26533)pydocstyle] Skip overload-with-docstring in stub files (D418) (#26318)fits_element in formatter (#26429)--extend-exclude to ruff format (#26372)flake8-bandit] Fix misleading docstring for mako-templates (S702) (#26432)ruff] Fix non-triggering example for if-key-in-dict-del (RUF051) (#26433)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.21/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.21/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Allow human-readable names in rule selectors
Released on 2026-06-25.
noqa shebang handling in ruff:ignore comments (#26286)ruff] Remove pytest-fixture-autouse (RUF076) (#26240, #26371)ruff_python_parser README for crates.io (#26315)perflint] Clarify that PERF402 applies to any iterable (#26242)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Support human-readable names when hovering suppression comments and in code actions
Released on 2026-06-23.
pylint] Update fix suggestions for __floor__, __trunc__, __length_hint__, and __matmul__ variants (PLC2801) (#26239)flake8-pyi] Note that PYI051 is an opinionated stylistic rule (#26179)pyupgrade] Clarify UP029 as a Python 2 compatibility rule (#26243)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.19/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.19/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Handle nested ruff:ignore comments
Released on 2026-06-18.
ruff:ignore comments (#25791)pydocstyle] Prevent property docstrings starting with verbs (D421) (#23775)flake8-pyi] Extend PYI033 to Python files (#26129)flake8-pyi] Rename PYI033 to legacy-type-comment (#26131)ThinVec for call keywords (#25999)flake8-tidy-imports] Add fix safety section (TID252) (#17491)__debug__ lambda parameters (#26022)_ as a match-pattern target (#25977)yield expressions after commas (#26024)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.18/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.18/ruff-installer.ps1 | iex"The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruffYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Allow human-readable names in suppression comments
Released on 2026-06-11.
ignore comments within a disable/enable pair (#25845)ruff:ignore suppressions (#25673)flake8-async] Add trio.as_safe_channel to safe decorators (ASYNC119) (#25775)flake8-pytest-style] Also check pytest_asyncio fixtures (#25375)ruff] Ban pytest autouse fixtures (RUF076) (#25477)pyupgrade] Add from __future__ import annotations automatically (UP007, UP045) (#23259)ruff:enable or ruff:disable appears where ruff:ignore is expected (#25700)pyupgrade] Preserve leading empty literals to avoid syntax errors (UP032) (#25491)flake8-pytest-style] Clarify diagnostic message for single parameters (PT007) (#25592)numpy] Drop autofix for np.in1d (NPY201) (#25612)pylint] Exempt Python version comparisons (PLR2004) (#25743)Vecs with correct capacity for common cases (#25451)ruff rule (#25640)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.17/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.17/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[flake8-async\] Implement yield-in-context-manager-in-async-generator (ASYNC119)
Released on 2026-06-04.
flake8-async] Implement yield-in-context-manager-in-async-generator (ASYNC119) (#24644)pylint] Narrow diagnostic range and exclude cases without exception handlers (PLW0717) (#25440)ruff] Treat yield before break from a terminal loop as terminal (RUF075) (#25447)eradicate] Avoid flagging ruff:ignore comments as code (ERA001) (#25537)eradicate] Fix ERA001/RUF100 conflict when noqa is on commented-out code (#25414)pyflakes] Avoid removing the format call when it would change behavior (F523) (#25320)pylint] Avoid syntax errors in invalid character replacements in f-strings before Python 3.12 (PLE2510, PLE2512, PLE2513, PLE2514, PLE2515) (#25544)pyupgrade] Avoid converting format calls with more kinds of side effects (UP032) (#25484)flake8-pytest-style] Avoid fixes for ambiguous argnames and argvalues combinations (PT006) (#24776)pydocstyle] Improve discoverability of rules enabled for each convention (#24973)ruff] Restore example code for Python versions before 3.15 (RUF017) (#25439)bin/active → bin/activate in tutorial (#25473)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.16/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.16/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Fix Markdown closing fence handling
Released on 2026-05-28.
pyflakes] Report duplicate imports in typing.TYPE_CHECKING block (F811) (#22560)pyflakes] Treat function-scope bare annotations as locals per PEP 526 (F821) (#21540)TokenValue drops in the lexer (#25300)Vec size (#25354)ThinVec in AST to shrink Stmt (#25361)line-length example for --config option (#25389)flake8-comprehensions] Document RecursionError edge case in __len__ (C416) (#25286)mccabe] Improve example (C901) (#25287)pyupgrade] Clarify fix safety docs (UP007, UP045) (#25288)refurb] Document FURB192 exception change for empty sequences (#25317)ruff] Document false negative for user-defined types (RUF013) (#25289)codeAction/resolve requests that contain no or no valid URL (#25365)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.15/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.15/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[airflow\] Implement airflow-task-implicit-multiple-outputs (AIR202)
Released on 2026-05-21.
airflow] Implement airflow-task-implicit-multiple-outputs (AIR202) (#25152)flake8-use-pathlib] Mark PTH101 fix as unsafe when first argument is a class attribute annotated as int (#25086)pylint] Implement too-many-try-statements (W0717) (#23970)ruff] Add incorrect-decorator-order (RUF074) (#23461)ruff] Add fallible-context-manager (RUF075) (#22844)frozenset annotations as immutable (#25251)flake8-type-checking] Avoid strict behavior when future-annotations are enabled (TC001, TC002, TC003) (#25035)pylint] Avoid false positives in else clause (PLR1733) (#25177)flake8-comprehensions] Skip C417 for lambdas with positional-only parameters (#25272)flake8-simplify] Preserve f-string source verbatim in SIM101 fix (#25061)ruff_python_stdlib APIs (#25273)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.14/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.14/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Add a rule to flag lazy imports that are eagerly evaluated
Released on 2026-05-14.
pylint] Standardize diagnostic message (PLR0914, PLR0917) (#24996)F811 false positive for class methods (#24933)eradicate] Fix false positive for lines with leading whitespace (ERA001) (#25122)flake8-pyi] Fix false positive for f-string debug specifier (PYI016) (#24098)PYI034 for in-place operations to enclosing class (#24511)global (#24902)isort] Avoid constructing glob::Patterns for literal known modules (#25123)line-length setting (#24962)D203 to rules that conflict with the formatter (#25044)COM819 and formatter interaction (#25045)NotImplemented is a value, not an exception (F901) (#25054)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.13/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.13/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Implement #ruff:file-ignore file-level suppressions
Released on 2026-04-24.
#ruff:file-ignore file-level suppressions (#23599)#ruff:ignore logical-line suppressions (#23404)airflow] Implement task-branch-as-short-circuit (AIR004) (#23579)flake8-bugbear] Fix break/continue handling in loop-iterator-mutation (B909) (#24440)pylint] Fix PLC2701 for type parameter scopes (#24576)pandas-vet] Suggest .array as well in PD011 (#24805)pylint] Fix PLR0124 description not to claim self-comparison always returns the same value (#24749)pyupgrade] Expand docs on reusable TypeVars and scoping (UP046) (#24153)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.12/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.12/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[ruff\] Ignore RUF029 when function is decorated with asynccontextmanager
Released on 2026-04-16.
ruff] Ignore RUF029 when function is decorated with asynccontextmanager (#24642)airflow] Implement airflow-xcom-pull-in-template-string (AIR201) (#23583)flake8-bandit] Fix S103 false positives and negatives in mask analysis (#24424)flake8-async] Omit overridden methods for ASYNC109 (#24648)flake8-async] Add override mention to ASYNC109 docs (#24666)vim.lsp.config (#24577)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.11/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.11/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[flake8-logging\] Allow closures in except handlers (LOG004)
Released on 2026-04-09.
flake8-logging] Allow closures in except handlers (LOG004) (#24464)flake8-self] Make SLF diagnostics robust to non-self-named variables (#24281)flake8-simplify] Make the fix for collapsible-if safe in preview (SIM102) (#24371)E502 fixes in f-strings and t-strings (#24410)dedent_to (#24381)pyupgrade] Fix panic caused by handling of octals (UP012) (#24390)ruff] Treat f-string interpolation as potential side effect (RUF019) (#24426)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.10/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.10/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[pyflakes\] Flag annotated variable redeclarations as F811 in preview mode
Released on 2026-04-02.
pyflakes] Flag annotated variable redeclarations as F811 in preview mode (#24244)ruff] Allow dunder-named assignments in non-strict mode for RUF067 (#24089)flake8-errmsg] Avoid shadowing existing msg in fix for EM101 (#24363)flake8-simplify] Ignore pre-initialization references in SIM113 (#24235)pycodestyle] Fix W391 fixes for consecutive empty notebook cells (#24236)pyupgrade] Fix UP008 nested class matching (#24273)pyupgrade] Ignore strings with string-only escapes (UP012) (#16058)ruff] RUF072: skip formfeeds on dedent (#24308)ruff] Avoid re-using symbol in RUF024 fix (#24316)ruff] Parenthesize expression in RUF050 fix (#24234)flake8-simplify] Suppress SIM105 for except* before Python 3.12 (#23869)pyflakes] Extend F507 to flag %-format strings with zero placeholders (#24215)pyupgrade] UP018 should detect more unnecessarily wrapped literals (UP018) (#24093)pyupgrade] Fix UP008 callable scope handling to support lambdas (#24274)ruff] RUF010: Mark fix as unsafe when it deletes a comment (#24270)nested-string-quote-style formatting option (#24312)flake8-bugbear] Clarify RUF071 fix safety for non-path string comparisons (#24149)flake8-type-checking] Clarify import cycle wording for TC001/TC002/TC003 (#24322)| (#24343)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.9/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.9/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[ruff\] New rule unnecessary-if (RUF050)
Released on 2026-03-26.
ruff] New rule unnecessary-if (RUF050) (#24114)ruff] New rule useless-finally (RUF072) (#24165)ruff] New rule f-string-percent-format (RUF073): warn when using % operator on an f-string (#24162)pyflakes] Recognize frozendict as a builtin for Python 3.15+ (#24100)flake8-async] Use fully-qualified anyio.lowlevel import in autofix (ASYNC115) (#24166)flake8-bandit] Check tuple arguments for partial paths in S607 (#24080)pyflakes] Skip undefined-name (F821) for conditionally deleted variables (#24088)E501/W505/formatter: Exclude nested pragma comments from line width calculation (#24071)%foo? parsing in IPython assignment expressions (#24152)analyze graph: resolve string imports that reference attributes, not just modules (#24058)eradicate] ignore ty: ignore comments in ERA001 (#24192)flake8-bandit] Treat sys.executable as trusted input in S603 (#24106)flake8-self] Recognize Self annotation and self assignment in SLF001 (#24144)pyflakes] F507: Fix false negative for non-tuple RHS in %-formatting (#24142)refurb] Parenthesize generator arguments in FURB142 fixer (#24200)extend-ignore and extend-select settings documentation (#24064)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.8/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.8/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Display output severity in preview
Released on 2026-03-19.
pycodestyle] Recognize pyrefly: as a pragma comment (E501) (#24019)pylint] Improve phrasing (PLC0208) (#24033)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.7/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.7/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Add support for lazy import parsing
Released on 2026-03-12.
lazy import parsing (#23755)airflow] Flag Variable.get() calls outside of task execution context (AIR003) (#23584)airflow] Flag runtime-varying values in DAG/task constructor arguments (AIR304) (#23631)flake8-bugbear] Implement delattr-with-constant (B043) (#23737)flake8-tidy-imports] Add TID254 to enforce lazy imports (#23777)flake8-tidy-imports] Allow users to ban lazy imports with TID254 (#23847)isort] Retain lazy keyword when sorting imports (#23762)pyupgrade] Add from __future__ import annotations automatically (UP006) (#23260)refurb] Support newline parameter in FURB101 for Python 3.13+ (#23754)ruff] Add os-path-commonprefix (RUF071) (#23814)ruff] Add unsafe fix for os-path-commonprefix (RUF071) (#23852)ruff] Limit RUF036 to typing contexts; make it unsafe for non-typing-only (#23765)ruff] Use starred unpacking for RUF017 in Python 3.15+ (#23789)--add-noqa creating unwanted leading whitespace (#23773)--add-noqa breaking shebangs (#23577)flake8-annotations] Fix stack overflow in ANN401 on quoted annotations with escape sequences (#23912)pep8-naming] Check naming conventions in match pattern bindings (N806, N815, N816) (#23899)perflint] Fix comment duplication in fixes (PERF401, PERF403) (#23729)pyupgrade] Properly trigger super change in nested class (UP008) (#22677)ruff] Avoid syntax errors in RUF036 fixes (#23764)flake8-bandit] Flag S501 with requests.request (#23873)flake8-executable] Fix WSL detection in non-Docker containers (#22879)flake8-print] Ignore pprint calls with stream= (#23787)flake8-bugbear] Fix misleading description for B904 (#23731)curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.15.6/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.15.6/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Discover Markdown files by default in preview mode
Released on 2026-03-05.
perflint] Extend PERF102 to comprehensions and generators (#23473)refurb] Fix FURB101 and FURB103 false positives when I/O variable is used later (#23542)ruff] Add fix for none-not-at-end-of-union (RUF036) (#22829)ruff] Fix false positive for re.split with empty string pattern (RUF055) (#23634)fastapi] Handle callable class dependencies with __call__ method (FAST003) (#23553)pydocstyle] Fix numpy section ordering (D420) (#23685)pyflakes] Fix false positive for names shadowing re-exports (F811) (#23356)pyupgrade] Avoid inserting redundant None elements in UP045 (#23459)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.5/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.5/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
This is a follow-up release to 0.15.3 that resolves a panic when the new rule PLR1712 was enabled with any rule that analyzes definitions, such as man
Released on 2026-02-26.
This is a follow-up release to 0.15.3 that resolves a panic when the new rule PLR1712 was enabled with any rule that analyzes definitions, such as many of the ANN or D rules.
pyflakes] Suppress false positive in F821 for names used before del in stub files (#23550)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.4/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.4/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
Drop explicit support for .qmd file extension
Released on 2026-02-26.
Drop explicit support for .qmd file extension (#23572)
This can now be enabled instead by setting the extension option:
# ruff.toml
extension = { qmd = "markdown" }
# pyproject.toml
[tool.ruff]
extension = { qmd = "markdown" }
Include configured extensions in file discovery (#23400)
[flake8-bandit] Allow suspicious imports in TYPE_CHECKING blocks (S401-S415) (#23441)
[flake8-bugbear] Allow B901 in pytest hook wrappers (#21931)
[flake8-import-conventions] Add missing conventions from upstream (ICN001, ICN002) (#21373)
[pydocstyle] Add rule to enforce docstring section ordering (D420) (#23537)
[pylint] Implement swap-with-temporary-variable (PLR1712) (#22205)
[ruff] Add unnecessary-assign-before-yield (RUF070) (#23300)
[ruff] Support file-level noqa in RUF102 (#23535)
[ruff] Suppress diagnostic for invalid f-strings before Python 3.12 (RUF027) (#23480)
[flake8-bandit] Don't flag BaseLoader/CBaseLoader as unsafe (S506) (#23510)
I002 and PYI025 (#23352)pyflakes] Fix false positive for @overload from lint.typing-modules (F811) (#23357)pyupgrade] Fix false positive for TypeVar default before Python 3.12 (UP046) (#23540)pyupgrade] Fix handling of \N in raw strings (UP032) (#22149)Render sub-diagnostics in the GitHub output format (#23455)
[flake8-bugbear] Tag certain B007 diagnostics as unnecessary (#23453)
[ruff] Ignore unknown rule codes in RUF100 (#23531)
These are now flagged by RUF102 instead.
pydocstyle] Fix double comma in description of D404 (#23440)find_ruff_bin) for parity with uv (#23406)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.3/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.3/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
In preview, Ruff now enables a significantly expanded default rule set of 412 rules, up from the stable default set of 59 rules. The new rules are mos
Released on 2026-02-19.
Expand the default rule set (#23385)
In preview, Ruff now enables a significantly expanded default rule set of 412 rules, up from the stable default set of 59 rules. The new rules are mostly a superset of the stable defaults, with the exception of these rules, which are removed from the preview defaults:
multiple-imports-on-one-line (E401)module-import-not-at-top-of-file (E402)module-import-not-at-top-of-file (E701)multiple-statements-on-one-line-semicolon (E702)useless-semicolon (E703)none-comparison (E711)true-false-comparison (E712)not-in-test (E713)not-is-test (E714)type-comparison (E721)lambda-assignment (E731)ambiguous-variable-name (E741)ambiguous-class-name (E742)ambiguous-function-name (E743)undefined-local-with-import-star (F403)undefined-local-with-import-star-usage (F405)undefined-local-with-nested-import-star-usage (F406)forward-annotation-syntax-error (F722)If you use preview and prefer the old defaults, you can restore them with configuration like:
# ruff.toml
[lint]
select = ["E4", "E7", "E9", "F"]
# pyproject.toml
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F"]
If you do give them a try, feel free to share your feedback in the GitHub discussion!
[flake8-pyi] Also check string annotations (PYI041) (#19023)
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)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)noqa warning (#23270)Q004 to the list of conflicting rules (#23340)ruff] Expand lint.external docs and add sub-diagnostic (RUF100, RUF102) (#23268)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.2/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.2/ruff-installer.ps1 | iex"
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo astral-sh/ruff
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>
\[airflow\] Add ruff rules to catch deprecated Airflow imports for Airflow 3.1 (AIR321)
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 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)pycon Markdown code blocks (#23112)FAST001 (#23224)FAST003 autofix (#23227)InitVar for __post_init__ that references PEP 695 type parameters (#23226)RUF020 target for multiline fixes (#23210)UP007 target for multiline fixes (#23208)pyupgrade] Fix syntax error on string with newline escape and comment (UP037) (#22968)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)format --check --silent (#17736)runtime-evaluated-decorators example (#23187)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.1/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.1/ruff-installer.ps1 | iex"
Check out the blog post for a migration guide and overview of the changes!
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 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.
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:
--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.This release introduces the new 2026 style guide, with the following changes:
except clauses will now be removed on Python 3.14 and later (#20768)as captures in match statements (#21176)Apply formatting to Markdown code blocks (#22470, #22990, #22996)
See the documentation for more details.
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)didOpen instead of .ipynb file extension (#22810)--color CLI option to force colored output (#22806)- stdin convention in CLI help text (#22817)refurb] Change example to re.search with ^ anchor (FURB167) (#22984)pydocstyle] Clarify which quote styles are allowed (D300) (#22825)flake8-bugbear] Improve docs for no-explicit-stacklevel (B028) (#22538)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.15.0/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.15.0/ruff-installer.ps1 | iex"
Preserve required parentheses in lambda bodies
Released on 2026-01-22.
airflow] Second positional argument to Asset/Dataset should not be a dictionary (AIR303) (#22453)ruff] Detect duplicate entries in __all__ (RUF068) (#22114)pyupgrade] Allow shadowing non-builtin bindings (UP029) (#22749)pyupgrade] Apply UP045 to string arguments of typing.cast (#22320)flake8-pie] Detect duplicated declared class fields in PIE794 (#22717)flake8-pyi] Fix inconsistent handling of forward references for __new__, __enter__, __aenter__ in PYI034 (#22798)flake8-pytest-style] Support check parameter in PT011 (#22725)ruff] Add exception for ctypes.Structure._fields_ (RUF012) (#22559)--exit-non-zero-on-format to formatter exit codes section (#22761)FastAPI] Document fix safety for FAST001 (#22655)flake8-async] Tweak explanation to focus on latency/efficiency tradeoff (ASYNC110) (#22715)pandas-vet] Make example error out-of-the-box (PD002) (#22561)refurb] Make the example work out of box (FURB101) (#22770)refurb] Make the example work out of box (FURB103) (#22769)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.14/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.14/ruff-installer.ps1 | iex"
This is a follow-up release to 0.14.12. Because of an issue publishing the WASM packages, there is no GitHub release or Git tag for 0.14.12, although
Released on 2026-01-15.
This is a follow-up release to 0.14.12. Because of an issue publishing the WASM packages, there is no GitHub release or Git tag for 0.14.12, although the package was published to PyPI. The contents of the 0.14.13 release are identical to 0.14.12.
flake8-blind-except] Allow more logging methods (BLE001) (#22057)ruff] Respect lint.pydocstyle.property-decorators in RUF066 (#22515)--show-settings (#22478)fmt: skip for multiple statements on the same logical line (#22119)pydocstyle] Update Rust crate imperative to v1.0.7 (D401) (#22519)isort] Insert imports in alphabetical order (I002) (#22493)flake8-pytest-style] Add check parameter example to PT017 docs (#22546)ruff] Make example error out-of-the-box (RUF103) (#22558)ruff] document RUF100 trailing comment fix behavior (#22479)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.13/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.13/ruff-installer.ps1 | iex"
Nothing published for this version
Consolidate diagnostics for matched disable/enable suppression comments
Released on 2026-01-08.
airflow] Passing positional argument into airflow.lineage.hook.HookLineageCollector.create_asset is not allowed (AIR303) (#22046)refurb] Mark FURB192 fix as always unsafe (#22210)ruff] Add non-empty-init-module (RUF067) (#22143)flake8-unused-arguments] Mark **kwargs in TypeVar as used (ARG001) (#22214)help: subdiagnostics for several Ruff rules that can sometimes appear to disagree with ty (#22331)pylint] Demote PLW1510 fix to display-only (#22318)pylint] Ignore identical members (PLR1714) (#22220)pylint] Improve diagnostic range for PLC0206 (#22312)ruff] Improve fix title for RUF102 invalid rule code (#22100)flake8-simplify]: Avoid unnecessary builtins import for SIM105 (#22358)target-version value in preview (#22419)required-version before parsing rules (#22410)src directories when resolving graphs (#22451)T201 suggestion to not use root logger to satisfy LOG015 (#22059)iter example in unsafe fixes doc (#22118)flake8_print] better suggestion for basicConfig in T201 docs (#22101)pylint] Restore the fix safety docs for PLW0133 (#22211)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.11/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.11/ruff-installer.ps1 | iex"
[formatter] Fluent formatting of method chains
Released on 2025-12-18.
flake8-implicit-str-concat] New rule to prevent implicit string concatenation in collections (ISC004) (#21972)flake8-use-pathlib] Make fixes unsafe when types change in compound statements (PTH104, PTH105, PTH109, PTH115) (#22009)refurb] Extend support for Path.open (FURB101, FURB103) (#21080)pyupgrade] Fix parsing named Unicode escape sequences (UP032) (#21901)eradicate] Ignore ruff:disable and ruff:enable comments in ERA001 (#22038)flake8-pytest-style] Allow match and check keyword arguments without an expected exception type (PT010) (#21964)uv and ty to the Ruff README (#21996)setup.md (#22024)flake8-bandit] Fix broken link (S704) (#22039)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.10/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.10/ruff-installer.ps1 | iex"
\[ruff\] New RUF100 diagnostics for unused range suppressions
Released on 2025-12-11.
ruff] New RUF100 diagnostics for unused range suppressions (#21783)pylint] Detect subclasses of builtin exceptions (PLW0133) (#21382)flake8-bandit] Fix false positive when using non-standard CSafeLoader path (S506). (#21830)flake8-bugbear] Accept immutable slice default arguments (B008) (#21823)pydocstyle] Suppress D417 for parameters with Unpack annotations (#21816)memchr for computing line indexes (#21838)*.pyw is included by default in preview (#21885)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.9/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.9/ruff-installer.ps1 | iex"
\[flake8-bugbear\] Catch yield expressions within other statements (B901)
Released on 2025-12-04.
flake8-bugbear] Catch yield expressions within other statements (B901) (#21200)flake8-use-pathlib] Mark fixes unsafe for return type changes (PTH104, PTH105, PTH109, PTH115) (#21440)await outside functions (#21763)flake8-simplify] Fix truthiness assumption for non-iterable arguments in tuple/list/set calls (SIM222, SIM223) (#21479)--output-file option in GitLab integration (#21706)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.8/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.8/ruff-installer.ps1 | iex"
\[flake8-bandit\] Handle string literal bindings in suspicious-url-open-usage (S310)
Released on 2025-11-28.
flake8-bandit] Handle string literal bindings in suspicious-url-open-usage (S310) (#21469)pylint] Fix PLR1708 false positives on nested functions (#21177)pylint] Fix suppression for empty dict without tuple key annotation (PLE1141) (#21290)ruff] Add rule RUF066 to detect unnecessary class properties (#21535)ruff] Catch more dummy variable uses (RUF052) (#19799)flake8-implicit-str-concat] Avoid invalid fix in (ISC003) (#21517)parser] Fix panic when parsing IPython escape command expressions (#21480)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.7/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.7/ruff-installer.ps1 | iex"
\[flake8-bandit\] Support new PySNMP API paths (S508, S509)
Released on 2025-11-21.
flake8-bandit] Support new PySNMP API paths (S508, S509) (#21374)fmt: skip for compound statements on a single line (#20633)refurb] Fix FURB103 autofix (#21454)ruff] Fix false positive for complex conversion specifiers in logging-eager-conversion (RUF065) (#21464)ruff] Avoid false positive on ClassVar reassignment (RUF012) (#21478)ruff analyze option to skip over imports in TYPE_CHECKING blocks (#21472)eglot-format hook to eglot-managed Python buffers (#21459)force-exclude in "Configuration > Python file discovery" (#21500)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.6/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.6/ruff-installer.ps1 | iex"
\[pyupgrade\] Consistently set the deprecated tag (UP035)
Released on 2025-11-13.
flake8-simplify] Apply SIM113 when index variable is of type int (#21395)pydoclint] Fix false positive when Sphinx directives follow a "Raises" section (DOC502) (#20535)pydoclint] Support NumPy-style comma-separated parameters (DOC102) (#20972)refurb] Auto-fix annotated assignments (FURB101) (#21278)ruff] Ignore str() when not used for simple conversion (RUF065) (#21330)match patterns (#21362)flake8-simplify] Fix false positive for iterable initializers with generator arguments (SIM222) (#21187)pyupgrade] Fix false positive on relative imports from local .builtins module (UP029) (#21309)pyupgrade] Consistently set the deprecated tag (UP035) (#21396)refurb] Detect empty f-strings (FURB105) (#21348)--add-noqa (#21294)ruff linter --output-format=json (#21316)--help (#21337)flake8-annotations] Add link to allow-star-arg-any option (ANN401) (#21326)configuration] Improve error message when line-length exceeds u16::MAX (#21329)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.5/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.5/ruff-installer.ps1 | iex"
\[airflow\] extend deprecated argument concurrency in airflow..DAG (AIR301)
Released on 2025-11-06.
match patterns with as captures (#21176)refurb] Expand fix safety for keyword arguments and Decimals (FURB164) (#21259)refurb] Preserve argument ordering in autofix (FURB103) (#20790)flake8-bugbear] Ignore non-NFKC attribute names in B009 and B010 (#21131)refurb] Fix false negative for underscores before sign in Decimal constructor (FURB157) (#21190)ruff] Fix false positives on starred arguments (RUF057) (#21256)airflow] extend deprecated argument concurrency in airflow..DAG (AIR301) (#21220)extend docs (#21135)flake8-comprehensions] Fix typo in C416 documentation (#21184)ruff analyze graph work with jupyter notebooks (#21161)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.4/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.4/ruff-installer.ps1 | iex"
Respect --output-format with --watch
Released on 2025-10-30.
--output-format with --watch (#21097)pydoclint] Fix false positive on explicit exception re-raising (DOC501, DOC502) (#21011)pyflakes] Revert to stable behavior if imports for module lie in alternate branches for F401 (#20878)pylint] Implement stop-iteration-return (PLR1708) (#20733)ruff] Add support for additional eager conversion patterns (RUF065) (#20657)ISC001] Fix panic when string literals are unclosed (#21034)flake8-django] Apply DJ001 to annotated fields (#20907)flake8-pyi] Fix PYI034 to not trigger on metaclasses (PYI034) (#20881)flake8-type-checking] Fix TC003 false positive with future-annotations (#21125)pyflakes] Fix false positive for __class__ in lambda expressions within class definitions (F821) (#20564)pyupgrade] Fix false positive for TypeVar with default on Python <3.13 (UP046,UP047) (#21045)airflow] Extend airflow.models..Param check (AIR311) (#21043)airflow] Warn that airflow....DAG.create_dagrun has been removed (AIR301) (#21093)refurb] Preserve digit separators in Decimal constructor (FURB157) (#20588)flake8-bandit] Fix correct example for S308 (#21128)line-length goes beyond threshold (#21072)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.3/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.3/ruff-installer.ps1 | iex"
\[flake8-gettext\] Resolve qualified names and built-in bindings (INT001, INT002, INT003)
Released on 2025-10-23.
flake8-gettext] Resolve qualified names and built-in bindings (INT001, INT002, INT003) (#19045)fastapi] Handle ellipsis defaults in FAST002 autofix (#20810)flake8-simplify] Skip SIM911 when unknown arguments are present (#20697)pyupgrade] Always parenthesize assignment expressions in fix for f-string (UP032) (#21003)pyupgrade] Fix UP032 conversion for decimal ints with underscores (#21022)fastapi] Skip autofix for keyword and __debug__ path params (FAST003) (#20960)flake8-bugbear] Skip B905 and B912 for fewer than two iterables and no starred arguments (#20998)ruff] Use DiagnosticTag for more pyflakes and pandas rules (#20801)ruff rule (#20168)match patterns bind different names (#20682)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.2/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.2/ruff-installer.ps1 | iex"
[formatter] Remove parentheses around multiple exception types on Python 3.14+
Released on 2025-10-16.
flake8-bugbear] Omit annotation in preview fix for B006 (#20877)flake8-logging-format] Avoid dropping implicitly concatenated pieces in the G004 fix (#20793)pydoclint] Implement docstring-extraneous-parameter (DOC102) (#20376)pyupgrade] Extend UP019 to detect typing_extensions.Text (UP019) (#20825)pyupgrade] Fix false negative for TypeVar with default argument in non-pep695-generic-class (UP046) (#20660)Truthiness::from_expr for lambdas, generators, and f-strings (#20704)fastapi] Fix false positives for path parameters that FastAPI doesn't recognize (FAST003) (#20687)flake8-pyi] Fix operator precedence by adding parentheses when needed (PYI061) (#20508)ruff] Suppress diagnostic for f-string interpolations with debug text (RUF010) (#20525)airflow] Add warning to airflow.datasets.DatasetEvent usage (AIR301) (#20551)flake8-bugbear] Mark B905 and B912 fixes as unsafe (#20695)DiagnosticTag for more rules - changes display in editors (#20758,#20734)lint.flake8-type-checking.quoted-annotations docs (#20765)flake8-datetimez] Clarify docs for several rules (#20778)RUF015 description (#20873)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.1/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.1/ruff-installer.ps1 | iex"
Update default and latest Python versions for 3.14
Released on 2025-10-07.
flake8-bugbear] Include certain guaranteed-mutable expressions: tuples, generators, and assignment expressions (B006) (#20024)refurb] Add fixes for FURB101 and FURB103 (#20520)ruff] Extend FA102 with listed PEP 585-compatible APIs (#20659)flake8-annotations] Fix return type annotations to handle shadowed builtin symbols (ANN201, ANN202, ANN204, ANN205, ANN206) (#20612)flynt] Fix f-string quoting for mixed quote joiners (FLY002) (#20662)isort] Fix inserting required imports before future imports (I002) (#20676)ruff] Handle argfile expansion errors gracefully (#20691)ruff] Skip RUF051 if else/elif block is present (#20705)ruff] Improve handling of intermixed comments inside from-imports (#20561)flake8-comprehensions] Clarify fix safety documentation (C413) (#20640)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.0/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.0/ruff-installer.ps1 | iex"
Display diffs for ruff format --check and add support for different output formats
Released on 2025-10-02.
ruff format --check and add support for different output formats (#20443)pyflakes] Handle some common submodule import situations for unused-import (F401) (#20200)ruff] Do not flag %r + repr() combinations (RUF065) (#20600)cli] Add conflict between --add-noqa and --diff options (#20642)pylint] Exempt required imports from PLR0402 (#20381)pylint] Fix missing max-nested-blocks in settings display (#20574)pyupgrade] Prevent infinite loop with I002 and UP026 (#20634)flake8-simplify] Improve help message clarity (SIM105) (#20548)isort] Clarify dependency between order-by-type and case-sensitive settings (#20559)pylint] Clarify fix safety to include left-hand hashability (PLR6201) (#20518)playground] Fix quick fixes for empty ranges in playground (#20599)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.13.3/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.13.3/ruff-installer.ps1 | iex"
\[flake8-async\] Implement blocking-path-method (ASYNC240)
Released on 2025-09-25.
flake8-async] Implement blocking-path-method (ASYNC240) (#20264)flake8-bugbear] Implement map-without-explicit-strict (B912) (#20429)flake8-bultins] Detect class-scope builtin shadowing in decorators, default args, and attribute initializers (A003) (#20178)ruff] Implement logging-eager-conversion (RUF065) (#19942).pyw files by default when linting and formatting (#20458)flake8-comprehensions] Preserve trailing commas for single-element lists (C409) (#19571)flake8-pyi] Avoid syntax error from conflict with PIE790 (PYI021) (#20010)flake8-simplify] Correct fix for positive maxsplit without separator (SIM905) (#20056)pyupgrade] Fix UP008 not to apply when __class__ is a local variable (#20497)ruff] Fix B004 to skip invalid hasattr/getattr calls (#20486)ruff] Replace -nan with nan when using the value to construct a Decimal (FURB164 ) (#20391)ruff-wasm-web (#20539)flake8-bandit] Clarify the supported hashing functions (S324) (#20534)playground] Allow hover quick fixes to appear for overlapping diagnostics (#20527)playground] Fix non‑BMP code point handling in quick fixes and markers (#20526)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.13.2/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.13.2/ruff-installer.ps1 | iex"
\[flake8-simplify\] Detect unnecessary None default for additional key expression types (SIM910)
Released on 2025-09-18.
flake8-simplify] Detect unnecessary None default for additional key expression types (SIM910) (#20343)flake8-use-pathlib] Add fix for PTH123 (#20169)flake8-use-pathlib] Fix PTH101, PTH104, PTH105, PTH121 fixes (#20143)flake8-use-pathlib] Make PTH111 fix unsafe because it can change behavior (#20215)pycodestyle] Fix E301 to only trigger for functions immediately within a class (#19768)refurb] Mark single-item-membership-test fix as always unsafe (FURB171) (#20279)flake8-bandit] Fix truthiness: dict-only ** displays not truthy for shell (S602, S604, S609) (#20177)flake8-simplify] Fix diagnostic to show correct method name for str.rsplit calls (SIM905) (#20459)flynt] Use triple quotes for joined raw strings with newlines (FLY002) (#20197)pyupgrade] Fix false positive when class name is shadowed by local variable (UP008) (#20427)pyupgrade] Prevent infinite loop with I002 and UP026 (#20327)ruff] Recognize t-strings, generators, and lambdas in invalid-index-type (RUF016) (#20213)RUF102] Respect rule redirects in invalid rule code detection (#20245)flake8-bugbear] Mark the fix for unreliable-callable-check as always unsafe (B004) (#20318)ruff] Allow dataclass attribute value instantiation from nested frozen dataclass (RUF009) (#20352)output-format=sarif (#20300)ruff] Add analyze.string-imports-min-dots to settings (#20375)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.13.1/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.13.1/ruff-installer.ps1 | iex"
Deprecated rules must now be selected by exact rule code
Check out the blog post for a migration guide and overview of the changes!
Several rules can now add from __future__ import annotations automatically
TC001, TC002, TC003, RUF013, and UP037 now add from __future__ import annotations as part of their fixes when the lint.future-annotations setting is enabled. This allows the rules to move more imports into TYPE_CHECKING blocks (TC001, TC002, and TC003), use PEP 604 union syntax on Python versions before 3.10 (RUF013), and unquote more annotations (UP037).
Full module paths are now used to verify first-party modules
Ruff now checks that the full path to a module exists on disk before categorizing it as a first-party import. This change makes first-party import detection more accurate, helping to avoid false positives on local directories with the same name as a third-party dependency, for example. See the FAQ section on import categorization for more details.
Deprecated rules must now be selected by exact rule code
Ruff will no longer activate deprecated rules selected by their group name or prefix. As noted below, the two remaining deprecated rules were also removed in this release, so this won't affect any current rules, but it will still affect any deprecations in the future.
The deprecated macOS configuration directory fallback has been removed
Ruff will no longer look for a user-level configuration file at ~/Library/Application Support/ruff/ruff.toml on macOS. This feature was deprecated in v0.5 in favor of using the XDG specification (usually resolving to ~/.config/ruff/ruff.toml), like on Linux. The fallback and accompanying deprecation warning have now been removed.
The following rules have been removed:
pandas-df-variable-name (PD901)non-pep604-isinstance (UP038)The following rules have been stabilized and are no longer in preview:
airflow-dag-no-schedule-argument (AIR002)airflow3-removal (AIR301)airflow3-moved-to-provider (AIR302)airflow3-suggested-update (AIR311)airflow3-suggested-to-move-to-provider (AIR312)long-sleep-not-forever (ASYNC116)f-string-number-format (FURB116)os-symlink (PTH211)generic-not-last-base-class (PYI059)redundant-none-literal (PYI061)pytest-raises-ambiguous-pattern (RUF043)unused-unpacked-variable (RUF059)useless-class-metaclass-type (UP050)The following behaviors have been stabilized:
assert-raises-exception (B017) now checks for direct calls to unittest.TestCase.assert_raises and pytest.raises instead of only the context manager forms.missing-trailing-comma (COM812) and prohibited-trailing-comma (COM819) now check for trailing commas in PEP 695 type parameter lists.raw-string-in-exception (EM101) now also checks for byte strings in exception messages.invalid-mock-access (PGH005) now checks for AsyncMock methods like not_awaited in addition to the synchronous variants.useless-import-alias (PLC0414) no longer applies to __init__.py files, where it conflicted with one of the suggested fixes for unused-import (F401).bidirectional-unicode (PLE2502) now also checks for U+061C (Arabic Letter Mark).multiple-with-statements (SIM117) is now marked as always safe.pyupgrade] Enable UP043 in stub files (#20027)pyupgrade] Apply UP008 only when the __class__ cell exists (#19424)ruff] Fix empty f-string detection in in-empty-collection (RUF060) (#20249)pep8-naming] Fix formatting of __all__ (N816) (#20301)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.13.0/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.13.0/ruff-installer.ps1 | iex"
Your coding agent can read these notes before it upgrades. Set up the MCP server →