Keep lambda parameters on one line and parenthesize the body if it expands by ntBre · Pull Request #21385 · astral-sh/ruff (original) (raw)
added formatter
Related to the formatter
Related to preview mode features
labels
ntBre added a commit that referenced this pull request
ntBre changed the title
[WIP] Indent lambda parameters if parameters wrap [WIP] Keep lambda parameters on one line and parenthesize the body if it expands
ntBre changed the title
[WIP] Keep lambda parameters on one line and parenthesize the body if it expands Keep lambda parameters on one line and parenthesize the body if it expands
ntBre marked this pull request as ready for review
ntBre marked this pull request as draft
ntBre added a commit that referenced this pull request
Summary
This PR changes our formatting of lambda expressions to keep the parameters on
a single line, at least if there are no comments. This fixes #8179.
Black formatting and this PR's formatting:
def a():
return b(
c,
d,
e,
f=lambda self, *args, **kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
*args, **kwargs
),
)Stable Ruff formatting
def a():
return b(
c,
d,
e,
f=lambda self,
*args,
**kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs),
)I split this off from #21385 because it seemed like the simpler change and helpful to isolate from the body parenthesization ecosystem and performance changes. However, as Micha pointed out, we need the formatting from #21385 to land first, so this branch is currently stacked on that one.
Test Plan
New formatting on tests from #8465 and #21385
ntBre deleted the brent/indent-lambda-params branch
dcreager added a commit that referenced this pull request
- origin/main: (22 commits)
[ty] Allow gradual lower/upper bounds in a constraint set (#21957)
[ty] disallow explicit specialization of type variables themselves (#21938)
[ty] Improve diagnostics for unsupported binary operations and unsupported augmented assignments (#21947)
[ty] update implicit root docs (#21955)
[ty] Enable even more goto-definition on inlay hints (#21950)
Document known lambda formatting deviations from Black (#21954)
[ty] fix hover type on named expression target (#21952)
Bump benchmark dependencies (#21951)
Keep lambda parameters on one line and parenthesize the body if it expands (#21385)
[ty] Improve resolution of absolute imports in tests (#21817)
[ty] Support
__all__ += submodule.__all__[ty] Change frequency of invalid__all__debug message [ty] AddKnownUnion::to_type()(#21948) [ty] Classifyclsas class parameter (#21944) [ty] Stabilize rename (#21940) [ty] Ignore__all__for document and workspace symbol requests [ty] Attach db to background request handler task (#21941) [ty] Fix outdated version in publish diagnostics afterdidChange(#21943) [ty] avoid fixpoint unioning of types containing current-cycle Divergent (#21910) [ty] improve bad specialization results & error messages (#21840) ...
This was referenced
Feb 9, 2026
nicopauss pushed a commit to Intersec/lib-common that referenced this pull request
Note this update introcudes the new warning ISC004, which requires some fixes in our code.
Released on 2026-01-22.
Preserve required parentheses in lambda bodies (#22747)
Combine range suppression code diagnostics (#22613)
[
airflow] Second positional argument toAsset/Datasetshould not be a dictionary (AIR303) (#22453)[
ruff] Detect duplicate entries in__all__(RUF068) (#22114)[
pyupgrade] Allow shadowing non-builtin bindings (UP029) (#22749)[
pyupgrade] ApplyUP045to string arguments oftyping.cast(#22320)[
flake8-pie] Detect duplicated declared class fields inPIE794(#22717)[
flake8-pyi] Fix inconsistent handling of forward references for__new__,__enter__,__aenter__inPYI034(#22798)[
flake8-pytest-style] Supportcheckparameter inPT011(#22725)[
ruff] Add exception forctypes.Structure._fields_(RUF012) (#22559)Many fixes are now marked unsafe if they would remove comments:
Add
--exit-non-zero-on-formatto formatter exit codes section (#22761)Update contributing guide for adding a new rule (#22779)
[
FastAPI] Document fix safety forFAST001(#22655)[
flake8-async] Tweak explanation to focus on latency/efficiency tradeoff (ASYNC110) (#22715)[
pandas-vet] Make example error out-of-the-box (PD002) (#22561)[
refurb] Make the example work out of box (FURB101) (#22770)[
refurb] Make the example work out of box (FURB103) (#22769)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.14/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.14/ruff-installer.ps1 | iex"Released on 2026-01-15.
This is a follow-up release to 0.14.12. Because of an issue publishing the WASM packages, there is no GitHub release or Git tag for 0.14.12, although the package was published to PyPI. The contents of the 0.14.13 release are identical to 0.14.12.
[
flake8-blind-except] Allow more logging methods (BLE001) (#22057)[
ruff] Respectlint.pydocstyle.property-decoratorsinRUF066(#22515)Fix configuration path in
--show-settings(#22478)Respect
fmt: skipfor multiple statements on the same logical line (#22119)[
pydocstyle] Update Rust crate imperative to v1.0.7 (D401) (#22519)[
isort] Insert imports in alphabetical order (I002) (#22493)Add llms.txt support for documentation (#22463)
Use prek in documentation and CI (#22505)
[
flake8-pytest-style] Addcheckparameter example toPT017docs (#22546)[
ruff] Make example error out-of-the-box (RUF103) (#22558)[
ruff] documentRUF100trailing comment fix behavior (#22479)wasm: Require explicit logging initialization (#22587)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.13/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.13/ruff-installer.ps1 | iex"Released on 2026-01-08.
Consolidate diagnostics for matched disable/enable suppression comments (#22099)
Report diagnostics for invalid/unmatched range suppression comments (#21908)
[
airflow] Passing positional argument intoairflow.lineage.hook.HookLineageCollector.create_assetis not allowed (AIR303) (#22046)[
refurb] MarkFURB192fix as always unsafe (#22210)[
ruff] Addnon-empty-init-module(RUF067) (#22143)Fix GitHub format for multi-line diagnostics (#22108)
[
flake8-unused-arguments] Mark**kwargsinTypeVaras used (ARG001) (#22214)Add
help:subdiagnostics for several Ruff rules that can sometimes appear to disagree withty(#22331)[
pylint] DemotePLW1510fix to display-only (#22318)[
pylint] Ignore identical members (PLR1714) (#22220)[
pylint] Improve diagnostic range forPLC0206(#22312)[
ruff] Improve fix title forRUF102invalid rule code (#22100)[
flake8-simplify]: Avoid unnecessary builtins import forSIM105(#22358)Allow Python 3.15 as valid
target-versionvalue in preview (#22419)Check
required-versionbefore parsing rules (#22410)Include configured
srcdirectories when resolving graphs (#22451)Update
T201suggestion to not use root logger to satisfyLOG015(#22059)Fix
iterexample in unsafe fixes doc (#22118)[
flake8_print] better suggestion forbasicConfiginT201docs (#22101)[
pylint] Restore the fix safety docs forPLW0133(#22211)Fix Jupyter notebook discovery info for editors (#22447)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.11/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.11/ruff-installer.ps1 | iex"Released on 2025-12-18.
[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 forPath.open(FURB101,FURB103) (#21080)[
pyupgrade] Fix parsing named Unicode escape sequences (UP032) (#21901)[
eradicate] Ignoreruff:disableandruff:enablecomments inERA001(#22038)[
flake8-pytest-style] Allowmatchandcheckkeyword arguments without an expected exception type (PT010) (#21964)[syntax-errors] Annotated name cannot be global (#20868)
Add
uvandtyto the Ruff README (#21996)Document known lambda formatting deviations from Black (#21954)
Update
setup.md(#22024)[
flake8-bandit] Fix broken link (S704) (#22039)Fix playground Share button showing "Copied!" before clipboard copy completes (#21942)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.10/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.10/ruff-installer.ps1 | iex"Released on 2025-12-11.
[
ruff] NewRUF100diagnostics for unused range suppressions (#21783)[
pylint] Detect subclasses of builtin exceptions (PLW0133) (#21382)Fix comment placement in lambda parameters (#21868)
Skip over trivia tokens after re-lexing (#21895)
[
flake8-bandit] Fix false positive when using non-standardCSafeLoaderpath (S506). (#21830)[
flake8-bugbear] Accept immutable slice default arguments (B008) (#21823)[
pydocstyle] SuppressD417for parameters withUnpackannotations (#21816)Use
memchrfor computing line indexes (#21838)Document
*.pywis included by default in preview (#21885)Document range suppressions, reorganize suppression docs (#21884)
Update mkdocs-material to 9.7.0 (Insiders now free) (#21797)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.9/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.9/ruff-installer.ps1 | iex"Released on 2025-12-04.
[
flake8-bugbear] Catchyieldexpressions within other statements (B901) (#21200)[
flake8-use-pathlib] Mark fixes unsafe for return type changes (PTH104,PTH105,PTH109,PTH115) (#21440)Fix syntax error false positives for
awaitoutside functions (#21763)[
flake8-simplify] Fix truthiness assumption for non-iterable arguments in tuple/list/set calls (SIM222,SIM223) (#21479)Suggest using
--output-fileoption in GitLab integration (#21706)[syntax-error] Default type parameter followed by non-default type parameter (#21657)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.8/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.8/ruff-installer.ps1 | iex"Released on 2025-11-28.
[
flake8-bandit] Handle string literal bindings in suspicious-url-open-usage (S310) (#21469)[
pylint] FixPLR1708false positives on nested functions (#21177)[
pylint] Fix suppression for empty dict without tuple key annotation (PLE1141) (#21290)[
ruff] Add ruleRUF066to detect unnecessary class properties (#21535)[
ruff] Catch more dummy variable uses (RUF052) (#19799)[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)Show partial fixability indicator in statistics output (#21513)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.7/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.7/ruff-installer.ps1 | iex"Released on 2025-11-21.
[
flake8-bandit] Support new PySNMP API paths (S508,S509) (#21374)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: skipfor compound statements on a single line (#20633)[
refurb] FixFURB103autofix (#21454)[
ruff] Fix false positive for complex conversion specifiers inlogging-eager-conversion(RUF065) (#21464)[
ruff] Avoid false positive onClassVarreassignment (RUF012) (#21478)Render hyperlinks for lint errors (#21514)
Add a
ruff analyzeoption to skip over imports inTYPE_CHECKINGblocks (#21472)Limit
eglot-formathook to eglot-managed Python buffers (#21459)Mention
force-excludein "Configuration > Python file discovery" (#21500)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/ruff/releases/download/0.14.6/ruff-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/ruff/releases/download/0.14.6/ruff-installer.ps1 | iex"| File | Platform | Checksum |
|---|---|---|
| ruff-aarch64-apple-darwin.tar.gz | Apple Silicon macOS | checksum |
| ruff-x86_64-apple-darwin.tar.gz | Intel macOS | checksum |
| ruff-aarch64-pc-windows-msvc.zip | ARM64 Windows | checksum |
| ruff-i686-pc-windows-msvc.zip | x86 Windows | [checksum](https://github.com/astral-sh/ruff/releases/download/0.14.6/ru… |
nicopauss pushed a commit to Intersec/lib-common that referenced this pull request
Released on 2026-03-19.
Display output severity in preview (#23845)
Don't show
noqahover for non-Python documents (#24040)[
pycodestyle] Recognizepyrefly:as a pragma comment (E501) (#24019)Don't return code actions for non-Python documents (#23905)
Add company AI policy to contributing guide (#24021)
Document editor features for Markdown code formatting (#23924)
[
pylint] Improve phrasing (PLC0208) (#24033)Use PEP 639 license information (#19661)
Released on 2026-03-12.
Add support for
lazyimport 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] FlagVariable.get()calls outside of task execution context (AIR003) (#23584)[
airflow] Flag runtime-varying values in DAG/task constructor arguments (AIR304) (#23631)[
flake8-bugbear] Implementdelattr-with-constant(B043) (#23737)[
flake8-tidy-imports] AddTID254to enforce lazy imports (#23777)[
flake8-tidy-imports] Allow users to ban lazy imports withTID254(#23847)[
isort] Retainlazykeyword when sorting imports (#23762)[
pyupgrade] Addfrom __future__ import annotationsautomatically (UP006) (#23260)[
refurb] Supportnewlineparameter inFURB101for Python 3.13+ (#23754)[
ruff] Addos-path-commonprefix(RUF071) (#23814)[
ruff] Add unsafe fix for os-path-commonprefix (RUF071) (#23852)[
ruff] LimitRUF036to typing contexts; make it unsafe for non-typing-only (#23765)[
ruff] Use starred unpacking forRUF017in Python 3.15+ (#23789)Fix
--add-noqacreating unwanted leading whitespace (#23773)Fix
--add-noqabreaking 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 inANN401on quoted annotations with escape sequences (#23912)[
pep8-naming] Check naming conventions inmatchpattern bindings (N806,N815,N816) (#23899)[
perflint] Fix comment duplication in fixes (PERF401,PERF403) (#23729)[
pyupgrade] Properly triggersuperchange in nested class (UP008) (#22677)[
ruff] Avoid syntax errors inRUF036fixes (#23764)[
flake8-bandit] FlagS501withrequests.request(#23873)[
flake8-executable] Fix WSL detection in non-Docker containers (#22879)[
flake8-print] Ignorepprintcalls withstream=(#23787)Update docs for Markdown code block formatting (#23871)
[
flake8-bugbear] Fix misleading description forB904(#23731)
Released on 2026-03-05.
Discover Markdown files by default in preview mode (#23434)
[
perflint] ExtendPERF102to comprehensions and generators (#23473)[
refurb] FixFURB101andFURB103false positives when I/O variable is used later (#23542)[
ruff] Add fix fornone-not-at-end-of-union(RUF036) (#22829)[
ruff] Fix false positive forre.splitwith empty string pattern (RUF055) (#23634)[
fastapi] Handle callable class dependencies with__call__method (FAST003) (#23553)[
pydocstyle] Fix numpy section ordering (D420) (#23685)[
pyflakes] Fix false positive for names shadowing re-exports (F811) (#23356)[
pyupgrade] Avoid inserting redundantNoneelements inUP045(#23459)Document extension mapping for Markdown code formatting (#23574)
Update default Python version examples (#23605)
Publish releases to Astral mirror (#23616)
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.
Fix panic on access to definitions after analyzing definitions (#23588)
[
pyflakes] Suppress false positive inF821for names used beforedelin stub files (#23550)Clarify first-party import detection in Ruff (#23591)
Fix incorrect
import-headingexample (#23568)
Released on 2026-02-26.
Drop explicit support for
.qmdfile extension (#23572)This can now be enabled instead by setting the
extensionoption:# ruff.toml extension = { qmd = "markdown" } # pyproject.toml [tool.ruff] extension = { qmd = "markdown" }Include configured extensions in file discovery (#23400)
[
flake8-bandit] Allow suspicious imports inTYPE_CHECKINGblocks (S401-S415) (#23441)[
flake8-bugbear] AllowB901in 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] Implementswap-with-temporary-variable(PLR1712) (#22205)[
ruff] Addunnecessary-assign-before-yield(RUF070) (#23300)[
ruff] Support file-level noqa inRUF102(#23535)[
ruff] Suppress diagnostic for invalid f-strings before Python 3.12 (RUF027) (#23480)[
flake8-bandit] Don't flagBaseLoader/CBaseLoaderas unsafe (S506) (#23510)Avoid infinite loop between
I002andPYI025(#23352)[
pyflakes] Fix false positive for@overloadfromlint.typing-modules(F811) (#23357)[
pyupgrade] Fix false positive forTypeVardefault before Python 3.12 (UP046) (#23540)[
pyupgrade] Fix handling of\Nin raw strings (UP032) (#22149)Render sub-diagnostics in the GitHub output format (#23455)
[
flake8-bugbear] Tag certainB007diagnostics as unnecessary (#23453)[
ruff] Ignore unknown rule codes inRUF100(#23531)These are now flagged by
RUF102instead.Fix missing settings links for several linters (#23519)
Update isort action comments heading (#23515)
[
pydocstyle] Fix double comma in description ofD404(#23440)Update the Python module (notably
find_ruff_bin) for parity with uv (#23406)
Released on 2026-02-19.
Expand the default rule set (#23385)
In preview, Ruff now enables a significantly expanded default rule set of 412 rules, up from the stable default set of 59 rules. The new rules are mostly a superset of the stable defaults, with the exception of these rules, which are removed from the preview defaults:
multiple-imports-on-one-line(E401)module-import-not-at-top-of-file(E402)module-import-not-at-top-of-file(E701)multiple-statements-on-one-line-semicolon(E702)useless-semicolon(E703)none-comparison(E711)true-false-comparison(E712)not-in-test(E713)not-is-test(E714)type-comparison(E721)lambda-assignment(E731)ambiguous-variable-name(E741)ambiguous-class-name(E742)ambiguous-function-name(E743)undefined-local-with-import-star(F403)undefined-local-with-import-star-usage(F405)undefined-local-with-nested-import-star-usage(F406)forward-annotation-syntax-error(F722)
If you use preview and prefer the old defaults, you can restore them with configuration like:
# ruff.toml [lint] select = ["E4", "E7", "E9", "F"] # pyproject.toml [tool.ruff.lint] select = ["E4", "E7", "E9", "F"]If you do give them a try, feel free to share your feedback in the GitHub discussion!
[
flake8-pyi] Also check string annotations (PYI041) (#19023)[
flake8-async] Fixin_async_contextlogic (#23426)[
ruff] Fix forRUF102should delete entire comment (#23380)[
ruff] Suppress diagnostic for strings with backslashes in interpolations before Python 3.12 (RUF027) (#21069)[
flake8-bugbear] FixB023false 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)
[
flake8-executable] Allow global flags in uv shebangs (EXE003) (#22582)[
pyupgrade] Fix handling oftyping.{io,re}(UP035) (#23131)[
ruff] DetectPLC0207on chainedstr.split()calls (#23275)Remove invalid inline
noqawarning (#23270)Add extension mapping to configuration file options (#23384)
Add
Q004to the list of conflicting rules (#23340)[
ruff] Expandlint.externaldocs and add sub-diagnostic (RUF100,RUF102) (#23268)
Released on 2026-02-12.
[
airflow] Add ruff rules to catch deprecated Airflow imports for Airflow 3.1 (AIR321) (#22376)[
airflow] Third positional parameter not namedti_keyshould be flagged forBaseOperatorLink.get_link(AIR303) (#22828)[
flake8-gettext] Fix false negatives for plural argument ofngettext(INT001,INT002,INT003) (#21078)[
pyflakes] Fix infinite loop in preview fix forunused-import(F401) (#23038)[
pygrep-hooks] Detect non-existent mock methods in standalone expressions (PGH005) (#22830)[
pylint] Allow dunder submodules and improve diagnostic range (PLC2701) (#22804)[
pyupgrade] Improve diagnostic range for tuples (UP024) (#23013)[
refurb] Check subscripts in tuple do not use lambda parameters inreimplemented-operator(FURB118) (#23079)[
ruff] Detect mutable defaults infieldcalls (RUF008) (#23046)[
ruff] Ignore stdcmath.inf(RUF069) (#23120)[
ruff] New rulefloat-equality-comparison(RUF069) (#20585)Don't format unlabeled Markdown code blocks (#23106)
Markdown formatting support in LSP (#23063)
Support Quarto Markdown language markers (#22947)
Support formatting
pyconMarkdown code blocks (#23112)Use extension mapping to select Markdown code block language (#22934)
Avoid false positive for undefined variables in
FAST001(#23224)Avoid introducing syntax errors for
FAST003autofix (#23227)Avoid suggesting
InitVarfor__post_init__that references PEP 695 type parameters (#23226)Deduplicate type variables in generic functions (#23225)
Fix exception handler parenthesis removal for Python 3.14+ (#23126)
Fix f-string middle panic when parsing t-strings (#23232)
Wrap
RUF020target for multiline fixes (#23210)Wrap
UP007target for multiline fixes (#23208)Fix missing diagnostics for last range suppression in file (#23242)
[
pyupgrade] Fix syntax error on string with newline escape and comment (UP037) (#22968)Use
ruffinstead ofRuffas the program name in GitHub output format (#23240)[
PT006] Fix syntax error when unpacking nested tuples inparametrizefixes (#22441) (#22464)[
airflow] Catch deprecated attribute access from context key for Airflow 3.0 (AIR301) (#22850)[
airflow] Capture deprecated arguments and a decorator (AIR301) (#23170)[
flake8-boolean-trap] Addmultiprocessing.Valueto excluded functions forFBT003(#23010)[
flake8-bugbear] Add a secondary annotation showing the previous occurrence (B033) (#22634)[
flake8-type-checking] Add sub-diagnostic showing the runtime use of an annotation (TC004) (#23091)[
isort] Support configurable import section heading comments (#23151)[
ruff] Improve the diagnostic forRUF012(#23202)Suppress diagnostic output for
format --check --silent(#17736)Add tabbed shell completion documentation (#23169)
Explain how to enable Markdown formatting for pre-commit hook (#23077)
Fixed import in
runtime-evaluated-decoratorsexample (#23187)Update ruff server contributing guide (#23060)
Exclude WASM artifacts from GitHub releases (#23221)
Released on 2026-02-03.
Check out the blog post for a migration guide and overview of the changes!
Ruff now formats your code according to the 2026 style guide. See the formatter section below or in the blog post for a detailed list of changes.
The linter now supports block suppression comments. For example, to suppress
N803for all parameters in this function:# ruff: disable[N803] def foo( legacyArg1, legacyArg2, legacyArg3, legacyArg4, ): ... # ruff: enable[N803]See the documentation for more details.
The
ruff:alpineDocker image is now based on Alpine 3.23 (up from 3.21).The
ruff:debianandruff:debian-slimDocker images are now based on Debian 13 "Trixie" instead of Debian 12 "Bookworm."Binaries for the
ppc64(64-bit big-endian PowerPC) architecture are no longer included in our releases. It should still be possible to build Ruff manually for this platform, if needed.Ruff now resolves all
extended configuration files before falling back on a default Python version.
The following rules have been stabilized and are no longer in preview:
blocking-http-call-httpx-in-async-function(ASYNC212)blocking-path-method-in-async-function(ASYNC240)blocking-input-in-async-function(ASYNC250)map-without-explicit-strict(B912)if-exp-instead-of-or-operator(FURB110)single-item-membership-test(FURB171)missing-maxsplit-arg(PLC0207)unnecessary-lambda(PLW0108)unnecessary-empty-iterable-within-deque-call(RUF037)in-empty-collection(RUF060)legacy-form-pytest-raises(RUF061)non-octal-permissions(RUF064)invalid-rule-code(RUF102)invalid-suppression-comment(RUF103)unmatched-suppression-comment(RUF104)replace-str-enum(UP042)
The following behaviors have been stabilized:
- The
--output-formatflag is now respected when running Ruff in--watchmode, and thefulloutput format is now used by default, matching the regular CLI output. builtin-attribute-shadowing(A003) now detects the use of shadowed built-in names in additional contexts like decorators, default arguments, and other attribute definitions.duplicate-union-member(PYI016) now considerstyping.Optionalwhen searching for duplicate union members.split-static-string(SIM905) now offers an autofix when themaxsplitargument is provided, even without asepargument.dict-get-with-none-default(SIM910) now applies to more types of key expressions.super-call-with-parameters(UP008) now has a safe fix when it will not delete comments.unnecessary-default-type-args(UP043) now applies to stub (.pyi) files on Python versions before 3.13.
This release introduces the new 2026 style guide, with the following changes:
Lambda parameters are now kept on the same line and lambda bodies will be parenthesized to let them break across multiple lines (#21385)
Parentheses around tuples of exceptions in
exceptclauses will now be removed on Python 3.14 and later (#20768)A single empty line is now permitted at the beginning of function bodies (#21110)
Parentheses are avoided for long
ascaptures inmatchstatements (#21176)Extra spaces between escaped quotes and ending triple quotes can now be omitted (#17216)
Blank lines are now enforced before classes with decorators in stub files (#18888)
Apply formatting to Markdown code blocks (#22470, #22990, #22996)
See the documentation for more details.
Fix suppression indentation matching (#22903)
Customize where the
fix_titlesub-diagnostic appears (#23044)[
FastAPI] Add sub-diagnostic explaining why a fix was unavailable (FAST002) (#22565)[
flake8-annotations] Don't suggestNoReturnfor functions raisingNotImplementedError(ANN201,ANN202,ANN205,ANN206) (#21311)[
pyupgrade] Make fix unsafe if it deletes comments (UP017) (#22873)[
pyupgrade] Make fix unsafe if it deletes comments (UP020) (#22872)[
pyupgrade] Make fix unsafe if it deletes comments (UP033) (#22871)[
refurb] Do not addabc.ABCif already present (FURB180) (#22234)[
refurb] Make fix unsafe if it deletes comments (FURB110) (#22768)[
ruff] Add sub-diagnostics with permissions (RUF064) (#22972)Identify notebooks by LSP
didOpeninstead of.ipynbfile extension (#22810)Add
--colorCLI option to force colored output (#22806)Document
-stdin convention in CLI help text (#22817)[
refurb] Change example tore.searchwith^anchor (FURB167) (#22984)Fix link to Sphinx code block directives (#23041)
[
pydocstyle] Clarify which quote styles are allowed (D300) (#22825)[
flake8-bugbear] Improve docs forno-explicit-stacklevel(B028) (#22538)Update MSRV to 1.91 (#22874)
Renovate-Branch: renovate/2024.6-ruff-0.x Change-Id: I8f8e865435fde1fc736fe2528261a604acb46215 Priv-Id: f7e1d99008e3617149c4b639a9a2bbc06212d064
ntBre mentioned this pull request
ntBre added a commit that referenced this pull request
Summary
This PR fixes #24807 by making RemoveSoftLinesBuffer aware of
BestFitting and always selecting the most-flat variant, as suggested
in [Micha's comment], assuming I interpreted it correctly.
As I noted on the issue, I was hoping I could get away with making a
local change to the lambda formatting, but this turned out to affect
the two other uses of RemoveSoftLinesBuffer too.
The formatting of the new regression tests:
def foo():
subprocess.check_call(f"rm -rf {' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))}", shell=True)
def bar():
lambda x=" ".join(
map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
): ...
value = f"prefix {
' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))
} suffix"now (nearly) matches the output before #21385:
❯ git diff <(uvx ruff@0.14.10 format - < fmt.py) <(./target/debug/ruff format - < fmt.py)
def bar():
- lambda x=" ".join(
- map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
- ): ...
+ lambda x=" ".join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)): (
+ ...
+ )
value = f"prefix {with the only difference being that the body of this second lambda still wraps in the new formatting.
Test Plan
New tests based on the reported issue and possibly the ecosystem check on this PR
[Micha's comment]: #24807 (comment)
thejchap pushed a commit to thejchap/ruff that referenced this pull request
Summary
This PR fixes astral-sh#24807 by making RemoveSoftLinesBuffer aware of
BestFitting and always selecting the most-flat variant, as suggested
in [Micha's comment], assuming I interpreted it correctly.
As I noted on the issue, I was hoping I could get away with making a
local change to the lambda formatting, but this turned out to affect
the two other uses of RemoveSoftLinesBuffer too.
The formatting of the new regression tests:
def foo():
subprocess.check_call(f"rm -rf {' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))}", shell=True)
def bar():
lambda x=" ".join(
map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
): ...
value = f"prefix {
' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))
} suffix"now (nearly) matches the output before astral-sh#21385:
❯ git diff <(uvx ruff@0.14.10 format - < fmt.py) <(./target/debug/ruff format - < fmt.py)
def bar():
- lambda x=" ".join(
- map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
- ): ...
+ lambda x=" ".join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)): (
+ ...
+ )
value = f"prefix {with the only difference being that the body of this second lambda still wraps in the new formatting.
Test Plan
New tests based on the reported issue and possibly the ecosystem check on this PR
[Micha's comment]: astral-sh#24807 (comment)
anishgirianish pushed a commit to anishgirianish/ruff that referenced this pull request
Summary
This PR fixes astral-sh#24807 by making RemoveSoftLinesBuffer aware of
BestFitting and always selecting the most-flat variant, as suggested
in [Micha's comment], assuming I interpreted it correctly.
As I noted on the issue, I was hoping I could get away with making a
local change to the lambda formatting, but this turned out to affect
the two other uses of RemoveSoftLinesBuffer too.
The formatting of the new regression tests:
def foo():
subprocess.check_call(f"rm -rf {' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))}", shell=True)
def bar():
lambda x=" ".join(
map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
): ...
value = f"prefix {
' '.join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove))
} suffix"now (nearly) matches the output before astral-sh#21385:
❯ git diff <(uvx ruff@0.14.10 format - < fmt.py) <(./target/debug/ruff format - < fmt.py)
def bar():
- lambda x=" ".join(
- map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)
- ): ...
+ lambda x=" ".join(map(lambda object_name: os.path.join(dest_path, object_name), objects_to_remove)): (
+ ...
+ )
value = f"prefix {with the only difference being that the body of this second lambda still wraps in the new formatting.
Test Plan
New tests based on the reported issue and possibly the ecosystem check on this PR
[Micha's comment]: astral-sh#24807 (comment)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})