Populært: Data opdateret 26. oktober 2026

Kategorier

Internet1.355
Kommunikation321
Lyd og video898
Grafik og design539
Kontor og produktivitet1.120
Udviklerværktøjer3.132
AI-værktøjer527
Sikkerhed og privatliv385
Systemværktøjer3.113
Spil523
Uddannelse og videnskab239
Netværk og IT284

Ruff: download ældre versioner

An extremely fast Python linter, written in Rust.

Astral Sprog og SDK’er #41 Sprog og SDK’er

Her er 140 versioner af Ruff, fra 9. juni 2023 til den aktuelle 0.17.1. Hver version linker til udgiverens egne installationsfiler.

2023: 1 1 23 2024: 47 47 24 2025: 55 55 25 2026: 37 37 26

140 versioner på 3 år · cirka 42 om året

VersionDatoStørrelseFiler
0.17.1Nyeste 15. oktober 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-10-15.

Preview features
- [pycodestyle] Don't treat `None`, `True`, or `False` as keywords (E271-E274) (#29322)

Bug fixes
- Fix dedent with multiple leading comments (#29382)
- [flake8-pyi] Detect legacy positional-only parameters in `__new__` methods (PYI063) (#28502)
- [flake8-pyi] Fix false positives on quoted annotations (PYI036) (#29274)
- [perflint] Avoid invalid comprehension suggestions (PERF401, PERF403) (#29366)

Rule changes
- Treat more `collections` and `weakref` containers as mutable (#29213)

Documentation
- [flake8-import-conventions] Update default and example `aliases` (#29333)
0.17.0 9. oktober 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-10-09.

The executables in our macOS and Windows release archives and `ruff` wheels are now code-signed. macOS executables are signed with an Apple Developer ID certificate and notarized by Apple. Windows executables have timestamped Authenticode signatures from Azure Artifact Signing. This enables verification of the release publisher and binary integrity, supports publisher-based allowlisting, and should reduce security warnings and antivirus false positives.

Breaking changes
- Update the default and latest Python versions for 3.15 (#28792)

Ruff now defaults to Python 3.11 instead of 3.10 when no Python version is configured through `target-version` or `requires-python`. When checking for syntax errors without a configured Python version, Ruff now defaults to Python 3.15 instead of 3.14.

- Update the default rule set (#28786)

Several of the `flake8-datetimez` rules (DTZ001, DTZ005, DTZ006, DTZ007, DTZ011, DTZ012, and DTZ901) are no longer enabled by default, while `undefined-local-with-nested-import-star-usage` (F406), which corresponds to a syntax error, is now enabled by default.

- Update Rust crate quick-junit to 0.8.0 (#27295)

JUnit output now uses a `skipped` attribute instead of `disabled` on `<testsuite>` elements and includes a `skipped` attribute on the root `<testsuites>` element.

- [flake8-import-conventions] Add `datetime as dt` as a conventional alias (ICN001) (#28790)

- Support Unicode dummy variable names (#28722)

The default `lint.dummy-variable-rgx` now recognizes underscore-prefixed Unicode names, such as `_次`, as dummy variables.

- Update to Unicode 17 (#21229, #28784)

Ruff now uses Unicode 17 data for identifier normalization and named character escapes (`"\N{...}"`).

- Always show unsafe and display-only fixes in the CLI (#27810)

The default `full` output format now shows unsafe fixes and suggestions requiring manual review, regardless of the `unsafe-fixes` setting. Actually applying unsafe fixes still requires explicit opt-in.

- Remove the Python dependency from conda-forge builds (conda-forge/ruff-feedstock#361)

The conda-forge build no longer depends on Python, now supports linux-riscv64, win-arm64, and linux-ppc64le platforms, and now includes shell completions. However, no longer depending on Python means that `python -m ruff` and `import ruff` will no longer work. Use `ruff` directly from `PATH` instead. PyPI installations and those from the standalone installer are unaffected.

- Remove support for ruff-lsp (#28750)

Support for `ruff-lsp`, the legacy Python language server deprecated in Ruff v0.9.5, has been removed. The Ruff VS Code extension now always uses the native language server; `ruff.nativeServer` is deprecated and ignored. See the migration guide.

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

- `lazy-import-mismatch` (TID254)
- `lazy-import-immediately-resolved` (TID255)
- `os-path-commonprefix` (RUF071)

The following behaviors have been stabilized:

- The formatter, `unsorted-imports` (I001), `line-too-long` (E501), and `doc-line-too-long` (W505) now consistently ignore trailing pragma comments when computing line length. This resolved several bugs involving interactions between these rules (#27313) but may also cause existing imports to be reformatted and was thus classified as a breaking change.

Preview features
- [flake8-bugbear] Report the method name and a more precise range (B005) (#27050)
- [refurb] Mark fix unsafe and move to `suspicious` (FURB152) (#28405)
- [ruff] Allow docstrings in strict mode (RUF067) (#28679)

Bug fixes
- [flake8-builtins] Expand checks in class scopes (A001) (#29076)
- [flake8-self] Allow private access on `object.__new__(cls)` instances (SLF001) (#29001)
- [flake8-tidy-imports] Skip `lazy-import-mismatch` in stubs (TID254) (#29095)
- [flake8-type-checking] Add the notion of runtime-ambiguous references (#26508)
- [flake8-type-checking] Never flag annotations in function scopes (#
0.16.10 1. oktober 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-10-01.

Preview features
- Add a migration guide for categories (#28087)
- [pyupgrade] Add rule for context manager iterator annotations (UP052) (#29000)

Performance
- Reduce memory used by diagnostics (#28951)

Server
- Avoid running `uv format` in untrusted workspaces (#28873)

Documentation
- Fix links to moved changelog sections and renamed mdtests (#28941)
- Add Python 3.15 as a supported version (#28907)
- Add ty as a type checker example (#28906)

Other changes
- Update Rust toolchain to 1.99 and MSRV to 1.97 (#29047)
0.16.9 24. september 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-09-24.

Preview features
- [ruff] Avoid false positives for overloaded division (RUF069) (#28309)

Bug fixes
- [flake8-bugbear] Avoid false positives for calls with keyword arguments (B009, B010, B043) (#28776)
- [flake8-tidy-imports] Allow lazy imports to be used in deferred annotations (TID255) (#28767)

Rule changes
- Update LibCST-based fixes for Python 3.15 (#28616)
- [flake8-pyi] Mention stubs in the diagnostic message (PYI002) (#28542)

Documentation
- Fix horizontal overflow on the rules documentation page (#28699)
- Update rules table with category information (#28651)
- [flake8-annotations] Clarify that ANN401 checks return types in addition to arguments (#28334)
- [flake8-bugbear] Document type-checker interaction (B010) (#28509)
- [flake8-comprehensions] Document `map`/generator exception behavior (C417) (#27794)
- [ruff] Mention related isort settings (RUF022) (#28719)
0.16.8 16. september 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-09-16.

Bug fixes
- Visit functional `TypedDict` keyword arguments correctly (#28584)
- [flake8-simplify] Detect nested `async with` under sync parent (SIM117) (#27821)
- [flake8-simplify] Preserve operand order in SIM109 fix (#27824)
- [pyupgrade] Preserve required parentheses in multiline UP040 fixes (#28164)
- [pyupgrade] Skip `TypeVarTuple` and `ParamSpec` conversions with bounds or constraints (UP040, UP046, UP047) (#28505)

Rule changes
- Add support for `__lazy_modules__` (#28459)
- Recognize PEP-728 `TypedDict` class keywords (#28533)
- Recognize quoted types in `typing.TypeForm` (#28507)
- Support conditional assignment to `__lazy_modules__` (#28491)
- [flake8-type-checking] Prefer lazy imports over `TYPE_CHECKING` on Python 3.15 and later (TC001, TC002, TC003) (#28541)
- [pyupgrade] Make the fix for UP040 always unsafe (#28526)
- [pyupgrade] Stop recommending deprecated `ByteString` aliases (UP035) (#28498)
- [ruff`, `flake8-use-pathlib] Recognize the `parent_mode` argument (RUF064, PTH103) (#28528)
- [ruff] Detect `\Z` in `pytest.raises()` match patterns (RUF043) (#28598)

CLI
- Use rule name and code in formatter incompatibility warnings (#28571)

Configuration
- [flake8-tidy-imports] Add `extend-banned-api` (#28644)
0.16.7 10. september 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-09-10.

Preview features
- [ruff] Add rule for default values on method receivers (RUF077) (#26700)
- [ruff] Recognize `re.prefixmatch` (RUF039, RUF055) (#28311)

Bug fixes
- Alternate nested quotes inside format spec interpolations (#28259)
- [flake8-implicit-str-concat] Mark fix unsafe when it creates a docstring (ISC003) (#27981)
- [flake8-tidy-imports] Skip fixes for multi-member imports (TID254) (#26584)
- [pylint] Gate `ImportCycleError` on Python 3.15 (PLW0133) (#28310)

Rule changes
- Correct D211 and D203 rule conflict diagnostic (#28444)
- Recognize `slice` and `frozendict` generics (#28477)
- Stop defining `__cached__` for Python 3.15 (#28476)
- [pyupgrade] Stop recommending removed `typing.no_type_check_decorator` (UP035) (#28475)

Performance
- Reuse parser name lookups when interning (#28399)
- Speed up inherited configuration resolution (#28299)

Documentation
- Fix `line-length` path in `--config` example (#28392)
- Remove the "Who’s Using Ruff?" list (#28455)

Other changes
- Embed archive checksums in the shell installer (#28281)
0.16.6 3. september 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-09-03.

Preview features
- Move `pytest-fixture-autouse` to the `restriction` category (#28219)
- [flake8-pytest-style] Add an autofix for PT020 (#27993)
- [flake8-tidy-imports] Prevent fix loop between TID254 and TID255 (#28262)
- [isort] Exclude pragma comments from line length calculation (I001) (#27313)

Bug fixes
- Validate unary expressions when parsing (#28233)
- [flake8-async`, `pylint] Recognize `builtins.open` (ASYNC230, PLW1514) (#28021)
- [flake8-bugbear] Fix panic on `match` subjects (B031) (#27781)
- [flake8-datetimez] Reject `tzinfo=None` for `datetime` bounds (DTZ901) (#28022)
- [flake8-pytest-style] Avoid duplicate PT017 diagnostics (#27918)
- [ruff] Remove `lint.external` hint for Ruff-specific suppressions (RUF102) (#27923)

Rule changes
- [flake8-use-pathlib] Add display-only fix for `os.listdir` (PTH208) (#28027)

Documentation
- Add another example and glob reference for `lint.per-file-ignores` (#28106)
- Add duplicate work guidance (#28229)
- [flake8-async] Document thread offloading (ASYNC240) (#28008)
- [pyupgrade] Clarify default `encoding` argument handling (UP012) (#27315)

Other changes
- Allow unary plus in match patterns on Python 3.15 (#28231)
0.16.5 27. august 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-08-27.

Preview features
- Allow rules without codes (#28049)
- Introduce category selectors (#27666)
- Update preview default rules and categories (#27877)

Bug fixes
- [flake8-async] Detect blocking generic HTTP requests (ASYNC210) (#28024)
- [flake8-datetimez] Allow timezone-safe `strptime` chains (DTZ007) (#28023)
- [flake8-simplify] Respect side effects in `lambda` defaults (SIM401) (#28000)

Server
- Fix duplicated "of" in `ClientOptions` doc comment (#27978)

Documentation
- Document rule acceptance guidelines (#27910)
- Document the new category selectors (#27906)
0.16.4 20. august 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-08-20.

Preview features
- [flake8-use-pathlib] Add autofix for PTH116 (#26460)
- [refurb] Restrict `delete-full-slice` to lists (FURB131) (#27711)
- [refurb] Skip FURB101 and FURB103 when the `open` argument is a file descriptor (#27643)

Bug fixes
- Fix `InvalidInstruction` on Windows CPUs that do not support `POPCNT` (#27803)
- [pyflakes] Emit semantic syntax errors in string type definitions as F722 (#27835)
- [pylint] Allow `os._exit` imports in `import-private-name` (PLC2701) (#27738)

Rule changes
- [syntax-errors] Align mixed t-string/bytes error message with CPython 3.14 (#27766)
- [ruff] Add `ctypes.LittleEndianStructure` and related types to existing exception (RUF012) (#27753)
- [syntax-errors] Detect duplicate keyword arguments (#17804)
- [syntax-errors] Detect parameters declared `nonlocal` (#27628)

Server
- Offer display-only fixes and mark safe fixes preferred (#27807)
- Support pull diagnostics for notebook cells (#27779)

Documentation
- Add default indicator to rules table (#27724)
- Fix broken link to Python docs (#27757)

Other changes
- Fix s390x stacker assembly in release builds (#27776)
- Guarantee minimum stack size when parsing a module, standalone expression, and suites (#25464)
- Reduce configuration deserialization code size (#27924)
- Check packed AST index bounds (#27849)
0.16.3 13. august 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-08-13.

Preview features
- [pylint] Fix false negatives on negative numbers (PLR6104) (#27251)
- [pyupgrade] Add rule to replace `while 1` with `while True` (UP048) (#27190)

Bug fixes
- [flake8-bandit] Also check keyword arguments (S602, S603, S607, S609) (#27687)
- [pylint] Allow `continue` in `finally` on Python 3.8 (#27626)
- [pylint] Fix PLE1307 false positive with bools (#27651)
- [pylint] Fix false positives and negatives with `%b` format character (PLE1300, PLE1307) (#27560)
- [pylint] Improve handling of concatenated strings (PLE1300) (#27659)

Rule changes
- [numpy] Make `np.chararray` autofix backwards-compatible (NPY201) (#27527)

Performance
- Enable PGO for Linux x86-64 Ruff releases (#27570)
- Enable PGO for Linux ARM64 Ruff releases (#27574)
- Enable PGO for Windows x86-64 Ruff releases (#27573)
- Enable PGO for macOS ARM64 Ruff releases (#27572)
- Reduce `Expr` size to 64 bytes (#27591)

CLI
- Hyperlink rule codes in `ruff check --statistics` output (#27646)

Documentation
- [ruff] Also suggest `asyncio.TaskGroup` (RUF006) (#27461)

Other changes
- Use mimalloc v3 (#27586)
0.16.2 7. august 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-08-06.

Bug fixes
- [flake8-pyi] Avoid false positives on `singledispatch` functions (PYI041) (#27335)

Server
- Register formatting capabilities dynamically to exclude TOML files (#27332)
0.16.1 30. juli 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-07-30.

Preview features
- Add an option to opt out of human-readable names (#27160)
- [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
- [pyupgrade] Skip fix when a defaulted `TypeVar` precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
- [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)

Bug fixes
- Bump `gen-lsp-types` to gracefully handle unknown enumeration values in LSP messages (#27230)
- [flake8-bugbear] Mark `range` as immutable (B008) (#27247)
- [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
- [flake8-return] Fix false positive when variable is read in `finally` clause (RET504) (#25441)
- [pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)
- [refurb] Parenthesize `yield` arguments in the FURB192 fix (#27192)

Rule changes
- [flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)
- [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)

Server
- Fix indexing of excluded nested Ruff workspaces (#27303)
- Lint TOML files in the LSP (#26862)

Documentation
- Cover `pycon` Markdown formatting (#27153)
- [flake8-bandit] Document `TYPE_CHECKING` exception (S101) (#27004)
- [flake8-import-conventions] Document that `extend-aliases` can override default aliases (#27191)
- [pylint] Add missing fix safety gotchas for `non-augmented-assignment` (PLR6104) (#27250)

Other changes
- Reduce syntax error noise by swallowing dedents like indents (#27170)
- Vendor latest annotate-snippets (#27033)
0.16.0 23. juli 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-07-23.

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

Breaking changes
- Ruff now enables a much larger set of rules by default (413, up from 59). See the blog post for more details and the new Default Rules page for a full listing of the enabled rules.

- Ruff can now format Python code blocks in Markdown files and will do this by default. See the documentation for more details.

- Ruff now supports `ruff: ignore` comments at the ends of lines, like `noqa` comments, or on the line preceding a diagnostic. For example, these both suppress an `unused-import` (F401) diagnostic:

```py
import math # ruff: ignore[F401]

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

- Fixes are now shown in `check` and `format --check` output:

````console
❯ ruff format --check .
unformatted: File would be reformatted
--> try.md:1:1
|
1 | ```python
- import math
2 + import math
3 | ```
|

1 file would be reformatted
````

This example also shows off the Markdown formatting.

- `format --check` now supports the same output formats as the linter, including the `github` and `gitlab` outputs for rendering annotations in CI:

```console
❯ ruff format --check --output-format github .
::error title=ruff (unformatted),file=try.md,line=2,col=8,endLine=2,endColumn=10::try.md:2:8: unformatted: File would be reformatted
```

See the CLI help or documentation for the full list of supported formats.

- The `filename`, `location`, `end_location`, `fix.edits[].location`, and `fix.edits[].end_location` fields in the JSON output format may now be `null` rather than defaulting to the empty string and row 1, column 1, respectively.

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

- `airflow3-incompatible-function-signature` (AIR303)
- `missing-copyright-notice` (CPY001)
- `unnecessary-from-float` (FURB164)
- `sorted-min-max` (FURB192)
- `implicit-string-concatenation-in-collection-literal` (ISC004)
- `log-exception-outside-except-handler` (LOG004)
- `invalid-bool-return-type` (PLE0304)
- `too-many-positional-arguments` (PLR0917)
- `stop-iteration-return` (PLR1708)
- `none-not-at-end-of-union` (RUF036)
- `access-annotations-from-class-dict` (RUF063)
- `duplicate-entry-in-dunder-all` (RUF068)

The following behaviors have been stabilized:

- `blind-except` (BLE001) is now suppressed when the exception is logged via `logging` methods other than `critical`, `error` and `exception`.
- `future-required-type-annotation` (FA102) now checks for additional PEP 585-compatible APIs, such as those from `collections.abc`.
- `f-string-in-get-text-func-call` (INT001), `format-in-get-text-func-call` (INT002), and `printf-in-get-text-func-call` (INT003) now check for additional common ways of using the `gettext` module, such as assigning it to `builtins._`.
- `suspicious-url-open-usage` (S310) now resolves local string literal bindings to avoid more false positives.
- `snmp-insecure-version` (S508) and `snmp-weak-cryptography` (S509) now support the recommended API from newer versions of PySNMP.
- `typing-text-str-alias` (UP019) now recognizes `typing_extensions.Text` in addition to `typing.Text`.

Preview features
- [pyupgrade] Fix false positive with `TypeVar` default before Python 3.13 (UP040) (#26888)

Bug fixes
- [ruff] Fix missing check on unrecognized early bound (RUF016) (#26986)

Rule changes
- Insert a space after the colon in Ruff suppression comments (#27123)

Performance
- [pyupgrade] Speed up `unnecessary-future-import` (UP010) (#27047)

Documentation
- [ruff] Add missing period in "Why is this bad?" section (RUF200) (#26930)
- [flake8-simplify] Clarify `os.environ` behavior on Windows (SIM112) (#26972)
- [pydocstyle] Document fix safety (D400) (#26971)
0.15.22 16. juli 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-07-16.

Preview features
- [pycodestyle] Add an autofix for E402 (#22212)
- [refurb] Allow subclassing builtins in stub files (FURB189) (#26812)
- [ruff] Add rule to replace `noqa` comments with `ruff:ignore` (RUF105) (#26423)
- [ruff] Add rule to use human-readable names in `ruff:ignore` comments (RUF106) (#26682)
- [ruff] Add rule to use human-readable names in configuration selectors (RUF201) (#26772)

Bug fixes
- [flake8-pyi] Fix false positive in `__all__` (PYI053) (#26872)

Rule changes
- [pylint] Ignore mutable type updates in `redefined-loop-name` (PLW2901) (#25733)

Performance
- Avoid redundant lexer token bookkeeping (#26765)
- Avoid redundant pending-indentation writes (#26774)
- Avoid unnecessary identifier lookahead (#26525)
- Reuse parser scratch buffers (#26798)

Documentation
- Document argfile support (#26803)
- [flake8-datetimez] Clarify naming guidance for `datetime.today` (DTZ002) (#26658)
- [pycodestyle] Document E731 fix safety (#26847)
- [ruff] Clarify intentional async contexts for `unused-async` (RUF029) (#26641)
0.15.21 9. juli 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-07-09.

Preview features
- Add `--add-ignore` for adding `ruff:ignore` comments (#26346)
- [flake8-comprehensions] Drop C409 tuple comprehension preview behavior (#25707)
- Avoid whitespace normalization when formatting comments (#26455)
- [pyupgrade] Lint and fix use of deprecated `abc` decorators (UP051) (#26417)

Bug fixes
- Refine non-empty f-string detection (#26526)
- Detect syntax errors in individual notebook cells (#26419)
- [flake8-implicit-str-concat] Fix ISC003 autofix incorrectly stripping `+` from comments (#26554)

Rule changes
- [flake8-executable] Mark EXE004 fix as unsafe (#26033)
- [flake8-pyi] Mark PYI061 fixes as unsafe in Python files (#26533)
- [pydocstyle] Skip `overload-with-docstring` in stub files (D418) (#26318)

Performance
- Avoid per-token source index visitor calls (#26506)
- Cache parenthesized expression boundaries in the formatter (#26344)
- Improve performance of rendering edits in preview mode (#26565)
- Inline `fits_element` in formatter (#26429)
- Inline formatter printing hot paths (#26504)
- Lazily create builtin bindings (#26510)
- Skip empty trivia scans in the source indexer (#26507)
- Use ICF for macOS release builds (#25780)

Formatter
- Add `--extend-exclude` to `ruff format` (#26372)

Documentation
- Add "How does Ruff's import sorting compare to isort?" link to README (#26530)
- Fix Mozilla Firefox repository link in README (#26537)
- [flake8-bandit] Fix misleading docstring for `mako-templates` (S702) (#26432)
- [ruff] Fix non-triggering example for `if-key-in-dict-del` (RUF051) (#26433)
0.15.20 25. juni 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-06-25.

Preview features
- Allow human-readable names in rule selectors (#25887)
- Emit a warning instead of an error for unknown rule selectors (#26113)
- Match `noqa` shebang handling in `ruff:ignore` comments (#26286)
- [ruff] Remove `pytest-fixture-autouse` (RUF076) (#26240, #26371)

Documentation
- Add versioning sections to custom crate READMEs (#26317)
- Update `ruff_python_parser` README for crates.io (#26315)
- [perflint] Clarify that PERF402 applies to any iterable (#26242)
0.15.17 11. juni 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-06-11.

Preview features
- Allow human-readable names in suppression comments (#25614)
- Fix handling of `ignore` comments within a `disable`/`enable` pair (#25845)
- Prioritize human-readable names in CLI output (#25869)
- Respect diagnostic start and parent ranges and trailing comments in `ruff:ignore` suppressions (#25673)
- [flake8-async] Add `trio.as_safe_channel` to safe decorators (ASYNC119) (#25775)
- [flake8-pytest-style] Also check `pytest_asyncio` fixtures (#25375)
- [ruff] Ban `pytest` autouse fixtures (RUF076) (#25477)
- [pyupgrade] Add `from __future__ import annotations` automatically (UP007, UP045) (#23259)

Bug fixes
- Fix diagnostic when `ruff:enable` or `ruff:disable` appears where `ruff:ignore` is expected (#25700)
- [pyupgrade] Preserve leading empty literals to avoid syntax errors (UP032) (#25491)

Rule changes
- [flake8-pytest-style] Clarify diagnostic message for single parameters (PT007) (#25592)
- [numpy] Drop autofix for `np.in1d` (NPY201) (#25612)
- [pylint] Exempt Python version comparisons (PLR2004) (#25743)

Performance
- Reserve AST `Vec`s with correct capacity for common cases (#25451)

Formatter
- Preserve whitespace for Quarto cell option comments (#25641)

CLI
- Allow rule names in `ruff rule` (#25640)

Other changes
- Fix playground diagnostics scrollbars (#25642)
0.15.16 4. juni 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-06-04.

Preview features
- [flake8-async] Implement `yield-in-context-manager-in-async-generator` (ASYNC119) (#24644)
- [pylint] Narrow diagnostic range and exclude cases without exception handlers (PLW0717) (#25440)
- [ruff] Treat `yield` before `break` from a terminal loop as terminal (RUF075) (#25447)

Bug fixes
- [eradicate] Avoid flagging `ruff:ignore` comments as code (ERA001) (#25537)
- [eradicate] Fix ERA001/RUF100 conflict when `noqa` is on commented-out code (#25414)
- [pyflakes] Avoid removing the `format` call when it would change behavior (F523) (#25320)
- [pylint] Avoid syntax errors in invalid character replacements in f-strings before Python 3.12 (PLE2510, PLE2512, PLE2513, PLE2514, PLE2515) (#25544)
- [pyupgrade] Avoid converting `format` calls with more kinds of side effects (UP032) (#25484)

Rule changes
- [flake8-pytest-style] Avoid fixes for ambiguous `argnames` and `argvalues` combinations (PT006) (#24776)

Performance
- Drop excess capacity from statement suites during parsing (#25368)

Documentation
- [pydocstyle] Improve discoverability of rules enabled for each convention (#24973)
- [ruff] Restore example code for Python versions before 3.15 (RUF017) (#25439)
- Fix typo `bin/active` → `bin/activate` in tutorial (#25473)

Other changes
- Shrink additional parser AST collections (#25465)
0.15.15 28. maj 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-05-28.

Preview features
- Fix Markdown closing fence handling (#25310)
- [pyflakes] Report duplicate imports in `typing.TYPE_CHECKING` block (F811) (#22560)

Bug fixes
- [pyflakes] Treat function-scope bare annotations as locals per PEP 526 (F821) (#21540)

Performance
- Avoid redundant `TokenValue` drops in the lexer (#25300)
- Reduce memory usage by dropping token-excess capacity and improve performance by approximating the initial tokens `Vec` size (#25354)
- Use `ThinVec` in AST to shrink `Stmt` (#25361)

Documentation
- Fix `line-length` example for `--config` option (#25389)
- [flake8-comprehensions] Document `RecursionError` edge case in `__len__` (C416) (#25286)
- [mccabe] Improve example (C901) (#25287)
- [pyupgrade] Clarify fix safety docs (UP007, UP045) (#25288)
- [refurb] Document FURB192 exception change for empty sequences (#25317)
- [ruff] Document false negative for user-defined types (RUF013) (#25289)

Formatter
- Fix formatting of lambdas nested within f-strings (#25398)

Server
- Return code action for `codeAction/resolve` requests that contain no or no valid URL (#25365)

Other changes
- Expand semantic syntax errors for invalid walruses (#25415)
0.15.14 21. maj 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-05-21.

Preview features
- [airflow] Implement `airflow-task-implicit-multiple-outputs` (AIR202) (#25152)
- [flake8-use-pathlib] Mark PTH101 fix as unsafe when first argument is a class attribute annotated as `int` (#25086)
- [pylint] Implement `too-many-try-statements` (W0717) (#23970)
- [ruff] Add `incorrect-decorator-order` (RUF074) (#23461)
- [ruff] Add `fallible-context-manager` (RUF075) (#22844)

Bug fixes
- Fix lambda formatting in interpolated string expressions (#25144)
- Treat generic `frozenset` annotations as immutable (#25251)
- [flake8-type-checking] Avoid `strict` behavior when `future-annotations` are enabled (TC001, TC002, TC003) (#25035)
- [pylint] Avoid false positives in `else` clause (PLR1733) (#25177)

Rule changes
- [flake8-comprehensions] Skip C417 for lambdas with positional-only parameters (#25272)
- [flake8-simplify] Preserve f-string source verbatim in SIM101 fix (#25061)

Performance
- Avoid unnecessary parser lookahead for operators (#25290)

Documentation
- Update code example setting Neovim LSP log level (#25284)

Other changes
- Add full PEP 798 support (#25104)
- Add a parser recursion limit (#24810)
- Update various `ruff_python_stdlib` APIs (#25273)
0.15.13 14. maj 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-05-14.

Preview features
- Add a rule to flag lazy imports that are eagerly evaluated (#25016)
- [pylint] Standardize diagnostic message (PLR0914, PLR0917) (#24996)

Bug fixes
- Fix F811 false positive for class methods (#24933)
- Fix setting selection for multi-folder workspace (#24819)
- [eradicate] Fix false positive for lines with leading whitespace (ERA001) (#25122)
- [flake8-pyi] Fix false positive for f-string debug specifier (PYI016) (#24098)

Rule changes
- Always include panic payload in panic diagnostic message (#24873)
- Restrict PYI034 for in-place operations to enclosing class (#24511)
- Improve error message for parameters that are declared `global` (#24902)
- Update known stdlib (#25103)

Performance
- [isort] Avoid constructing `glob::Pattern`s for literal known modules (#25123)

CLI
- Add TOML examples to `--config` help text (#25013)
- Colorize ruff check 'All checks passed' (#25085)

Configuration
- Increase max allowed value of `line-length` setting (#24962)

Documentation
- Add D203 to rules that conflict with the formatter (#25044)
- Clarify COM819 and formatter interaction (#25045)
- Clarify that `NotImplemented` is a value, not an exception (F901) (#25054)
- Update number of lint rules supported (#24942)

Other changes
- Simplify the playground's markdown template (#24924)
0.15.12 24. april 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-04-24.

Preview features
- Implement `#ruff:file-ignore` file-level suppressions (#23599)
- Implement `#ruff:ignore` logical-line suppressions (#23404)
- Revert preview changes to displayed diagnostic severity in LSP (#24789)
- [airflow] Implement `task-branch-as-short-circuit` (AIR004) (#23579)
- [flake8-bugbear] Fix `break`/`continue` handling in `loop-iterator-mutation` (B909) (#24440)
- [pylint] Fix PLC2701 for type parameter scopes (#24576)

Rule changes
- [pandas-vet] Suggest `.array` as well in PD011 (#24805)

CLI
- Respect default Unix permissions for cache files (#24794)

Documentation
- [pylint] Fix PLR0124 description not to claim self-comparison always returns the same value (#24749)
- [pyupgrade] Expand docs on reusable `TypeVar`s and scoping (UP046) (#24153)
- Improve rules table accessibility (#24711)
0.15.11 16. april 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-04-16.

Preview features
- [ruff] Ignore RUF029 when function is decorated with `asynccontextmanager` (#24642)
- [airflow] Implement `airflow-xcom-pull-in-template-string` (AIR201) (#23583)
- [flake8-bandit] Fix S103 false positives and negatives in mask analysis (#24424)

Bug fixes
- [flake8-async] Omit overridden methods for ASYNC109 (#24648)

Documentation
- [flake8-async] Add override mention to ASYNC109 docs (#24666)
- Update Neovim config examples to use `vim.lsp.config` (#24577)
0.15.10 9. april 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-04-09.

Preview features
- [flake8-logging] Allow closures in except handlers (LOG004) (#24464)
- [flake8-self] Make `SLF` diagnostics robust to non-self-named variables (#24281)
- [flake8-simplify] Make the fix for `collapsible-if` safe in `preview` (SIM102) (#24371)

Bug fixes
- Avoid emitting multi-line f-string elements before Python 3.12 (#24377)
- Avoid syntax error from E502 fixes in f-strings and t-strings (#24410)
- Strip form feeds from indent passed to `dedent_to` (#24381)
- [pyupgrade] Fix panic caused by handling of octals (UP012) (#24390)
- Reject multi-line f-string elements before Python 3.12 (#24355)

Rule changes
- [ruff] Treat f-string interpolation as potential side effect (RUF019) (#24426)

Server
- Add support for custom file extensions (#24463)

Documentation
- Document adding fixes in CONTRIBUTING.md (#24393)
- Fix JSON typo in settings example (#24517)
0.15.9 2. april 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-04-02.

Preview features
- [pyflakes] Flag annotated variable redeclarations as F811 in preview mode (#24244)
- [ruff] Allow dunder-named assignments in non-strict mode for RUF067 (#24089)

Bug fixes
- [flake8-errmsg] Avoid shadowing existing `msg` in fix for EM101 (#24363)
- [flake8-simplify] Ignore pre-initialization references in SIM113 (#24235)
- [pycodestyle] Fix W391 fixes for consecutive empty notebook cells (#24236)
- [pyupgrade] Fix UP008 nested class matching (#24273)
- [pyupgrade] Ignore strings with string-only escapes (UP012) (#16058)
- [ruff] RUF072: skip formfeeds on dedent (#24308)
- [ruff] Avoid re-using symbol in RUF024 fix (#24316)
- [ruff] Parenthesize expression in RUF050 fix (#24234)
- Disallow starred expressions as values of starred expressions (#24280)

Rule changes
- [flake8-simplify] Suppress SIM105 for `except*` before Python 3.12 (#23869)
- [pyflakes] Extend F507 to flag `%`-format strings with zero placeholders (#24215)
- [pyupgrade] UP018 should detect more unnecessarily wrapped literals (UP018) (#24093)
- [pyupgrade] Fix UP008 callable scope handling to support lambdas (#24274)
- [ruff] RUF010: Mark fix as unsafe when it deletes a comment (#24270)

Formatter
- Add `nested-string-quote-style` formatting option (#24312)

Documentation
- [flake8-bugbear] Clarify RUF071 fix safety for non-path string comparisons (#24149)
- [flake8-type-checking] Clarify import cycle wording for TC001/TC002/TC003 (#24322)

Other changes
- Avoid rendering fix lines with trailing whitespace after `|` (#24343)
0.15.8 26. marts 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-03-26.

Preview features
- [ruff] New rule `unnecessary-if` (RUF050) (#24114)
- [ruff] New rule `useless-finally` (RUF072) (#24165)
- [ruff] New rule `f-string-percent-format` (RUF073): warn when using `%` operator on an f-string (#24162)
- [pyflakes] Recognize `frozendict` as a builtin for Python 3.15+ (#24100)

Bug fixes
- [flake8-async] Use fully-qualified `anyio.lowlevel` import in autofix (ASYNC115) (#24166)
- [flake8-bandit] Check tuple arguments for partial paths in S607 (#24080)
- [pyflakes] Skip `undefined-name` (F821) for conditionally deleted variables (#24088)
- E501/W505/formatter: Exclude nested pragma comments from line width calculation (#24071)
- Fix `%foo?` parsing in IPython assignment expressions (#24152)
- `analyze graph`: resolve string imports that reference attributes, not just modules (#24058)

Rule changes
- [eradicate] ignore `ty: ignore` comments in ERA001 (#24192)
- [flake8-bandit] Treat `sys.executable` as trusted input in S603 (#24106)
- [flake8-self] Recognize `Self` annotation and `self` assignment in SLF001 (#24144)
- [pyflakes] F507: Fix false negative for non-tuple RHS in `%`-formatting (#24142)
- [refurb] Parenthesize generator arguments in FURB142 fixer (#24200)

Performance
- Speed up diagnostic rendering (#24146)

Server
- Warn when Markdown files are skipped due to preview being disabled (#24150)

Documentation
- Clarify `extend-ignore` and `extend-select` settings documentation (#24064)
- Mention AI policy in PR template (#24198)

Other changes
- Use trusted publishing for NPM packages (#24171)
0.15.7 19. marts 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-03-19.

Preview features
- Display output severity in preview (#23845)
- Don't show `noqa` hover for non-Python documents (#24040)

Rule changes
- [pycodestyle] Recognize `pyrefly:` as a pragma comment (E501) (#24019)

Server
- Don't return code actions for non-Python documents (#23905)

Documentation
- Add company AI policy to contributing guide (#24021)
- Document editor features for Markdown code formatting (#23924)
- [pylint] Improve phrasing (PLC0208) (#24033)

Other changes
- Use PEP 639 license information (#19661)
0.15.6 12. marts 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-03-12.

Preview features
- Add support for `lazy` import parsing (#23755)
- Add support for star-unpacking of comprehensions (PEP 798) (#23788)
- Reject semantic syntax errors for lazy imports (#23757)
- Drop a few rules from the preview default set (#23879)
- [airflow] Flag `Variable.get()` calls outside of task execution context (AIR003) (#23584)
- [airflow] Flag runtime-varying values in DAG/task constructor arguments (AIR304) (#23631)
- [flake8-bugbear] Implement `delattr-with-constant` (B043) (#23737)
- [flake8-tidy-imports] Add TID254 to enforce lazy imports (#23777)
- [flake8-tidy-imports] Allow users to ban lazy imports with TID254 (#23847)
- [isort] Retain `lazy` keyword when sorting imports (#23762)
- [pyupgrade] Add `from __future__ import annotations` automatically (UP006) (#23260)
- [refurb] Support `newline` parameter in FURB101 for Python 3.13+ (#23754)
- [ruff] Add `os-path-commonprefix` (RUF071) (#23814)
- [ruff] Add unsafe fix for os-path-commonprefix (RUF071) (#23852)
- [ruff] Limit RUF036 to typing contexts; make it unsafe for non-typing-only (#23765)
- [ruff] Use starred unpacking for RUF017 in Python 3.15+ (#23789)

Bug fixes
- Fix `--add-noqa` creating unwanted leading whitespace (#23773)
- Fix `--add-noqa` breaking shebangs (#23577)
- [formatter] Fix lambda body formatting for multiline calls and subscripts (#23866)
- [formatter] Preserve required annotation parentheses in annotated assignments (#23865)
- [formatter] Preserve type-expression parentheses in the formatter (#23867)
- [flake8-annotations] Fix stack overflow in ANN401 on quoted annotations with escape sequences (#23912)
- [pep8-naming] Check naming conventions in `match` pattern bindings (N806, N815, N816) (#23899)
- [perflint] Fix comment duplication in fixes (PERF401, PERF403) (#23729)
- [pyupgrade] Properly trigger `super` change in nested class (UP008) (#22677)
- [ruff] Avoid syntax errors in RUF036 fixes (#23764)

Rule changes
- [flake8-bandit] Flag S501 with `requests.request` (#23873)
- [flake8-executable] Fix WSL detection in non-Docker containers (#22879)
- [flake8-print] Ignore `pprint` calls with `stream=` (#23787)

Documentation
- Update docs for Markdown code block formatting (#23871)
- [flake8-bugbear] Fix misleading description for B904 (#23731)
0.15.5 5. marts 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-03-05.

Preview features
- Discover Markdown files by default in preview mode (#23434)
- [perflint] Extend PERF102 to comprehensions and generators (#23473)
- [refurb] Fix FURB101 and FURB103 false positives when I/O variable is used later (#23542)
- [ruff] Add fix for `none-not-at-end-of-union` (RUF036) (#22829)
- [ruff] Fix false positive for `re.split` with empty string pattern (RUF055) (#23634)

Bug fixes
- [fastapi] Handle callable class dependencies with `__call__` method (FAST003) (#23553)
- [pydocstyle] Fix numpy section ordering (D420) (#23685)
- [pyflakes] Fix false positive for names shadowing re-exports (F811) (#23356)
- [pyupgrade] Avoid inserting redundant `None` elements in UP045 (#23459)

Documentation
- Document extension mapping for Markdown code formatting (#23574)
- Update default Python version examples (#23605)

Other changes
- Publish releases to Astral mirror (#23616)
0.15.4 26. februar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-02-26.

This is a follow-up release to 0.15.3 that resolves a panic when the new rule PLR1712 was enabled with any rule that analyzes definitions, such as many of the `ANN` or `D` rules.

Bug fixes
- Fix panic on access to definitions after analyzing definitions (#23588)
- [pyflakes] Suppress false positive in F821 for names used before `del` in stub files (#23550)

Documentation
- Clarify first-party import detection in Ruff (#23591)
- Fix incorrect `import-heading` example (#23568)
0.15.3 26. februar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-02-26.

Preview features
- Drop explicit support for `.qmd` file extension (#23572)

This can now be enabled instead by setting the `extension` option:

```toml
# ruff.toml
extension = { qmd = "markdown" }

# pyproject.toml
[tool.ruff]
extension = { qmd = "markdown" }
```

- Include configured extensions in file discovery (#23400)

- [flake8-bandit] Allow suspicious imports in `TYPE_CHECKING` blocks (S401-S415) (#23441)

- [flake8-bugbear] Allow B901 in pytest hook wrappers (#21931)

- [flake8-import-conventions] Add missing conventions from upstream (ICN001, ICN002) (#21373)

- [pydocstyle] Add rule to enforce docstring section ordering (D420) (#23537)

- [pylint] Implement `swap-with-temporary-variable` (PLR1712) (#22205)

- [ruff] Add `unnecessary-assign-before-yield` (RUF070) (#23300)

- [ruff] Support file-level noqa in RUF102 (#23535)

- [ruff] Suppress diagnostic for invalid f-strings before Python 3.12 (RUF027) (#23480)

- [flake8-bandit] Don't flag `BaseLoader`/`CBaseLoader` as unsafe (S506) (#23510)

Bug fixes
- Avoid infinite loop between I002 and PYI025 (#23352)
- [pyflakes] Fix false positive for `@overload` from `lint.typing-modules` (F811) (#23357)
- [pyupgrade] Fix false positive for `TypeVar` default before Python 3.12 (UP046) (#23540)
- [pyupgrade] Fix handling of `\N` in raw strings (UP032) (#22149)

Rule changes
- Render sub-diagnostics in the GitHub output format (#23455)

- [flake8-bugbear] Tag certain B007 diagnostics as unnecessary (#23453)

- [ruff] Ignore unknown rule codes in RUF100 (#23531)

These are now flagged by RUF102 instead.

Documentation
- Fix missing settings links for several linters (#23519)
- Update isort action comments heading (#23515)
- [pydocstyle] Fix double comma in description of D404 (#23440)

Other changes
- Update the Python module (notably `find_ruff_bin`) for parity with uv (#23406)
0.15.2 19. februar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-02-19.

Preview features
- Expand the default rule set (#23385)

In preview, Ruff now enables a significantly expanded default rule set of 412
rules, up from the stable default set of 59 rules. The new rules are mostly a
superset of the stable defaults, with the exception of these rules, which are
removed from the preview defaults:

- `multiple-imports-on-one-line` (E401)
- `module-import-not-at-top-of-file` (E402)
- `module-import-not-at-top-of-file` (E701)
- `multiple-statements-on-one-line-semicolon` (E702)
- `useless-semicolon` (E703)
- `none-comparison` (E711)
- `true-false-comparison` (E712)
- `not-in-test` (E713)
- `not-is-test` (E714)
- `type-comparison` (E721)
- `lambda-assignment` (E731)
- `ambiguous-variable-name` (E741)
- `ambiguous-class-name` (E742)
- `ambiguous-function-name` (E743)
- `undefined-local-with-import-star` (F403)
- `undefined-local-with-import-star-usage` (F405)
- `undefined-local-with-nested-import-star-usage` (F406)
- `forward-annotation-syntax-error` (F722)

If you use preview and prefer the old defaults, you can restore them with
configuration like:

```toml

# ruff.toml

[lint]
select = ["E4", "E7", "E9", "F"]

# pyproject.toml

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

If you do give them a try, feel free to share your feedback in the GitHub
discussion!

- [flake8-pyi] Also check string annotations (PYI041) (#19023)

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

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

CLI
- Remove invalid inline `noqa` warning (#23270)

Configuration
- Add extension mapping to configuration file options (#23384)

Documentation
- Add Q004 to the list of conflicting rules (#23340)
- [ruff] Expand `lint.external` docs and add sub-diagnostic (RUF100, RUF102) (#23268)
0.15.1 13. februar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-02-12.

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

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

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

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

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

Other changes
- Exclude WASM artifacts from GitHub releases (#23221)
0.15.0 3. februar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-02-03.

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

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

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

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

See the documentation for more details.

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

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

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

- Ruff now resolves all `extend`ed configuration files before falling back on a default Python version.

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

- `blocking-http-call-httpx-in-async-function` (ASYNC212)
- `blocking-path-method-in-async-function` (ASYNC240)
- `blocking-input-in-async-function` (ASYNC250)
- `map-without-explicit-strict` (B912)
- `if-exp-instead-of-or-operator` (FURB110)
- `single-item-membership-test` (FURB171)
- `missing-maxsplit-arg` (PLC0207)
- `unnecessary-lambda` (PLW0108)
- `unnecessary-empty-iterable-within-deque-call` (RUF037)
- `in-empty-collection` (RUF060)
- `legacy-form-pytest-raises` (RUF061)
- `non-octal-permissions` (RUF064)
- `invalid-rule-code` (RUF102)
- `invalid-suppression-comment` (RUF103)
- `unmatched-suppression-comment` (RUF104)
- `replace-str-enum` (UP042)

The following behaviors have been stabilized:

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

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

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

Preview features
- Apply formatting to Markdown code blocks (#22470, #22990, #22996)

See the documentation for more details.

Bug fixes
- Fix suppression indentation matching (#22903)

Rule changes
- Customize where the `fix_title` sub-diagnostic appears (#23044)
- [FastAPI] Add sub-diagnostic explaining why a fix was unavailable (FAST002) (#22565)
- [flake8-annotations] Don't suggest `NoReturn` for functions raising `NotImplementedError` (ANN201, ANN202, ANN205, ANN206) (#21311)
- [pyupgrade] Make fix unsafe if it deletes comments (UP017) (#22873)
- [pyupgrade] Make fix unsafe if it 
0.14.14 22. januar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-01-22.

Preview features
- Preserve required parentheses in lambda bodies (#22747)
- Combine range suppression code diagnostics (#22613)
- [airflow] Second positional argument to `Asset`/`Dataset` should not be a dictionary (AIR303) (#22453)
- [ruff] Detect duplicate entries in `__all__` (RUF068) (#22114)

Bug fixes
- [pyupgrade] Allow shadowing non-builtin bindings (UP029) (#22749)
- [pyupgrade] Apply UP045 to string arguments of `typing.cast` (#22320)
- [flake8-pie] Detect duplicated declared class fields in PIE794 (#22717)

Rule changes
- [flake8-pyi] Fix inconsistent handling of forward references for `__new__`, `__enter__`, `__aenter__` in PYI034 (#22798)
- [flake8-pytest-style] Support `check` parameter in PT011 (#22725)
- [ruff] Add exception for `ctypes.Structure._fields_` (RUF012) (#22559)
- Many fixes are now marked unsafe if they would remove comments:
- [flake8-bugbear] B009, B010, B013, B014, B033
- [flake8-simplify] SIM910, SIM911
- [pyupgrade] UP007, UP039, UP041, UP045
- [refurb] FURB105, FURB116, FURB136, FURB140, FURB145, FURB154, FURB157, FURB164,FURB181, FURB188
- [ruff] RUF019, RUF020

Documentation
- Add `--exit-non-zero-on-format` to formatter exit codes section (#22761)
- Update contributing guide for adding a new rule (#22779)
- [FastAPI] Document fix safety for FAST001 (#22655)
- [flake8-async] Tweak explanation to focus on latency/efficiency tradeoff (ASYNC110) (#22715)
- [pandas-vet] Make example error out-of-the-box (PD002) (#22561)
- [refurb] Make the example work out of box (FURB101) (#22770)
- [refurb] Make the example work out of box (FURB103) (#22769)
0.14.13 15. januar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-01-15.

This is a follow-up release to 0.14.12. Because of an issue publishing the WASM packages, there is no GitHub release or Git tag for 0.14.12, although the package was published to PyPI. The contents of the 0.14.13 release are identical to 0.14.12.

0.14.12
### Preview features

- [flake8-blind-except] Allow more logging methods (BLE001) (#22057)
- [ruff] Respect `lint.pydocstyle.property-decorators` in RUF066 (#22515)

Bug fixes
- Fix configuration path in `--show-settings` (#22478)
- Respect `fmt: skip` for multiple statements on the same logical line (#22119)

Rule changes
- [pydocstyle] Update Rust crate imperative to v1.0.7 (D401) (#22519)
- [isort] Insert imports in alphabetical order (I002) (#22493)

Documentation
- Add llms.txt support for documentation (#22463)
- Use prek in documentation and CI (#22505)
- [flake8-pytest-style] Add `check` parameter example to PT017 docs (#22546)
- [ruff] Make example error out-of-the-box (RUF103) (#22558)
- [ruff] document RUF100 trailing comment fix behavior (#22479)

Other changes
- wasm: Require explicit logging initialization (#22587)
0.14.11 8. januar 2026 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2026-01-08.

Preview features
- Consolidate diagnostics for matched disable/enable suppression comments (#22099)
- Report diagnostics for invalid/unmatched range suppression comments (#21908)
- [airflow] Passing positional argument into `airflow.lineage.hook.HookLineageCollector.create_asset` is not allowed (AIR303) (#22046)
- [refurb] Mark FURB192 fix as always unsafe (#22210)
- [ruff] Add `non-empty-init-module` (RUF067) (#22143)

Bug fixes
- Fix GitHub format for multi-line diagnostics (#22108)
- [flake8-unused-arguments] Mark `**kwargs` in `TypeVar` as used (ARG001) (#22214)

Rule changes
- Add `help:` subdiagnostics for several Ruff rules that can sometimes appear to disagree with `ty` (#22331)
- [pylint] Demote PLW1510 fix to display-only (#22318)
- [pylint] Ignore identical members (PLR1714) (#22220)
- [pylint] Improve diagnostic range for PLC0206 (#22312)
- [ruff] Improve fix title for RUF102 invalid rule code (#22100)
- [flake8-simplify]: Avoid unnecessary builtins import for SIM105 (#22358)

Configuration
- Allow Python 3.15 as valid `target-version` value in preview (#22419)
- Check `required-version` before parsing rules (#22410)
- Include configured `src` directories when resolving graphs (#22451)

Documentation
- Update T201 suggestion to not use root logger to satisfy LOG015 (#22059)
- Fix `iter` example in unsafe fixes doc (#22118)
- [flake8_print] better suggestion for `basicConfig` in T201 docs (#22101)
- [pylint] Restore the fix safety docs for PLW0133 (#22211)
- Fix Jupyter notebook discovery info for editors (#22447)
0.14.10 18. december 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-12-18.

Preview features
- [formatter] Fluent formatting of method chains (#21369)
- [formatter] Keep lambda parameters on one line and parenthesize the body if it expands (#21385)
- [flake8-implicit-str-concat] New rule to prevent implicit string concatenation in collections (ISC004) (#21972)
- [flake8-use-pathlib] Make fixes unsafe when types change in compound statements (PTH104, PTH105, PTH109, PTH115) (#22009)
- [refurb] Extend support for `Path.open` (FURB101, FURB103) (#21080)

Bug fixes
- [pyupgrade] Fix parsing named Unicode escape sequences (UP032) (#21901)

Rule changes
- [eradicate] Ignore `ruff:disable` and `ruff:enable` comments in ERA001 (#22038)
- [flake8-pytest-style] Allow `match` and `check` keyword arguments without an expected exception type (PT010) (#21964)
- [syntax-errors] Annotated name cannot be global (#20868)

Documentation
- Add `uv` and `ty` to the Ruff README (#21996)
- Document known lambda formatting deviations from Black (#21954)
- Update `setup.md` (#22024)
- [flake8-bandit] Fix broken link (S704) (#22039)

Other changes
- Fix playground Share button showing "Copied!" before clipboard copy completes (#21942)
0.14.9 11. december 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-12-11.

Preview features
- [ruff] New RUF100 diagnostics for unused range suppressions (#21783)
- [pylint] Detect subclasses of builtin exceptions (PLW0133) (#21382)

Bug fixes
- Fix comment placement in lambda parameters (#21868)
- Skip over trivia tokens after re-lexing (#21895)
- [flake8-bandit] Fix false positive when using non-standard `CSafeLoader` path (S506). (#21830)
- [flake8-bugbear] Accept immutable slice default arguments (B008) (#21823)

Rule changes
- [pydocstyle] Suppress D417 for parameters with `Unpack` annotations (#21816)

Performance
- Use `memchr` for computing line indexes (#21838)

Documentation
- Document `*.pyw` is included by default in preview (#21885)
- Document range suppressions, reorganize suppression docs (#21884)
- Update mkdocs-material to 9.7.0 (Insiders now free) (#21797)
0.14.8 4. december 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-12-04.

Preview features
- [flake8-bugbear] Catch `yield` expressions within other statements (B901) (#21200)
- [flake8-use-pathlib] Mark fixes unsafe for return type changes (PTH104, PTH105, PTH109, PTH115) (#21440)

Bug fixes
- Fix syntax error false positives for `await` outside functions (#21763)
- [flake8-simplify] Fix truthiness assumption for non-iterable arguments in tuple/list/set calls (SIM222, SIM223) (#21479)

Documentation
- Suggest using `--output-file` option in GitLab integration (#21706)

Other changes
- [syntax-error] Default type parameter followed by non-default type parameter (#21657)
0.14.7 28. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-11-28.

Preview features
- [flake8-bandit] Handle string literal bindings in suspicious-url-open-usage (S310) (#21469)
- [pylint] Fix PLR1708 false positives on nested functions (#21177)
- [pylint] Fix suppression for empty dict without tuple key annotation (PLE1141) (#21290)
- [ruff] Add rule RUF066 to detect unnecessary class properties (#21535)
- [ruff] Catch more dummy variable uses (RUF052) (#19799)

Bug fixes
- [server] Set severity for non-rule diagnostics (#21559)
- [flake8-implicit-str-concat] Avoid invalid fix in (ISC003) (#21517)
- [parser] Fix panic when parsing IPython escape command expressions (#21480)

CLI
- Show partial fixability indicator in statistics output (#21513)
0.14.6 21. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-11-21.

Preview features
- [flake8-bandit] Support new PySNMP API paths (S508, S509) (#21374)

Bug fixes
- Adjust own-line comment placement between branches (#21185)
- Avoid syntax error when formatting attribute expressions with outer parentheses, parenthesized value, and trailing comment on value (#20418)
- Fix panic when formatting comments in unary expressions (#21501)
- Respect `fmt: skip` for compound statements on a single line (#20633)
- [refurb] Fix FURB103 autofix (#21454)
- [ruff] Fix false positive for complex conversion specifiers in `logging-eager-conversion` (RUF065) (#21464)

Rule changes
- [ruff] Avoid false positive on `ClassVar` reassignment (RUF012) (#21478)

CLI
- Render hyperlinks for lint errors (#21514)
- Add a `ruff analyze` option to skip over imports in `TYPE_CHECKING` blocks (#21472)

Documentation
- Limit `eglot-format` hook to eglot-managed Python buffers (#21459)
- Mention `force-exclude` in "Configuration > Python file discovery" (#21500)
0.14.5 13. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-11-13.

Preview features
- [flake8-simplify] Apply SIM113 when index variable is of type `int` (#21395)
- [pydoclint] Fix false positive when Sphinx directives follow a "Raises" section (DOC502) (#20535)
- [pydoclint] Support NumPy-style comma-separated parameters (DOC102) (#20972)
- [refurb] Auto-fix annotated assignments (FURB101) (#21278)
- [ruff] Ignore `str()` when not used for simple conversion (RUF065) (#21330)

Bug fixes
- Fix syntax error false positive on alternative `match` patterns (#21362)
- [flake8-simplify] Fix false positive for iterable initializers with generator arguments (SIM222) (#21187)
- [pyupgrade] Fix false positive on relative imports from local `.builtins` module (UP029) (#21309)
- [pyupgrade] Consistently set the deprecated tag (UP035) (#21396)

Rule changes
- [refurb] Detect empty f-strings (FURB105) (#21348)

CLI
- Add option to provide a reason to `--add-noqa` (#21294)
- Add upstream linter URL to `ruff linter --output-format=json` (#21316)
- Add color to `--help` (#21337)

Documentation
- Add a new "Opening a PR" section to the contribution guide (#21298)
- Added the PyScripter IDE to the list of "Who is using Ruff?" (#21402)
- Update PyCharm setup instructions (#21409)
- [flake8-annotations] Add link to `allow-star-arg-any` option (ANN401) (#21326)

Other changes
- [configuration] Improve error message when `line-length` exceeds `u16::MAX` (#21329)
0.14.4 6. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-11-06.

Preview features
- [formatter] Allow newlines after function headers without docstrings (#21110)
- [formatter] Avoid extra parentheses for long `match` patterns with `as` captures (#21176)
- [refurb] Expand fix safety for keyword arguments and `Decimal`s (FURB164) (#21259)
- [refurb] Preserve argument ordering in autofix (FURB103) (#20790)

Bug fixes
- [server] Fix missing diagnostics for notebooks (#21156)
- [flake8-bugbear] Ignore non-NFKC attribute names in B009 and B010 (#21131)
- [refurb] Fix false negative for underscores before sign in `Decimal` constructor (FURB157) (#21190)
- [ruff] Fix false positives on starred arguments (RUF057) (#21256)

Rule changes
- [airflow] extend deprecated argument `concurrency` in `airflow..DAG` (AIR301) (#21220)

Documentation
- Improve `extend` docs (#21135)
- [flake8-comprehensions] Fix typo in C416 documentation (#21184)
- Revise Ruff setup instructions for Zed editor (#20935)

Other changes
- Make `ruff analyze graph` work with jupyter notebooks (#21161)
0.14.3 4. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-10-30.

Preview features
- Respect `--output-format` with `--watch` (#21097)
- [pydoclint] Fix false positive on explicit exception re-raising (DOC501, DOC502) (#21011)
- [pyflakes] Revert to stable behavior if imports for module lie in alternate branches for F401 (#20878)
- [pylint] Implement `stop-iteration-return` (PLR1708) (#20733)
- [ruff] Add support for additional eager conversion patterns (RUF065) (#20657)

Bug fixes
- Fix finding keyword range for clause header after statement ending with semicolon (#21067)
- Fix syntax error false positive on nested alternative patterns (#21104)
- [ISC001] Fix panic when string literals are unclosed (#21034)
- [flake8-django] Apply DJ001 to annotated fields (#20907)
- [flake8-pyi] Fix PYI034 to not trigger on metaclasses (PYI034) (#20881)
- [flake8-type-checking] Fix TC003 false positive with `future-annotations` (#21125)
- [pyflakes] Fix false positive for `__class__` in lambda expressions within class definitions (F821) (#20564)
- [pyupgrade] Fix false positive for `TypeVar` with default on Python \<3.13 (UP046,UP047) (#21045)

Rule changes
- Add missing docstring sections to the numpy list (#20931)
- [airflow] Extend `airflow.models..Param` check (AIR311) (#21043)
- [airflow] Warn that `airflow....DAG.create_dagrun` has been removed (AIR301) (#21093)
- [refurb] Preserve digit separators in `Decimal` constructor (FURB157) (#20588)

Server
- Avoid sending an unnecessary "clear diagnostics" message for clients supporting pull diagnostics (#21105)

Documentation
- [flake8-bandit] Fix correct example for S308 (#21128)

Other changes
- Clearer error message when `line-length` goes beyond threshold (#21072)
0.14.2 6. november 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-10-23.

Preview features
- [flake8-gettext] Resolve qualified names and built-in bindings (INT001, INT002, INT003) (#19045)

Bug fixes
- Avoid reusing nested, interpolated quotes before Python 3.12 (#20930)
- Catch syntax errors in nested interpolations before Python 3.12 (#20949)
- [fastapi] Handle ellipsis defaults in FAST002 autofix (#20810)
- [flake8-simplify] Skip SIM911 when unknown arguments are present (#20697)
- [pyupgrade] Always parenthesize assignment expressions in fix for `f-string` (UP032) (#21003)
- [pyupgrade] Fix UP032 conversion for decimal ints with underscores (#21022)
- [fastapi] Skip autofix for keyword and `__debug__` path params (FAST003) (#20960)

Rule changes
- [flake8-bugbear] Skip B905 and B912 for fewer than two iterables and no starred arguments (#20998)
- [ruff] Use `DiagnosticTag` for more `pyflakes` and `pandas` rules (#20801)

CLI
- Improve JSON output from `ruff rule` (#20168)

Documentation
- Add source to testimonial (#20971)
- Document when a rule was added (#21035)

Other changes
- [syntax-errors] Name is parameter and global (#20426)
- [syntax-errors] Alternative `match` patterns bind different names (#20682)
0.14.1 23. oktober 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-10-16.

Preview features
- [formatter] Remove parentheses around multiple exception types on Python 3.14+ (#20768)
- [flake8-bugbear] Omit annotation in preview fix for B006 (#20877)
- [flake8-logging-format] Avoid dropping implicitly concatenated pieces in the G004 fix (#20793)
- [pydoclint] Implement `docstring-extraneous-parameter` (DOC102) (#20376)
- [pyupgrade] Extend UP019 to detect `typing_extensions.Text` (UP019) (#20825)
- [pyupgrade] Fix false negative for `TypeVar` with default argument in `non-pep695-generic-class` (UP046) (#20660)

Bug fixes
- Fix false negatives in `Truthiness::from_expr` for lambdas, generators, and f-strings (#20704)
- Fix syntax error false positives for escapes and quotes in f-strings (#20867)
- Fix syntax error false positives on parenthesized context managers (#20846)
- [fastapi] Fix false positives for path parameters that FastAPI doesn't recognize (FAST003) (#20687)
- [flake8-pyi] Fix operator precedence by adding parentheses when needed (PYI061) (#20508)
- [ruff] Suppress diagnostic for f-string interpolations with debug text (RUF010) (#20525)

Rule changes
- [airflow] Add warning to `airflow.datasets.DatasetEvent` usage (AIR301) (#20551)
- [flake8-bugbear] Mark B905 and B912 fixes as unsafe (#20695)
- Use `DiagnosticTag` for more rules - changes display in editors (#20758,#20734)

Documentation
- Update Python compatibility from 3.13 to 3.14 in README.md (#20852)
- Update `lint.flake8-type-checking.quoted-annotations` docs (#20765)
- Update setup instructions for Zed 0.208.0+ (#20902)
- [flake8-datetimez] Clarify docs for several rules (#20778)
- Fix typo in RUF015 description (#20873)

Other changes
- Reduce binary size (#20863)
- Improved error recovery for unclosed strings (including f- and t-strings) (#20848)
0.14.0 7. oktober 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-10-07.

Breaking changes
- Update default and latest Python versions for 3.14 (#20725)

Preview features
- [flake8-bugbear] Include certain guaranteed-mutable expressions: tuples, generators, and assignment expressions (B006) (#20024)
- [refurb] Add fixes for FURB101 and FURB103 (#20520)
- [ruff] Extend FA102 with listed PEP 585-compatible APIs (#20659)

Bug fixes
- [flake8-annotations] Fix return type annotations to handle shadowed builtin symbols (ANN201, ANN202, ANN204, ANN205, ANN206) (#20612)
- [flynt] Fix f-string quoting for mixed quote joiners (FLY002) (#20662)
- [isort] Fix inserting required imports before future imports (I002) (#20676)
- [ruff] Handle argfile expansion errors gracefully (#20691)
- [ruff] Skip RUF051 if `else`/`elif` block is present (#20705)
- [ruff] Improve handling of intermixed comments inside from-imports (#20561)

Documentation
- [flake8-comprehensions] Clarify fix safety documentation (C413) (#20640)
0.13.3 2. oktober 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-10-02.

Preview features
- Display diffs for `ruff format --check` and add support for different output formats (#20443)
- [pyflakes] Handle some common submodule import situations for `unused-import` (F401) (#20200)
- [ruff] Do not flag `%r` + `repr()` combinations (RUF065) (#20600)

Bug fixes
- [cli] Add conflict between `--add-noqa` and `--diff` options (#20642)
- [pylint] Exempt required imports from PLR0402 (#20381)
- [pylint] Fix missing `max-nested-blocks` in settings display (#20574)
- [pyupgrade] Prevent infinite loop with I002 and UP026 (#20634)

Rule changes
- [flake8-simplify] Improve help message clarity (SIM105) (#20548)

Documentation
- Add the *The Basics* title back to CONTRIBUTING.md (#20624)
- Fixed documentation for try_consider_else (#20587)
- [isort] Clarify dependency between `order-by-type` and `case-sensitive` settings (#20559)
- [pylint] Clarify fix safety to include left-hand hashability (PLR6201) (#20518)

Other changes
- [playground] Fix quick fixes for empty ranges in playground (#20599)
0.13.2 25. september 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-09-25.

Preview features
- [flake8-async] Implement `blocking-path-method` (ASYNC240) (#20264)
- [flake8-bugbear] Implement `map-without-explicit-strict` (B912) (#20429)
- [flake8-bultins] Detect class-scope builtin shadowing in decorators, default args, and attribute initializers (A003) (#20178)
- [ruff] Implement `logging-eager-conversion` (RUF065) (#19942)
- Include `.pyw` files by default when linting and formatting (#20458)

Bug fixes
- Deduplicate input paths (#20105)
- [flake8-comprehensions] Preserve trailing commas for single-element lists (C409) (#19571)
- [flake8-pyi] Avoid syntax error from conflict with PIE790 (PYI021) (#20010)
- [flake8-simplify] Correct fix for positive `maxsplit` without separator (SIM905) (#20056)
- [pyupgrade] Fix UP008 not to apply when `__class__` is a local variable (#20497)
- [ruff] Fix B004 to skip invalid `hasattr`/`getattr` calls (#20486)
- [ruff] Replace `-nan` with `nan` when using the value to construct a `Decimal` (FURB164 ) (#20391)

Documentation
- Add 'Finding ways to help' to CONTRIBUTING.md (#20567)
- Update import path to `ruff-wasm-web` (#20539)
- [flake8-bandit] Clarify the supported hashing functions (S324) (#20534)

Other changes
- [playground] Allow hover quick fixes to appear for overlapping diagnostics (#20527)
- [playground] Fix non‑BMP code point handling in quick fixes and markers (#20526)
0.13.1 18. september 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Released on 2025-09-18.

Preview features
- [flake8-simplify] Detect unnecessary `None` default for additional key expression types (SIM910) (#20343)
- [flake8-use-pathlib] Add fix for PTH123 (#20169)
- [flake8-use-pathlib] Fix PTH101, PTH104, PTH105, PTH121 fixes (#20143)
- [flake8-use-pathlib] Make PTH111 fix unsafe because it can change behavior (#20215)
- [pycodestyle] Fix E301 to only trigger for functions immediately within a class (#19768)
- [refurb] Mark `single-item-membership-test` fix as always unsafe (FURB171) (#20279)

Bug fixes
- Handle t-strings for token-based rules and suppression comments (#20357)
- [flake8-bandit] Fix truthiness: dict-only `**` displays not truthy for `shell` (S602, S604, S609) (#20177)
- [flake8-simplify] Fix diagnostic to show correct method name for `str.rsplit` calls (SIM905) (#20459)
- [flynt] Use triple quotes for joined raw strings with newlines (FLY002) (#20197)
- [pyupgrade] Fix false positive when class name is shadowed by local variable (UP008) (#20427)
- [pyupgrade] Prevent infinite loop with I002 and UP026 (#20327)
- [ruff] Recognize t-strings, generators, and lambdas in `invalid-index-type` (RUF016) (#20213)

Rule changes
- [RUF102] Respect rule redirects in invalid rule code detection (#20245)
- [flake8-bugbear] Mark the fix for `unreliable-callable-check` as always unsafe (B004) (#20318)
- [ruff] Allow dataclass attribute value instantiation from nested frozen dataclass (RUF009) (#20352)

CLI
- Add fixes to `output-format=sarif` (#20300)
- Treat panics as fatal diagnostics, sort panics last (#20258)

Documentation
- [ruff] Add `analyze.string-imports-min-dots` to settings (#20375)
- Update README.md with Albumentations new repository URL (#20415)

Other changes
- Bump MSRV to Rust 1.88 (#20470)
- Enable inline noqa for multiline strings in playground (#20442)
0.13.0 10. september 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration
guide and overview of the changes!

Breaking changes
- **Several rules can now add `from __future__ import annotations` automatically**

TC001, TC002, TC003, RUF013, and UP037 now add `from __future__ import annotations` as part of their fixes when the
`lint.future-annotations` setting is enabled. This allows the rules to move
more imports into `TYPE_CHECKING` blocks (TC001, TC002, and TC003),
use PEP 604 union syntax on Python versions before 3.10 (RUF013), and
unquote more annotations (UP037).

- Full module paths are now used to verify first-party modules

Ruff now checks that the full path to a module exists on disk before
categorizing it as a first-party import. This change makes first-party
import detection more accurate, helping to avoid false positives on local
directories with the same name as a third-party dependency, for example. See
the FAQ
section on import categorization for more details.

- Deprecated rules must now be selected by exact rule code

Ruff will no longer activate deprecated rules selected by their group name
or prefix. As noted below, the two remaining deprecated rules were also
removed in this release, so this won't affect any current rules, but it will
still affect any deprecations in the future.

- The deprecated macOS configuration directory fallback has been removed

Ruff will no longer look for a user-level configuration file at
`~/Library/Application Support/ruff/ruff.toml` on macOS. This feature was
deprecated in v0.5 in favor of using the XDG
specification
(usually resolving to `~/.config/ruff/ruff.toml`), like on Linux. The
fallback and accompanying deprecation warning have now been removed.

Removed Rules
The following rules have been removed:

- `pandas-df-variable-name` (PD901)
- `non-pep604-isinstance` (UP038)

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

- `airflow-dag-no-schedule-argument`
(AIR002)
- `airflow3-removal` (AIR301)
- `airflow3-moved-to-provider`
(AIR302)
- `airflow3-suggested-update`
(AIR311)
- `airflow3-suggested-to-move-to-provider`
(AIR312)
- `long-sleep-not-forever` (ASYNC116)
- `f-string-number-format` (FURB116)
- `os-symlink` (PTH211)
- `generic-not-last-base-class`
(PYI059)
- `redundant-none-literal` (PYI061)
- `pytest-raises-ambiguous-pattern`
(RUF043)
- `unused-unpacked-variable`
(RUF059)
- `useless-class-metaclass-type`
(UP050)

The following behaviors have been stabilized:

- `assert-raises-exception` (B017)
now checks for direct calls to `unittest.TestCase.assert_raises` and `pytest.raises` instead of
only the context manager forms.
- `missing-trailing-comma` (COM812)
and `prohibited-trailing-comma`
(COM819) now check for trailing commas in PEP 695 type parameter lists.
- `raw-string-in-exception` (EM101)
now also checks for byte strings in exception messages.
- `invalid-mock-access` (PGH005) now
checks for `AsyncMock` methods like `not_awaited` in addition to the synchronous variants.
- `useless-import-alias` (PLC0414) no
longer applies to `__init__.py` files, where it conflicted with one of the suggested fixes for
`unused-import` (F401).
- `bidirectional-unicode` (PLE2502) now
also checks for U+061C (Arabic Letter Mark).
- The fix for
`multiple-with-statements`
(SIM117) is now marked as always safe.

Preview features
- [pyupgrade] Enable UP043 in stub files (#20027)

Bug fixes
- [pyupgrade] Apply UP008 only when the `__class__` cell exists (#19424)
- [ruff] Fix empty f-string detection in `in-empty-collection` (RUF060) (#20249)

Server
- Add support for using uv as an alternative formatter backend (#19665)

Documentation
- [pep8-naming] Fix formatting of `__all__` (N816) (#20301)
0.12.12 4. september 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Show fixes by default (#19919)
- [airflow] Convert `DatasetOrTimeSchedule(datasets=...)` to `AssetOrTimeSchedule(assets=...)` (AIR311) (#20202)
- [airflow] Improve the AIR002 error message (#20173)
- [airflow] Move `airflow.operators.postgres_operator.Mapping` from AIR302 to AIR301 (#20172)
- [flake8-async] Implement `blocking-input` rule (ASYNC250) (#20122)
- [flake8-use-pathlib] Make PTH119 and PTH120 fixes unsafe because they can change behavior (#20118)
- [pylint] Add U+061C to PLE2502 (#20106)
- [ruff] Fix false negative for empty f-strings in `deque` calls (RUF037) (#20109)

Bug fixes
- Less confidently mark f-strings as empty when inferring truthiness (#20152)
- [fastapi] Fix false positive for paths with spaces around parameters (FAST003) (#20077)
- [flake8-comprehensions] Skip C417 when lambda contains `yield`/`yield from` (#20201)
- [perflint] Handle tuples in dictionary comprehensions (PERF403) (#19934)

Rule changes
- [pycodestyle] Preserve return type annotation for `ParamSpec` (E731) (#20108)

Documentation
- Add fix safety sections to docs (#17490,#17499)
0.12.11 28. august 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [airflow] Extend AIR311 and AIR312 rules (#20082)
- [airflow] Replace wrong path `airflow.io.storage` with `airflow.io.store` (AIR311) (#20081)
- [flake8-async] Implement `blocking-http-call-httpx-in-async-function` (ASYNC212) (#20091)
- [flake8-logging-format] Add auto-fix for f-string logging calls (G004) (#19303)
- [flake8-use-pathlib] Add autofix for PTH211 (#20009)
- [flake8-use-pathlib] Make PTH100 fix unsafe because it can change behavior (#20100)

Bug fixes
- [pyflakes`, `pylint] Fix false positives caused by `__class__` cell handling (F841, PLE0117) (#20048)
- [pyflakes] Fix `allowed-unused-imports` matching for top-level modules (F401) (#20115)
- [ruff] Fix false positive for t-strings in `default-factory-kwarg` (RUF026) (#20032)
- [ruff] Preserve relative whitespace in multi-line expressions (RUF033) (#19647)

Rule changes
- [ruff] Handle empty t-strings in `unnecessary-empty-iterable-within-deque-call` (RUF037) (#20045)

Documentation
- Fix incorrect D413 links in docstrings convention FAQ (#20089)
- [flake8-use-pathlib] Update links to the table showing the correspondence between `os` and `pathlib` (#20103)
0.12.10 21. august 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [flake8-simplify] Implement fix for `maxsplit` without separator (SIM905) (#19851)
- [flake8-use-pathlib] Add fixes for PTH102 and PTH103 (#19514)

Bug fixes
- [isort] Handle multiple continuation lines after module docstring (I002) (#19818)
- [pyupgrade] Avoid reporting `__future__` features as unnecessary when they are used (UP010) (#19769)
- [pyupgrade] Handle nested `Optional`s (UP045) (#19770)

Rule changes
- [pycodestyle] Make E731 fix unsafe instead of display-only for class assignments (#19700)
- [pyflakes] Add secondary annotation showing previous definition (F811) (#19900)

Documentation
- Fix description of global config file discovery strategy (#19188)
- Update outdated links to <https://typing.python.org/en/latest/source/stubs.html> (#19992)
- [flake8-annotations] Remove unused import in example (ANN401) (#20000)
0.12.9 14. august 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [airflow] Add check for `airflow.secrets.cache.SecretCache` (AIR301) (#17707)
- [ruff] Offer a safe fix for multi-digit zeros (RUF064) (#19847)

Bug fixes
- [flake8-blind-except] Fix BLE001 false-positive on `raise ... from None` (#19755)
- [flake8-comprehensions] Fix false positive for C420 with attribute, subscript, or slice assignment targets (#19513)
- [flake8-simplify] Fix handling of U+001C..U+001F whitespace (SIM905) (#19849)

Rule changes
- [pylint] Use lowercase hex characters to match the formatter (PLE2513) (#19808)

Documentation
- Fix `lint.future-annotations` link (#19876)

Other changes
- Build `riscv64` binaries for release (#19819)
- Add rule code to error description in GitLab output (#19896)
0.12.8 7. august 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [flake8-use-pathlib] Expand PTH201 to check all `PurePath` subclasses (#19440)

Bug fixes
- [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)

Rule changes
- [eradicate] Don't flag `pyrefly` pragmas as unused code (ERA001) (#19731)

Documentation
- Replace "associative" with "commutative" in docs for RUF036 (#19706)
- Fix copy and line separator colors in dark mode (#19630)
- Fix link to `typing` documentation (#19648)
- [refurb] Make more examples error out-of-the-box (#19695,#19673,#19672)

Other changes
- Include column numbers in GitLab output format (#19708)
- Always expand tabs to four spaces in diagnostics (#19618)
- Update pre-commit's `ruff` id (#19654)
0.12.7 29. juli 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
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.

0.12.6 Release Notes
### Preview features

- [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)

Bug fixes
- Support `.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)

Rule changes
- [flake8-blind-except] Change BLE001 to permit `logging.critical(..., exc_info=True)` (#19520)

Performance
- Add support for specifying minimum dots in detected string imports (#19538)
0.12.5 24. juli 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [flake8-use-pathlib] Add autofix for PTH101, PTH104, PTH105, PTH121 (#19404)
- [ruff] Support byte strings (RUF055) (#18926)

Bug fixes
- Fix `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)

Rule changes
- [pep8-naming] Fix N802 false positives for `CGIHTTPRequestHandler` and `SimpleHTTPRequestHandler` (#19432)
0.12.4 17. juli 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- [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)

Rule changes
- [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)

Documentation
- [flake8-type-checking] Make TC010 docs example more realistic (#19356)
- Make more documentation examples error out-of-the-box (#19288,#19272,#19291,#19296,#19292,#19295,#19297,#19309)
0.12.3 11. juli 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- [flake8-return] Fix false-positive for variables used inside nested functions in RET504 (#18433)
- Treat form feed as valid whitespace before a line continuation (#19220)
- [flake8-type-checking] Fix syntax error introduced by fix (TC008) (#19150)
- [pyupgrade] Keyword arguments in `super` should suppress the UP008 fix (#19131)

Documentation
- [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)
0.12.2 3. juli 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [flake8-pyi] Expand `Optional[A]` to `A | None` (PYI016) (#18572)
- [pyupgrade] Mark UP008 fix safe if no comments are in range (#18683)

Bug fixes
- [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)

Rule changes
- [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)

Documentation
- Document link between `import-outside-top-level (PLC0415)` and `lint.flake8-tidy-imports.banned-module-level-imports` (#18733)
- Fix description of the `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)
0.12.1 26. juni 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)
- [formatter] Fix missing blank lines before decorated classes in `.pyi` files (#18888)

Bug fixes
- Avoid generating diagnostics with per-file ignores (#18801)
- Handle parenthesized arguments in `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)
- Fix casing of `analyze.direction` variant names (#18892)

Rule changes
- Fix f-string interpolation escaping in generated fixes (#18882)
- [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)

Server
- Consider virtual path for various server actions (#18910)

Documentation
- Add fix safety sections (#18940,#18841,#18802,#18837,#18800,#18415,#18853,#18842)
- Use updated pre-commit id (#18718)
- [perflint] Small docs improvement to PERF401 (#18786)
- [pyupg
0.12.0 17. juni 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration
guide and overview of the changes!

Breaking 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.

Removed Rules
The following rules have been removed:

- `suspicious-xmle-tree-usage`
(S320)

Deprecated Rules
The following rules have been deprecated:

- `pandas-df-variable-name`

Stabilization
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.
- The fix for [`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.

Preview features
- [ruff] Check for non-context-manager use of `pytest.raises`, `pytest.warns`, and `pytest.deprecated_call` (RUF061) (#17368)
- [syntax-errors] Raise unsupported syntax error for template strings prior to Python 3.14 (#18664)

Bug fixes
- Add syntax error when conv
0.11.13 5. juni 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- [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)

Rule changes
- [fastapi] Avoid false positive for class dependencies (FAST003) (#18271)

Documentation
- Update editor setup docs for Neovim and Vim (#18324)

Other changes
- Support Python 3.14 template strings (t-strings) in formatter and parser (#17851)
0.11.12 29. maj 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- [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)

Rule changes
- [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)

Documentation
- Simplify rules table to improve readability (#18297)
- Update editor integrations link in README (#17977)
- [flake8-bugbear] Add fix safety section (B006) (#17652)
0.11.11 22. maj 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- Fix inconsistent formatting of match-case on `[]` and `_` (#18147)
- [pylint] Fix PLW1514 not recognizing the `encoding` positional argument of `codecs.open` (#18109)

CLI
- Add full option name in formatter warning (#18217)

Documentation
- Fix rendering of admonition in docs (#18163)
- [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)
0.11.10 15. maj 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- [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)

Rule changes
- [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)

CLI
- Disable jemalloc on Android (#18033)

Documentation
- Update Neovim setup docs (#18108)
- [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)
0.11.9 9. maj 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Default to latest supported Python version for version-related syntax errors (#17529)
- Implement deferred annotations for Python 3.14 (#17658)
- [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)

Bug fixes
- Fix missing `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)
- [parser] Flag single unparenthesized generator expr with trailing comma in arguments. (#17893)

Documentation
- Add instructions on how to upgrade to a newer Rust version (#17928)
- Update code of conduct email address (#17875)
- Add fix safety sections to PLC2801, PLR1722, and RUF013 (#17825, #17826, #17759)
- Add link to `check-typed-exception` from S110 and S112 (#17786)

Other changes
- Allow passing a virtual environment to `ruff analyze graph` (#17743)
0.11.8 1. maj 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)
- [syntax-errors] `nonlocal` declaration at module level (#17559)
- [syntax-errors] Detect single starred expression assignment `x = *y` (#17624)

Bug fixes
- [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)
- [syntax-errors] Make `async-comprehension-in-sync-comprehension` more specific (#17460)

Configuration
- Add option to disable `typing_extensions` imports (#17611)

Documentation
- Fix example syntax for the `lint.pydocstyle.ignore-var-parameters` option (#17740)
- Add fix safety sections (ASYNC116, FLY002, D200, RUF005, RUF017, RUF027, RUF028, RUF057) (#17497, #17496, #17502, #17484, #17480, #17485, #17722, #17483)

Other changes
- Add Python 3.14 to configuration options (#17647)
- Make syntax error for unparenthesized except tuples version specific to before 3.14 (#17660)
0.11.7 24. april 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)
- [syntax-errors] Make duplicate parameter names a semantic error (#17131)

Bug fixes
- [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)

Rule changes
- [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)

Documentation
- Add fix safety sections to docs for several rules (#17410,#17440,#17441,#17443,#17444)
0.11.6 17. april 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Avoid adding whitespace to the end of a docstring after an escaped quote (#17216)
- [airflow] Extract AIR311 from AIR301 rules (AIR301, AIR311) (#17310, #17422)

Bug fixes
- Raise syntax error when `\` is at end of file (#17409)
0.11.5 10. april 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)
- [syntax-errors] Async comprehension in sync comprehension (#17177)
- [syntax-errors] Check annotations in annotated assignments (#17283)
- [syntax-errors] Extend annotation checks to `await` (#17282)

Bug fixes
- [flake8-pie] Avoid false positive for multiple assignment with `auto()` (PIE796) (#17274)

Rule changes
- [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)

Documentation
- Fix formatting of "See Style Guide" link (#17272)
0.11.4 4. april 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [ruff] Implement `invalid-rule-code` as RUF102 (#17138)
- [syntax-errors] Detect duplicate keys in `match` mapping patterns (#17129)
- [syntax-errors] Detect duplicate attributes in `match` class patterns (#17186)
- [syntax-errors] Detect invalid syntax in annotations (#17101)

Bug fixes
- [syntax-errors] Fix multiple assignment error for class fields in `match` patterns (#17184)
- Don't skip visiting non-tuple slice in `typing.Annotated` subscripts (#17201)
0.11.3 3. april 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)
- [syntax-errors] Start detecting compile-time syntax errors (#16106)
- [syntax-errors] Duplicate type parameter names (#16858)
- [syntax-errors] Irrefutable `case` pattern before final case (#16905)
- [syntax-errors] Multiple assignments in `case` pattern (#16957)
- [syntax-errors] Single starred assignment target (#17024)
- [syntax-errors] Starred expressions in `return`, `yield`, and `for` (#17134)
- [syntax-errors] Store to or delete `__debug__` (#16984)

Bug fixes
- Error instead of `panic!` when running Ruff from a deleted directory (#16903) (#17054)
- [syntax-errors] Fix false positive for parenthesized tuple index (#16948)

CLI
- Check `pyproject.toml` correctly when it is passed via stdin (#16971)

Configuration
- [flake8-import-conventions] Add import `numpy.typing as npt` to default `flake8-import-conventions.aliases` (#17133)

Documentation
- [refurb] Document why `UserDict`, `UserList`, and `UserString` are preferred over `dict`, `list`, and `str` (FURB189) (#16927)
0.11.2 21. marts 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [syntax-errors] Fix false-positive syntax errors emitted for annotations on variadic parameters before Python 3.11 (#16878)
0.11.1 20. marts 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [airflow] Add `chain`, `chain_linear` and `cross_downstream` for AIR302 (#16647)
- [syntax-errors] Improve error message and range for pre-PEP-614 decorator syntax errors (#16581)
- [syntax-errors] PEP 701 f-strings before Python 3.12 (#16543)
- [syntax-errors] Parenthesized context managers before Python 3.9 (#16523)
- [syntax-errors] Star annotations before Python 3.11 (#16545)
- [syntax-errors] Star expression in index before Python 3.11 (#16544)
- [syntax-errors] Unparenthesized assignment expressions in sets and indexes (#16404)

Bug fixes
- Server: Allow `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)
- Fix `--statistics` reporting for unsafe fixes (#16756)

Rule changes
- [flake8-executables] Allow `uv run` in shebang line for `shebang-missing-python` (EXE003) (#16849,#16855)

CLI
- Add `--exit-non-zero-on-format` (#16009)

Documentation
- Update Ruff tutorial to avoid non-existent fix in `__init__.py` (#16818)
- [flake8-gettext] Swap `format-` and `printf-in-get-text-func-call` examples (INT002, INT003) (#16769)
0.11.0 14. marts 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
This is a follow-up to release 0.10.0. Because of a mistake in the release process, the `requires-python` inference changes were not included in that release. Ruff 0.11.0 now includes this change as well as the stabilization of the preview behavior for PGH004.

Breaking changes
- **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:

- The `target-version` option in a `ruff.toml` file or the `[tool.ruff]` section of a pyproject.toml file.
- The `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:

- If Ruff finds a `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.
- If Ruff finds a user-level configuration, the `requires-python` field of the closest `pyproject.toml` in a parent directory will take precedence.
- If there is no config file (`ruff.toml`or `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.

Stabilization
The following behaviors have been stabilized:

- `blanket-noqa` (PGH004): Also detect blanked file-level noqa comments (and not just line level comments).

Preview features
- [syntax-errors] Tuple unpacking in `for` statement iterator clause before Python 3.9 (#16558)
0.10.0 13. marts 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration guide and overview of the changes!

Breaking 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)

In previous versions of Ruff, you could specify your Python version with:

- The `target-version` option in a `ruff.toml` file or the `[tool.ruff]` section of a pyproject.toml file.
- The `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:

- If Ruff finds a `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.
- If Ruff finds a user-level configuration, the `requires-python` field of the closest `pyproject.toml` in a parent directory will take precedence.
- If there is no config file (`ruff.toml`or `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.

- **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.

Deprecated Rules
The following rules have been deprecated:

- `non-pep604-isinstance` (UP038)
- `suspicious-xmle-tree-usage` (S320)

Remapped rules
The following rules have been remapped to new rule codes:

- [unsafe-markup-use]: RUF035 to S704

Stabilization
The 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.
- `
0.9.10 7. marts 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Bug fixes
- Escape template filenames in glob patterns in configuration (#16407)
- [flake8-simplify] Exempt unittest context methods for SIM115 rule (#16439)
- Formatter: Fix syntax error location in notebooks (#16499)
- [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)

CLI
- Move rule code from `description` to `check_name` in GitLab output serializer (#16437)

Documentation
- [pydocstyle] Clarify that D417 only checks docstrings with an arguments section (#16494)
0.9.9 28. februar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Fix caching of unsupported-syntax errors (#16425)

Bug fixes
- Only show unsupported-syntax errors in editors when preview mode is enabled (#16429)
0.9.8 27. februar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Start detecting version-related syntax errors in the parser (#16090)

Rule changes
- [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)

Server
- Avoid indexing the project if `configurationPreference` is `editorOnly` (#16381)
- Avoid unnecessary info at non-trace server log level (#16389)
- Expand `ruff.configuration` to allow inline config (#16296)
- Notify users for invalid client settings (#16361)

Configuration
- Add `per-file-target-version` option (#16257)

Bug fixes
- [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)

Documentation
- Fix example for S611 (#16316)
- Normalize inconsistent markdown headings in docstrings (#16364)
- Document MSRV policy (#16384)
0.9.7 20. februar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Consider `__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)

Rule changes
- [flake8-comprehensions]: Handle trailing comma in C403 fix (#16110)
- [flake8-debugger] Also flag `sys.breakpointhook` and `sys.__breakpointhook__` (T100) (#16191)
- [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)
- [ruff] Skip RUF001 diagnostics when visiting string type definitions (#16122)
- [flake8-pyi] Avoid flagging `custom-typevar-for-self` on metaclass methods (PYI019) (#16141)
- [pycodestyle] Exempt `site.addsitedir(...)` calls (E402) (#16251)

Formatter
- Fix unstable formatting of trailing end-of-line comments of parenthesized attribute values (#16187)

Server
- Fix handling of requests received after shutdown message (#16262)
- Ignore `source.organizeImports.ruff` and `source.fixAll.ruff` code actions for a notebook cell (#16154)
- Include document specific debug info for `ruff.printDebugInformation` (#16215)
- Update server to return the debug info as string with `ruff.printDebugInformation` (#16214)

CLI
- Warn on invalid `noqa` even when there are no diagnostics (#16178)
- Better error messages while loading configuration `extend`s (#15658)

Bug fixes
- [refurb] Correctly handle lengths of literal strings in `slice-to-remove-prefix-or-suffix` (FURB188) (#16237)

Documentation
- Add FAQ entry for `source.*` code actions in Notebook (#16212)
- Add `SECURITY.md` (#16224)
0.9.6 10. februar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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)

Server
- Root exclusions in the server to project root (#16043)

Bug fixes
- [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)

Documentation
- Improve `ruff-lsp` migration document (#16072)
- Undeprecate `ruff.nativeServer` (#16039)
0.9.5 6. februar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Recognize all symbols named `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)

Rule changes
- Preserve triple quotes and prefixes for strings (#15818)
- [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)

Configuration
- Config error only when `flake8-import-conventions` alias conflicts with `isort.required-imports` bound name (#15918)
- Workaround Even Better TOML crash related to `allOf` (#15992)

Bug fixes
- [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)

Documentation
- Add deprecation warning for `ruff-lsp` related settings (#15850)
- Docs (`linter.md`): clarify that Python files are always searched for in subdirectories (#15882)
- Fix a typo in `non_pep695_generic_class.rs` (#15946)
- Improve Docs: Pylint subcategories' codes (#15909)
- Remove non-existing `lint.extendIgnore` editor setting (#15844)
- Update black deviations (#15928)
- Mention UP049 in UP046 and UP047, add `See also` section to UP040 (#15956)
- Add instance variable examples to RUF012 (#15982)
- Explain precedence for `ignore` and `select` config (#15883)
0.9.4 30. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- Preserve quote style in generated code (#15726, #15778, #15794)
- [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)

CLI
- Fix formatter warning message for `flake8-quotes` option (#15788)
- Implement tab autocomplete for `ruff config` (#15603)

Bug fixes
- [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)

Documentation
- Add missing config docstrings (#15803)
- Add references to `trio.run_process` and `anyio.run_process` (#15761)
- Use `uv init --lib` in tutorial (#15718)
0.9.3 23. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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-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)

Formatter
- Fix bracket spacing for single-element tuples in f-string expressions (#15537)
- Fix unstable f-string formatting for expressions containing a trailing comma (#15545)

Performance
- Avoid quadratic membership check in import fixes (#15576)

Server
- Allow `unsafe-fixes` settings for code actions (#15666)

Bug fixes
- [flake8-bandit] Add missing single-line/dotall regex flag (S608) (#15654)
- [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)
- [unconventional-import-alias] Fix infinite loop between ICN001 and I002 (ICN001) (#15480)

Documentation
- Generate documentation redirects for lowercase rule codes (#15564)
- TRY300: Add some extra notes on not catching exceptions you didn't expect (#15036)
0.9.2 16. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [flake8-todos] Allow VSCode GitHub PR extension style links in `missing-todo-link` (TD003) (#15519)
- [pyflakes] Show syntax error message for F722 (#15523)

Formatter
- Fix curly bracket spacing around f-string expressions containing curly braces (#15471)
- Fix joining of f-strings with different quotes when using quote style `Preserve` (#15524)

Server
- Avoid indexing the same workspace multiple times (#15495)
- Display context for `ruff.configuration` errors (#15452)

Configuration
- Remove `flatten` to improve deserialization error messages (#15414)

Bug fixes
- Parse triple-quoted string annotations as if parenthesized (#15387)
- [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)
0.9.1 10. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [flake8-bugbear] Improve `assert-raises-exception` message (B017) (#15389)

Formatter
- Preserve trailing end-of line comments for the last string literal in implicitly concatenated strings (#15378)

Server
- Fix a bug where the server and client notebooks were out of sync after reordering cells (#15398)

Bug fixes
- [flake8-pie] Correctly remove wrapping parentheses (PIE800) (#15394)
- [pyupgrade] Handle comments and multiline expressions correctly (UP037) (#15337)
0.9.0 9. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration guide and overview of the changes!

Breaking 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.

Stabilization
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)

Formatter
This release introduces the new 2025 stable style (#13371), stabilizing the following changes:

- Format expressions in f-string elements (#7594)
- Alternate quotes for strings inside f-strings (#13860)
- Preserve the casing of hex codes in f-string debug expressions (#14766)
- Choose the quote style for each string literal in an implicitly concatenated f-string rather than for the entire string (#13539)
- Automatically join an implicitly concatenated string into a single string literal if it fits on a single line (#9457)
- Remove the ISC001 incompatibility warning (#15123)
- Prefer parenthesizing the `assert` message over breaking the assertion expression (#9457)
- Automatically parenthesize over-long `if` guards in `match` `case` clauses (#13513)
- More consistent formatting for `match` `case` patterns (#6933)
- Avoid unnecessary parentheses around return type annotations (#13381)
- Keep the opening parentheses on the same line as the `if` keyword for comprehensions where the condition has a leading comment (#12282)
- More consistent formatting for `with` statements with a single context manager for Python 3.8 or older (#10276)
- Correctly calculate the line-width for code blocks in docstrings when using `max-doc-code-line-length = "dynamic"` (#13523)

Preview features
- [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)

Rule changes
- [flake8-builtins] Ignore `stdlib-module-shadowing` in stub files(A005) (#15350)
- [flake8-return] Add support for functions returning `typing.Never` (RET503) (#15298)

Server
- Improve the observability by removing the need for the "trace" value to turn on or off logging. The server logging is solely controlled using the `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)
- Ignore diagnostics from other sources for code action requests (#15373)

CLI
- Improve the error message for `--config key=value` when the `key` is for a table and it’s a simple `value`

Bug fixes
- [eradi
0.8.6 4. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [flake8-todos] remove issue code length restriction (TD003) (#15175)
- [pyflakes] Ignore errors in `@no_type_check` string annotations (F722, F821) (#15215)

CLI
- Show errors for attempted fixes only when passed `--verbose` (#15237)

Bug fixes
- [ruff] Avoid syntax error when removing int over multiple lines (RUF046) (#15230)
- [pyupgrade] Revert "Add all PEP-585 names to UP006 rule" (#15250)
0.8.5 2. januar 2025 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- Visit PEP 764 inline `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)

Configuration
- [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)

Bug fixes
- Fix type subscript on older python versions (#15090)
- Use `TypeChecker` for detecting `fastapi` routes (#15093)
- [pycodestyle] Avoid false positives and negatives related to type parameter default syntax (E225, E251) (#15214)

Documentation
- Fix incorrect doc in `shebang-not-executable` (EXE001) and add git+windows solution to executable bit (#15208)
- Rename rules currently not conforming to naming convention (#15102)
0.8.4 19. december 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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)

Bug
- [perflint] Parenthesize walrus expressions in autofix for `manual-list-comprehension` (PERF401) (#15050)

Server
- Check diagnostic refresh support from client capability which enables dynamic configuration for various editors (#15014)
0.8.3 12. december 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Fix fstring formatting removing overlong implicit concatenated string in expression part (#14811)
- [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)

Rule changes
- [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)

Bug fixes
- Raise syntax error for mixing `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)
0.8.2 5. december 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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)

Configuration
- [flake8-import-conventions] Improve syntax check for aliases supplied in configuration for `unconventional-import-alias` (ICN001) (#14745)

Bug fixes
- Revert: [pyflakes] Avoid false positives in `@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 `assert`s (RUF018) (#14661)

Documentation
- Improve docs for `flake8-use-pathlib` rules (#14741)
- Improve error messages and docs for `flake8-comprehensions` rules (#14729)
- [flake8-type-checking] Expands TC006 docs to better explain itself (#14749)
0.8.1 29. november 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Formatter: Avoid invalid syntax for format-spec with quotes for all Python versions (#14625)
- Formatter: Consider quotes inside format-specs when choosing the quotes for an f-string (#14493)
- Formatter: Do not consider f-strings with escaped newlines as multiline (#14624)
- Formatter: Fix f-string formatting in assignment statement (#14454)
- Formatter: Fix unnecessary space around power operator (`**`) 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)

Rule changes
- Ignore more rules for stub files (#14541)
- [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)

Bug fixes
- Avoid fixing code to `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)
0.8.0 22. november 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration guide and overview of the changes!

Breaking 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).

Removed Rules
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)

Remapped rules
The following rules have been remapped to new rule codes:

- `flake8-type-checking`: `TCH` to `TC`

Stabilization
The 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-argument` (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 available

The following fixes have been stabilized:

- `zip-instead-of-pairwise` (RUF007)

Preview features
- [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)

Rule changes
- `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)

Configuration
- Ruff now emits a warning instead of an error when a configuration `ig
0.7.4 15. november 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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)

Server
- Use the current working directory to resolve settings from `ruff.configuration` (#14352)

Bug fixes
- Avoid conflicts between 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)

Documentation
- Add "Notebook behavior" section for F704, PLE1142 (#14266)
- Document comment policy around fix safety (#14300)
0.7.3 8. november 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Formatter: Disallow single-line implicit concatenated strings (#13928)
- [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)

Rule changes
- Detect items that hash to same value in duplicate sets (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)

Bug fixes
- Avoid parsing joint rule codes as distinct codes in `# 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)

Documentation
- Add links to missing related options within rule documentations (#13971)
- Add rule short code to mkdocs tags to allow searching via rule codes (#14040)
0.7.2 1. november 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Fix formatting of single with-item with trailing comment (#14005)
- [pyupgrade] Add PEP 646 `Unpack` conversion to `*` with fix (UP044) (#13988)

Rule changes
- Regenerate `known_stdlibs.rs` with stdlibs 2024.10.25 (#13963)
- [flake8-no-pep420] Skip namespace package enforcement for PEP 723 scripts (INP001) (#13974)

Server
- Fix server panic when undoing an edit (#14010)

Bug fixes
- Fix issues in discovering ruff in pip build environments (#13881)
- [flake8-type-checking] Fix false positive for `singledispatchmethod` (TCH003) (#13941)
- [flake8-type-checking] Treat return type of `singledispatch` as runtime-required (TCH003) (#13957)

Documentation
- [flake8-simplify] Include caveats of enabling `if-else-block-instead-of-if-exp` (SIM108) (#14019)
0.7.1 24. oktober 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Fix E221 and E222 to flag missing or extra whitespace around `==` operator (#13890)
- Formatter: Alternate quotes for strings inside f-strings in preview (#13860)
- Formatter: Join implicit concatenated strings when they fit on a line (#13663)
- [pylint] Restrict `iteration-over-set` to only work on sets of literals (PLC0208) (#13731)

Rule changes
- [flake8-type-checking] Support auto-quoting when annotations contain quotes (#11811)

Server
- Avoid indexing the workspace for single-file mode (#13770)

Bug fixes
- Make ARG002 compatible with EM101 when raising `NotImplementedError` (#13714)

Other changes
- Introduce more Docker tags for Ruff (similar to uv) (#13274)
0.7.0 17. oktober 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Check out the blog post for a migration guide and overview of the changes!

Breaking changes
- The pytest rules 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.
- The `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.
- The `lint.allow-unused-imports` setting has been removed (#13677). Use
`lint.pyflakes.allow-unused-imports`
instead.

Formatter preview style
- Normalize implicit concatenated f-string quotes per part (#13539)

Preview linter features
- [refurb] implement `hardcoded-string-charset` (FURB156) (#13530)
- [refurb] Count codepoints not bytes for `slice-to-remove-prefix-or-suffix (FURB188)` (#13631)

Rule changes
- [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).

CLI
- Add explanation of fixable in `--statistics` command (#13774)

Bug fixes
- [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)
0.6.9 4. oktober 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Fix codeblock dynamic line length calculation for indented docstring examples (#13523)
- [refurb] Mark FURB118 fix as unsafe (#13613)

Rule changes
- [pydocstyle] Don't raise D208 when last line is non-empty (#13372)
- [pylint] Preserve trivia (i.e. comments) in PLR5501 autofix (#13573)

Configuration
- [pyflakes] Add `allow-unused-imports` setting for `unused-import` rule (F401) (#13601)

Bug fixes
- Support ruff discovery in pip build environments (#13591)
- [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)

Documentation
- Update GitHub Action link to `astral-sh/ruff-action` (#13551)
0.6.8 26. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Remove unnecessary parentheses around `match case` clauses (#13510)
- Parenthesize overlong `if` guards in `match..case` clauses (#13513)
- Detect basic wildcard imports in `ruff analyze graph` (#13486)
- [pylint] Implement `boolean-chained-comparison` (R1716) (#13435)

Rule changes
- [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)

Bug fixes
- Detect tuples bound to variadic positional arguments i.e. `*args` (#13512)
- Exit gracefully on broken pipe errors (#13485)
- Avoid panic when analyze graph hits broken pipe (#13484)

Performance
- Reuse `BTreeSets` in module resolver (#13440)
- Skip traversal for non-compound statements (#13441)
0.6.7 21. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- Add Python version support to ruff analyze CLI (#13426)
- Add `exclude` support to `ruff analyze` (#13425)
- Fix parentheses around return type annotations (#13381)

Rule changes
- [pycodestyle] Fix: Don't autofix if the first line ends in a question mark? (D400) (#13399)

Bug fixes
- Respect `lint.exclude` in ruff check `--add-noqa` (#13427)

Performance
- Avoid tracking module resolver files in Salsa (#13437)
- Use `forget` for module resolver database (#13438)
0.6.6 20. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [refurb] Skip `slice-to-remove-prefix-or-suffix` (FURB188) when non-trivial slice steps are present (#13405)
- Add a subcommand to generate dependency graphs (#13402)

Formatter
- Fix placement of inline parameter comments (#13379)

Server
- Fix off-by one error in the `LineIndex::offset` calculation (#13407)

Bug fixes
- [fastapi] Respect FastAPI aliases in route definitions (#13394)
- [pydocstyle] Respect word boundaries when detecting function signature in docs (#13388)

Documentation
- Add backlinks to rule overview linter (#13368)
- Fix documentation for editor vim plugin ALE (#13348)
- Fix rendering of FURB188 docs (#13406)
0.6.5 13. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [pydoclint] Ignore DOC201 when function name is "new" (#13300)
- [refurb] Implement `slice-to-remove-prefix-or-suffix` (FURB188) (#13256)

Rule changes
- [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)

Server
- Add support for extensionless Python files for server (#13326)
- Fix configuration inheritance for configurations specified in the LSP settings (#13285)

Bug fixes
- [ruff] Handle unary operators in `decimal-from-float-literal` (RUF032) (#13275)

CLI
- Only include rules with diagnostics in SARIF metadata (#13268)

Playground
- Add "Copy as pyproject.toml/ruff.toml" and "Paste from TOML" (#13328)
- Fix errors not shown for restored snippet on page load (#13262)
0.6.4 5. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Preview features
- [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)

Rule changes
- [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)

CLI
- Enrich messages of SARIF results (#13180)
- Handle singular case for incompatible rules warning in `ruff format` output (#13212)

Bug fixes
- [pydocstyle] Improve heuristics for detecting Google-style docstrings (#13142)
- [refurb] Treat `sep` arguments with effects as unsafe removals (FURB105) (#13165)
0.6.3 6. september 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.6.2 23. august 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.6.1 19. august 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.6.0 16. august 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.7 12. august 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.6 6. august 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.5 26. juli 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.4 24. juli 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.3 24. juli 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.2 17. juli 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.1 15. juli 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.5.0 27. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Release Notes
Check out the blog post for a migration guide and overview of the changes!Breaking changes
See also, the "Remapped rules" section which may result in disabled rules.- Follow the XDG specification to discover user-level configurations on macOS (same as on other Unix platforms)
- Selecting ALL now excludes deprecated rules
- The released archives now include an extra level of nesting, which can be removed with --strip-components=1 when untarring.
- The release artifact's file name no longer includes the version tag. This enables users to install via /latest URLs on GitHub.
Deprecations
The following rules are now deprecated:- syntax-error (E999): Syntax errors are now always shown
Remapped rules
The following rules have been remapped to new rule codes:- blocking-http-call-in-async-function: ASYNC100 to ASYNC210
- open-sleep-or-subprocess-in-async-function: ASYNC101 split into ASYNC220, ASYNC221, ASYNC230, and ASYNC251
- blocking-os-call-in-async-function: ASYNC102 has been merged into ASYNC220 and ASYNC221
- trio-timeout-without-await: TRIO100 to ASYNC100
- trio-sync-call: TRIO105 to ASYNC105
- trio-async-function-with-timeout: TRIO109 to ASYNC109
- trio-unneeded-sleep: TRIO110 to ASYNC110
- trio-zero-sleep-call: TRIO115 to ASYNC115
- repeated-isinstance-calls: PLR1701 to SIM101
Stabilization
The following rules have been stabilized and are no longer in preview:- mutable-fromkeys-value (RUF024)
- default-factory-kwarg (RUF026)
- django-extra (S610)
- manual-dict-comprehension (PERF403)
- print-empty-string (FURB105)
- readlines-in-for (FURB129)
- if-expr-min-max (FURB136)
- bit-count (FURB161)
- redundant-log-base (FURB163)
- regex-flag-alias (FURB167)
- isinstance-type-none (FURB168)
- type-none-comparison (FURB169)
- implicit-cwd (FURB177)
- hashlib-digest-hex (FURB181)
- list-reverse-copy (FURB187)
- bad-open-mode (PLW1501)
- empty-comment (PLR2044)
- global-at-module-level (PLW0604)
- misplaced-bare-raise (PLE0744)
- non-ascii-import-name (PLC2403)
- non-ascii-name (PLC2401)
- nonlocal-and-global (PLE0115)
- potential-index-error (PLE0643)
- redeclared-assigned-name (PLW0128)
- redefined-argument-from-local (PLR1704)
- repeated-keyword-argument (PLE1132)
- super-without-brackets (PLW0245)
- unnecessary-list-index-lookup (PLR1736)
- useless-exception-statement (PLW0133)
- useless-with-lock (PLW2101)
The following behaviors have been stabilized:- is-literal (F632) now warns for identity checks against list, set or dictionary literals
- needless-bool (SIM103) now detects if expressions with implicit else branches
- module-import-not-at-top-of-file (E402) now allows os.environ modifications between import statements
- type-comparison (E721) now allows idioms such as type(x) is int
- yoda-condition (SIM300) now flags a wider range of expressions
Removals
The following deprecated settings have been removed:- output-format=text; use output-format=concise or output-format=full
- tab-size; use indent-width
The following deprecated CLI options have been removed:- --show-source; use --output-format=full
- --no-show-source; use --output-format=concise
The following deprecated CLI commands have been removed:- ruff <path>; use ruff check <path>
- ruff --clean; use ruff clean
- ruff --generate-shell-completion; use ruff generate-shell-completion
Preview features
- [ruff] Add assert-with-print-message rule (#11981)
CLI
- Use rule name rather than message in --statistics (#11697)
- Use the output format full by default (#12010)
- Don't log syntax errors to the console (#11902)
Rule changes
- [ruff] Fix false positives if gettext is imported using an alias (RUF027) (#12025)
- [npy] Update trapz and in1d deprecation (NPY201) (#11948)
- [flake8-bandit] Modify diagnostic ranges for shell-related rules (#10667)
Server
- Closing an untitled, unsaved notebook document no longer throws an error (#11942)
- Support the usage of tildes and environment variables in logFile (#11945)
- Add option to configure whether to show syntax errors (#
0.4.10 20. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
Udgivelsesnoter
Changes
Parser
- Implement re-lexing logic for better error recovery (#11845)
Rule changes
- [flake8-copyright] Update CPY001 to check the first 4096 bytes instead of 1024 (#11927)
- [pycodestyle] Update E999 to show all syntax errors instead of just the first one (#11900)
Server
- Add tracing setup guide to Helix documentation (#11883)
- Add tracing setup guide to Neovim documentation (#11884)
- Defer notebook cell deletion to avoid an error message (#11864)
Security
- Guard against malicious ecosystem comment artifacts (#11879)
Contributors
- @AlexWaygood
- @MichaReiser
- @adrinjalali
- @dhruvmanila
- @github-actions
- @psychedelicious
- @renovate
- @snowsignal
- @zanieb
0.4.9 25. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.8 10. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.7 10. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.6 29. maj 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.5 4. juni 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.4 13. maj 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.3 6. maj 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.2 29. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.1 22. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.4.0 22. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.7 22. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.6 15. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.5 4. april 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.4 25. marts 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.3 24. marts 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.2 16. marts 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.3.1 18. marts 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.1.14 9. februar 2024 — 64-bit ZIPARM64 ZIP32-bit ZIP
0.0.272 9. juni 2023 — 64-bit ZIPARM64 ZIP32-bit ZIP

Mest populære i Sprog og SDK’er

Se alle
  1. Go Programming LanguageSprog og SDK’er
  2. LLVMSprog og SDK’er · LLVM
  3. DenoSprog og SDK’er · Deno Land Inc.
  4. CMakeSprog og SDK’er · Kitware
  5. YarnSprog og SDK’er · Yarn Contributors
  6. CcacheSprog og SDK’er · Joel Rosdahl
  7. sbtSprog og SDK’er · Lightbend, Inc.
  8. BOINCSprog og SDK’er · Space Sciences Laboratory, U.C. Berkeley
  9. Dart SDKSprog og SDK’er · Google
  10. NVM for WindowsSprog og SDK’er · Ecor Ventures LLC

Tags

Del