Consistency

These checks limit the Python’s inconsistency.

We can do the same things differently in Python. For example, there are three ways to format a string. There are several ways to write the same number.

We like our code to be consistent. It is easier to bare with your code base if you follow these rules.

Note

Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren’t special enough to break the rules. In the face of ambiguity, refuse the temptation to guess. There should be one– and preferably only one –obvious way to do it.

Summary

LocalFolderImportViolation Forbids to have imports relative to the current folder.
DottedRawImportViolation Forbids to use imports like import os.path.
UnicodeStringViolation Forbids to use u string prefix.
UnderscoredNumberViolation Forbids to use underscores (_) in numbers.
PartialFloatViolation Forbids to use partial floats like .05 or 23..
FormattedStringViolation Forbids to use f strings.
RequiredBaseClassViolation Forbids to write classes without base classes.
MultipleIfsInComprehensionViolation Forbids to have multiple if statements inside list comprehensions.

Consistency checks

class LocalFolderImportViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to have imports relative to the current folder.

Reasoning:
We should pick one style and stick to it. We have decided to use the explicit one.

Example:

# Correct:
from my_package.version import get_version

# Wrong:
from .version import get_version
from ..drivers import MySQLDriver

Note

Returns Z300 as error code

error_template = 'Found local folder import "{0}"'

Error message shown to the user.

class DottedRawImportViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to use imports like import os.path.

Reasoning:
There too many different ways to import something. We should pick one style and stick to it. We have decided to use the readable one.
Solution:
Refactor your import statement.

Example:

# Correct:
from os import path

# Wrong:
import os.path

Note

Returns Z301 as error code

error_template = 'Found dotted raw import "{0}"'

Error message shown to the user.

class UnicodeStringViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use u string prefix.

Reasoning:
We do not need this prefix since python2. But, it is still possible to find it inside the codebase.
Solution:
Remove this prefix.

Example:

# Correct:
nickname = 'sobolevn'
file_contents = b'aabbcc'

# Wrong:
nickname = u'sobolevn'

Note

Returns Z302 as error code

error_template = 'Found unicode string prefix: {0}'

Error message shown to the user.

class UnderscoredNumberViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use underscores (_) in numbers.

Reasoning:
It is possible to write 1000 in three different ways: 1_000, 10_00, and 100_0. And it would be still the same number. Count how many ways there are to write bigger numbers. Currently, it all depends on cultural habits of the author. We enforce a single way to write numbers: without the underscore.
Solution:
Numbers should be written as numbers: 1000. If you have a very big number with a lot of zeros, use multiplication.

Example:

# Correct:
phone = 88313443
million = 1000000

# Wrong:
phone = 8_83_134_43
million = 100_00_00

Note

Returns Z303 as error code

error_template = 'Found underscored number: {0}'

Error message shown to the user.

class PartialFloatViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use partial floats like .05 or 23..

Reasoning:
Partial numbers are hard to read and they can be confused with other numbers. For example, it is really easy to confuse 0.5 and .05 when reading through the source code.
Solution:
Use full versions with leading and starting zeros.

Example:

# Correct:
half = 0.5
ten_float = 10.0

# Wrong:
half = .5
ten_float = 10.

Note

Returns Z304 as error code

error_template = 'Found partial float: {0}'

Error message shown to the user.

class FormattedStringViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to use f strings.

Reasoning:
f strings looses context too often and they are hard to lint. Imagine that you have a string that breaks when you move it two lines above. That’s not how a string should behave. Also, they promote a bad practice: putting your logic inside the template.
Solution:
Use .format() with indexed params instead.

Example:

# Wrong:
f'Result is: {2 + 2}'

# Correct:
'Result is: {0}'.format(2 + 2)
'Hey {user}! How are you?'.format(user='sobolevn')

Note

Returns Z305 as error code

error_template = 'Found `f` string'

Error message shown to the user.

class RequiredBaseClassViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to write classes without base classes.

Reasoning:
We just need to decide how to do it. We need a single and unified rule about base classes. We have decided to stick to the explicit base class notation.
Solution:
Add a base class.

Example:

# Correct:
class Some(object): ...

# Wrong:
class Some: ...

Note

Returns Z306 as error code

error_template = 'Found class without a base class "{0}"'

Error message shown to the user.

class MultipleIfsInComprehensionViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to have multiple if statements inside list comprehensions.

Reasoning:
It is very hard to read multiple if statements inside a list comprehension. Since, it is even hard to tell all of them should pass or fail.
Solution:
Use a single if statement inside list comprehensions. Use filter() if you have complicated logic.

Example:

# Wrong:
nodes = [node for node in html if node != 'b' if node != 'i']

# Correct:
nodes = [node for node in html if node not in ('b', 'i')]

Note

Returns Z307 as error code

error_template = 'Found list comprehension with multiple `if`s'

Error message shown to the user.

class LocalFolderImportViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to have imports relative to the current folder.

Reasoning:
We should pick one style and stick to it. We have decided to use the explicit one.

Example:

# Correct:
from my_package.version import get_version

# Wrong:
from .version import get_version
from ..drivers import MySQLDriver

Note

Returns Z300 as error code

error_template = 'Found local folder import "{0}"'

Error message shown to the user.

class DottedRawImportViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to use imports like import os.path.

Reasoning:
There too many different ways to import something. We should pick one style and stick to it. We have decided to use the readable one.
Solution:
Refactor your import statement.

Example:

# Correct:
from os import path

# Wrong:
import os.path

Note

Returns Z301 as error code

error_template = 'Found dotted raw import "{0}"'

Error message shown to the user.

class UnicodeStringViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use u string prefix.

Reasoning:
We do not need this prefix since python2. But, it is still possible to find it inside the codebase.
Solution:
Remove this prefix.

Example:

# Correct:
nickname = 'sobolevn'
file_contents = b'aabbcc'

# Wrong:
nickname = u'sobolevn'

Note

Returns Z302 as error code

error_template = 'Found unicode string prefix: {0}'

Error message shown to the user.

class UnderscoredNumberViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use underscores (_) in numbers.

Reasoning:
It is possible to write 1000 in three different ways: 1_000, 10_00, and 100_0. And it would be still the same number. Count how many ways there are to write bigger numbers. Currently, it all depends on cultural habits of the author. We enforce a single way to write numbers: without the underscore.
Solution:
Numbers should be written as numbers: 1000. If you have a very big number with a lot of zeros, use multiplication.

Example:

# Correct:
phone = 88313443
million = 1000000

# Wrong:
phone = 8_83_134_43
million = 100_00_00

Note

Returns Z303 as error code

error_template = 'Found underscored number: {0}'

Error message shown to the user.

class PartialFloatViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbids to use partial floats like .05 or 23..

Reasoning:
Partial numbers are hard to read and they can be confused with other numbers. For example, it is really easy to confuse 0.5 and .05 when reading through the source code.
Solution:
Use full versions with leading and starting zeros.

Example:

# Correct:
half = 0.5
ten_float = 10.0

# Wrong:
half = .5
ten_float = 10.

Note

Returns Z304 as error code

error_template = 'Found partial float: {0}'

Error message shown to the user.

class FormattedStringViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to use f strings.

Reasoning:
f strings looses context too often and they are hard to lint. Imagine that you have a string that breaks when you move it two lines above. That’s not how a string should behave. Also, they promote a bad practice: putting your logic inside the template.
Solution:
Use .format() with indexed params instead.

Example:

# Wrong:
f'Result is: {2 + 2}'

# Correct:
'Result is: {0}'.format(2 + 2)
'Hey {user}! How are you?'.format(user='sobolevn')

Note

Returns Z305 as error code

error_template = 'Found `f` string'

Error message shown to the user.

class RequiredBaseClassViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to write classes without base classes.

Reasoning:
We just need to decide how to do it. We need a single and unified rule about base classes. We have decided to stick to the explicit base class notation.
Solution:
Add a base class.

Example:

# Correct:
class Some(object): ...

# Wrong:
class Some: ...

Note

Returns Z306 as error code

error_template = 'Found class without a base class "{0}"'

Error message shown to the user.

class MultipleIfsInComprehensionViolation(node, text=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbids to have multiple if statements inside list comprehensions.

Reasoning:
It is very hard to read multiple if statements inside a list comprehension. Since, it is even hard to tell all of them should pass or fail.
Solution:
Use a single if statement inside list comprehensions. Use filter() if you have complicated logic.

Example:

# Wrong:
nodes = [node for node in html if node != 'b' if node != 'i']

# Correct:
nodes = [node for node in html if node not in ('b', 'i')]

Note

Returns Z307 as error code

error_template = 'Found list comprehension with multiple `if`s'

Error message shown to the user.