Pylint: False positive for "bad-continuation"

Created on 29 Jul 2014  路  27Comments  路  Source: PyCQA/pylint

Originally reported by: Steven Myint (BitBucket: myint, GitHub: @myint?)


This valid style is incorrectly labeled as bad-continuation.

def test():
    if (
        True or
        False
    ):
        pass
C:  3, 0: Wrong hanging indentation before block.
        True or
        ^   | (bad-continuation)
C:  4, 0: Wrong hanging indentation before block.
        False
        ^   | (bad-continuation)

As described in #232, there are more false positives demonstrated in E12not.py.


bug

Most helpful comment

This hits me too. PEP-8 requires extra indents if the result would otherwise be visually confusing.

# Bad - no visual separation between condition and code block
if (
    condition 1
    or condition2):
    do_something()

# Good - extra indent for visual separation
if (
        condition 1
        or condition2):
    do_something()`

# Good - closing paren on separate line, visual separation
if (
    condition1
    or condition2
):
    do_something()

The latter form (which is my preferred style) is specifically allowed by PEP-8 but flagged as bad-continuation by pylint.

All 27 comments

_Original comment by_ Niklas Hamb眉chen (BitBucket: nh2, GitHub: @nh2?):


Relatedly, which of these two is correct?

#!python


for x in [
  1,
  2,
  ]:
  print x

for x in [
    1,
    2,
  ]:
  print x

Pylint 1.4 says that the upper one is correct and the lower one is wrong; can you tell me whether that's true according to PEP8?

(Of course assuming I'm working with indent-string = " " and indent-after-paren = 2.)

_Original comment by_ Olegs Jeremejevs (BitBucket: jeremejevs, GitHub: @jeremejevs?):


Similarly, the following gets labeled as bad-continuation as well:

#!python

for x in [
    1,
    2
]:
    pass

_Original comment by_ Steven Myint (BitBucket: myint, GitHub: @myint?):


def test():
    if (
        True or
        False
    ):
        pass

c00365b shows what is happening in more detail. It looks like it wants the thing to be doubly indented for some reason.

C:  3, 0: Wrong hanging indentation before block (add 4 spaces).
        True or
        ^   | (bad-continuation)
C:  4, 0: Wrong hanging indentation before block (add 4 spaces).
        False
        ^   | (bad-continuation)

That would look odd:

def test():
    if (
            True or
            False
    ):
        pass

_Original comment by_ Debanshu Kundu (BitBucket: debanshuk, GitHub: @debanshuk?):


I am forced to use pylint-1.1.0 (instead of latest the 1.4.3), due to this bug.

Following is another example of false positive for 'bad-continuation':

#!python

def abc(
    arg1,
    arg2
):
    pass

Only the following should be reported as 'bad-continuation' and not the one above.

#!python

def abc(
    arg1,
    arg2
    ):
    pass

+1

At least, it would be very nice to have a way to disable these checks (so they are covered by pep8)

Is this bug hard to fix, does someone has some hint on where the bug may be located ?

Just to know if it's something one's can easily try to fix, or if it requires deep knowledge of the codebase.

I found that I could disable this using code C0330 and use pep8 (or flake8) for this particular check 馃槃

Hope this helps
Fotis

This bug is really annoying. It forces me to turn off C0330. But I suppose if it hasn't been fixed in 4 year, it won't be fixed at all...

At this point you might just use black and disable pylint's formatting altogether. Or wait until we'll get to it, or send a patch. Lots of solutions .:)

I was thinking of using black but it is still in beta and it breaks some formatting as well. I wish I could help fixing this. I guess I'll just wait whatever becomes usable first and I'll stick with the unnecessary spacing until then. Thanks for replying :) Much appreciated.

I like to use Donald E. Knuth 's style which is more readable. My compromise for this if - bug is to add an extra space after/before the outer left/right parenthesis:

if ( foo is not None
     and bar is None ):
    shake_gizmo()
````
ATM I haven't found an compromise for expression like this one

```python
gizmo = {
    'foo'   : foo
    , 'bar' : bar }

so I have to use disable :(

@return42 We'll most likely never support that extra space.

Sorry, I do not understand what you mean "extra space" .. it is simply a bug when linting continuation .. and what I show is just a workaround for parenthesis case which does not work for dicts (curly brace) ..
I'am wondering that it is not fixable or hard to fix .. I mean .. indentation in python is elementary .. so why is this "extra spcae"?

@return42 This is not conforming to PEP 8. If this style is your preference, feel free to enforce it with any tool you want, but pylint is not likely to support it.

You misunderstood me, what I want is PEP8, I prefer to write PEP8, but when I write PEP8 I got this "bad-continuation" messages.

@PCManticore: by example ..

# test123.py
if (not True
    and False):
    pass

and then ..

$ pylint3 test123.py
No config file found, using default configuration
************* Module test123
C:  3, 0: Wrong continued indentation before block (add 4 spaces).
    and False):
    ^   | (bad-continuation)
C:  1, 0: Missing module docstring (missing-docstring)

---------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: -50.00/10, +50.00)

This hits me too. PEP-8 requires extra indents if the result would otherwise be visually confusing.

# Bad - no visual separation between condition and code block
if (
    condition 1
    or condition2):
    do_something()

# Good - extra indent for visual separation
if (
        condition 1
        or condition2):
    do_something()`

# Good - closing paren on separate line, visual separation
if (
    condition1
    or condition2
):
    do_something()

The latter form (which is my preferred style) is specifically allowed by PEP-8 but flagged as bad-continuation by pylint.

Am I correct in guessing that a fix would probably involve something in the vicinity of this function?

https://github.com/PyCQA/pylint/blob/25ffb2f3dee11854ec7a50203c62e230df085001/pylint/checkers/format.py#L392-L403

Is there any progress on this issue? Or maybe I will start to fix it.

Came here looking for a fix to this. I think I'll disable the rule.

@forrestchang I made partial progress on this but I didn't really like my solution: https://github.com/brycepg/pylint/commits/issue/289-bad-continuation

You're welcome to take over / I'd be happy to answer any questions

@rmcfatter

# Good - closing paren on separate line, visual separation
if (
    condition1
    or condition2
):
    do_something()

The latter form (which is my preferred style) is specifically allowed by PEP-8 but flagged as bad-continuation by pylint.

Where exactly does PEP-8 allow this?

Current version of PEP-8 has the following on the subject:

Acceptable options in this situation include, but are not limited to:

    # No extra indentation.
    if (this_is_one_thing and
        that_is_another_thing):
        do_something()

    # Add a comment, which will provide some distinction in editors
    # supporting syntax highlighting.
    if (this_is_one_thing and
        that_is_another_thing):
        # Since both conditions are true, we can frobnicate.
        do_something()

    # Add some extra indentation on the conditional continuation line.
    if (this_is_one_thing
            and that_is_another_thing):
        do_something()

Debanshu Kundu in his comment wrote:

Following is another example of false positive for 'bad-continuation':

#!python

def abc(
    arg1,
    arg2
):
    pass

I believe this not a false positive as PEP-8 specifically says

When using a hanging indent the following should be considered; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.

So according to PEP-8 the only valid option of distinguishing continuation lines from the following block is to use further indentation and not to mess with the position of parenthesis.

See https://github.com/psf/black/issues/1178

PEP-8 that you quote also say some lines above:

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.
Acceptable options

so I read it as pylint considering its "acceptable options" better than black (which does not seem forbidden as per pep8)

added a request for clarity in PEP-8 https://github.com/python/peps/issues/1267 I've added a request for more clarity in pep-8 , so that we're less prone to interpretation.

@allan-simon

PEP-8 that you quote also say some lines above:

Yes, but as @rmcfatter wrote (emphasis mine)

The latter form (which is my preferred style) is specifically allowed by PEP-8

you would expect to see such a formatting (closing parenthesis on its own line) given as one of examples in the PEP whereas that is not the case.

sure but then we're no more debating that it's forbidden just that it's not clearly accepted . and on my side I've never been arguing that your proposition was wrong. Therefore that your preferred way of formatting is accepted does not prevent other form froms being acceptable. Especially as several times in PEP-8 they clearly state that they have no strong opinion on which formatting is best and gives only opinion on what could be acceptable (they specifically state "not limited to"). Moreover if you've been in programming for quite some times, you have certainly noticed that the closing character on a separate line has gained traction only recently, so I'm not surprised it's not mentioned by a document mostly written in 2001.

For that matter and in order to not have the discussion on several thread of several projects over and over, I've directly asked for clarifying pep-8 here https://discuss.python.org/t/pep-8-clarify-if-multiline-argument-list-with-a-closing-on-a-separate-line-is-acceptable/2948 , so that people with authority on PEP-8 can add either the example in "don't" or "acceptable".

PS: I do not like the style above , but as it was at first the point of the issue, note that this style

def abc(
    arg1,
    args):
    """docstring"""
    pass

is being acceptable as per the explicit example of PEP-8 :

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()
Was this page helpful?
0 / 5 - 0 ratings

Related issues

adamtheturtle picture adamtheturtle  路  3Comments

DevynCJohnson picture DevynCJohnson  路  3Comments

PCManticore picture PCManticore  路  3Comments

Hubro picture Hubro  路  3Comments

ethanchewy picture ethanchewy  路  3Comments