black icon indicating copy to clipboard operation
black copied to clipboard

Strange placement of one-digit index in boolean expression

Open costika1234 opened this issue 3 years ago • 3 comments

Describe the style change I've just encountered an odd situation where black places a list index on a completely separately line.

Examples in the current Black style Under default parameters, the following code snippet

def f(special_chars):
    return (len([c for c in special_chars[1:] if c.isupper()]) > 0) and special_chars[0].islower()

is converted by black 22.1.0 to:

def f(special_chars):
    return (len([c for c in special_chars[1:] if c.isupper()]) > 0) and special_chars[
        0
    ].islower()

Desired style The above is clearly not ideal as 0 is placed on its own line. I imagined that black would format the original function along the lines of:

def f(special_chars):
    return (
        (len([c for c in special_chars[1:] if c.isupper()]) > 0)
        and special_chars[0].islower()
    )

Additional context That being said, if the original snippet is changed to:

def f(special_chars):
    return len([c for c in special_chars[1:] if c.isupper()]) > 0 and special_chars[0].islower()

(that is, if we remove the parentheses around the inequality condition), then black formats everything correctly:

def f(special_chars):
    return (
        len([c for c in special_chars[1:] if c.isupper()]) > 0
        and special_chars[0].islower()
    )

Is this a bug or not?

costika1234 avatar Mar 22 '22 23:03 costika1234

Looks related to #1094 and #2156.

FichteFoll avatar Jul 20 '22 08:07 FichteFoll

this particular example can also be rewritten so that it actually fits on one line 🙃

    return any(c.isupper() for c in special_chars[1:]) and special_chars[0].islower()

anyway, i believe this can be closed as a duplicate of #2156. if there are more than 2 expressions the expression will be split over multiple lines, e.g. with 3

    return (
        any(c.isupper() for c in special_chars[1:])
        and special_chars[0].islower()
        and True
    )

and 4 and so on:

    return (
        any(c.isupper() for c in special_chars[1:])
        and special_chars[0].islower()
        and True
        and True
    )

wbolster avatar Jul 20 '22 15:07 wbolster

Also related to #236. Feel free to close if you'd be happy with any of the proposed duplicate issues being resolved!

felix-hilden avatar Aug 15 '22 20:08 felix-hilden