Search code examples
pythonpep8flake8

Additional spaces to align continuation lines


I've started using Flake8 to check my python code, but the one error/warning it always give me which I find a pain to sort is the "continuation line over/under indented".

Flake8 wants my continuation line to align exactly with the starting bracket. So in the example below, Flake8 won't like the first two, but will like the third: (» = 4 spaces, · = single space)

let_us_pass.some_function(with_a_lot_of=['strings'], or_other_arguments,
»   »   »   »   »   »   and_another)

let_us_pass.some_function(with_a_lot_of=['strings'], or_other_arguments,
»   »   »   »   »   »   »   and_another)

let_us_pass.some_function(with_a_lot_of=['strings'], or_other_arguments,
»   »   »   »   »   »   ··and_another)

So Flake8 doesn't complain about mixing 4-space blocks and single spaces.
All I can find in PEP8 is a comment in an example: # Hanging indents *may* be indented to other than 4 spaces.

Does this mean it's frowned upon? Should I stick with clearing all Flake8 warnings (and mixing numbers of spaces), or live with the warnings to maintain 4-space purity.


Solution

  • Quoting from a footnote on the relevant PEP8 page:

    Hanging indentation is a type-setting style where all the lines in a paragraph are indented except the first line. In the context of Python, the term is used to describe a style where the opening parenthesis of a parenthesized statement is the last non-whitespace character of the line, with subsequent lines being indented until the closing parenthesis.

    # Hanging indents *may* be indented to other than 4 spaces.
    foo = long_function_name(
      var_one, var_two,
      var_three, var_four)
    

    This is not the same case as your example, since you have arguments on the first line. PEP8 states that you should keep the function arguments vertically aligned, so Flake8 is correct here. Don't worry about "maintaining 4-space purity" if doing so would violate other PEP8 rules.

    If you really hate having spaces in non-multiples of 4, you can switch to one of the following styles:

    # More indentation included to distinguish this from the rest.
    def long_function_name(
            var_one, var_two, var_three,
            var_four):
        print(var_one)
    
    # Hanging indents should add a level.
    foo = long_function_name(
        var_one, var_two,
        var_three, var_four)