NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #123 most downloaded on PyPI
An extremely fast Python linter and code formatter, written in Rust.
Last release 2 days ago
16 Sep 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
424 releases · first in 2022
One column per quarter.
\[flake8-use-pathlib\] Expand PTH201 to check all PurePath subclasses
flake8-use-pathlib] Expand PTH201 to check all PurePath subclasses (#19440)flake8-blind-except] Change BLE001 to correctly parse exception tuples (#19747)flake8-errmsg] Exclude typing.cast from EM101 (#19656)flake8-simplify] Fix raw string handling in SIM905 for embedded quotes (#19591)flake8-import-conventions] Avoid false positives for NFKC-normalized __debug__ import aliases in ICN001 (#19411)isort] Fix syntax error after docstring ending with backslash (I002) (#19505)pylint] Mark PLC0207 fixes as unsafe when *args unpacking is present (#19679)pyupgrade] Prevent infinite loop with I002 (UP010, UP035) (#19413)ruff] Parenthesize generator expressions in f-strings (RUF010) (#19434)eradicate] Don't flag pyrefly pragmas as unused code (ERA001) (#19731)RUF036 (#19706)typing documentation (#19648)refurb] Make more examples error out-of-the-box (#19695,#19673,#19672)ruff id (#19654)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.8/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.8/ruff-installer.ps1 | iex"
This is a follow-up release to 0.12.6. Because of an issue in the package metadata, 0.12.6 failed to publish fully to PyPI and has been yanked. Simila
This is a follow-up release to 0.12.6. Because of an issue in the package metadata, 0.12.6 failed to publish fully to PyPI and has been yanked. Similarly, there is no GitHub release or Git tag for 0.12.6. The contents of the 0.12.7 release are identical to 0.12.6, except for the updated metadata.
flake8-commas] Add support for trailing comma checks in type parameter lists (COM812, COM819) (#19390)pylint] Implement auto-fix for missing-maxsplit-arg (PLC0207) (#19387)ruff] Offer fixes for RUF039 in more cases (#19065).pyi files in ruff analyze graph (#19611)flake8-pyi] Preserve inline comment in ellipsis removal (PYI013) (#19399)perflint] Ignore rule if target is global or nonlocal (PERF401) (#19539)pyupgrade] Fix UP030 to avoid modifying double curly braces in format strings (#19378)refurb] Ignore decorated functions for FURB118 (#19339)refurb] Mark int and bool cases for Decimal.from_float as safe fixes (FURB164) (#19468)ruff] Fix RUF033 for named default expressions (#19115)flake8-blind-except] Change BLE001 to permit logging.critical(..., exc_info=True) (#19520)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.7/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.7/ruff-installer.ps1 | iex"
Nothing published for this version
\[flake8-use-pathlib\] Add autofix for PTH101, PTH104, PTH105, PTH121
flake8-use-pathlib] Add autofix for PTH101, PTH104, PTH105, PTH121 (#19404)ruff] Support byte strings (RUF055) (#18926)unreachable panic in parser (#19183)flake8-pyi] Skip fix if all Union members are None (PYI016) (#19416)perflint] Parenthesize generator expressions (PERF401) (#19325)pylint] Handle empty comments after line continuation (PLR2044) (#19405)pep8-naming] Fix N802 false positives for CGIHTTPRequestHandler and SimpleHTTPRequestHandler (#19432)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.5/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.5/ruff-installer.ps1 | iex"
\[flake8-type-checking, pyupgrade, ruff\] Add from __future__ import annotations when it would allow new fixes (TC001, TC002, TC003, UP037, RUF013)
flake8-type-checking, pyupgrade, ruff] Add from __future__ import annotations when it would allow new fixes (TC001, TC002, TC003, UP037, RUF013) (#19100)flake8-use-pathlib] Add autofix for PTH109 (#19245)pylint] Detect indirect pathlib.Path usages for unspecified-encoding (PLW1514) (#19304)flake8-bugbear] Fix B017 false negatives for keyword exception arguments (#19217)flake8-use-pathlib] Fix false negative on direct Path() instantiation (PTH210) (#19388)flake8-django] Fix DJ008 false positive for abstract models with type-annotated abstract field (#19221)isort] Fix I002 import insertion after docstring with multiple string statements (#19222)isort] Treat form feed as valid whitespace before a semicolon (#19343)pydoclint] Fix SyntaxError from fixes with line continuations (D201, D202) (#19246)refurb] FURB164 fix should validate arguments and should usually be marked unsafe (#19136)flake8-use-pathlib] Skip single dots for invalid-pathlib-with-suffix (PTH210) on versions >= 3.14 (#19331)pep8_naming] Avoid false positives on standard library functions with uppercase names (N802) (#18907)pycodestyle] Handle brace escapes for t-strings in logical lines (#19358)pylint] Extend invalid string character rules to include t-strings (#19355)ruff] Allow strict kwarg when checking for starmap-zip (RUF058) in Python 3.14+ (#19333)flake8-type-checking] Make TC010 docs example more realistic (#19356)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.4/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.4/ruff-installer.ps1 | iex"
\[flake8-bugbear\] Support non-context-manager calls in B017
flake8-bugbear] Support non-context-manager calls in B017 (#19063)flake8-use-pathlib] Add autofixes for PTH100, PTH106, PTH107, PTH108, PTH110, PTH111, PTH112, PTH113, PTH114, PTH115, PTH117, PTH119, PTH120 (#19213)flake8-use-pathlib] Add autofixes for PTH203, PTH204, PTH205 (#18922)flake8-return] Fix false-positive for variables used inside nested functions in RET504 (#18433)flake8-type-checking] Fix syntax error introduced by fix (TC008) (#19150)pyupgrade] Keyword arguments in super should suppress the UP008 fix (#19131)flake8-pyi] Make example error out-of-the-box (PYI007, PYI008) (#19103)flake8-simplify] Make example error out-of-the-box (SIM116) (#19111)flake8-type-checking] Make example error out-of-the-box (TC001) (#19151)flake8-use-pathlib] Make example error out-of-the-box (PTH210) (#19189)pycodestyle] Make example error out-of-the-box (E272) (#19191)pycodestyle] Make example not raise unnecessary SyntaxError (E114) (#19190)pydoclint] Make example error out-of-the-box (DOC501) (#19218)pylint, pyupgrade] Fix syntax errors in examples (PLW1501, UP028) (#19127)pylint] Update missing-maxsplit-arg docs and error to suggest proper usage (PLC0207) (#18949)flake8-bandit] Make example error out-of-the-box (S412) (#19241)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.3/ruff-installer.ps1 | iex"
\[flake8-pyi\] Expand Optional[A] to A | None (PYI016)
flake8-pyi] Expand Optional[A] to A | None (PYI016) (#18572)pyupgrade] Mark UP008 fix safe if no comments are in range (#18683)flake8-comprehensions] Fix C420 to prepend whitespace when needed (#18616)perflint] Fix PERF403 panic on attribute or subscription loop variable (#19042)pydocstyle] Fix D413 infinite loop for parenthesized docstring (#18930)pylint] Fix PLW0108 autofix introducing a syntax error when the lambda's body contains an assignment expression (#18678)refurb] Fix false positive on empty tuples (FURB168) (#19058)ruff] Allow more field calls from attrs (RUF009) (#19021)ruff] Fix syntax error introduced for an empty string followed by a u-prefixed string (UP025) (#18899)flake8-executable] Allow uvx in shebang line (EXE003) (#18967)pandas] Avoid flagging PD002 if pandas is not imported (#18963)pyupgrade] Avoid PEP-604 unions with typing.NamedTuple (UP007, UP045) (#18682)import-outside-top-level (PLC0415) and lint.flake8-tidy-imports.banned-module-level-imports (#18733)format.skip-magic-trailing-comma example (#19095)airflow] Make AIR302 example error out-of-the-box (#18988)airflow] Make AIR312 example error out-of-the-box (#18989)flake8-annotations] Make ANN401 example error out-of-the-box (#18974)flake8-async] Make ASYNC100 example error out-of-the-box (#18993)flake8-async] Make ASYNC105 example error out-of-the-box (#19002)flake8-async] Make ASYNC110 example error out-of-the-box (#18975)flake8-async] Make ASYNC210 example error out-of-the-box (#18977)flake8-async] Make ASYNC220, ASYNC221, and ASYNC222 examples error out-of-the-box (#18978)flake8-async] Make ASYNC251 example error out-of-the-box (#18990)flake8-bandit] Make S201 example error out-of-the-box (#19017)flake8-bandit] Make S604 and S609 examples error out-of-the-box (#19049)flake8-bugbear] Make B028 example error out-of-the-box (#19054)flake8-bugbear] Make B911 example error out-of-the-box (#19051)flake8-datetimez] Make DTZ011 example error out-of-the-box (#19055)flake8-datetimez] Make DTZ901 example error out-of-the-box (#19056)flake8-pyi] Make PYI032 example error out-of-the-box (#19061)flake8-pyi] Make example error out-of-the-box (PYI014, PYI015) (#19097)flake8-pyi] Make example error out-of-the-box (PYI042) (#19101)flake8-pyi] Make example error out-of-the-box (PYI059) (#19080)flake8-pyi] Make example error out-of-the-box (PYI062) (#19079)flake8-pytest-style] Make example error out-of-the-box (PT023) (#19104)flake8-pytest-style] Make example error out-of-the-box (PT030) (#19105)flake8-quotes] Make example error out-of-the-box (Q003) (#19106)flake8-simplify] Make example error out-of-the-box (SIM110) (#19113)flake8-simplify] Make example error out-of-the-box (SIM113) (#19109)flake8-simplify] Make example error out-of-the-box (SIM401) (#19110)pyflakes] Fix backslash in docs (F621) (#19098)pylint] Fix PLC0415 example (#18970)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.2/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.2/ruff-installer.ps1 | iex"
\[flake8-errmsg\] Extend EM101 to support byte strings
flake8-errmsg] Extend EM101 to support byte strings (#18867)flake8-use-pathlib] Add autofix for PTH202 (#18763)pygrep-hooks] Add AsyncMock methods to invalid-mock-access (PGH005) (#18547)pylint] Ignore __init__.py files in (PLC0414) (#18400)ruff] Trigger RUF037 for empty string and byte strings (#18862).pyi files (#18888)remove_argument (#18805)flake8-logging] Avoid false positive for exc_info=True outside logger.exception (LOG014) (#18737)flake8-pytest-style] Enforce pytest import for decorators (#18779)flake8-pytest-style] Mark autofix for PT001 and PT023 as unsafe if there's comments in the decorator (#18792)flake8-pytest-style] PT001/PT023 fix makes syntax error on parenthesized decorator (#18782)flake8-raise] Make fix unsafe if it deletes comments (RSE102) (#18788)flake8-simplify] Fix SIM911 autofix creating a syntax error (#18793)flake8-simplify] Fix false negatives for shadowed bindings (SIM910, SIM911) (#18794)flake8-simplify] Preserve original behavior for except () and bare except (SIM105) (#18213)flake8-pyi] Fix PYI041's fix causing TypeError with None | None | ... (#18637)perflint] Fix PERF101 autofix creating a syntax error and mark autofix as unsafe if there are comments in the list call expr (#18803)perflint] Fix false negative in PERF401 (#18866)pylint] Avoid flattening nested min/max when outer call has single argument (PLW3301) (#16885)pylint] Fix PLC2801 autofix creating a syntax error (#18857)pylint] Mark PLE0241 autofix as unsafe if there's comments in the base classes (#18832)pylint] Suppress PLE2510/PLE2512/PLE2513/PLE2514/PLE2515 autofix if the text contains an odd number of backslashes (#18856)refurb] Detect more exotic float literals in FURB164 (#18925)refurb] Fix FURB163 autofix creating a syntax error for yield expressions (#18756)refurb] Mark FURB129 autofix as unsafe if there's comments in the readlines call (#18858)ruff] Fix false positives and negatives in RUF010 (#18690)analyze.direction variant names (#18892)flake8-return] Mark RET501 fix unsafe if comments are inside (#18780)flake8-async] Fix detection for large integer sleep durations in ASYNC116 rule (#18767)flake8-async] Mark autofix for ASYNC115 as unsafe if the call expression contains comments (#18753)flake8-bugbear] Mark autofix for B004 as unsafe if the hasattr call expr contains comments (#18755)flake8-comprehension] Mark autofix for C420 as unsafe if there's comments inside the dict comprehension (#18768)flake8-comprehensions] Handle template strings for comprehension fixes (#18710)flake8-future-annotations] Add autofix (FA100) (#18903)pyflakes] Mark F504/F522/F523 autofix as unsafe if there's a call with side effect (#18839)pylint] Allow fix with comments and document performance implications (PLW3301) (#18936)pylint] Detect more exotic NaN literals in PLW0177 (#18630)pylint] Fix PLC1802 autofix creating a syntax error and mark autofix as unsafe if there's comments in the len call (#18836)pyupgrade] Extend version detection to include sys.version_info.major (UP036) (#18633)ruff] Add lint rule RUF064 for calling chmod with non-octal integers (#18541)ruff] Added cls.__dict__.get('__annotations__') check (RUF063) (#18233)ruff] Frozen dataclass default should be valid (RUF009) (#18735)perflint] Small docs improvement to PERF401 (#18786)pyupgrade]: Use super(), not __super__ in error messages (UP008) (#18743)flake8-pie] Small docs fix to PIE794 (#18829)flake8-pyi] Correct collections-named-tuple example to use PascalCase assignment (#16884)flake8-pie] Add note on type checking benefits to unnecessary-dict-kwargs (PIE804) (#18666)pycodestyle] Clarify PEP 8 relationship to whitespace-around-operator rules (#18870)flake8-logging] Add fix safety section to LOG002 (#18840)pyupgrade] Add fix safety section to UP010 (#18838)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.1/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.1/ruff-installer.ps1 | iex"
The following rules have been deprecated:
Check out the blog post for a migration guide and overview of the changes!
Detection of more syntax errors
Ruff now detects version-related syntax errors, such as the use of the match
statement on Python versions before 3.10, and syntax errors emitted by
CPython's compiler, such as irrefutable match patterns before the final
case arm.
New default Python version handling for syntax errors
Ruff will default to the latest supported Python version (3.13) when checking for the version-related syntax errors mentioned above to prevent false positives in projects without a Python version configured. The default in all other cases, like applying lint rules, is unchanged and remains at the minimum supported Python version (3.9).
Updated f-string formatting
Ruff now formats multi-line f-strings with format specifiers to avoid adding a line break after the format specifier. This addresses a change to the Python grammar in version 3.13.4 that made such a line break a syntax error.
rust-toolchain.toml is no longer included in source distributions
The rust-toolchain.toml is used to specify a higher Rust version than Ruff's
minimum supported Rust version (MSRV) for development and building release
artifacts. However, when present in source distributions, it would also cause
downstream package maintainers to pull in the same Rust toolchain, even if
their available toolchain was MSRV-compatible.
The following rules have been removed:
suspicious-xmle-tree-usage (S320)The following rules have been deprecated:
The following rules have been stabilized and are no longer in preview:
for-loop-writes (FURB122)check-and-remove-from-set (FURB132)verbose-decimal-constructor (FURB157)fromisoformat-replace-z (FURB162)int-on-sliced-str (FURB166)exc-info-outside-except-handler (LOG014)import-outside-top-level (PLC0415)unnecessary-dict-index-lookup (PLR1733)nan-comparison (PLW0177)eq-without-hash (PLW1641)pytest-parameter-with-default-argument (PT028)pytest-warns-too-broad (PT030)pytest-warns-with-multiple-statements (PT031)invalid-formatter-suppression-comment (RUF028)dataclass-enum (RUF049)class-with-mixed-type-vars (RUF053)unnecessary-round (RUF057)starmap-zip (RUF058)non-pep604-annotation-optional (UP045)non-pep695-generic-class (UP046)non-pep695-generic-function (UP047)private-type-parameter (UP049)The following behaviors have been stabilized:
collection-literal-concatenation (RUF005) now recognizes slices, in
addition to list literals and variables.readlines-in-for (FURB129) is now marked as always safe.if-else-block-instead-of-if-exp (SIM108) will now further simplify
expressions to use or instead of an if expression, where possible.unused-noqa (RUF100) now checks for file-level noqa comments as well
as inline comments.subprocess-without-shell-equals-true (S603) now accepts literal strings,
as well as lists and tuples of literal strings, as trusted input.boolean-type-hint-positional-argument (FBT001) now applies to types that
include bool, like bool | int or typing.Optional[bool], in addition to
plain bool annotations.non-pep604-annotation-union (UP007) has now been split into two rules.
UP007 now applies only to typing.Union, while
non-pep604-annotation-optional (UP045) checks for use of
typing.Optional. UP045 has also been stabilized in this release, but you
may need to update existing include, ignore, or noqa settings to
accommodate this change.ruff] Check for non-context-manager use of pytest.raises, pytest.warns, and pytest.deprecated_call (RUF061) (#17368)readlines (#18542)\r and \r\n handling in t- and f-string debug texts (#18673)} when f-string expression has a format specifier (#18704)flake8-pyi] Avoid syntax error in the case of starred and keyword arguments (PYI059) (#18611)flake8-return] Fix RET504 autofix generating a syntax error (#18428)pep8-naming] Suppress fix for N804 and N805 if the recommended name is already used (#18472)pycodestyle] Avoid causing a syntax error in expressions spanning multiple lines (E731) (#18479)pyupgrade] Suppress UP008 if super is shadowed (#18688)refurb] Parenthesize lambda and ternary expressions (FURB122, FURB142) (#18592)ruff] Handle extra arguments to deque (RUF037) (#18614)ruff] Preserve parentheses around deque in fix for unnecessary-empty-iterable-within-deque-call (RUF037) (#18598)ruff] Validate arguments before offering a fix (RUF056) (#18631)ruff] Skip fix for RUF059 if dummy name is already bound (#18509)pylint] Fix PLW0128 to check assignment targets in square brackets and after asterisks (#18665)return statements (B909) (#18408)ty: comments as pragma comments (#18532)flake8-pyi] Apply custom-typevar-for-self to string annotations (PYI019) (#18311)pyupgrade] Don't offer a fix for Optional[None] (UP007, UP045) (#18545)pyupgrade] Fix super(__class__, self) detection (UP008) (#18478)refurb] Make the fix for FURB163 unsafe for log2, log10, *args, and deleted comments (#18645)* from glob pattern example for per-file-target-version (#18709)pylint] De-emphasize __hash__ = Parent.__hash__ (PLW1641) (#18613)refurb] Add a note about float literal handling (FURB157) (#18615)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.12.0/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.12.0/ruff-installer.ps1 | iex"
\[airflow\] Add unsafe fix for module moved cases (AIR301,AIR311,AIR312,AIR302) (#18367,#18366,#18363,#18093)
airflow] Add unsafe fix for module moved cases (AIR301,AIR311,AIR312,AIR302) (#18367,#18366,#18363,#18093)refurb] Add coverage of set and frozenset calls (FURB171) (#18035)refurb] Mark FURB180 fix unsafe when class has bases (#18149)perflint] Fix missing parentheses for lambda and ternary conditions (PERF401, PERF403) (#18412)pyupgrade] Apply UP035 only on py313+ for get_type_hints() (#18476)pyupgrade] Make fix unsafe if it deletes comments (UP004,UP050) (#18393, #18390)fastapi] Avoid false positive for class dependencies (FAST003) (#18271)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.13/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.13/ruff-installer.ps1 | iex"
\[airflow\] Revise fix titles (AIR3)
airflow] Revise fix titles (AIR3) (#18215)pylint] Implement missing-maxsplit-arg (PLC0207) (#17454)pyupgrade] New rule UP050 (useless-class-metaclass-type) (#18334)flake8-use-pathlib] Replace os.symlink with Path.symlink_to (PTH211) (#18337)flake8-bugbear] Ignore __debug__ attribute in B010 (#18357)flake8-async] Fix anyio.sleep argument name (ASYNC115, ASYNC116) (#18262)refurb] Fix FURB129 autofix generating invalid syntax (#18235)flake8-implicit-str-concat] Add autofix for ISC003 (#18256)pycodestyle] Improve the diagnostic message for E712 (#18328)flake8-2020] Fix diagnostic message for != comparisons (YTT201) (#18293)pyupgrade] Make fix unsafe if it deletes comments (UP010) (#18291)flake8-bugbear] Add fix safety section (B006) (#17652)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.12/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.12/ruff-installer.ps1 | iex"
\[airflow\] Add autofixes for AIR302 and AIR312
airflow] Add autofixes for AIR302 and AIR312 (#17942)airflow] Move rules from AIR312 to AIR302 (#17940)airflow] Update AIR301 and AIR311 with the latest Airflow implementations (#17985)flake8-simplify] Enable fix in preview mode (SIM117) (#18208)[] and _ (#18147)pylint] Fix PLW1514 not recognizing the encoding positional argument of codecs.open (#18109)flake8-print] Improve print/pprint docs for T201 and T203 (#18130)flake8-simplify] Add fix safety section (SIM110,SIM210) (#18114,#18100)pylint] Fix docs example that produced different output (PLW0603) (#18216)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.11/ruff-installer.ps1 | iex"
\[pyupgrade\] Add resource.error as deprecated alias of OSError (UP024)
ruff] Implement a recursive check for RUF060 (#17976)airflow] Enable autofixes for AIR301 and AIR311 (#17941)airflow] Apply try catch guard to all AIR3 rules (#17887)airflow] Extend AIR311 rules (#17913)flake8-bugbear] Ignore B028 if skip_file_prefixes is present (#18047)flake8-pie] Mark autofix for PIE804 as unsafe if the dictionary contains comments (#18046)flake8-simplify] Correct behavior for str.split/rsplit with maxsplit=0 (SIM905) (#18075)flake8-simplify] Fix SIM905 autofix for rsplit creating a reversed list literal (#18045)flake8-use-pathlib] Suppress diagnostics for all os.* functions that have the dir_fd parameter (PTH) (#17968)refurb] Mark autofix as safe only for number literals (FURB116) (#17692)flake8-bandit] Skip S608 for expressionless f-strings (#17999)flake8-pytest-style] Don't recommend usefixtures for parametrize values (PT019) (#17650)pyupgrade] Add resource.error as deprecated alias of OSError (UP024) (#17933)flake8-simplify] Add fix safety section (SIM103) (#18086)flake8-simplify] Add fix safety section (SIM112) (#18099)pylint] Add fix safety section (PLC0414) (#17802)pylint] Add fix safety section (PLE4703) (#17824)pylint] Add fix safety section (PLW1514) (#17932)pylint] Add fix safety section (PLW3301) (#17878)ruff] Add fix safety section (RUF007) (#17755)ruff] Add fix safety section (RUF033) (#17760)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.10/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.10/ruff-installer.ps1 | iex"
Default to latest supported Python version for version-related syntax errors
airflow] Fix SQLTableCheckOperator typo (AIR302) (#17946)airflow] Remove airflow.utils.dag_parsing_context.get_parsing_context (AIR301) (#17852)airflow] Skip attribute check in try catch block (AIR301) (#17790)flake8-bandit] Mark tuples of string literals as trusted input in S603 (#17801)isort] Check full module path against project root(s) when categorizing first-party imports (#16565)ruff] Add new rule in-empty-collection (RUF060) (#16480)combine call for lint.typing-extensions setting (#17823)flake8-async] Fix module name in ASYNC110, ASYNC115, and ASYNC116 fixes (#17774)pyupgrade] Add spaces between tokens as necessary to avoid syntax errors in UP018 autofix (#17648)refurb] Fix false positive for float and complex numbers in FURB116 (#17661)PLC2801, PLR1722, and RUF013 (#17825, #17826, #17759)check-typed-exception from S110 and S112 (#17786)ruff analyze graph (#17743)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.9/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.9/ruff-installer.ps1 | iex"
\[airflow\] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR302, AIR311) (#17553, #17570, #17571)
airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR302, AIR311) (#17553, #17570, #17571)airflow] Extend AIR301 rule (#17598)airflow] Update existing AIR302 rules with better suggestions (#17542)refurb] Mark fix as safe for readlines-in-for (FURB129) (#17644)nonlocal declaration at module level (#17559)x = *y (#17624)flake8-pyi] Ensure Literal[None,] | Literal[None,] is not autofixed to None | None (PYI061) (#17659)flake8-use-pathlib] Avoid suggesting Path.iterdir() for os.listdir with file descriptor (PTH208) (#17715)flake8-use-pathlib] Fix PTH104 false positive when rename is passed a file descriptor (#17712)flake8-use-pathlib] Fix PTH116 false positive when stat is passed a file descriptor (#17709)flake8-use-pathlib] Fix PTH123 false positive when open is passed a file descriptor from a function call (#17705)pycodestyle] Fix duplicated diagnostic in E712 (#17651)pylint] Detect global declarations in module scope (PLE0118) (#17411)async-comprehension-in-sync-comprehension more specific (#17460)typing_extensions imports (#17611)lint.pydocstyle.ignore-var-parameters option (#17740)ASYNC116, FLY002, D200, RUF005, RUF017, RUF027, RUF028, RUF057) (#17497, #17496, #17502, #17484, #17480, #17485, #17722, #17483)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.8/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.8/ruff-installer.ps1 | iex"
\[airflow\] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR301)
airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR301) (#17355)perflint] Implement fix for manual-dict-comprehension (PERF403) (#16719)airflow] Fix typos in provider package names (AIR302, AIR312) (#17574)flake8-type-checking] Visit keyword arguments in checks involving typing.cast/typing.NewType arguments (#17538)pyupgrade] Preserve parenthesis when fixing native literals containing newlines (UP018) (#17220)refurb] Mark the FURB161 fix unsafe except for integers and booleans (#17240)perflint] Allow list function calls to be replaced with a comprehension (PERF401) (#17519)pycodestyle] Auto-fix redundant boolean comparison (E712) (#17090)pylint] make fix unsafe if delete comments (PLR1730) (#17459)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.7/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.7/ruff-installer.ps1 | iex"
Avoid adding whitespace to the end of a docstring after an escaped quote
airflow] Extract AIR311 from AIR301 rules (AIR301, AIR311) (#17310, #17422)\ is at end of file (#17409)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.6/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.6/ruff-installer.ps1 | iex"
\[airflow\] Add missing AIR302 attribute check
airflow] Add missing AIR302 attribute check (#17115)airflow] Expand module path check to individual symbols (AIR302) (#17278)airflow] Extract AIR312 from AIR302 rules (AIR302, AIR312) (#17152)airflow] Update oudated AIR301, AIR302 rules (#17123)await (#17282)flake8-pie] Avoid false positive for multiple assignment with auto() (PIE796) (#17274)ruff] Fix RUF100 to detect unused file-level noqa directives with specific codes (#17042) (#17061)flake8-pytest-style] Avoid false positive for legacy form of pytest.raises (PT011) (#17231)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.5/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.5/ruff-installer.ps1 | iex"
\[ruff\] Implement invalid-rule-code as RUF102
ruff] Implement invalid-rule-code as RUF102 (#17138)match mapping patterns (#17129)match class patterns (#17186)match patterns (#17184)typing.Annotated subscripts (#17201)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.4/ruff-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.4/ruff-installer.ps1 | iex"
\[airflow\] Add more autofixes for AIR302 (#16876, #16977, #16976, #16965)
airflow] Add more autofixes for AIR302 (#16876, #16977, #16976, #16965)airflow] Move AIR301 to AIR002 (#16978)airflow] Move AIR302 to AIR301 and AIR303 to AIR302 (#17151)flake8-bandit] Mark str and list[str] literals as trusted input (S603) (#17136)ruff] Support slices in RUF005 (#17078)case pattern before final case (#16905)case pattern (#16957)return, yield, and for (#17134)__debug__ (#16984)panic! when running Ruff from a deleted directory (#16903) (#17054)pyproject.toml correctly when it is passed via stdin (#16971)flake8-import-conventions] Add import numpy.typing as npt to default flake8-import-conventions.aliases (#17133)refurb] Document why UserDict, UserList, and UserString are preferred over dict, list, and str (FURB189) (#16927)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.3/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.3/ruff-installer.ps1 | iex"
[syntax-errors] Fix false-positive syntax errors emitted for annotations on variadic parameters before Python 3.11
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.2/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.2/ruff-installer.ps1 | iex"
\[airflow\] Add chain, chain_linear and cross_downstream for AIR302
airflow] Add chain, chain_linear and cross_downstream for AIR302 (#16647)FixAll action in presence of version-specific syntax errors (#16848)flake8-bandit] Allow raw strings in suspicious-mark-safe-usage (S308) #16702 (#16770)refurb] Avoid panicking unwrap in verbose-decimal-constructor (FURB157) (#16777)refurb] Fix starred expressions fix (FURB161) (#16550)--statistics reporting for unsafe fixes (#16756)flake8-executables] Allow uv run in shebang line for shebang-missing-python (EXE003) (#16849,#16855)--exit-non-zero-on-format (#16009)__init__.py (#16818)flake8-gettext] Swap format- and printf-in-get-text-func-call examples (INT002, INT003) (#16769)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.1/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.1/ruff-installer.ps1 | iex"
This is a follow-up to release 0.10.0. The requires-python inference changes were unintentionally omitted from 0.10.0, and have been included here. Th
This is a follow-up to release 0.10.0. The requires-python inference changes were unintentionally omitted from 0.10.0, and have been included here. This release also includes stabilization of the preview behavior for PGH004.
Changes to how the Python version is inferred when a target-version is not specified (#16319)
In previous versions of Ruff, you could specify your Python version with:
target-version option in a ruff.toml file or the [tool.ruff] section of a pyproject.toml file.project.requires-python field in a pyproject.toml file with a [tool.ruff] section.These options worked well in most cases, and are still recommended for fine control of the Python version. However, because of the way Ruff discovers config files, pyproject.toml files without a [tool.ruff] section would be ignored, including the requires-python setting. Ruff would then use the default Python version (3.9 as of this writing) instead, which is surprising when you've attempted to request another version.
In v0.10, config discovery has been updated to address this issue:
ruff.toml file without a target-version, it will check
for a pyproject.toml file in the same directory and respect its
requires-python version, even if it does not contain a [tool.ruff]
section.requires-python field of the closest pyproject.toml in a parent directory will take precedence.ruff.tomlor pyproject.toml with a
[tool.ruff] section) in the directory of the file being checked, Ruff will
search for the closest pyproject.toml in the parent directories and use its
requires-python setting.The following behaviors have been stabilized:
blanket-noqa (PGH004): Also detect blanked file-level noqa comments (and not just line level comments).for statement iterator clause before Python 3.9 (#16558)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.11.0/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.11.0/ruff-installer.ps1 | iex"
The following rules have been deprecated:
Check out the blog post for a migration guide and overview of the changes!
See also, the "Remapped rules" section which may result in disabled rules.
Changes to how the Python version is inferred when a target-version is not specified (#16319)
While this change was intended to be released in 0.10.0, it was unintentionally omitted. It was subsequently released in 0.11.0 — see the changelog there for details.
Updated TYPE_CHECKING behavior (#16669)
Previously, Ruff only recognized typechecking blocks that tested the typing.TYPE_CHECKING symbol. Now, Ruff recognizes any local variable named TYPE_CHECKING. This release also removes support for the legacy if 0: and if False: typechecking checks. Use a local TYPE_CHECKING variable instead.
More robust noqa parsing (#16483)
The syntax for both file-level and in-line suppression comments has been unified and made more robust to certain errors. In most cases, this will result in more suppression comments being read by Ruff, but there are a few instances where previously read comments will now log an error to the user instead. Please refer to the documentation on Error suppression for the full specification.
Avoid unnecessary parentheses around with statements with a single context manager and a trailing comment (#14005)
This change fixes a bug in the formatter where it introduced unnecessary parentheses around with statements with a single context manager and a trailing comment. This change may result in a change in formatting for some users.
Bump alpine default tag to 3.21 for derived Docker images (#16456)
Alpine 3.21 was released in Dec 2024 and is used in the official Alpine-based Python images. Now the ruff:alpine image will use 3.21 instead of 3.20 and ruff:alpine3.20 will no longer be updated.
The following rules have been deprecated:
non-pep604-isinstance (UP038)suspicious-xmle-tree-usage (S320)The following rules have been remapped to new rule codes:
unsafe-markup-use]: RUF035 to S704The following rules have been stabilized and are no longer in preview:
batched-without-explicit-strict (B911)unnecessary-dict-comprehension-for-iterable (C420)datetime-min-max (DTZ901)fast-api-unused-path-parameter (FAST003)root-logger-call (LOG015)len-test (PLC1802)shallow-copy-environ (PLW1507)os-listdir (PTH208)invalid-pathlib-with-suffix (PTH210)invalid-assert-message-literal-argument (RUF040)unnecessary-nested-literal (RUF041)unnecessary-cast-to-int (RUF046)map-int-version-parsing (RUF048)if-key-in-dict-del (RUF051)unsafe-markup-use (S704). This rule has also been renamed from RUF035.split-static-string (SIM905)runtime-cast-value (TC006)unquoted-type-alias (TC007)non-pep646-unpack (UP044)The following behaviors have been stabilized:
bad-staticmethod-argument (PLW0211) invalid-first-argument-name-for-class-method (N804): __new__ methods are now no longer flagged by invalid-first-argument-name-for-class-method (N804) but instead by bad-staticmethod-argument (PLW0211)bad-str-strip-call (PLE1310): The rule now applies to objects which are known to have type str or bytes.custom-type-var-for-self (PYI019): More accurate detection of custom TypeVars replaceable by Self. The range of the diagnostic is now the full function header rather than just the return annotation.invalid-argument-name (N803): Ignore argument names of functions decorated with typing.overrideinvalid-envvar-default (PLW1508): Detect default value arguments to os.environ.get with invalid type.pytest-raises-with-multiple-statements (PT012) pytest-warns-with-multiple-statements (PT031): Allow for statements with an empty body in pytest.raises and pytest.warns with statements.redundant-open-modes (UP015): The diagnostic range is now the range of the redundant mode argument where it previously was the range of the entire open call. You may have to replace your noqa comments when suppressing UP015.stdlib-module-shadowing (A005): Changes the default value of lint.flake8-builtins.strict-checking from true to false.type-none-comparison (FURB169): Now also recognizes type(expr) is type(None) comparisons where expr isn't a name expression.The following fixes or improvements to fixes have been stabilized:
repeated-equality-comparison (PLR1714) (#16685)needless-bool (SIM103) (#16684)unused-private-type-var (PYI018) (#16682)ruff.printDebugInformation (#16617)flake8-builtins] Deprecate the builtins- prefixed options in favor of the unprefixed options (e.g. builtins-allowed-modules is now deprecated in favor of allowed-modules) (#16092)ruff] Fix last_tag/commits_since_last_tag for version command (#16686)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.10.0/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.10.0/ruff-installer.ps1 | iex"
\[ruff\] Add new rule RUF059: Unused unpacked assignment
ruff] Add new rule RUF059: Unused unpacked assignment (#16449)syntax-errors] Detect assignment expressions before Python 3.8 (#16383)syntax-errors] Named expressions in decorators before Python 3.9 (#16386)syntax-errors] Parenthesized keyword argument names after Python 3.8 (#16482)syntax-errors] Positional-only parameters before Python 3.8 (#16481)syntax-errors] Tuple unpacking in return and yield before Python 3.8 (#16485)syntax-errors] Type parameter defaults before Python 3.13 (#16447)syntax-errors] Type parameter lists before Python 3.12 (#16479)syntax-errors] except* before Python 3.11 (#16446)syntax-errors] type statements before Python 3.12 (#16478)flake8-simplify] Exempt unittest context methods for SIM115 rule (#16439)pyupgrade] Do not offer fix when at least one target is global/nonlocal (UP028) (#16451)flake8-builtins] Ignore variables matching module attribute names (A001) (#16454)pylint] Convert code keyword argument to a positional argument in fix for (PLR1722) (#16424)description to check_name in GitLab output serializer (#16437)pydocstyle] Clarify that D417 only checks docstrings with an arguments section (#16494)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.10/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.10/ruff-installer.ps1 | iex"
Fix caching of unsupported-syntax errors
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.9/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.9/ruff-installer.ps1 | iex"
Start detecting version-related syntax errors in the parser
pylint] Mark fix unsafe (PLW1507) (#16343)pylint] Catch case np.nan/case math.nan in match statements (PLW0177) (#16378)ruff] Add more Pydantic models variants to the list of default copy semantics (RUF012) (#16291)configurationPreference is editorOnly (#16381)ruff.configuration to allow inline config (#16296)per-file-target-version option (#16257)refurb] Do not consider docstring(s) (FURB156) (#16391)flake8-self] Ignore attribute accesses on instance-like variables (SLF001) (#16149)pylint] Fix false positives, add missing methods, and support positional-only parameters (PLE0302) (#16263)flake8-pyi] Mark PYI030 fix unsafe when comments are deleted (#16322)S611 (#16316)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.8/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.8/ruff-installer.ps1 | iex"
\[airflow\] Improve the internal logic to differentiate deprecated symbols (AIR303)
__new__ methods as special function type for enforcing class method or static method rules (#13305)airflow] Improve the internal logic to differentiate deprecated symbols (AIR303) (#16013)refurb] Manual timezone monkeypatching (FURB162) (#16113)ruff] Implicit class variable in dataclass (RUF045) (#14349)ruff] Skip singleton starred expressions for incorrectly-parenthesized-tuple-in-subscript (RUF031) (#16083)refurb] Check for subclasses includes subscript expressions (FURB189) (#16155)flake8-debugger] Also flag sys.breakpointhook and sys.__breakpointhook__ (T100) (#16191)pycodestyle] Exempt site.addsitedir(...) calls (E402) (#16251)source.organizeImports.ruff and source.fixAll.ruff code actions for a notebook cell (#16154)ruff.printDebugInformation (#16215)ruff.printDebugInformation (#16214)noqa even when there are no diagnostics (#16178)extends (#15658)flake8-comprehensions] Handle trailing comma in C403 fix (#16110)flake8-pyi] Avoid flagging custom-typevar-for-self on metaclass methods (PYI019) (#16141)pydocstyle] Handle arguments with the same names as sections (D417) (#16011)pylint] Correct ordering of arguments in fix for if-stmt-min-max (PLR1730) (#16080)pylint] Do not offer fix for raw strings (PLE251) (#16132)pyupgrade] Do not upgrade functional TypedDicts with private field names to the class-based syntax (UP013) (#16219)pyupgrade] Handle micro version numbers correctly (UP036) (#16091)pyupgrade] Unwrap unary expressions correctly (UP018) (#15919)refurb] Correctly handle lengths of literal strings in slice-to-remove-prefix-or-suffix (FURB188) (#16237)ruff] Skip RUF001 diagnostics when visiting string type definitions (#16122)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.7/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.7/ruff-installer.ps1 | iex"
\[airflow\] Add external_task.{ExternalTaskMarker, ExternalTaskSensor} for AIR302
airflow] Add external_task.{ExternalTaskMarker, ExternalTaskSensor} for AIR302 (#16014)flake8-builtins] Make strict module name comparison optional (A005) (#15951)flake8-pyi] Extend fix to Python <= 3.9 for redundant-none-literal (PYI061) (#16044)pylint] Also report when the object isn't a literal (PLE1310) (#15985)ruff] Implement indented-form-feed (RUF054) (#16049)ruff] Skip type definitions for missing-f-string-syntax (RUF027) (#16054)flake8-annotations] Correct syntax for typing.Union in suggested return type fixes for ANN20x rules (#16025)flake8-builtins] Match upstream module name comparison (A005) (#16006)flake8-comprehensions] Detect overshadowed list/set/dict, ignore variadics and named expressions (C417) (#15955)flake8-pie] Remove following comma correctly when the unpacked dictionary is empty (PIE800) (#16008)flake8-simplify] Only trigger SIM401 on known dictionaries (#15995)pylint] Do not report calls when object type and argument type mismatch, remove custom escape handling logic (PLE1310) (#15984)pyupgrade] Comments within parenthesized value ranges should not affect applicability (UP040) (#16027)pyupgrade] Don't introduce invalid syntax when upgrading old-style type aliases with parenthesized multiline values (UP040) (#16026)pyupgrade] Ensure we do not rename two type parameters to the same name (UP049) (#16038)pyupgrade] [ruff] Don't apply renamings if the new name is shadowed in a scope of one of the references to the binding (UP049, RUF052) (#16032)ruff] Update RUF009 to behave similar to B008 and ignore attributes with immutable types (#16048)flake8-datetime] Ignore .replace() calls while looking for .astimezone (#16050)flake8-type-checking] Avoid TC004 false positive where the runtime definition is provided by __getattr__ (#16052)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.6/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.6/ruff-installer.ps1 | iex"
Add deprecation warning for ruff-lsp related settings
TYPE_CHECKING for in_type_checking_block (#15719)flake8-comprehensions] Handle builtins at top of file correctly for unnecessary-dict-comprehension-for-iterable (C420) (#15837)flake8-logging] .exception() and exc_info= outside exception handlers (LOG004, LOG014) (#15799)flake8-pyi] Fix incorrect behaviour of custom-typevar-return-type preview-mode autofix if typing was already imported (PYI019) (#15853)flake8-pyi] Fix more complex cases (PYI019) (#15821)flake8-pyi] Make PYI019 autofixable for .py files in preview mode as well as stubs (#15889)flake8-pyi] Remove type parameter correctly when it is the last (PYI019) (#15854)pylint] Fix missing parens in unsafe fix for unnecessary-dunder-call (PLC2801) (#15762)pyupgrade] Better messages and diagnostic range (UP015) (#15872)pyupgrade] Rename private type parameters in PEP 695 generics (UP049) (#15862)refurb] Also report non-name expressions (FURB169) (#15905)refurb] Mark fix as unsafe if there are comments (FURB171) (#15832)ruff] Classes with mixed type variable style (RUF053) (#15841)airflow] BashOperator has been moved to airflow.providers.standard.operators.bash.BashOperator (AIR302) (#15922)flake8-pyi] Add autofix for unused-private-type-var (PYI018) (#15999)flake8-pyi] Significantly improve accuracy of PYI019 if preview mode is enabled (#15888)flake8-comprehensions] Skip when TypeError present from too many (kw)args for C410,C411, and C418 (#15838)flake8-pyi] Rename PYI019 and improve its diagnostic message (#15885)pep8-naming] Ignore @override methods (N803) (#15954)pyupgrade] Reuse replacement logic from UP046 and UP047 to preserve more comments (UP040) (#15840)ruff] Analyze deferred annotations before enforcing mutable-(data)class-default and function-call-in-dataclass-default-argument (RUF008,RUF009,RUF012) (#15921)pycodestyle] Exempt sys.path += ... calls (E402) (#15980)flake8-import-conventions alias conflicts with isort.required-imports bound name (#15918)allOf (#15992)flake8-comprehensions] Unnecessary list comprehension (rewrite as a set comprehension) (C403) - Handle extraneous parentheses around list comprehension (#15877)flake8-comprehensions] Handle trailing comma in fixes for unnecessary-generator-list/set (C400,C401) (#15929)flake8-pyi] Fix several correctness issues with custom-type-var-return-type (PYI019) (#15851)pep8-naming] Consider any number of leading underscore for N801 (#15988)pyflakes] Visit forward annotations in TypeAliasType as types (F401) (#15829)pylint] Correct min/max auto-fix and suggestion for (PL1730) (#15930)refurb] Handle unparenthesized tuples correctly (FURB122, FURB142) (#15953)refurb] Avoid None | None as well as better detection and fix (FURB168) (#15779)ruff-lsp related settings (#15850)linter.md): clarify that Python files are always searched for in subdirectories (#15882)non_pep695_generic_class.rs (#15946)lint.extendIgnore editor setting (#15844)UP049 in UP046 and UP047, add See also section to UP040 (#15956)RUF012 (#15982)ignore and select config (#15883)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.5/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.5/ruff-installer.ps1 | iex"
\[airflow\] Update AIR302 to check for deprecated context keys
airflow] Extend airflow context parameter check for BaseOperator.execute (AIR302) (#15713)airflow] Update AIR302 to check for deprecated context keys (#15144)flake8-bandit] Permit suspicious imports within stub files (S4) (#15822)pylint] Do not trigger PLR6201 on empty collections (#15732)refurb] Do not emit diagnostic when loop variables are used outside loop body (FURB122) (#15757)ruff] Add support for more re patterns (RUF055) (#15764)ruff] Check for shadowed map before suggesting fix (RUF058) (#15790)ruff] Do not emit diagnostic when all arguments to zip() are variadic (RUF058) (#15744)ruff] Parenthesize fix when argument spans multiple lines for unnecessary-round (RUF057) (#15703)flake8-bugbear] Exempt NewType calls where the original type is immutable (B008) (#15765)pylint] Honor banned top-level imports by TID253 in PLC0415. (#15628)pyupgrade] Ignore is_typeddict and TypedDict for deprecated-import (UP035) (#15800)flake8-quotes option (#15788)ruff config (#15603)flake8-comprehensions] Do not emit unnecessary-map diagnostic when lambda has different arity (C417) (#15802)flake8-comprehensions] Parenthesize sorted when needed for unnecessary-call-around-sorted (C413) (#15825)pyupgrade] Handle end-of-line comments for quoted-annotation (UP037) (#15824)trio.run_process and anyio.run_process (#15761)uv init --lib in tutorial (#15718)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.4/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.4/ruff-installer.ps1 | iex"
\[airflow\] Argument fail_stop in DAG has been renamed as fail_fast (AIR302)
airflow] Argument fail_stop in DAG has been renamed as fail_fast (AIR302) (#15633)airflow] Extend AIR303 with more symbols (#15611)flake8-bandit] Report all references to suspicious functions (S3) (#15541)flake8-pytest-style] Do not emit diagnostics for empty for loops (PT012, PT031) (#15542)flake8-simplify] Avoid double negations (SIM103) (#15562)pyflakes] Fix infinite loop with unused local import in __init__.py (F401) (#15517)pylint] Do not report methods with only one EM101-compatible raise (PLR6301) (#15507)pylint] Implement redefined-slots-in-subclass (W0244) (#9640)pyupgrade] Add rules to use PEP 695 generics in classes and functions (UP046, UP047) (#15565, #15659)refurb] Implement for-loop-writes (FURB122) (#10630)ruff] Implement needless-else clause (RUF047) (#15051)ruff] Implement starmap-zip (RUF058) (#15483)flake8-bugbear] Do not raise error if keyword argument is present and target-python version is less or equals than 3.9 (B903) (#15549)flake8-comprehensions] strip parentheses around generators in unnecessary-generator-set (C401) (#15553)flake8-pytest-style] Rewrite references to .exception (PT027) (#15680)flake8-simplify] Mark fixes as unsafe (SIM201, SIM202) (#15626)flake8-type-checking] Fix some safe fixes being labeled unsafe (TC006,TC008) (#15638)isort] Omit trailing whitespace in unsorted-imports (I001) (#15518)pydoclint] Allow ignoring one line docstrings for DOC rules (#13302)pyflakes] Apply redefinition fixes by source code order (F811) (#15575)pyflakes] Avoid removing too many imports in redefined-while-unused (F811) (#15585)pyflakes] Group redefinition fixes by source statement (F811) (#15574)pylint] Include name of base class in message for redefined-slots-in-subclass (W0244) (#15559)ruff] Update fix for RUF055 to use var == value (#15605)unsafe-fixes settings for code actions (#15666)flake8-bandit] Add missing single-line/dotall regex flag (S608) (#15654)flake8-import-conventions] Fix infinite loop between ICN001 and I002 (ICN001) (#15480)flake8-simplify] Do not emit diagnostics for expressions inside string type annotations (SIM222, SIM223) (#15405)pyflakes] Treat arguments passed to the default= parameter of TypeVar as type expressions (F821) (#15679)pyupgrade] Avoid syntax error when the iterable is a non-parenthesized tuple (UP028) (#15543)ruff] Exempt NewType calls where the original type is immutable (RUF009) (#15588)TRY300: Add some extra notes on not catching exceptions you didn't expect (#15036)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.3/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.3/ruff-installer.ps1 | iex"
\[airflow\] Fix typo "security_managr" to "security_manager" (AIR303)
airflow] Fix typo "security_managr" to "security_manager" (AIR303) (#15463)airflow] extend and fix AIR302 rules (#15525)fastapi] Handle parameters with Depends correctly (FAST003) (#15364)flake8-pytest-style] Implement pytest.warns diagnostics (PT029, PT030, PT031) (#15444)flake8-pytest-style] Test function parameters with default arguments (PT028) (#15449)flake8-type-checking] Avoid false positives for | in TC008 (#15201)flake8-todos] Allow VSCode GitHub PR extension style links in missing-todo-link (TD003) (#15519)pyflakes] Show syntax error message for F722 (#15523)Preserve (#15524)ruff.configuration errors (#15452)flatten to improve deserialization error messages (#15414)fastapi] Update Annotated fixes (FAST002) (#15462)flake8-bandit] Check for builtins instead of builtin (S102, PTH123) (#15443)flake8-pathlib] Fix --select for os-path-dirname (PTH120) (#15446)ruff] Fix false positive on global keyword (RUF052) (#15235)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.2/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.2/ruff-installer.ps1 | iex"
\[pycodestyle\] Run too-many-newlines-at-end-of-file on each cell in notebooks (W391)
pycodestyle] Run too-many-newlines-at-end-of-file on each cell in notebooks (W391) (#15308)ruff] Omit diagnostic for shadowed private function parameters in used-dummy-variable (RUF052) (#15376)flake8-bugbear] Improve assert-raises-exception message (B017) (#15389)flake8-pie] Correctly remove wrapping parentheses (PIE800) (#15394)pyupgrade] Handle comments and multiline expressions correctly (UP037) (#15337)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.1/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.1/ruff-installer.ps1 | iex"
Check out the blog post for a migration guide and overview of the changes!
Check out the blog post for a migration guide and overview of the changes!
Ruff now formats your code according to the 2025 style guide. As a result, your code might now get formatted differently. See the formatter section for a detailed list of changes.
This release doesn’t remove or remap any existing stable rules.
The following rules have been stabilized and are no longer in preview:
stdlib-module-shadowing (A005).
This rule has also been renamed: previously, it was called builtin-module-shadowing.builtin-lambda-argument-shadowing (A006)slice-to-remove-prefix-or-suffix (FURB188)boolean-chained-comparison (PLR1716)decimal-from-float-literal (RUF032)post-init-default (RUF033)useless-if-else (RUF034)The following behaviors have been stabilized:
pytest-parametrize-names-wrong-type (PT006): Detect pytest.parametrize calls outside decorators and calls with keyword arguments.module-import-not-at-top-of-file (E402): Ignore pytest.importorskip calls between import statements.mutable-dataclass-default (RUF008) and function-call-in-dataclass-default-argument (RUF009): Add support for attrs.bad-version-info-comparison (PYI006): Extend the rule to check non-stub files.The following fixes or improvements to fixes have been stabilized:
redundant-numeric-union (PYI041)duplicate-union-members (PYI016)This release introduces the new 2025 stable style (#13371), stabilizing the following changes:
ISC001 incompatibility warning (#15123)assert message over breaking the assertion expression (#9457)if guards in match case clauses (#13513)match case patterns (#6933)if keyword for comprehensions where the condition has a leading comment (#12282)with statements with a single context manager for Python 3.8 or older (#10276)max-doc-code-line-length = "dynamic" (#13523)flake8-bugbear] Implement class-as-data-structure (B903) (#9601)flake8-type-checking] Apply quoted-type-alias more eagerly in TYPE_CHECKING blocks and ignore it in stubs (TC008) (#15180)pylint] Ignore eq-without-hash in stub files (PLW1641) (#15310)pyupgrade] Split UP007 into two individual rules: UP007 for Union and UP045 for Optional (UP007, UP045) (#15313)ruff] New rule that detects classes that are both an enum and a dataclass (RUF049) (#15299)ruff] Recode RUF025 to RUF037 (RUF037) (#15258)flake8-builtins] Ignore stdlib-module-shadowing in stub files(A005) (#15350)flake8-return] Add support for functions returning typing.Never (RET503) (#15298)logLevel server setting
which defaults to info. This addresses the issue where users were notified about an error and told to consult the log, but it didn’t contain any messages. (#15232)--config key=value when the key is for a table and it’s a simple valueeradicate] Ignore metadata blocks directly followed by normal blocks (ERA001) (#15330)flake8-django] Recognize other magic methods (DJ012) (#15365)pycodestyle] Avoid false positives related to type aliases (E252) (#15356)pydocstyle] Avoid treating newline-separated sections as sub-sections (D405) (#15311)pyflakes] Remove call when removing final argument from format (F523) (#15309)refurb] Mark fix as unsafe when the right-hand side is a string (FURB171) (#15273)ruff] Treat ) as a regex metacharacter (RUF043, RUF055) (#15318)ruff] Parenthesize the int-call argument when removing the int call would change semantics (RUF046) (#15277)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.9.0/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.9.0/ruff-installer.ps1 | iex"
\[format\]: Preserve multiline implicit concatenated strings in docstring positions
format]: Preserve multiline implicit concatenated strings in docstring positions (#15126)ruff] Add rule to detect empty literal in deque call (RUF025) (#15104)ruff] Avoid reporting when ndigits is possibly negative (RUF057) (#15234)flake8-todos] remove issue code length restriction (TD003) (#15175)pyflakes] Ignore errors in @no_type_check string annotations (F722, F821) (#15215)--verbose (#15237)ruff] Avoid syntax error when removing int over multiple lines (RUF046) (#15230)pyupgrade] Revert "Add all PEP-585 names to UP006 rule" (#15250)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.6/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.6/ruff-installer.ps1 | iex"
\[airflow\] Extend names moved from core to provider (AIR303) (#15145, #15159, #15196, #15216)
airflow] Extend names moved from core to provider (AIR303) (#15145, #15159, #15196, #15216)airflow] Extend rule to check class attributes, methods, arguments (AIR302) (#15054, #15083)fastapi] Update FAST002 to check keyword-only arguments (#15119)flake8-type-checking] Disable TC006 and TC007 in stub files (#15179)pylint] Detect nested methods correctly (PLW1641) (#15032)ruff] Detect more strict-integer expressions (RUF046) (#14833)ruff] Implement falsy-dict-get-fallback (RUF056) (#15160)ruff] Implement unnecessary-round (RUF057) (#14828)TypedDict keys as non-type-expressions (#15073)flake8-comprehensions] Skip C416 if comprehension contains unpacking (#14909)flake8-pie] Allow cast(SomeType, ...) (PIE796) (#15141)flake8-simplify] More precise inference for dictionaries (SIM300) (#15164)flake8-use-pathlib] Catch redundant joins in PTH201 and avoid syntax errors (#15177)pycodestyle] Preserve original value format (E731) (#15097)pydocstyle] Split on first whitespace character (D403) (#15082)pyupgrade] Add all PEP-585 names to UP006 rule (#5454)flake8-type-checking] Improve flexibility of runtime-evaluated-decorators (#15204)pydocstyle] Add setting to ignore missing documentation for *args and **kwargs parameters (D417) (#15210)ruff] Add an allowlist for unsafe-markup-use (RUF035) (#15076)TypeChecker for detecting fastapi routes (#15093)pycodestyle] Avoid false positives and negatives related to type parameter default syntax (E225, E251) (#15214)shebang-not-executable (EXE001) and add git+windows solution to executable bit (#15208)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.5/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.5/ruff-installer.ps1 | iex"
\[airflow\] Extend AIR302 with additional functions and classes
airflow] Extend AIR302 with additional functions and classes (#15015)airflow] Implement moved-to-provider-in-3 for modules that has been moved to Airflow providers (AIR303) (#14764)flake8-use-pathlib] Extend check for invalid path suffix to include the case "." (PTH210) (#14902)perflint] Fix panic in PERF401 when list variable is after the for loop (#14971)perflint] Simplify finding the loop target in PERF401 (#15025)pylint] Preserve original value format (PLR6104) (#14978)ruff] Avoid false positives for RUF027 for typing context bindings (#15037)ruff] Check for ambiguous pattern passed to pytest.raises() (RUF043) (#14966)flake8-bandit] Check S105 for annotated assignment (#15059)flake8-pyi] More autofixes for redundant-none-literal (PYI061) (#14872)pydocstyle] Skip leading whitespace for D403 (#14963)ruff] Skip SQLModel base classes for mutable-class-default (RUF012) (#14949)perflint] Parenthesize walrus expressions in autofix for manual-list-comprehension (PERF401) (#15050)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.4/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.4/ruff-installer.ps1 | iex"
\[airflow\] Add fix to remove deprecated keyword arguments (AIR302)
airflow] Add fix to remove deprecated keyword arguments (AIR302) (#14887)airflow]: Extend rule to include deprecated names for Airflow 3.0 (AIR302) (#14765 and #14804)flake8-bugbear] Improve error messages for except* (B025, B029, B030, B904) (#14815)flake8-bugbear] itertools.batched() without explicit strict (B911) (#14408)flake8-use-pathlib] Dotless suffix passed to Path.with_suffix() (PTH210) (#14779)pylint] Include parentheses and multiple comparators in check for boolean-chained-comparison (PLR1716) (#14781)ruff] Do not simplify round() calls (RUF046) (#14832)ruff] Don't emit used-dummy-variable on function parameters (RUF052) (#14818)ruff] Implement if-key-in-dict-del (RUF051) (#14553)ruff] Mark autofix for RUF052 as always unsafe (#14824)ruff] Teach autofix for used-dummy-variable about TypeVars etc. (RUF052) (#14819)flake8-bugbear] Offer unsafe autofix for no-explicit-stacklevel (B028) (#14829)flake8-pyi] Skip all type definitions in string-or-bytes-too-long (PYI053) (#14797)pyupgrade] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (UP009) (#14728)pyupgrade] Mark fixes for convert-typed-dict-functional-to-class and convert-named-tuple-functional-to-class as unsafe if they will remove comments (UP013, UP014) (#14842)except and except* (#14895)flake8-bugbear] Fix B028 to allow stacklevel to be explicitly assigned as a positional argument (#14868)flake8-bugbear] Skip B028 if warnings.warn is called with *args or **kwargs (#14870)flake8-comprehensions] Skip iterables with named expressions in unnecessary-map (C417) (#14827)flake8-pyi] Also remove self and cls's annotation (PYI034) (#14801)flake8-pytest-style] Fix pytest-parametrize-names-wrong-type (PT006) to edit both argnames and argvalues if both of them are single-element tuples/lists (#14699)perflint] Improve autofix for PERF401 (#14369)pylint] Fix PLW1508 false positive for default string created via a mult operation (#14841)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.3/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.3/ruff-installer.ps1 | iex"
\[airflow\] Avoid deprecated values (AIR302)
airflow] Avoid deprecated values (AIR302) (#14582)airflow] Extend removed names for AIR302 (#14734)ruff] Extend unnecessary-regular-expression to non-literal strings (RUF055) (#14679)ruff] Implement used-dummy-variable (RUF052) (#14611)ruff] Implement unnecessary-cast-to-int (RUF046) (#14697)airflow] Check AIR001 from builtin or providers operators module (#14631)flake8-pytest-style] Remove @ in pytest.mark.parametrize rule messages (#14770)pandas-vet] Skip rules if the panda module hasn't been seen (#14671)pylint] Fix false negatives for ascii and sorted in len-as-condition (PLC1802) (#14692)refurb] Guard hashlib imports and mark hashlib-digest-hex fix as safe (FURB181) (#14694)flake8-import-conventions] Improve syntax check for aliases supplied in configuration for unconventional-import-alias (ICN001) (#14745)@no_type_check contexts (F821, F722) (#14615) (#14726)pep8-naming] Avoid false positive for class Bar(type(foo)) (N804) (#14683)pycodestyle] Handle f-strings properly for invalid-escape-sequence (W605) (#14748)pylint] Ignore @overload in PLR0904 (#14730)refurb] Handle non-finite decimals in verbose-decimal-constructor (FURB157) (#14596)ruff] Avoid emitting assignment-in-assert when all references to the assigned variable are themselves inside asserts (RUF018) (#14661)flake8-use-pathlib rules (#14741)flake8-comprehensions rules (#14729)flake8-type-checking] Expands TC006 docs to better explain itself (#14749)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.2/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.2/ruff-installer.ps1 | iex"
Formatter: Avoid invalid syntax for format-spec with quotes for all Python versions
**) in overlong f-string expressions (#14489)airflow] Avoid implicit schedule argument to DAG and @dag (AIR301) (#14581)flake8-builtins] Exempt private built-in modules (A005) (#14505)flake8-pytest-style] Fix pytest.mark.parametrize rules to check calls instead of decorators (#14515)flake8-type-checking] Implement runtime-cast-value (TC006) (#14511)flake8-type-checking] Implement unquoted-type-alias (TC007) and quoted-type-alias (TC008) (#12927)flake8-use-pathlib] Recommend Path.iterdir() over os.listdir() (PTH208) (#14509)pylint] Extend invalid-envvar-default to detect os.environ.get (PLW1508) (#14512)pylint] Implement len-test (PLC1802) (#14309)refurb] Fix bug where methods defined using lambdas were flagged by FURB118 (#14639)ruff] Auto-add r prefix when string has no backslashes for unraw-re-pattern (RUF039) (#14536)ruff] Implement invalid-assert-message-literal-argument (RUF040) (#14488)ruff] Implement unnecessary-nested-literal (RUF041) (#14323)ruff] Implement unnecessary-regular-expression (RUF055) (#14659)pep8-naming] Eliminate false positives for single-letter names (N811, N814) (#14584)pyflakes] Avoid false positives in @no_type_check contexts (F821, F722) (#14615)ruff] Detect redirected-noqa in file-level comments (RUF101) (#14635)ruff] Mark fixes for unsorted-dunder-all and unsorted-dunder-slots as unsafe when there are complex comments in the sequence (RUF022, RUF023) (#14560)None | None for redundant-none-literal (PYI061) and never-union (RUF020) (#14583, #14589)flake8-bugbear] Fix mutable-contextvar-default to resolve annotated function calls properly (B039) (#14532)flake8-pyi, ruff] Fix traversal of nested literals and unions (PYI016, PYI051, PYI055, PYI062, RUF041) (#14641)flake8-pyi] Avoid rewriting invalid type expressions in unnecessary-type-union (PYI055) (#14660)flake8-type-checking] Avoid syntax errors and type checking problem for quoted annotations autofix (TC003, TC006) (#14634)pylint] Do not wrap function calls in parentheses in the fix for unnecessary-dunder-call (PLC2801) (#14601)ruff] Handle attrs's auto_attribs correctly (RUF009) (#14520)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.1/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.1/ruff-installer.ps1 | iex"
The following deprecated rules have been removed:
Check out the blog post for a migration guide and overview of the changes!
See also, the "Remapped rules" section which may result in disabled rules.
Default to Python 3.9
Ruff now defaults to Python 3.9 instead of 3.8 if no explicit Python version is configured using ruff.target-version or project.requires-python (#13896)
Changed location of pydoclint diagnostics
pydoclint diagnostics now point to the first-line of the problematic docstring. Previously, this was not the case.
If you've opted into these preview rules but have them suppressed using
noqa comments in
some places, this change may mean that you need to move the noqa suppression
comments. Most users should be unaffected by this change.
Use XDG (i.e. ~/.local/bin) instead of the Cargo home directory in the standalone installer
Previously, Ruff's installer used $CARGO_HOME or ~/.cargo/bin for its target install directory. Now, Ruff will be installed into $XDG_BIN_HOME, $XDG_DATA_HOME/../bin, or ~/.local/bin (in that order).
This change is only relevant to users of the standalone Ruff installer (using the shell or PowerShell script). If you installed Ruff using uv or pip, you should be unaffected.
Changes to the line width calculation
Ruff now uses a new version of the unicode-width Rust crate to calculate the line width. In very rare cases, this may lead to lines containing Unicode characters being reformatted, or being considered too long when they were not before (E501).
The following deprecated rules have been removed:
missing-type-self (ANN101)missing-type-cls (ANN102)syntax-error (E999)pytest-missing-fixture-name-underscore (PT004)pytest-incorrect-fixture-name-underscore (PT005)unpacked-list-comprehension (UP027)The following rules have been remapped to new rule codes:
flake8-type-checking: TCH to TCThe following rules have been stabilized and are no longer in preview:
builtin-import-shadowing (A004)mutable-contextvar-default (B039)fast-api-redundant-response-model (FAST001)fast-api-non-annotated-dependency (FAST002)dict-index-missing-items (PLC0206)pep484-style-positional-only-parameter (PYI063)redundant-final-literal (PYI064)bad-version-info-order (PYI066)parenthesize-chained-operators (RUF021)unsorted-dunder-all (RUF022)unsorted-dunder-slots (RUF023)assert-with-print-message (RUF030)unnecessary-default-type-args (UP043)The following behaviors have been stabilized:
ambiguous-variable-name (E741): Violations in stub files are now ignored. Stub authors typically don't control variable names.printf-string-formatting (UP031): Report all printf-like usages even if no autofix is availableThe following fixes have been stabilized:
zip-instead-of-pairwise (RUF007)flake8-datetimez] Exempt min.time() and max.time() (DTZ901) (#14394)flake8-pie] Mark fix as unsafe if the following statement is a string literal (PIE790) (#14393)flake8-pyi] New rule redundant-none-literal (PYI061) (#14316)flake8-pyi] Add autofix for redundant-numeric-union (PYI041) (#14273)ruff] New rule map-int-version-parsing (RUF048) (#14373)ruff] New rule redundant-bool-literal (RUF038) (#14319)ruff] New rule unraw-re-pattern (RUF039) (#14446)pycodestyle] Exempt pytest.importorskip() calls (E402) (#14474)pylint] Autofix suggests using sets when possible (PLR1714) (#14372)invalid-pyproject-toml (RUF200): Updated to reflect the provisionally accepted PEP 639.flake8-pyi] Avoid panic in unfixable case (PYI041) (#14402)flake8-type-checking] Correctly handle quotes in subscript expression when generating an autofix (#14371)pylint] Suggest correct autofix for __contains__ (PLC2801) (#14424)ignores a rule that has been removed (#14435)lint.flake8-import-conventions.aliases only uses valid module names and aliases (#14477)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.8.0/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.8.0/ruff-installer.ps1 | iex"
\[flake8-datetimez\] Detect usages of datetime.max/datetime.min (DTZ901)
flake8-datetimez] Detect usages of datetime.max/datetime.min (DTZ901) (#14288)flake8-logging] Implement root-logger-calls (LOG015) (#14302)flake8-no-pep420] Detect empty implicit namespace packages (INP001) (#14236)flake8-pyi] Add "replace with Self" fix (PYI019) (#14238)perflint] Implement quick-fix for manual-list-comprehension (PERF401) (#13919)pylint] Implement shallow-copy-environ (W1507) (#14241)ruff] Implement none-not-at-end-of-union (RUF036) (#14314)ruff] Implementation unsafe-markup-call from flake8-markupsafe plugin (RUF035) (#14224)ruff] Report problems for attrs dataclasses (RUF008, RUF009) (#14327)flake8-boolean-trap] Exclude dunder methods that define operators (FBT001) (#14203)flake8-pyi] Add "replace with Self" fix (PYI034) (#14217)flake8-pyi] Always autofix duplicate-union-members (PYI016) (#14270)flake8-pyi] Improve autofix for nested and mixed type unions for unnecessary-type-union (PYI055) (#14272)flake8-pyi] Mark fix as unsafe when type annotation contains comments for duplicate-literal-member (PYI062) (#14268)ruff.configuration (#14352)PLC014 (useless-import-alias) and I002 (missing-required-import) by considering lint.isort.required-imports for PLC014 (#14287)flake8-type-checking] Skip quoting annotation if it becomes invalid syntax (TCH001)flake8-pyi] Avoid using typing.Self in stub files pre-Python 3.11 (PYI034) (#14230)flake8-pytest-style] Flag pytest.raises call with keyword argument expected_exception (PT011) (#14298)flake8-simplify] Infer "unknown" truthiness for literal iterables whose items are all unpacks (SIM222) (#14263)flake8-type-checking] Fix false positives for typing.Annotated (TCH001) (#14311)pylint] Allow await at the top-level scope of a notebook (PLE1142) (#14225)pylint] Fix miscellaneous issues in await-outside-async detection (PLE1142) (#14218)pyupgrade] Avoid applying PEP 646 rewrites in invalid contexts (UP044) (#14234)pyupgrade] Detect permutations in redundant open modes (UP015) (#14255)refurb] Avoid triggering hardcoded-string-charset for reordered sets (FURB156) (#14233)refurb] Further special cases added to verbose-decimal-constructor (FURB157) (#14216)refurb] Use UserString instead of non-existent UserStr (FURB189) (#14209)ruff] Avoid treating lowercase letters as # noqa codes (RUF100) (#14229)ruff] Do not report when Optional has no type arguments (RUF013) (#14181)F704, PLE1142 (#14266)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.7.4/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.7.4/ruff-installer.ps1 | iex"
Formatter: Disallow single-line implicit concatenated strings
flake8-pyi] Include all Python file types for PYI006 and PYI066 (#14059)flake8-simplify] Implement split-of-static-string (SIM905) (#14008)refurb] Implement subclass-builtin (FURB189) (#14105)ruff] Improve diagnostic messages and docs (RUF031, RUF032, RUF034) (#14068)B033, PLC0208) (#14064)eradicate] Better detection of IntelliJ language injection comments (ERA001) (#14094)flake8-pyi] Add autofix for docstring-in-stub (PYI021) (#14150)flake8-pyi] Update duplicate-literal-member (PYI062) to alawys provide an autofix (#14188)pyflakes] Detect items that hash to same value in duplicate dictionaries (F601) (#14065)ruff] Fix false positive for decorators (RUF028) (#14061)# noqa (#12809)eradicate] ignore # language= in commented-out-code rule (ERA001) (#14069)flake8-bugbear] - do not run mutable-argument-default on stubs (B006) (#14058)flake8-builtins] Skip lambda expressions in builtin-argument-shadowing (A002) (#14144)flake8-comprehension] Also remove trailing comma while fixing C409 and C419 (#14097)flake8-simplify] Allow open without context manager in return statement (SIM115) (#14066)pylint] Respect hash-equivalent literals in iteration-over-set (PLC0208) (#14063)pylint] Update known dunder methods for Python 3.13 (PLW3201) (#14146)pyupgrade] - ignore kwarg unpacking for UP044 (#14053)refurb] Parse more exotic decimal strings in verbose-decimal-constructor (FURB157) (#14098)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.7.3/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.7.3/ruff-installer.ps1 | iex"
Fix formatting of single with-item with trailing comment
pyupgrade] Add PEP 646 Unpack conversion to * with fix (UP044) (#13988)known_stdlibs.rs with stdlibs 2024.10.25 (#13963)flake8-no-pep420] Skip namespace package enforcement for PEP 723 scripts (INP001) (#13974)flake8-type-checking] Fix false positive for singledispatchmethod (TCH003) (#13941)flake8-type-checking] Treat return type of singledispatch as runtime-required (TCH003) (#13957)flake8-simplify] Include caveats of enabling if-else-block-instead-of-if-exp (SIM108) (#14019)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.7.2/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.7.2/ruff-installer.ps1 | iex"
Fix E221 and E222 to flag missing or extra whitespace around == operator
E221 and E222 to flag missing or extra whitespace around == operator (#13890)pylint] Restrict iteration-over-set to only work on sets of literals (PLC0208) (#13731)flake8-type-checking] Support auto-quoting when annotations contain quotes (#11811)ARG002 compatible with EM101 when raising NotImplementedError (#13714)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.7.1/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.7.1/ruff-installer.ps1 | iex"
Check out the blog post for a migration guide and overview of the changes!
Check out the blog post for a migration guide and overview of the changes!
PT001 and PT023 now default to omitting the decorator parentheses when there are no arguments
(#12838, #13292).
This was a change that we attempted to make in Ruff v0.6.0, but only partially made due to an error on our part.
See the blog post for more details.useless-try-except rule (in our tryceratops category) has been recoded from TRY302 to
TRY203 (#13502). This ensures Ruff's code is consistent with
the same rule in the tryceratops linter.lint.allow-unused-imports setting has been removed (#13677). Use
lint.pyflakes.allow-unused-imports
instead.refurb] implement hardcoded-string-charset (FURB156) (#13530)refurb] Count codepoints not bytes for slice-to-remove-prefix-or-suffix (FURB188) (#13631)pylint] Mark PLE1141 fix as unsafe (#13629)flake8-async] Consider async generators to be "checkpoints" for cancel-scope-no-checkpoint (ASYNC100) (#13639)flake8-bugbear] Do not suggest setting parameter strict= to False in B905 diagnostic message (#13656)flake8-todos] Only flag the word "TODO", not words starting with "todo" (TD006) (#13640)pycodestyle] Fix whitespace-related false positives and false negatives inside type-parameter lists (E231, E251) (#13704)flake8-simplify] Stabilize preview behavior for SIM115 so that the rule can detect files
being opened from a wider range of standard-library functions (#12959).--statistics command (#13774)pyflakes] Allow ipytest cell magic (F401) (#13745)flake8-use-pathlib] Fix PTH123 false positive when open is passed a file descriptor (#13616)flake8-bandit] Detect patterns from multi line SQL statements (S608) (#13574)flake8-pyi] - Fix dropped expressions in PYI030 autofix (#13727)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.7.0/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.7.0/ruff-installer.ps1 | iex"
Fix codeblock dynamic line length calculation for indented docstring examples
refurb] Mark FURB118 fix as unsafe (#13613)pydocstyle] Don't raise D208 when last line is non-empty (#13372)pylint] Preserve trivia (i.e. comments) in PLR5501 autofix (#13573)pyflakes] Add allow-unused-imports setting for unused-import rule (F401) (#13601)flake8-bugbear] Avoid short circuiting B017 for multiple context managers (#13609)pylint] Do not offer an invalid fix for PLR1716 when the comparisons contain parenthesis (#13527)pyupgrade] Fix UP043 to apply to collections.abc.Generator and collections.abc.AsyncGenerator (#13611)refurb] Fix handling of slices in tuples for FURB118, e.g., x[:, 1] (#13518)astral-sh/ruff-action (#13551)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.9/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.9/ruff-installer.ps1 | iex"
Remove unnecessary parentheses around match case clauses
match case clauses (#13510)if guards in match..case clauses (#13513)ruff analyze graph (#13486)pylint] Implement boolean-chained-comparison (R1716) (#13435)lake8-simplify] Detect SIM910 when using variadic keyword arguments, i.e., **kwargs (#13503)pyupgrade] Avoid false negatives with non-reference shadowed bindings of loop variables (UP028) (#13504)*args (#13512)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.8/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.8/ruff-installer.ps1 | iex"
Add Python version support to ruff analyze CLI
exclude support to ruff analyze (#13425)pycodestyle] Fix: Don't autofix if the first line ends in a question mark? (D400) (#13399)lint.exclude in ruff check --add-noqa (#13427)forget for module resolver database (#13438)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.7/ruff-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.7/ruff-installer.ps1 | iex"
\[refurb\] Skip slice-to-remove-prefix-or-suffix (FURB188) when non-trivial slice steps are present
refurb] Skip slice-to-remove-prefix-or-suffix (FURB188) when non-trivial slice steps are present (#13405)LineIndex::offset calculation (#13407)fastapi] Respect FastAPI aliases in route definitions (#13394)pydocstyle] Respect word boundaries when detecting function signature in docs (#13388)FURB188 docs (#13406)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.6/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.6/ruff-installer.ps1 | iex"
\[pydoclint\] Ignore DOC201 when function name is "new"
pydoclint] Ignore DOC201 when function name is "new" (#13300)refurb] Implement slice-to-remove-prefix-or-suffix (FURB188) (#13256)eradicate] Ignore script-comments with multiple end-tags (ERA001) (#13283)pyflakes] Improve error message for UndefinedName when a builtin was added in a newer version than specified in Ruff config (F821) (#13293)ruff] Handle unary operators in decimal-from-float-literal (RUF032) (#13275)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.5/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.5/ruff-installer.ps1 | iex"
\[flake8-builtins\] Use dynamic builtins list based on Python version
flake8-builtins] Use dynamic builtins list based on Python version (#13172)pydoclint] Permit yielding None in DOC402 and DOC403 (#13148)pylint] Update diagnostic message for PLW3201 (#13194)ruff] Implement post-init-default (RUF033) (#13192)ruff] Implement useless if-else (RUF034) (#13218)flake8-pyi] Respect pep8_naming.classmethod-decorators settings when determining if a method is a classmethod in custom-type-var-return-type (PYI019) (#13162)flake8-pyi] Teach various rules that annotations might be stringized (#12951)pylint] Avoid no-self-use for attrs-style validators (#13166)pylint] Recurse into subscript subexpressions when searching for list/dict lookups (PLR1733, PLR1736) (#13186)pyupgrade] Detect aiofiles.open calls in UP015 (#13173)pyupgrade] Mark sys.version_info[0] < 3 and similar comparisons as outdated (UP036) (#13175)ruff format output (#13212)pydocstyle] Improve heuristics for detecting Google-style docstrings (#13142)refurb] Treat sep arguments with effects as unsafe removals (FURB105) (#13165)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.4/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.4/ruff-installer.ps1 | iex"
\[flake8-simplify\] Extend open-file-with-context-handler to work with dbm.sqlite3 (SIM115)
flake8-simplify] Extend open-file-with-context-handler to work with dbm.sqlite3 (SIM115) (#13104)pycodestyle] Disable E741 in stub files (.pyi) (#13119)pydoclint] Avoid DOC201 on explicit returns in functions that only return None (#13064)flake8-async] Disable check for asyncio before Python 3.11 (ASYNC109) (#13023)FastAPI] Avoid introducing invalid syntax in fix for fast-api-non-annotated-dependency (FAST002) (#13133)flake8-implicit-str-concat] Normalize octals before merging concatenated strings in single-line-implicit-string-concatenation (ISC001) (#13118)flake8-pytest-style] Improve help message for pytest-incorrect-mark-parentheses-style (PT023) (#13092)pylint] Avoid autofix for calls that aren't min or max as starred expression (PLW3301) (#13089)ruff] Add datetime.time, datetime.tzinfo, and datetime.timezone as immutable function calls (RUF009) (#13109)ruff] Extend comment deletion for RUF100 to include trailing text from noqa directives while preserving any following comments on the same line, if any (#13105)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.3/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.3/ruff-installer.ps1 | iex"
\[flake8-simplify\] Extend open-file-with-context-handler to work with other standard-library IO modules (SIM115)
flake8-simplify] Extend open-file-with-context-handler to work with other standard-library IO modules (SIM115) (#12959)ruff] Avoid unused-async for functions with FastAPI route decorator (RUF029) (#12938)ruff] Ignore fstring-missing-syntax (RUF027) for fastAPI paths (#12939)ruff] Implement check for Decimal called with a float literal (RUF032) (#12909)flake8-bugbear] Update diagnostic message when expression is at the end of function (B015) (#12944)flake8-pyi] Skip type annotations in string-or-bytes-too-long (PYI053) (#13002)flake8-type-checking] Always recognise relative imports as first-party (#12994)flake8-unused-arguments] Ignore unused arguments on stub functions (ARG001) (#12966)pylint] Ignore augmented assignment for self-cls-assignment (PLW0642) (#12957)pep8-naming] Don't flag from imports following conventional import names (N817) (#12946)pylint] - Allow __new__ methods to have cls as their first argument even if decorated with @staticmethod for bad-staticmethod-argument (PLW0211) (#12958)hyperfine installation instructions; update hyperfine code samples (#13034)PT001 as per the new default behavior (#13019)perflint] Improve docs for try-except-in-loop (PERF203) (#12947)pydocstyle] Add reference to lint.pydocstyle.ignore-decorators setting to rule docs (#12996)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.2/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.2/ruff-installer.ps1 | iex"
This is a hotfix release to address an issue with ruff-pre-commit. In v0.6, Ruff changed its behavior to lint and format Jupyter notebooks by default;
This is a hotfix release to address an issue with ruff-pre-commit. In v0.6, Ruff changed its behavior to lint and format Jupyter notebooks by default; however, due to an oversight, these files were still excluded by default if Ruff was run via pre-commit, leading to inconsistent behavior. This has now been fixed.
fastapi] Implement fast-api-unused-path-parameter (FAST003) (#12638)pylint] Rename too-many-positional to too-many-positional-arguments (R0917) (#12905)flake8-naming]: Respect import conventions (N817) (#12922)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.1/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.1/ruff-installer.ps1 | iex"
The following rules are now deprecated:
Check out the blog post for a migration guide and overview of the changes!
See also, the "Remapped rules" section which may result in disabled rules.
src layouts by default for isort rules (#12848)PT001 and PT023 now default to omitting the decorator parentheses when there are no arguments (#12838).The following rules are now deprecated:
pytest-missing-fixture-name-underscore (PT004)pytest-incorrect-fixture-name-underscore (PT005)unpacked-list-comprehension (UP027)The following rules have been remapped to new rule codes:
unnecessary-dict-comprehension-for-iterable: RUF025 to C420The following rules have been stabilized and are no longer in preview:
singledispatch-method (PLE1519)singledispatchmethod-function (PLE1520)bad-staticmethod-argument (PLW0211)if-stmt-min-max (PLR1730)invalid-bytes-return-type (PLE0308)invalid-hash-return-type (PLE0309)invalid-index-return-type (PLE0305)invalid-length-return-type (E303)self-or-cls-assignment (PLW0642)byte-string-usage (PYI057)duplicate-literal-member (PYI062)redirected-noqa (RUF101)The following behaviors have been stabilized:
cancel-scope-no-checkpoint (ASYNC100): Support asyncio and anyio context mangers.async-function-with-timeout (ASYNC109): Support asyncio and anyio context mangers.async-busy-wait (ASYNC110): Support asyncio and anyio context mangers.async-zero-sleep (ASYNC115): Support anyio context mangers.long-sleep-not-forever (ASYNC116): Support anyio context mangers.The following fixes have been stabilized:
superfluous-else-return (RET505)superfluous-else-raise (RET506)superfluous-else-continue (RET507)superfluous-else-break (RET508)flake8-simplify] Further simplify to binary in preview for (SIM108) (#12796)pyupgrade] Show violations without auto-fix (UP031) (#11229)flake8-import-conventions] Add xml.etree.ElementTree to default conventions (#12455)flake8-pytest-style] Add a space after comma in CSV output (PT006) (#12853)flake8-async] Do not lint yield in context manager (ASYNC100) (#12896)flake8-comprehensions] Do not lint async for comprehensions (C419) (#12895)flake8-return] Only add return None at end of a function (RET503) (#11074)flake8-type-checking] Avoid treating dataclasses.KW_ONLY as typing-only (TCH003) (#12863)pep8-naming] Treat type(Protocol) et al as metaclass base (N805) (#12770)pydoclint] Don't enforce returns and yields in abstract methods (DOC201, DOC202) (#12771)ruff] Skip tuples with slice expressions in (RUF031) (#12768)ruff] Ignore unparenthesized tuples in subscripts when the subscript is a type annotation or type alias (RUF031) (#12762)ruff] Ignore template strings passed to logging and builtins._() calls (RUF027) (#12889)ruff] Do not remove parens for tuples with starred expressions in Python <=3.10 (RUF031) (#12784)kernelspec notebook metadata when detecting the preferred language for a Jupyter Notebook (#12875)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.6.0/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.6.0/ruff-installer.ps1 | iex"
\[flake8-comprehensions\] Account for list and set comprehensions in unnecessary-literal-within-tuple-call (C409)
flake8-comprehensions] Account for list and set comprehensions in unnecessary-literal-within-tuple-call (C409) (#12657)flake8-pyi] Add autofix for future-annotations-in-stub (PYI044) (#12676)flake8-return] Avoid syntax error when auto-fixing RET505 with mixed indentation (space and tabs) (#12740)pydoclint] Add docstring-missing-yields (DOC402) and docstring-extraneous-yields (DOC403) (#12538)pydoclint] Avoid DOC201 if docstring begins with "Return", "Returns", "Yield", or "Yields" (#12675)pydoclint] Deduplicate collected exceptions after traversing function bodies (DOC501) (#12642)pydoclint] Ignore DOC errors for stub functions (#12651)pydoclint] Teach rules to understand reraised exceptions as being explicitly raised (DOC501, DOC502) (#12639)ruff] Implement incorrectly-parenthesized-tuple-in-subscript (RUF031) (#12480)ruff] Mark RUF023 fix as unsafe if __slots__ is not a set and the binding is used elsewhere (#12692)refurb] Add autofix for implicit-cwd (FURB177) (#12708)ruff] Add autofix for zip-instead-of-pairwise (RUF007) (#12663)tryceratops] Add BaseException to raise-vanilla-class rule (TRY002) (#12620)pyproject.toml files (#12727)flake8-async] Fix false positives with multiple async with items (ASYNC100) (#12643)flake8-bandit] Avoid false-positives for list concatenations in SQL construction (S608) (#12720)flake8-bugbear] Treat return as equivalent to break (B909) (#12646)flake8-comprehensions] Set comprehensions not a violation for sum in unnecessary-comprehension-in-call (C419) (#12691)flake8-simplify] Parenthesize conditions based on precedence when merging if arms (SIM114) (#12737)pydoclint] Try both 'Raises' section styles when convention is unspecified (DOC501) (#12649)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.5.7/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.5.7/ruff-installer.ps1 | iex"
Ruff 0.5.6 automatically enables linting and formatting of notebooks in *preview mode*. You can opt-out of this behavior by adding *.ipynb to the exte
Ruff 0.5.6 automatically enables linting and formatting of notebooks in preview mode.
You can opt-out of this behavior by adding *.ipynb to the extend-exclude setting.
[tool.ruff]
extend-exclude = ["*.ipynb"]
flake8-builtins] Implement import, lambda, and module shadowing (#12546)pydoclint] Add docstring-missing-returns (DOC201) and docstring-extraneous-returns (DOC202) (#12485)flake8-return] Exempt cached properties and other property-like decorators from explicit return rule (RET501) (#12563)$/logTrace for server trace logs in Zed and VS Code (#12564)flake8-implicit-str-concat] Always allow explicit multi-line concatenations when implicit concatenations are banned (#12532)flake8-async] Avoid flagging asyncio.timeouts as unused when the context manager includes asyncio.TaskGroup (#12605)flake8-slots] Avoid recommending __slots__ for classes that inherit from more than namedtuple (#12531)isort] Avoid marking required imports as unused (#12537)isort] Preserve trailing inline comments on import-from statements (#12498)pycodestyle] Add newlines before comments (E305) (#12606)pycodestyle] Don't attach comments with mismatched indents (#12604)pyflakes] Fix preview-mode bugs in F401 when attempting to autofix unused first-party submodule imports in an __init__.py file (#12569)pylint] Respect start index in unnecessary-list-index-lookup (#12603)pyupgrade] Avoid recommending no-argument super in slots=True dataclasses (#12530)pyupgrade] Use colon rather than dot formatting for integer-only types (#12534)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.5.6/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.5.6/ruff-installer.ps1 | iex"
Add note about the breaking change in nvim-lspconfig
fastapi] Implement fastapi-redundant-response-model (FAST001) and fastapi-non-annotated-dependency(FAST002) (#11579)pydoclint] Implement docstring-missing-exception (DOC501) and docstring-extraneous-exception (DOC502) (#11471)numpy] Fix NumPy 2.0 rule for np.alltrue and np.sometrue (#12473)numpy] Ignore NPY201 inside except blocks for compatibility with older numpy versions (#12490)pep8-naming] Avoid applying ignore-names to self and cls function names (N804, N805) (#12497)Ord implementation of cmp_fix (#12471)pydoclint] Fix panic in DOC501 reported in #12428 (#12435)flake8-bugbear] Allow singleton tuples with starred expressions in B013 (#12484)nvim-lspconfig (#12507)curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.5.5/ruff-installer.sh | sh
powershell -c "irm https://github.com/astral-sh/ruff/releases/download/0.5.5/ruff-installer.ps1 | iex"
Your coding agent can read these notes before it upgrades. Set up the MCP server →