black: pylint: [pylint] C0330:Wrong hanging indentation before block (add 4 spaces).

Operating system: Win7 x64 Python version: 3.6.0 Black version: black==18.3a3 installed from pypi into venv Does also happen on master:

Code:

def doc_dl_job(
    doc_ids,
    dl_folder,
    root_url=None,
    api_username=None,
    api_password=None,
    updatedcontent_root_url=None,
):
    '''Download documents by list of doc ids.'''
    api = API(api_username, api_password, root_url=root_url)

Pylint complains about all lines with function arguments.

Command: black -l 100 testfile.py

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 16

Commits related to this issue

Most upvoted comments

For the next person: This is a known issue and was reported to pylint in 2014, https://github.com/PyCQA/pylint/issues/289

This is a pylint problem. Pylint thinks that the arguments aren’t separated visually from the body of the function. They are, by the line with the colon.

@yech1990 this is clearly explained in the readme:

You might have noticed that closing brackets are always dedented and that a trailing comma is always added. Such formatting produces smaller diffs; when you add or remove an element, it’s always just one line. Also, having the closing bracket dedented provides a clear delimiter between two distinct sections of the code that otherwise share the same indentation level (like the arguments list and the docstring in the example above).

Please read the docs. There will be no flags to control formatting. This pylint warning is wrong, it should be disabled.

I think there is a misunderstanding in what pylint is saying here: Black does not add enough indent to comply with the indent recommendations in pep8 regarding function definitions:

# Correct:
...
# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

I do understand that black puts each parameter on a separate line on purpose (and I love the idea), but I think it should be adding an extra level of indent to the parameters for increased readability, like the following:

def doc_dl_job(
        doc_ids,
        dl_folder,
        root_url=None,
        api_username=None,
        api_password=None,
        updatedcontent_root_url=None,
    ):
    '''Download documents by list of doc ids.'''
    api = API(api_username, api_password, root_url=root_url)

As for the aforementioned bug report https://github.com/PyCQA/pylint/issues/289 in the pylint repository: That one is about indents for if-statements and there is still (even six years later) an ongoing discussion on the validity of that bug report (i.e. on how to interpret pep8 exactly). Guido seems to think that black violates pep8 in that regard, though: https://discuss.python.org/t/pep-8-clarify-if-multiline-argument-list-with-a-closing-on-a-separate-line-is-acceptable/2948/7

So I wouldn’t consider this a hard bug, but a change I would love to see nonetheless, as it makes code more readable IMHO and makes black-formatted code a bit more pep8-compliant.

it is possible to run:

pylint <path> --disable C0330

It’s possible, but there is not really a need to do so. Just update to pylint>=2.6.0, they have removed ā€œC0330ā€ entirely.

See https://github.com/PyCQA/pylint/issues/289 and the 2.6.0 release notes:

bad-continuation and bad-whitespace have been removed, black or another formatter can help you with this better than Pylint

http://pylint.pycqa.org/en/latest/whatsnew/changelog.html#what-s-new-in-pylint-2-6-0

Thanks for your report but this isn’t something we will change in Black.

I think the solution @soulmerge suggested is a good one. He’s right about black not conforming to PEP8 in this way. I also think visually it is easier to see what is going on without the ): at the same indent level as def. Code folding is also easier with this style (just fold based on indentation).

def long_function_name(
    a_really_long_variable_name_1,
    a_really_long_variable_name_2,
    a_really_long_variable_name_3,
    a_really_long_variable_name_4,
):
    pass

vs.

def long_function_name(
        a_really_long_variable_name_1,
        a_really_long_variable_name_2,
        a_really_long_variable_name_3,
        a_really_long_variable_name_4,
    ):
    pass

@egabrum That’s just a criticism of whatever you’re using for code folding, not an inherent limitation of the formatting.

In defense of pylint, to be honest, it’s annoying that to collapse a function with Black’s formatting, you have to collapse the definition AND then the function body (2 steps) … 😦

@mrcoles that sounds like you should report it to VSCode (or whatever plugin you’re using), not to Black.