16

According to the PEP standards, indents should come before binary operators. Furthermore, multiline conditions should be enclosed within parentheses to avoid using backslashes before newlines. These two conventions lead to the following situation

if (long_condition_1
    or long_condition_2):
    do_some_function()

This code in turn breaks E129 visually indented line with same indent as next logical line in PEP8. However, the second line must be indented exactly four spaces, as otherwise it breaks E128 or E127 for under-indented or over-indented lines.

How should one format the above so that it confirms to PEP8 standards?

Bip Lob
  • 485
  • 2
  • 6
  • 15
Jon Claus
  • 2,862
  • 4
  • 22
  • 33
  • 1
    I don't know whether this will pass the automatic checker nor do I know if this is considered the Correct Solution, but what I've done sometimes is put three or four extra spaces in between the 'if' and the '(', and then indent the continued condition lines to match. – zwol Jun 19 '17 at 19:14
  • That does actually conform to the standards. Apparently E127 and E128 check against the position of the grouping parentheses, not the indentation of the previous line. – Jon Claus Jun 19 '17 at 19:17
  • 1
    @tdelaney This isn't a duplicated because that question deals with E125. The accepted answer for that question fails E127 for over-indented visual indents and also conforms to the outdated W503, which is deprecated as described [here](https://github.com/PyCQA/pycodestyle/issues/498). – Jon Claus Jun 19 '17 at 19:21
  • 2
    @zwol While that does conform to E127, E128, and the intended W503, it fails E271 multiple spaces after keyword. – Jon Claus Jun 19 '17 at 19:27
  • @JonClaus - running this code and the referenced code on my pep8 both result in E129 errors and changing the indents fixes them both. This code is acceptable in the pep8 style guide (_ This PEP takes no explicit position on how (or whether) to further visually distinguish such conditional lines from the nested suite inside the if -statement_) but run afoul of the pep8 script. That seems to change from time to time. I'm not sure why it triggered differently, but the answer is the normal way this problem is solved, hence my recommendation as a dup. I'm happy to undup it though. – tdelaney Jun 19 '17 at 20:01
  • @tdelaney Yes, the linked answer passes PEP8 but that is only because PEP8 has an error with checking for binary operators, described in the issue I linked. Multiline expressions with binary operators should place them at the beginning of lines, not at the end. – Jon Claus Jun 19 '17 at 20:12
  • That's a place where the style guide and checker script are in direct opposition. Move the 'or' to the line above and the warning goes away, but that is not the choice I would make. I thought you complaint was about under/over indented lines. Those errors don't happen with my run of pep8. The style guide suggests an extra indentation to visually separate the condition from the following block of code. The linked question solved the problem that way. That's about all I have to say about it! – tdelaney Jun 19 '17 at 20:16
  • I think it suggests using `if(long_condition_1` instead of `if (long_condition_1` on the first line. – martineau Jun 19 '17 at 20:20
  • @martineau That does manage to pass all checks. Still, I don't feel like it's ideal. Both PEP and Google always have a space between their keywords and parentheses, although it's not an explicit requirement. – Jon Claus Jun 19 '17 at 21:32
  • In the very first section of PEP 8, titled "A Foolish Consistency is the Hobgoblin of Little Minds", it says "However, know when to be inconsistent". Further down in the "Indentation" section, it discusses this specific problem, but takes no position and then lists a few options its considers acceptable. Note, too, this [related anecdote](https://en.wikipedia.org/wiki/Self-Reliance#In_popular_culture).They're all referring, I believe, to Emerson's philosophy of self-reliance—in other words, decide for yourself. – martineau Jun 20 '17 at 00:39
  • I edited W503 out of the title because it appears to be a red herring -- you get the same indentation for continuation lines as for the body of the condition, and thus an inability to satisfy E127, E128, and E129 simultaneously, whether or not the continuation lines start with a binary operator. – zwol Jan 21 '19 at 23:08

3 Answers3

11

This should work properly

if (long_condition_1 or
       long_condition_2):
    do_some_function()
mdew
  • 1,479
  • 1
  • 9
  • 9
  • 14
    Works but looks horrible. – goji Aug 24 '18 at 13:43
  • If you deindent `long_condition_2` line then it looks even worse. You have to actually scan the last collumn for where the two dots are. People with any vision impairment (let's face it, this either already includes you, or will include, in 10-15 years) will have a hard time reading it. – Błażej Michalik Jan 30 '23 at 15:49
7

The answer to this question has changed over time. Due to a change in stance from PEP8, W503 is now widely regarded to go against PEP8.

PEP8 now says it's fine to break before OR after, but to keep it consistent locally.

For newer code, Knuth-style is preferred (which I think refers to breaking before the operator).

if (
    long_condition_1
    or long_condition_2
    or (
        long_condition_3
        and long_condition4
    )
):
    do_some_function()
Ryan de Kleer
  • 1,246
  • 14
  • 24
  • 1
    W503 appears to be a red herring: the issue is having the continuation lines for the conditional be indented to the same visual depth as the body of the `if`, whether or not they begin with an operator. Your example addresses this by putting the closing `):` at the depth of the `if` keyword, which I like, but does it pass the automated style checker? – zwol Jan 21 '19 at 23:06
  • My linters have been happy with this :) – Ryan de Kleer Jun 02 '19 at 04:21
1
if any((long_condition_1,
        long_condition_2)):
    do_some_function()

it's better to read when both conditions aligned too ...

mani
  • 149
  • 1
  • 4