black icon indicating copy to clipboard operation
black copied to clipboard

`# fmt: skip` ignored inside multi-part if-clause

Open ElkMonster opened this issue 6 months ago • 1 comments

Describe the bug

#fmt: skip is ignored in the specific case demonstrated below.

Edit: Actually, thinking about it again I realised that (to me), the actual bug is that black changes the code at all. However, I'd already be happy if I could at least keep it from disfiguring my code via fmt: skip.

To Reproduce

Let black format this piece of code:

class ClassWithALongName:
    Constant1 = 1
    Constant2 = 2
    Constant3 = 3


def test():
    if (
        "cond1" == "cond1"
        and "cond2" == "cond2"
        and 1 in (  # fmt: skip
            ClassWithALongName.Constant1,
            ClassWithALongName.Constant2,
            ClassWithALongName.Constant3,
        )
    ):
        return True
    return False

Expected behavior

Leave the line marked with # fmt: skip unchanged. Instead, it moves the in to the next line, which I find confusing and hard to read:

def test():
    if (
        "cond1" == "cond1"
        and "cond2" == "cond2"
        and 1
        in (  # fmt: skip
            ClassWithALongName.Constant1,
            ClassWithALongName.Constant2,
            ClassWithALongName.Constant3,
        )
    ):
        return True
    return False

Environment

Arch Linux black, 25.1.0 (compiled: no) Python (CPython) 3.13.5

ElkMonster avatar Aug 07 '25 16:08 ElkMonster

Edit: Actually, thinking about it again I realised that (to me), the actual bug is that black changes the code at all. However, I'd already be happy if I could at least keep it from disfiguring my code via fmt: skip.

While I can’t speak to the style choices Black makes, I’ll take a closer look at why # fmt: skip isn’t working as expected.

In the meantime, a possible workaround is to use # fmt: off / # fmt: on (you might already know this—just thought I’d mention it!):

class ClassWithALongName:
    Constant1 = 1
    Constant2 = 2
    Constant3 = 3


def test():
    if (
        "cond1" == "cond1"
        and "cond2" == "cond2"
        # fmt: off
        and 1 in ( 
            ClassWithALongName.Constant1,
            ClassWithALongName.Constant2,
            ClassWithALongName.Constant3,
        )
        # fmt: on
    ):
        return True
    return False

I've tested this and it works as expected.

Edit: A better workaround would be to use # fmt: skip after the colon at the end of the if statement (L16).

ranjodhsingh1729 avatar Aug 08 '25 12:08 ranjodhsingh1729

#4883 was reverted, see #4893

cobaltt7 avatar Dec 08 '25 00:12 cobaltt7