Pep8 ошибка e126

Further if it did your statement would look like:

with (open('file0') as file0,
      open('file1') as file1):
    pass

Which means that to simulate that behaviour you would actually want to indent like so:

with open('file0') as file0, \
      open('file1') as file1:
    pass

I’m a little surprised by how you don’t see that the point is that the two opens are aligned in the first example and not in the second. I actually want to indent like so:

with open('file0') as file0, \
     open('file1') as file1:
    pass

Notice the aligned expressions (the open function calls in this example), this is visually pleasing.

And further the initial examples all show that pep8’s current behaviour is correct. It says you may indent to other indentation levels but that doesn’t mean the former examples are to be thrown out.

In that case shouldn’t E126 instead be a W1 warning? W191 (indentation with tabs) is a warning, while it is specifically banned by PEP8. On the flip side, non-4-space continuation lines is explicitly allowed by PEP8 (though, as you say, the examples all follow 4-space indents), yet it is reported as an error.

I can see why you would want to keep pep8’s current behavior, but I think that if pep8 isn’t going to ignore it (which I still think it should), it should at least be reduced to a warning for consistency’s sake.

I would like one more chance to convince you that removing E126 is consistent with the PEP8 style guide.

Specifically, PEP8 says the following:

Use 4 spaces per indentation level.

Note that this applies to indentation levels (for suites), and not continuation lines, which is the subject of E126. Continuation lines are described thusly.

Continuation lines should align wrapped elements either vertically using Python’s implicit line joining inside parentheses, brackets and braces, or using a hanging indent [5]. When using a hanging indent the following considerations should be applied; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.

Here we see that there are two options:

  1. vertical alignment using implicit line joining in parentheses
  2. hanging indent

The first doesn’t apply in this situation, so let’s look at the second. PEP8 describes a hanging ident as indenting the lines after the first line further than the first line to distinguish it from the first line, and specifically states that the 4-space indentation rule does not apply to continuation lines. Again recall that continuation lines are not the same as regular indentation of code in suites.

Thus, the only error PEP8 should report for the indentation of continuation lines is if the continuation line is indented the same amount as the first line, and any other style «errors», if they are kept in pep8, should be reduced to warnings at most.

For lines that are too long (e.g. > 79 characters), you can use parentheses to group your conditions:

if (first_index < 0 
        or second_index > self._number_of_plates - 1
        or condition2
        and candition3):
    raise ValueError

Note that any boolean conditions (or, and) should go at the start of the line before the condition.

In your case, there is a special rule because of the if (...) construct:

When the conditional part of an if-statement is long enough to require
that it be written across multiple lines, it’s worth noting that the
combination of a two character keyword (i.e. if), plus a single space,
plus an opening parenthesis creates a natural 4-space indent for the
subsequent lines of the multiline conditional. This can produce a
visual conflict with the indented suite of code nested inside the
if-statement, which would also naturally be indented to 4 spaces. 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 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()

(Also see the discussion of whether to break before or after binary
operators below.)

Source: PEP 8 Style Guide

Translate the contents of the pycodestyle error together with the actual error code so that you can understand it to some extent.
The code is mostly taken from the Flake8 Rules.
The tab-and-line-end-space relationship has been arbitrarily converted/deleted, so the bad code may be meaningless, so just for reference.

E1 — Errors about indentation

E101 : Indentation contains mixed spaces and tabs

  • Indentation mixed with tabs and spaces

    bad

    classTab:
        deffunc():
            pass
    
    

    good

    classTab:
        deffunc():
            pass
    
    

E111 : Indentation is not a multiple of four

  • The indentation space is not a multiple of 4

E112 : Expected an indented block

  • There is no indentation where it should be indented

E113 : Unexpected indentation

  • Unexpected indentation exists

E114 : Indentation is not a multiple of four (comment)

  • Indentation spaces are not multiples of 4 (comments)

    bad

    deffunc():
      # `pass` does nothing
        pass
    
    

    good

    deffunc():
        # `pass` does nothing
        pass
    
    

E115 : Expected an indented block (comment)

  • There is no indentation where it should be indented (comment)

    bad

    deffunc():
    # `pass` does nothing
        pass
    
    

    good

    deffunc():
        # `pass` does nothing
        pass
    
    

E116 : Expected an indented block (comment)

  • Unexpected indentation exists (comment)

    bad

        # This is function
    deffunc():
        pass
    
    

    good

    # This is function
    deffunc():
        pass
    
    

E117 : over-indented

  • Indentation is too deep

E121 1, 2: Continuation line under-indented for hanging indent

  • Shallow hanging indentation in continuation line 3

    bad

    {
       'key1':'value',
       'key2':'value',
    }
    
    

    good

    {
        'key1':'value',
        'key2':'value',
    }
    
    

    bad

    print("Python",(
      "Rules"))
    
    

    good

    print("Python", (
        "Rules"))
    
    

E122 2 : Continuation line missing indentation or outdented

  • The indentation of continuation line 3 is absent or the indentation level is above

    bad

    {
    'key1':'value',
    'key2':'value',
    }
    
    

    good

    {
        'key1':'value',
        'key2':'value',
    }
    
    

E123 1 : Closing bracket does not match indentation of opening bracket’s line

  • The closing parentheses do not match the indentation level of the open parentheses row

    bad

    {
        'key1':'value',
        'key2':'value',
        }
    
    

    good

    {
        'key1':'value',
        'key2':'value',
    }
    
    

    bad

    result=function_that_takes_arguments(
        'a','b','c',
        'd','e','f',
        )
    
    

    good

    result=function_that_takes_arguments(
        'a','b','c',
        'd','e','f',
    )
    
    

E124 2 : Closing bracket does not match visual indentation

  • The closing parentheses are not visually consistent

    bad

    result=function_that_takes_arguments('a','b','c',
                                           'd','e','f',
    )
    
    

    good

    result=function_that_takes_arguments('a','b','c',
                                           'd','e','f',
                                           )
    
    

E125 2 : Continuation line with same indent as next logical line

  • The indentation level of continuation line 3 is the same as the logical line that follows.

    • If the continuation line has the same indentation as the logical line that follows, increase the indentation level of the continuation line even further

    bad

    ifuserisnotNoneanduser.is_adminor \\
        user.name=='Grant':
        blah='yeahnah'
    
    

    good

    ifuserisnotNoneanduser.is_adminor \\
            user.name=='Grant':
        blah='yeahnah'
    
    

E126 1,2 : Continuation line over-indented for hanging indent

  • The indentation of continuation line 3 is too deep

    bad

    {
            'key1':'value',
            'key2':'value',
    }
    
    

    good

    {
        'key1':'value',
        'key2':'value',
    }
    
    

E127 2 : Continuation line over-indented for visual indent

  • The indentation of continuation line 3 is deeper than the indentation for visual unification

    bad

    print("Python",("Hello",
                       "World"))
    
    

    good

    print("Python",("Hello",
                     "World"))
    
    

E128 2 : Continuation line under-indented for visual indent

  • The indentation of continuation line 3 is shallower than the indentation for visual unification

    bad

    print("Python",("Hello",
                   "World"))
    
    

    good

    print("Python",("Hello",
                     "World"))
    
    

E129 2 : Visually indented line with same indent as next logical line

  • The indentation for visual unification is at the same indentation level as the logical line that follows

    bad

    if(row<0ormodule_count<=rowor
        col<0ormodule_count<=col):
        raiseException("%s,%s - %s"%(row,col,self.moduleCount))
    
    

    good

    if(row<0ormodule_count<=rowor
            col<0ormodule_count<=col):
        raiseException("%s,%s - %s"%(row,col,self.moduleCount))
    
    

E131 2 : Continuation line unaligned for hanging indent

  • The hanging indentation of continuation line 3 is not aligned

    bad

    {
        "key1":"value",
        "key2":"value value value"
            "value",
    }
    
    

    good

    {
        "key1":"value",
        "key2":"value value value"
                "value",
    }
    
    

E133 1 : Closing bracket is missing indentation

  • There is no indentation in closing parentheses
    (only occurs when the option--hang-closing is used)

    bad

    my_list=[
        1,2,3,
        4,5,6,
    ]
    
    

    good

    my_list=[
        1,2,3,
        4,5,6,
        ]
    
    

E131 2 : Continuation line unaligned for hanging indent

  • The hanging indentation of continuation line 3 is not aligned

    bad

    {
        "key1":"value",
        "key2":"value value value"
            "value",
    }
    
    

    good

    {
        "key1":"value",
        "key2":"value value value"
                "value",
    }
    
    

E2 — Errors about whitespace

E201 : Whitespace after ‘(‘

  • There is a space after the opening parentheses

    bad

    withopen('file.dat')asf:
        contents=f.read()
    
    

    good

    withopen('file.dat')asf:
        contents=f.read()
    
    

E202 : Whitespace before ‘)’

  • There is a space before the closing parentheses

    bad

    withopen('file.dat')asf:
        contents=f.read()
    
    

    good

    withopen('file.dat')asf:
        contents=f.read()
    
    

E203 : Whitespace before ‘:’

  • There is a space before the colon

    bad

    withopen('file.dat')asf:
        contents=f.read()
    
    

    good

    withopen('file.dat')asf:
        contents=f.read()
    
    

E211 : Whitespace before ‘(‘

  • There is a space before the opening parentheses

    bad

    withopen('file.dat')asf:
        contents=f.read()
    
    

    good

    withopen('file.dat')asf:
        contents=f.read()
    
    

E221 : Multiple spaces before operator

  • Multiple spaces before the operator

E222 : Multiple spaces before operator

  • Multiple spaces after the operator

E223 : tab before operator

  • Tab character precedes operator

E224 : tab after operator

  • Operator followed by a tab character

E225 : Missing whitespace around operator

  • There are no spaces before or after the operator

    bad

    ifage>15:
    print('Can drive')
    
    

    good

    ifage>15:
    print('Can drive')
    
    

E226 1 : Missing whitespace around arithmetic operator

  • There are no spaces before or after the arithmetic operator (+, , -/, ) *

E227 : Missing whitespace around bitwise or shift operator

  • There are no spaces before or after the bitwise or shift operator (<<, >>, , , &|) ^

E228 : Missing whitespace around modulo operator

  • There are no spaces before or after the modulus operator (%)

E231 : Missing whitespace after ‘,’, ‘;’, or ‘:’

  • ,, ;, :There are no spaces before or after

E241 1 : Multiple spaces after ‘,’

  • ,followed by multiple spaces

E242 1 : Tab after ‘,’

  • ,followed by a tab character

E251 : Unexpected spaces around keyword / parameter equals

  • There are spaces before and after the = function definition

    bad

    deffunc(key1='val1',
         key2='val2'):
         returnkey1,key2
    
    

    good

    deffunc(key1='val1',
         key2='val2'):
         returnkey1,key2
    
    

E261 : At least two spaces before inline comment

  • At least two spaces are required before inline comments

    bad

    defprint_name(self):
        print(self.name)# This comment needs an extra space
    
    

    good

    defprint_name(self):
        print(self.name)  # Comment is correct now
    
    

E262 : Inline comment should start with ‘# ‘

  • Inline comments must be followed by a # space

    bad

    defprint_name(self):
        print(self.name)  #This comment needs a space
    
    

    good

    defprint_name(self):
        print(self.name)  # Comment is correct now
    
    

E265 : Block comment should start with ‘# ‘

  • Block comments should # begin with

    bad

    #This comment needs a space
    defprint_name(self):
        print(self.name)
    
    

    good

    # Comment is correct now
    defprint_name(self):
        print(self.name)
    
    

E266 : Too many leading ‘#’ for block comment

  • Too many block comments to start #

    bad

    # Prints hello
    print('hello')
    
    

    good

    # Prints hello
    print('hello')
    
    

E271 : Multiple spaces after keyword

  • Multiple spaces after a keyword

E272 : Multiple spaces before keyword

  • Multiple spaces before a keyword

    bad

    deffunc():
        if1  in[1,2,3]:
            print('yep!')
    
    

    good

    deffunc():
        if1in[1,2,3]:
            print('yep!')
    
    

E273 : Tab after keyword

  • A keyword is followed by a tab character

E274 : Tab before keyword

  • A tab character precedes the keyword

    bad

    deffunc():
        if1    in[1,2,3]:
            print('yep!')
    
    

    good

    deffunc():
        if1in[1,2,3]:
            print('yep!')
    
    

E275 : Missing whitespace after keyword

  • No whitespace after keywords

    bad

    fromcollectionsimport(namedtuple,defaultdict)
    
    

    good

    fromcollectionsimport(namedtuple,defaultdict)
    
    

E3 — Error about empty lines

E301 : Expected 1 blank line, found 0

  • Need one blank line between the methods of the class

    bad

    classMyClass(object):
    deffunc1():
        pass
    deffunc2():
        pass
    
    

    good

    classMyClass(object):
    deffunc1():
        pass
    
    deffunc2():
        pass
    
    

E302 : Expected 2 blank lines, found 0

  • Need 2 blank lines between function and class

    bad

    deffunc1():
        pass
    deffunc2():
        pass
    
    

    good

    deffunc1():
        pass
    
    deffunc2():
        pass
    
    

E303 : Too many blank lines (3)

  • Too many blank lines

    bad

    deffunc1():
        pass
    
    deffunc2():
        pass
    
    

    good

    deffunc1():
        pass
    
    deffunc2():
        pass
    
    

E304 : Blank lines found after function decorator

  • There is a blank line after the function decorator

    bad

    classUser(object):
    
        @property
    
        defname(self):
            pass
    
    

    good

    classUser(object):
    
        @property
        defname(self):
            pass
    
    

## E305 : Expected 2 blank lines after end of function or class
* Two blank lines are required after the function or class ends

```python:bad
  class User(object):
      pass
  user = User()

```

```python:good
  class User(object):
      pass


  user = User()

```

E4 — Error with Import

E401 : Multiple imports on one line

  • Multiple imports are done in one row

    good

    importcollections
    importos
    importsys
    
    

E402 : Module level import not at top of file

  • Module-level imports occur outside the beginning of the file

    bad

    importlocale
    
    locale.setlocale(locale.LC_ALL,'en_US.UTF-8')
    
    importsys
    
    

    good

    importlocale
    importsys
    
    locale.setlocale(locale.LC_ALL,'en_US.UTF-8')
    
    

E5 — Error with line length

E501 2 : Line to long ((length) > 79 characters)

  • Too many characters per line
  • Recommended maximum number of characters is 79
  • It is common to change to 100 or 120 characters

E502 : The backslash is redundant between brackets

  • Redundant backslashes in parentheses

    bad

    print('Four score and seven years ago our fathers brought '\\
          'forth, upon this continent, a new nation, conceived '\\
          'in liberty, and dedicated to the proposition that '\\
          '"all men are created equal."')
    
    

    good

    print('Four score and seven years ago our fathers brought '
          'forth, upon this continent, a new nation, conceived '
          'in liberty, and dedicated to the proposition that '
          '"all men are created equal."')
    
    

E7 — Error with statement

E701 : Multiple statements on one line (colon)

  • Multiple statements exist on a single line( : )

E702 : Multiple statements on one line (semicolon)

  • Multiple statements exist on a single line( ; )

    bad

    fromgeventimportmonkey;monkey.patch_all()
    
    

    good

    fromgeventimportmonkey
    monkey.patch_all()
    
    

E703 : Statement ends with a semicolon

  • The statement ends with a semicolon

E704 1 : Multiple statements on one line (def)

  • Multiple statements in a function definition are made on a single line

E711 2 : Comparison to none should be ‘if cond is none:’

  • Comparing singleton objects such as True, False, and None by equality rather than identity

    bad

    ifvar!=True:
        print("var is not equal to True")
    ifvar==None:
        print("var is equal to None")
    
    

    good

    ifvarisnotTrue
        print("var is not True")
    ifvarisNone
        print("var is None")
    
    

E712 2 : Comparison to true should be ‘if cond is true:’ or ‘if cond:’

  • True and compare using the equality operator

    bad

    x=True
    ifx==True:
        print('True!')
    
    

    good

    x=True
    ifxisTrue:
        print('True!')
    
    # or simply:
    ifx:
        print('True!')
    
    

E713 : Test for membership should be ‘not in’

  • The negation of the result of is in used to verify the element

    bad

    my_list=[1,2,3]
    ifnotnuminmy_list:
        print(num)
    
    

    good

    my_list=[1,2,3]
    ifnumnotinmy_list:
        print(num)
    
    

E714 : Test for object identity should be ‘is not’

  • The negation of the result of is used to verify the identity of an is object

    bad

    ifnotuserisNone:
        print(user.name)
    
    

    good

    ifuserisnotNone:
        print(user.name)
    
    

E721 2 : Do not compare types, use ‘isinstance()’

  • Not using to isinstance() compare types

    bad

    iftype(user)==User:
        print(user.name)
    
    

    good

    ifisinstance(user,User):
        print(user.name)
    
    

E722 : Do not use bare except, specify exception instead

  • You do not specify an exception class when you catch an exception

    bad

    try:
        func()
    except:
        print("error")
    
    

    good

    try:
        func()
    exceptException:
        print("error")
    
    

E731 : Do not assign a lambda expression, use a def

  • Assigning a lambda expression to a variable

    bad

    root=lambdafolder_name:os.path.join(BASE_DIR,folder_name)
    
    

    good

    defroot(folder_name):
        returnos.path.join(BASE_DIR,folder_name)
    
    

E741 : Do not use variables named ‘l’, ‘O’, or ‘I’

  • lYou are using confusing variable names such as , , , OI

E742 : Do not define classes named ‘l’, ‘O’, or ‘I’

  • lYou are using confusing class names such as , , , OI

    good

    classIcon:
    
        deffunc():
            pass
    
    

E743 : Do not define functions named ‘l’, ‘O’, or ‘I’

  • lYou are using confusing function names such as , , , OI

E9 — Runtime error

E901 : SyntaxError or IndentationError

  • Syntax or indentation errors

E902 : IOError

  • I/O error

W1 — Warnings about indentation

W191 : Indentation contains tabs

  • There are lines that are indented in the tab

W2 — Whitespace warning

W291 : Trailing whitespace

  • There is white space at the end of the line

W292 : No newline at end of file

  • there is no newline at the end of the file

W293 : Blank line contains whitespace

  • There is a blank space or tab on a blank line

    bad

    deffirst_func():
        pass
        # This line contains four spaces
    
    defsecond_func():
        pass
    
    

    good

    deffirst_func():
        pass
    
    defsecond_func():
        pass
    
    

W3 — Warning about blank lines

W391 : Blank line at end of file

  • there are multiple blank lines at the end of the file

W5 — Line break warnings

W503 1 : Line break occurred before a binary operator

  • A newline appears before the binary operator

    • Currently deprecated, W504 and exclusive relationship

    bad

    income=(gross_wages
              +taxable_interest)
    
    

    good

    income=(gross_wages+
              taxable_interest)
    
    

W504 1 : Line break occurred after a binary operator

  • There is a newline after the binary operator

    • W503 and exclusive relationships

    bad

    income=(gross_wages+
              taxable_interest)
    
    

    good

    income=(gross_wages
              +taxable_interest)
    
    

W505 1 2 : Doc line too long ((length) > 79 characters)

  • Too many characters per line in a comment or docstring

    • 79 characters is the standard, but in flake8 you will not be warned if you do not give a max-doc-length value of

    bad

    deffunc():
        """
        Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
        """
    
        pass
    
    

    good

    deffunc():
        """
        Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
        Nothing
        """
    
        pass
    
    

W6 — Warnings about deprecation syntax

W601 : .has_key() is deprecated, use ‘in’

  • .has_key() Using Methods

    bad

    {'key':'value'}.has_key('key')
    
    

W602 : Deprecated form of raising exception

  • Raising an exception in the deprecated form ( raise Exception, message )

    bad

    defcan_drive(age):
        ifage<16:
            raiseValueError,'Not old enough to drive'
        returnTrue
    
    

    good

    defcan_drive(age):
        ifage<16:
            raiseValueError('Not old enough to drive')
        returnTrue
    
    

W603 : ‘<>’ is deprecated, use ‘!=’

  • Using for non-equivalent <> comparisons

W604 : Backticks are deprecated, use ‘repr()’

  • Trying to string an object with backticks, deprecated in Python3

    good

    obj=MyObj()
    print(repr(obj))
    
    

W605 : invalid escape sequence ‘x’

  • Using an invalid escape sequence

    • Any combination of backslash and value is considered an escape sequence

W606 : ‘async’ and ‘await’ are reserved keywords starting with Python 3.7

  • It uses and async , await which are reserved words since Python 3.7

E1 Indentation E101 indentation contains mixed spaces and tabs E111 indentation is not a multiple of four E112 expected an indented block E113 unexpected indentation E114 indentation is not a multiple of four (comment) E115 expected an indented block (comment) E116 unexpected indentation (comment) E117 over-indented E121 (*^) continuation line under-indented for hanging indent E122 (^) continuation line missing indentation or outdented E123 (*) closing bracket does not match indentation of opening bracket’s line E124 (^) closing bracket does not match visual indentation E125 (^) continuation line with same indent as next logical line E126 (*^) continuation line over-indented for hanging indent E127 (^) continuation line over-indented for visual indent E128 (^) continuation line under-indented for visual indent E129 (^) visually indented line with same indent as next logical line E131 (^) continuation line unaligned for hanging indent E133 (*) closing bracket is missing indentation     E2 Whitespace E201 whitespace after ‘(’ E202 whitespace before ‘)’ E203 whitespace before ‘,’, ‘;’, or ‘:’     E211 whitespace before ‘(’     E221 multiple spaces before operator E222 multiple spaces after operator E223 tab before operator E224 tab after operator E225 missing whitespace around operator E226 (*) missing whitespace around arithmetic operator E227 missing whitespace around bitwise or shift operator E228 missing whitespace around modulo operator     E231 missing whitespace after ‘,’, ‘;’, or ‘:’     E241 (*) multiple spaces after ‘,’ E242 (*) tab after ‘,’     E251 unexpected spaces around keyword / parameter equals     E261 at least two spaces before inline comment E262 inline comment should start with ‘# ‘ E265 block comment should start with ‘# ‘ E266 too many leading ‘#’ for block comment     E271 multiple spaces after keyword E272 multiple spaces before keyword E273 tab after keyword E274 tab before keyword E275 missing whitespace after keyword     E3 Blank line E301 expected 1 blank line, found 0 E302 expected 2 blank lines, found 0 E303 too many blank lines (3) E304 blank lines found after function decorator E305 expected 2 blank lines after end of function or class E306 expected 1 blank line before a nested definition     E4 Import E401 multiple imports on one line E402 module level import not at top of file     E5 Line length E501 (^) line too long (82 > 79 characters) E502 the backslash is redundant between brackets     E7 Statement E701 multiple statements on one line (colon) E702 multiple statements on one line (semicolon) E703 statement ends with a semicolon E704 (*) multiple statements on one line (def) E711 (^) comparison to None should be ‘if cond is None:’ E712 (^) comparison to True should be ‘if cond is True:’ or ‘if cond:’ E713 test for membership should be ‘not in’ E714 test for object identity should be ‘is not’ E721 (^) do not compare types, use ‘isinstance()’ E722 do not use bare except, specify exception instead E731 do not assign a lambda expression, use a def E741 do not use variables named ‘l’, ‘O’, or ‘I’ E742 do not define classes named ‘l’, ‘O’, or ‘I’ E743 do not define functions named ‘l’, ‘O’, or ‘I’     E9 Runtime E901 SyntaxError or IndentationError E902 IOError     W1 Indentation warning W191 indentation contains tabs     W2 Whitespace warning W291 trailing whitespace W292 no newline at end of file W293 blank line contains whitespace     W3 Blank line warning W391 blank line at end of file     W5 Line break warning W503 (*) line break before binary operator W504 (*) line break after binary operator W505 (*^) doc line too long (82 > 79 characters)     W6 Deprecation warning W605 invalid escape sequence ‘x’

Having a consistent code style for a project is important as it allows
developers to code correctly without thinking too much about it. It makes code
easier to read, maintain and after becomming used to the style also
easier to write.

Most of the time, it is not too important which standards to follow, but to
decide in the team which ones you want to have and follow those consistently.
To cite from PEP8:

A style guide is about consistency. Consistency with [PEP8] is important.
Consistency within a project is more important. Consistency within one module
or function is the most important.

Python has standards for general coding as well as for docstrings.

General Coding

PEP8

The PEP8 was posted in July 2001
and got an update in 2013.

PyFlakes

PyFlakes is a very common tool to check
Python code for potential errors. I’ve added the codes to the long table below.

Docstrings

Python packages are usually documented on a function / class / method / package
level directly in the code. The stuff in docs/ is often only for building
HTML out of the Python code, organzinging things (e.g. which package to show
first) and a user manual.

There is PEP257 which defines some
basic stuff. Building on this, there are two docstring style guides which
cannot be combined: NumpyDoc an Google.

Tools like napoleon
in combination with Sphinx can automatically create nice docs of both of them.

NumpyDoc

See GitHub for the guide.

It looks as follows:

def get_meta(filepath, a_number, a_dict):
    """
    Get meta-information of an image.

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis
    parturient montes, nascetur ridiculus mus.

    Parameters
    ----------
    filepath : str
        Get metadata from this file
    a_number : int
        Some more details
    a_dict : dict
        Configuration

    Returns
    -------
    meta : dict
        Extracted meta information

    Raises
    ------
    IOError
        File could not be read
    """

Google Style Docstrings

See Github
for the documentation.

It looks as follows:

def get_meta(filepath, a_number, a_dict):
    """Get meta-information of an image.

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis
    parturient montes, nascetur ridiculus mus.

    Args:
        filepath: Get metadata from this file.
        a_number: Some more details.
        a_dict: Configuration.

    Returns:
        Extracted meta information:

    Raises:
        IOError: File could not be read.
    """

SphinxDocString

It’s super ugly and I find it hard to read, but this docstring type is also out
there. SphinxDocString. They use reStructuredText:

def get_meta(filepath, a_number, a_dict):
    """
    Get meta-information of an image.

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis
    parturient montes, nascetur ridiculus mus.

    :param filepath: Get metadata from this file
    :type filepath: str
    :param a_number: Some more details
    :type a_number: int
    :param a_dict: Configuration
    :type a_dict: dict

    :returns: dict -- Extracted meta information

    :raises: IOError
    """

McCabe code complexity

The McCabe complexity
measures how difficult it is to read your code. To quote from Wikipedia:

It is a quantitative measure of the number of linearly independent paths
through a program’s source code.
[…]
One of McCabe’s original applications was to limit the complexity of routines
during program development; he recommended that programmers should count the
complexity of the modules they are developing, and split them into smaller
modules whenever the cyclomatic complexity of the module exceeded 10.[2] This
practice was adopted by the NIST Structured Testing methodology, with an
observation that since McCabe’s original publication, the figure of 10 had
received substantial corroborating evidence, but that in some circumstances
it may be appropriate to relax the restriction and permit modules with a
complexity as high as 15.

I think McCabe complexity is one way to find spots where the could could be
improved for readability, but I’m not certain how often that actually works.

There is a mccabe pytest plugin.

Linters

Linters are tools for static code analysis. Static code analysis is the task of
analyzing a computer program without executing it. With executing the program,
it would be dynamic code analysis which is done by coverage testing tools.

Common Python linters are:

  • pycodestyle which replaces pep8
  • pydocstyle
  • flake8
  • pyrama for checking package structure
  • radon: Measuring the code complexity

What you should forget

  • pylama: Only wraps some other tools.
    Use the pytest-plugins for those tools instead.

Don’t forget the Black Auto-Formatter. It is maintained by the Python Software Foundation, works well and has reasonable defaults. Makes you think and discuss less about formatting and solves many of the things linters complain about.

Error Codes

The following error codes are from pycodestyle and
pydocstyle.
I added to a couple why they exist and added a suggestion if I think you should take them
(from ✓✓ for a strong YES to ✘✘ for a strong NO). Please also have a
look at lintlyci.github.io/Flake8Rules
which gives a lot of good examples for those rules.

There are also two footnotes for some codes:

(*) In the default configuration, the checks E121, E123, E126, E133, E226,
E241, E242, E704, W503, W504 and W505 are ignored because they are not rules
unanimously accepted, and PEP 8 does not enforce them. Please note that if
the option –ignore=errors is used, the default configuration will be
overridden and ignore only the check(s) you skip. The check W503 is mutually
exclusive with check W504. The check E133 is mutually exclusive with check
E123. Use switch —hang-closing to report E133 instead of E123. Use switch
—max-doc-length=n to report W505.

(^) These checks can be disabled at the line level using the # noqa special
comment. This possibility should be reserved for special cases.

Code Meaning Suggestion
E1 Indentation Indentation carries a meaning in Python — if code is in a block or not.
E101 indentation contains mixed spaces and tabs
Why: When you mix spaces and tabs, you will get different indentation for different editor settings.
✓✓
E111 indentation is not a multiple of four
Why: My guess is that 95% of all projects use 4 spaces — a single spaces is hard to read and more than
four is something you don’t want to type that often
E112 expected an indented block
Why: A bug
✓✓
E113 unexpected indentation
Why: A bug
✓✓
E114 indentation is not a multiple of four (comment)
Why: Easily leads to bugs
✓✓
E115 expected an indented block (comment)
Why: Easily leads to bugs
✓✓
E116 unexpected indentation (comment)
Why: Easily leads to bugs
✓✓
E121 (*^) continuation line under-indented for hanging indent
Why: Usual code style
E122 (^) continuation line missing indentation or outdented
Why: Usual code style
E123 (*) closing bracket does not match indentation of opening bracket’s line
Why: Readability
E124 (^) closing bracket does not match visual indentation
Why: Readability
E125 (^) continuation line with same indent as next logical line
Why: Readability
E126 (*^) continuation line over-indented for hanging indent
Why: Readability
E127 (^) continuation line over-indented for visual indent
Why: Readability
E128 (^) continuation line under-indented for visual indent
Why: Readability
E129 (^) visually indented line with same indent as next logical line
Why: Readability
E131 (^) continuation line unaligned for hanging indent
Why: Readability
E133 (*) closing bracket is missing indentation
Why: Readability
E2 Whitespace
E201 whitespace after (
Why: Usual code style
E202 whitespace before )
Why: Usual code style
E203 whitespace before
Why: Usual code style
E211 whitespace before (
E221 multiple spaces before operator
E222 multiple spaces after operator
E223 tab before operator
Why: Try to avoid tabs in Python
✓✓
E224 tab after operator
Why: Try to avoid tabs in Python
✓✓
E225 missing whitespace around operator
E226 (*) missing whitespace around arithmetic operator
E227 missing whitespace around bitwise or shift operator
E228 missing whitespace around modulo operator
E231 missing whitespace after ,, ;, or :
E241 (*) multiple spaces after ,
E242 (*) tab after ,
Why: Try to avoid tabs in Python
✓✓
E251 unexpected spaces around keyword / parameter equals
E261 at least two spaces before inline comment
E262 inline comment should start with #
E265 block comment should start with #
E266 too many leading # for block comment
E271 multiple spaces after keyword
Why: I can see the reason for one space … but many?
✓✓
E272 multiple spaces before keyword
Why: I can see the reason for one space, but not for multiple
✓✓
E273 tab after keyword
Why: Try to avoid tabs in Python
✓✓
E274 tab before keyword
Why: Try to avoid tabs in Python
✓✓
E275 missing whitespace after keyword
E3 Blank line
E301 expected 1 blank line, found 0
E302 expected 2 blank lines, found 0
E303 too many blank lines (3)
Why: Don’t make your code too stretched out. If you want to
separate code, make a new module.
✓✓
E304 blank lines found after function decorator
Why: This is confusing. A function decorator changes the function
being decorated. If you separate them, I might miss that it
is there.
✓✓
E305 expected 2 blank lines after end of function or class
E306 expected 1 blank line before a nested definition
E4 Import
E401 multiple imports on one line
Why: It’s more readable to have one import per line, you can
structure them more easily and your editor can tell you which
one you’re not using
✓✓
E402 module level import not at top of file
Why: You should have all your imports at the top of your file.
However, there could be other code as well in between imports.
For example, setting the seed of random.
E5 Line length
E501 (^) line too long (> 79 characters)
Why: See below.
✓✓
E502 the backslash is redundant between brackets
E7 Statement
E701 multiple statements on one line (colon)
E702 multiple statements on one line (semicolon)
E703 statement ends with a semicolon
Why: Likely unnecessary and due to a C / C++ / Java developer
(trying to) write Python code.
✓✓
E704 (*) multiple statements on one line (def)
E711 (^) comparison to None should be if cond is None:
Why: Example
✓✓
E712 (^) comparison to True should be if cond is True: or if cond:
Why: Because if cond is way easier to read
✓✓
E713 test for membership should be not in
E714 test for object identity should be is not
E721 (^) do not compare types, use isinstance()
E722 do not use bare except, specify exception instead
E731 do not assign a lambda expression, use a def
Why: Example, DRY
E741 do not use variables named l, O, or I
Why: Those letters are hard to distinguish in some fonts.
✓✓
E742 do not define classes named l, O, or I
Why: Those letters are hard to distinguish in some fonts.
✓✓
E743 do not define functions named l, O, or I
Why: Those letters are hard to distinguish in some fonts.
✓✓
E9 Runtime
E901 SyntaxError or IndentationError
E902 IOError
W1 Indentation warning
W191 indentation contains tabs ✓✓
W2 Whitespace warning
W291 trailing whitespace
Why: It just adds noise to git diff
✓✓
W292 no newline at end of file
Why: answer
W293 blank line contains whitespace
Why: It just adds noise to git diff
✓✓
W3 Blank line warning
W391 blank line at end of file
W5 Line break warning
W503 (*) line break before binary operator
W504 (*) line break after binary operator
W505 (*^) doc line too long (82 > 79 characters)
W6 Deprecation warning
W601 .has_key() is deprecated, use in ✓✓
W602 deprecated form of raising exception
W603 <> is deprecated, use != ✓✓
W604 backticks are deprecated, use repr() ✓✓
W605 invalid escape sequence x
W606 async and await are reserved keywords starting with Python 3.7
F4 Flake8 module import
F401 module imported but unused
Why: Might keep unnecessary dependencies
F402 import module from line N shadowed by loop variable
Why: Potential bug.
✓✓
F403 from module import * used; unable to detect undefined names
F404 future import(s) name after other statements
F8 Flake8 name errors
F811 redefinition of unused name from line N
Why: Potentially unused code.
F812 list comprehension redefines name from line N
F821 undefined name name
F822 undefined name name in __all__
F823 local variable name … referenced before assignment
F831 duplicate argument name in function definition
F841 local variable name is assigned to but never used
N8 Naming conventions
N801 class names should use CapWords convention ✓✓
N802 function name should be lowercase ✓✓
N803 argument name should be lowercase ✓✓
N804 first argument of a classmethod should be named cls ✓✓
N805 first argument of a method should be named self ✓✓
N806 variable in function should be lowercase ✓✓
N807 function name should not start or end with __
N811 constant imported as non constant
N812 lowercase imported as non lowercase
N813 camelcase imported as lowercase
N814 camelcase imported as constant
D1 Missing Docstrings
D100 Missing docstring in public module
D101 Missing docstring in public class
D102 Missing docstring in public method
D103 Missing docstring in public function
D104 Missing docstring in public package
D105 Missing docstring in magic method
D2 Whitespace Issues
D200 One-line docstring should fit on one line with quotes
D201 No blank lines allowed before function docstring
D202 No blank lines allowed after function docstring
D203 1 blank line required before class docstring
D204 1 blank line required after class docstring
D205 1 blank line required between summary line and description
D206 Docstring should be indented with spaces, not tabs
D207 Docstring is under-indented
D208 Docstring is over-indented
D209 Multi-line docstring closing quotes should be on a separate line
D210 No whitespaces allowed surrounding docstring text
D211 No blank lines allowed before class docstring
D212 Multi-line docstring summary should start at the first line
D213 Multi-line docstring summary should start at the second line
D3 Quotes Issues
D300 Use “”“triple double quotes”“”
D301 Use r”“” if any backslashes in a docstring
D302 Use u”“” for Unicode docstrings
D4 Docstring Content Issues
D400 First line should end with a period
D401 First line should be in imperative mood
D402 First line should not be the functions signature
D403 First word of the first line should be properly capitalized

Editor Support

You should let your editor do as many automatic formatting changes as you can.

  • Sublime Text: Python Flake8 Lint (tested, works fine) and Auto PEP8 (not tested)
  • Spyder: Auto PEP8 (not tested)

Notes on Details

Maximum Line Length

You might consider a maximum line lenght of 80 characters too extreme /
outdated.

Well, please have a look how a 3-way merge would look like on your machine. This
is how it looks like on mine:

3-way merge with 80 character lines

3-way merge with 80 character lines

And now look at files with 100 characters:

3-way merge with 100 character lines

3-way merge with 100 character lines

Sure, you can still do it. But for sure it also is less comfortable.

Let’s see how famous projects do it (code on GitHub):

Project 95%-line length 99%-line length 100%-line length
numpy 75 80 589
scipy 76 83 5223
pandas 74 79 801
Pillow 73 80 185
sqlalchemy 73 78 144
requests 77 92 172
cpython 75 81 1182

As you can see, all projects try to be below 79 characters per line. They
only break it for tests and documentation. Not for code. While I admit there
are some cases where you will get above the 79 character threshold, in
most cases it just means that you should change the way you wrote your code.
I’ve often seen it when you have many nested loops or conditions.

Another argument against longer line lengths is readability. Long lines are
just harder to read. Newspapers could also have way longer lines and less
columns. But they don’t do that. Websites also make columns. Let’s look at the
number of characters in a line for a couple:

Website Category Characters
Focus.de News 70
washingtonpost.com News 99
Sueddeutsche.de News 68
Medium.com Blog posts 73

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Pes 2013 ошибка при установке
  • Perfnet ошибка 2004 windows 10
  • People playground ошибка модов
  • Pes 2016 exe ошибка приложения
  • Pentax ошибка карты памяти

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии