astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
32.74k stars 1.09k forks source link

Formatter: long walrus operator expression introduces parentheses #8546

Open tjkuson opened 1 year ago

tjkuson commented 1 year ago

This seems similar to #7246 which was closed as completed, but reproducible in the latest 0.1.4 release.

Input:

if True:
    if True:
        if True:
            if True:
                if foo := some.very.very.very.very.very.very.very.very.very.long.function(
                    search.study_id
                ):
                    pass

Ruff formatter output:

if True:
    if True:
        if True:
            if True:
                if (
                    foo
                    := some.very.very.very.very.very.very.very.very.very.long.function(
                        search.study_id
                    )
                ):
                    pass

Black doesn't make any changes to the input file.

Ruff playground

tjkuson commented 1 year ago

Behaviour is the same for long method chains.

Input:

if True:
    if True:
        if True:
            if True:
                if foo == some.very.very.very.very.very.very.very.very.long_function_name(
                    bar
                ):
                    pass

Output:

if True:
    if True:
        if True:
            if True:
                if (
                    foo
                    == some.very.very.very.very.very.very.very.very.long_function_name(
                        bar
                    )
                ):
                    pass

EDIT: I marked this as outdated as the revised reproduction in the original post now details this behaviour.

charliermarsh commented 1 year ago

I see the same behavior in Black, or am I misunderstanding?

https://black.vercel.app/?version=main&state=_Td6WFoAAATm1rRGAgAhARYAAAB0L-Wj4AFGAIRdAD2IimZxl1N_Wlws4TBexXdmg613D2cRmmkK6QFkhhlNwTAUx4cz8BUeWx-cuwgYYrUzOEI2SVBXlwXRQgtbOqCvafh3iEcmeVpQMwvjow_MFJgqFPO0sgLW_4N7UAXeDoEHF1scyvxK89Ro-KbTojpHo8ZMycPjVc16iGNlSFE4PBe88ADJBimajoVexAABoAHHAgAAUu43D7HEZ_sCAAAAAARZWg==

tjkuson commented 1 year ago

Sorry, I made an error in the reproduction!

Input:

if True:
    if True:
        if True:
            if True:
                if foo := some.very.very.very.very.very.very.very.very.very.long.function(
                    search.study_id
                ):
                    pass

Ruff

if True:
    if True:
        if True:
            if True:
                if (
                    foo
                    := some.very.very.very.very.very.very.very.very.very.long.function(
                        search.study_id
                    )
                ):
                    pass

Black

if True:
    if True:
        if True:
            if True:
                if foo := some.very.very.very.very.very.very.very.very.very.long.function(
                    search.study_id
                ):
                    pass
tjkuson commented 1 year ago

(I've updated the original post to include the proper reproduction.)

MichaReiser commented 11 months ago

It seems that black formats the walrus operator more closely to assignments where it only breaks the right but never the left (or before/after the operator), even if doing so would help fitting the content on the line.