black
black copied to clipboard
Strange placement of one-digit index in boolean expression
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?
Looks related to #1094 and #2156.
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
)
Also related to #236. Feel free to close if you'd be happy with any of the proposed duplicate issues being resolved!