Consistency¶
These checks limit Python’s inconsistencies.
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 work with your code base if you follow these rules.
So, we choose a single way to do things. It does not mean that we choose the best way to do it. But, we value consistency more than being 100% right and we are ready to suffer all trade-offs that might come.
Once again, these rules are highly subjective, but we love them.
Summary¶
WPS300 — Forbid imports relative to the current folder. |
|
WPS301 — Forbid imports like |
|
WPS302 — Forbid |
|
WPS303 — Forbid underscores ( |
|
WPS304 — Forbid partial floats like |
|
WPS305 — Forbid |
|
WPS306 — Forbid writing explicit object base class. |
|
WPS307 — Forbid multiple |
|
WPS308 — Forbid comparing between two literals. |
|
WPS309 — Forbid comparisons where the argument doesn't come first. |
|
WPS310 — Forbid uppercase |
|
WPS311 — Forbid comparisons with multiple |
|
WPS312 — Forbid comparisons of a variable to itself. |
|
WPS313 — Enforce separation of parenthesis from keywords with spaces. |
|
WPS314 — Forbid using |
|
WPS315 — Forbid extra |
|
WPS316 — Forbid multiple assignment targets for context managers. |
|
WPS317 — Forbid incorrect indentation for parameters. |
|
WPS318 — Forbid extra indentation. |
|
WPS319 — Forbid brackets in the wrong position. |
|
WPS320 — Forbid multi-line function type annotations. |
|
WPS321 — Forbid uppercase string modifiers. |
|
WPS322 — Forbid triple quotes for singleline strings. |
|
WPS323 — Forbid |
|
WPS324 — Enforce consistent |
|
WPS325 — Enforce consistent |
|
WPS326 — Forbid implicit string concatenation. |
|
WPS327 — Forbid meaningless |
|
WPS328 — Forbid meaningless nodes. |
|
WPS329 — Forbid meaningless |
|
WPS330 — Forbid unnecessary operators in your code. |
|
WPS331 — Forbid local variables that are only used in |
|
WPS332 — Forbid the use of the walrus operator (:=) in most cases. |
|
WPS333 — Forbid implicit complex comparison expressions. |
|
WPS334 — Forbid reversed order complex comparison expressions. |
|
WPS335 — Forbid wrong |
|
WPS336 — Forbid explicit string concatenation in favour of |
|
WPS337 — Forbid multiline conditions. |
|
WPS338 — Forbid incorrect order of methods inside a class. |
|
WPS339 — Forbid meaningless zeros. |
|
WPS340 — Forbid extra |
|
WPS341 — Forbid letters as hex numbers. |
|
WPS342 — Forbid |
|
WPS343 — Forbid uppercase complex number suffix. |
|
WPS344 — Forbid explicit division (or modulo) by zero. |
|
WPS345 — Forbid meaningless math operations with |
|
WPS346 — Forbid double minus operations. |
|
WPS347 — Forbid imports that may cause confusion outside of the module. |
|
WPS348 — Forbid starting lines with a dot. |
|
WPS349 — Forbid redundant components in a subscript's slice. |
|
WPS350 — Enforce using augmented assign pattern. |
|
WPS351 — Forbid unnecessary literals in your code. |
|
WPS352 — Forbid multiline loops. |
|
WPS353 — Forbid |
|
WPS354 — Forbid consecutive |
|
WPS355 — Forbid useless blank lines before and after brackets. |
|
WPS356 — Forbid unnecessary iterable unpacking. |
|
WPS357 — Forbid using |
|
WPS358 — Forbid using float zeros: |
|
WPS359 — Forbids to unpack iterable objects to lists. |
|
WPS360 — Forbid the use of raw strings when there is no backslash in the string. |
|
WPS361 — Forbids inconsistent newlines in comprehensions. |
|
WPS362 — Forbid assignment to a subscript slice. |
|
WPS363 — Forbid raising |
|
WPS364 — Forbid using |
|
WPS365 — Some |
|
WPS366 — Forbid meaningless boolean operations. |
- LocalFolderImportViolation[source]¶
WPS300 — Forbid imports relative to the current folder.
- Reasoning:
We should pick one style and stick to it. We have decided to use the explicit one.
- Solution:
Refactor your imports to use the absolute path.
Example:
# Correct: from my_package.version import get_version # Wrong: from .version import get_version from ..drivers import MySQLDriver
Added in version 0.1.0.
- full_code: ClassVar[str] = 'WPS300'¶
- summary: ClassVar[str] = 'Forbid imports relative to the current folder.'¶
- DottedRawImportViolation[source]¶
WPS301 — Forbid imports like
import os.path.- Reasoning:
There are too many 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
Added in version 0.1.0.
- full_code: ClassVar[str] = 'WPS301'¶
- summary: ClassVar[str] = 'Forbid imports like ``import os.path``.'¶
- UnicodeStringViolation[source]¶
WPS302 — Forbid
ustring prefix.- Reasoning:
We haven’t needed this prefix since
python2, but it is still possible to find it in a codebase.- Solution:
Remove this prefix.
Example:
# Correct: nickname = 'sobolevn' file_contents = b'aabbcc' # Wrong: nickname = u'sobolevn'
Added in version 0.1.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This rule is covered by
rufflinter. SeeUP025.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS302'¶
- summary: ClassVar[str] = 'Forbid ``u`` string prefix.'¶
- UnderscoredNumberViolation[source]¶
WPS303 — Forbid underscores (
_) in numbers.- Reasoning:
It is possible to write
1000in three different ways:1_000,10_00, and100_0. And it would be still the same number. Count how many ways there are to write bigger numbers. Currently, it all depends on the cultural habits of the author. We enforce a single way to write numbers with thousands separators. We allow only underscores to be used as thousands separators.- Solution:
Numbers should be written as numbers:
1000. Using underscores as thousands separators if necessary.
Example:
# Correct: phone = 88313443 million = 1_000_000.50_001 hexed = 1_234.157_000e-1_123 binary = 0b1_001_001 # Wrong: phone = 8_83_134_43 million = 100_00_00.1_0 octal = 0o00_11
Added in version 0.1.0.
Changed in version 1.0.0: Underscore
_is now allowed with exactly 3 digits after it.- full_code: ClassVar[str] = 'WPS303'¶
- summary: ClassVar[str] = 'Forbid underscores (``_``) in numbers.'¶
- PartialFloatViolation[source]¶
WPS304 — Forbid partial floats like
.05or23..- Reasoning:
Partial numbers are hard to read and they can be confused with other numbers. For example, it is really easy to confuse
0.5and.05when reading through the source code.- Solution:
Use full versions with leading and trailing zeros.
Example:
# Correct: half = 0.5 ten_float = 10.0 # Wrong: half = .5 ten_float = 10.
Added in version 0.1.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS304'¶
- summary: ClassVar[str] = 'Forbid partial floats like ``.05`` or ``23.``.'¶
- FormattedStringViolation[source]¶
WPS305 — Forbid
fstrings.- Reasoning:
fstrings implicitly rely on the context around them. 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. Moreover, they do two things at once: declare a template and format it in a single action.- Solution:
Use
.format()with indexed params instead.
Example:
# Correct: 'Result is: {0}'.format(2 + 2) 'Hey {user}! How are you?'.format(user='sobolevn') # Wrong: f'Result is: {2 + 2}'
Added in version 0.1.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
rufflinter. SeeWPS237.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS305'¶
- summary: ClassVar[str] = 'Forbid ``f`` strings.'¶
- ExplicitObjectBaseClassViolation[source]¶
WPS306 — Forbid writing explicit object base class.
- Reasoning:
Adding object base class does not have any effect in most cases. However, PEP695 adds new syntax to define classes: class Some[T]: which is equivalent to: class Some(Generic[T]):. If object is added to class Some[T](object): it will be a runtime error: it won’t be possible to create a proper MRO.
We don’t want to promote feature that can cause troubles.
This feature also has some legacy Python2 connotations.
- Solution:
Remove object base class.
Example:
# Correct: class Some: ... # Wrong: class Some(object): ...
Added in version 0.1.0.
Changed in version 0.19.0: Now the rule is inverted: we require no explicit object base class. See PEP695 for extra reasoning.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS306'¶
- summary: ClassVar[str] = 'Forbid writing explicit `object` base class.'¶
- MultipleIfsInComprehensionViolation[source]¶
WPS307 — Forbid multiple
ifstatements inside list comprehensions.- Reasoning:
It is very hard to read multiple
ifstatements inside a list comprehension. Since it is even hard to tell all of them should pass or fail.- Solution:
Use a single
ifstatement inside list comprehensions. Usefilter()if you have complicated logic.
Example:
# Correct: nodes = [node for node in html if node not in {'b', 'i'}] # Wrong: nodes = [node for node in html if node != 'b' if node != 'i']
Added in version 0.1.0.
- full_code: ClassVar[str] = 'WPS307'¶
- summary: ClassVar[str] = 'Forbid multiple ``if`` statements inside list comprehensions.'¶
- ConstantCompareViolation[source]¶
WPS308 — Forbid comparing between two literals.
- Reasoning:
When two constants are compared it is typically an indication of a mistake, since the Boolean value of the comparison, will always be the same.
- Solution:
Remove the constant comparison and any associated dead code.
Example:
# Correct: do_something_else() # Wrong: if 60 * 60 < 1000: do_something() else: do_something_else()
Added in version 0.3.0.
- full_code: ClassVar[str] = 'WPS308'¶
- summary: ClassVar[str] = 'Forbid comparing between two literals.'¶
- CompareOrderViolation[source]¶
WPS309 — Forbid comparisons where the argument doesn’t come first.
- Reasoning:
It is hard to read the code when you have to shuffle the ordering of the arguments all the time. Bring consistency to the comparison!
- Solution:
Refactor your comparison expression, place the argument first.
Example:
# Correct: if some_x > 3: if 3 < some_x < 10: # Wrong: if 3 < some_x:
Added in version 0.3.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
rufflinter. SeeSIM300.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS309'¶
- summary: ClassVar[str] = "Forbid comparisons where the argument doesn't come first."¶
- BadNumberSuffixViolation[source]¶
WPS310 — Forbid uppercase
X,O,B, andEin numbers.- Reasoning:
Octal, hex, binary and scientific notation suffixes could be written in two possible notations: lowercase and uppercase which brings confusion and decreases code consistency and readability. We enforce a single way to write numbers with suffixes: suffix with lowercase chars.
- Solution:
Octal, hex, binary and scientific notation suffixes in numbers should be written in lowercase.
Example:
# Correct: hex_number = 0xFF octal_number = 0o11 binary_number = 0b1001 number_with_scientific_notation = 1.5e+10 # Wrong: hex_number = 0XFF octal_number = 0O11 binary_number = 0B1001 number_with_scientific_notation = 1.5E+10
Added in version 0.3.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS310'¶
- summary: ClassVar[str] = 'Forbid uppercase ``X``, ``O``, ``B``, and ``E`` in numbers.'¶
- MultipleInCompareViolation[source]¶
WPS311 — Forbid comparisons with multiple
inchecks.- Reasoning:
Using multiple
inchecks is unreadable.- Solution:
Refactor your comparison expression to use several
andconditions or separateifstatements in cases where it is appropriate.
Example:
# Correct: if item in bucket and bucket in master_list_of_buckets: if x_coord not in line and line not in square: # Wrong: if item in bucket in master_list_of_buckets: if x_cord not in line not in square:
Added in version 0.3.0.
Changed in version 0.10.0.
- full_code: ClassVar[str] = 'WPS311'¶
- summary: ClassVar[str] = 'Forbid comparisons with multiple ``in`` checks.'¶
- UselessCompareViolation[source]¶
WPS312 — Forbid comparisons of a variable to itself.
- Reasoning:
When a variable is compared to itself, it is typically an indication of a mistake since the Boolean value of the comparison will always be the same.
- Solution:
Remove the comparison and any associated dead code.
Example:
# Correct: do_something() # Wrong: if a < a: do_something() else: do_something_else()
Added in version 0.3.0.
Changed in version 1.0.1: No longer produced, kept here for historic reasons. This is covered with
ruffandpylintlinters. SeePLR0124.- disabled_since: ClassVar[str | None] = '1.0.1'¶
- full_code: ClassVar[str] = 'WPS312'¶
- summary: ClassVar[str] = 'Forbid comparisons of a variable to itself.'¶
- MissingSpaceBetweenKeywordAndParenViolation[source]¶
WPS313 — Enforce separation of parenthesis from keywords with spaces.
- Reasoning:
Some people use
returnandyieldkeywords as functions. The same happened to good oldprintin Python2.- Solution:
Insert space symbol between the keyword and opening parenthesis.
Example:
# Correct: def func(): a = 1 del (a, b) yield (1, 2, 3) # Wrong: def func(): a = 1 b = 2 del(a, b) yield(1, 2, 3)
Added in version 0.3.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS313'¶
- summary: ClassVar[str] = 'Enforce separation of parenthesis from keywords with spaces.'¶
- ConstantConditionViolation[source]¶
WPS314 — Forbid using
iformatchstatements that use invalid conditionals.- Reasoning:
When invalid conditional arguments are used it is typically an indication of a mistake, since the value of the conditional result will always be the same.
- Solution:
Remove the conditional and any associated dead code.
Example:
# Correct: if value is True: ... match value: case True: ... # Wrong: if True: ... match True: case True: ...
Added in version 0.3.0.
- full_code: ClassVar[str] = 'WPS314'¶
- summary: ClassVar[str] = 'Forbid using ``if`` or ``match`` statements that use invalid conditionals.'¶
- ObjectInBaseClassesListViolation[source]¶
WPS315 — Forbid extra
objectin parent classes list.- Reasoning:
We should allow object only when we explicitly use it as a single parent class. When there is another class or there are multiple parents - we should not allow it for the consistency reasons.
- Solution:
Remove extra
objectparent class from the list.
Example:
# Correct: class SomeClassName: ... class SomeClassName(FirstParentClass, SecondParentClass): ... # Wrong: class SomeClassName(FirstParentClass, SecondParentClass, object): ...
Added in version 0.3.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
rufflinter. SeeUP004.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS315'¶
- summary: ClassVar[str] = 'Forbid extra ``object`` in parent classes list.'¶
- MultipleContextManagerAssignmentsViolation[source]¶
WPS316 — Forbid multiple assignment targets for context managers.
- Reasoning:
It is hard to distinguish whether
asshould unpack into a tuple or if we are just using two context managers.- Solution:
Use several context managers or explicit brackets.
Example:
# Correct: with open('') as first: with second: ... with some_context as (first, second): ... # Wrong: with open('') as first, second: ...
Added in version 0.6.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter. SeeSIM117.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS316'¶
- summary: ClassVar[str] = 'Forbid multiple assignment targets for context managers.'¶
- ParametersIndentationViolation[source]¶
WPS317 — Forbid incorrect indentation for parameters.
- Reasoning:
It is really easy to spoil your perfect, readable code with incorrect multi-line parameters indentation. Since it is really easy to style them in any of 100 possible ways. We enforce a strict rule about how it is possible to write these multi-line parameters.
- Solution:
Use consistent multi-line parameters indentation.
Example:
# Correct: def my_function(arg1, arg2, arg3) -> None: return None print(1, 2, 3, 4, 5, 6) def my_function( arg1, arg2, arg3, ) -> None: return None print( 1, 2, 3, 4, 5, 6, ) def my_function( arg1, arg2, arg3, ) -> None: return None print( first_variable, 2, third_value, 4, 5, last_item, ) # Special case: print('some text', 'description', [ first_variable, second_variable, third_variable, last_item, ], end='') # Correct complex case: @pytest.mark.parametrize(('boolean_arg', 'string_arg'), [ (True, "string"), (False, "another string"), ])
Everything else is considered a violation. This rule checks: lists, sets, tuples, dicts, calls, functions, methods, and classes.
Added in version 0.6.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS317'¶
- summary: ClassVar[str] = 'Forbid incorrect indentation for parameters.'¶
- ExtraIndentationViolation[source]¶
WPS318 — Forbid extra indentation.
- Reasoning:
You can use extra indentation for lines of code. Python allows you to do that in case you want to keep the indentation level equal for this specific node, but that’s insane!
- Solution:
We should stick to 4 spaces for an indentation block. Each next block level should be indented by just 4 extra spaces.
Example:
# Correct: def test(): print('test') # Wrong: def test(): print('test')
This rule is consistent with the “Vertical Hanging Indent” option for
multi_line_outputsetting ofisort. To avoid conflicting rules, you should setmulti_line_output = 3in theisortsettings.See also
https://github.com/timothycrosley/isort#multi-line-output-modes https://github.com/wemake-services/wemake-python-styleguide/blob/master/styles/isort.toml
Added in version 0.6.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS318'¶
- summary: ClassVar[str] = 'Forbid extra indentation.'¶
- WrongBracketPositionViolation[source]¶
WPS319 — Forbid brackets in the wrong position.
- Reasoning:
You can do bizarre things with bracket positioning in python. We require all brackets to be consistent.
- Solution:
Place bracket on the same line, in case of a single line expression. Or place the bracket on a new line in case of a multi-line expression.
Example:
# Correct: print([ 1, 2, 3, ]) print( 1, 2, ) def _annotate_brackets( tokens: List[tokenize.TokenInfo], ) -> TokenLines: ... # Wrong: print([ 1, 2, 3], ) print( 1, 2) def _annotate_brackets( tokens: List[tokenize.TokenInfo]) -> TokenLines: ...
We check round, square, and curly brackets.
Added in version 0.6.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS319'¶
- summary: ClassVar[str] = 'Forbid brackets in the wrong position.'¶
- MultilineFunctionAnnotationViolation[source]¶
WPS320 — Forbid multi-line function type annotations.
- Reasoning:
Functions with multi-line type annotations are unreadable.
- Solution:
Use type annotations that fit into a single line to annotate functions. If your annotation is too long, then use type aliases.
Example:
# Correct: def create_list(length: int) -> List[int]: ... # Wrong: def create_list(length: int) -> List[ int, ]: ...
This rule checks argument and return type annotations.
Added in version 0.6.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS320'¶
- summary: ClassVar[str] = 'Forbid multi-line function type annotations.'¶
- UppercaseStringModifierViolation[source]¶
WPS321 — Forbid uppercase string modifiers.
- Reasoning:
String modifiers should be consistent.
- Solution:
Use lowercase string modifiers.
Example:
# Correct: some_string = r'/regex/' some_bytes = b'123' # Wrong: some_string = R'/regex/' some_bytes = B'123'
Added in version 0.6.0.
- full_code: ClassVar[str] = 'WPS321'¶
- summary: ClassVar[str] = 'Forbid uppercase string modifiers.'¶
- UselessMultilineStringViolation[source]¶
WPS322 — Forbid triple quotes for singleline strings.
- Reasoning:
String quotes should be consistent.
- Solution:
Use single quotes for single-line strings. Triple quotes are only allowed for real multiline strings.
Example:
# Correct: single_line = 'abc' multiline = """ one two """ # Wrong: some_string = """abc""" some_bytes = b"""123"""
Docstrings are ignored from this rule. You must use triple quotes strings for docstrings.
Is not reported for f-strings on python3.12+
Added in version 0.7.0.
Changed in version 1.0.0: Now allows to have multiline strings without
\nwhen that string is the single token on each line.Also changed how multiline strings are detected.
- full_code: ClassVar[str] = 'WPS322'¶
- summary: ClassVar[str] = 'Forbid triple quotes for singleline strings.'¶
- ModuloStringFormatViolation[source]¶
WPS323 — Forbid
%formatting on strings.We check for string formatting. We try not to issue false positives. It is better for us to ignore a real (but hard to detect) case, then marking a valid one as incorrect.
Internally we check for this pattern in string definitions:
%[(name)] [flags] [width] [.precision] [{h | l}] type
This is a
Cformat specification. Related toFormattedStringViolationand solves the same problem.- Reasoning:
You must use a single formatting method across your project.
- Solution:
We enforce to use string
.format()method for this task.
Example:
# Correct: 'some string', 'your name: {0}', 'data: {data}' # Wrong: 'my name is: %s', 'data: %(data)d'
It might be a good idea to disable this rule and switch to
flake8-pep3101in case your project has a lot of false-positives due to some specific string chars that uses%a lot.See also
https://github.com/gforcada/flake8-pep3101 https://msdn.microsoft.com/en-us/library/56e442dc.aspx https://docs.python.org/3/library/stdtypes.html#old-string-formatting https://pyformat.info/
Added in version 0.14.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter. SeeUP031.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS323'¶
- summary: ClassVar[str] = 'Forbid ``%`` formatting on strings.'¶
- InconsistentReturnViolation[source]¶
WPS324 — Enforce consistent
returnstatements.Rules are: 1. If any
returnhas a value, allreturnnodes should have a value 2. Do not placereturnwithout a value at the end of a function 3. Do not usereturn Nonewhere justreturnis good enoughThis rule respects
mypystyle of placingreturnstatements. There should be no conflict with these two checks.- Reasoning:
This is done for pure consistency and readability of your code. Eventually, this rule may also find some bugs in your code.
- Solution:
Add or remove values from the
returnstatements to make them consistent. Removereturnstatement from the function end.
Example:
# Correct: def function(): if some: return 2 return 1 # Wrong: def function(): if some: return return 1
Added in version 0.7.0.
Changed in version 0.16.0.
- full_code: ClassVar[str] = 'WPS324'¶
- summary: ClassVar[str] = 'Enforce consistent ``return`` statements.'¶
- InconsistentYieldViolation[source]¶
WPS325 — Enforce consistent
yieldstatements.Rules are: 1. if any
yieldhas a value, allyieldnodes should have a value 2. Useyieldinstead ofyield Nonewhere possibleThis rule respects
mypystyle of placingyieldstatements. There should be no conflict with these two checks.- Reasoning:
This is done for pure consistency and readability of your code. Eventually, this rule may also find some bugs in your code.
- Solution:
Add or remove values from the
yieldstatements to make them consistent.
Example:
# Correct: def function(): if some: yield 2 yield 1 # Wrong: def function(): if some: yield yield 1
Added in version 0.7.0.
Changed in version 0.16.0.
- full_code: ClassVar[str] = 'WPS325'¶
- summary: ClassVar[str] = 'Enforce consistent ``yield`` statements.'¶
- ImplicitStringConcatenationViolation[source]¶
WPS326 — Forbid implicit string concatenation.
- Reasoning:
This is error-prone, since you can possibly miss a comma in a collection of strings and get an implicit concatenation. And because there are safer ways to do the same thing it is better to use them instead.
- Solution:
Use
+or.format()to join strings.
Example:
# Correct: text = 'first' + 'second' # Wrong: text = 'first' 'second'
Added in version 0.7.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter. SeeISC001.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS326'¶
- summary: ClassVar[str] = 'Forbid implicit string concatenation.'¶
- UselessContinueViolation[source]¶
WPS327 — Forbid meaningless
continuein loops.- Reasoning:
Placing this keyword at the end of any loop won’t make any difference to your code. And we prefer not to have meaningless constructs in our code.
- Solution:
Remove useless
continuefrom the loop.
Example:
# Correct: for number in [1, 2, 3]: if number < 2: continue print(number) for number in [1, 2, 3]: with suppress(Exception): do_smth(some_obj) # Wrong: for number in [1, 2, 3]: print(number) continue for number in [1, 2, 3]: try: do_smth(some_obj) except Exception: continue
Added in version 0.7.0.
- full_code: ClassVar[str] = 'WPS327'¶
- summary: ClassVar[str] = 'Forbid meaningless ``continue`` in loops.'¶
- UselessNodeViolation[source]¶
WPS328 — Forbid meaningless nodes.
- Reasoning:
Some nodes might be completely useless. They will literally do nothing. Sometimes they are hard to find, because this situation can be caused by a recent refactoring or just by accident. This might be also an overuse of syntax.
- Solution:
Remove node or make sure it makes sense.
Example:
# Wrong: for number in [1, 2, 3]: break
Added in version 0.7.0.
- full_code: ClassVar[str] = 'WPS328'¶
- summary: ClassVar[str] = 'Forbid meaningless nodes.'¶
- UselessExceptCaseViolation[source]¶
WPS329 — Forbid meaningless
exceptcases.- Reasoning:
Using
exceptcases that just reraise the same exception is error-prone. You can increase your stacktrace, silence some potential exceptions, and screw things up. It also does not make any sense to do so.- Solution:
Remove
exceptcase or make sure it makes sense.
Example:
# Correct: try: ... except IndexError: sentry.log() raise ValueError() try: ... except ValueError as exc: raise CustomReadableException from exc # Wrong: try: ... except TypeError: raise
Added in version 0.7.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
rufflinter. SeeTRY203.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS329'¶
- summary: ClassVar[str] = 'Forbid meaningless ``except`` cases.'¶
- UselessOperatorsViolation[source]¶
WPS330 — Forbid unnecessary operators in your code.
You can write:
5.4and+5.4. There’s no need to use the second version. Similarly--5.4,---5.4,not not foo, and~~42contain unnecessary operators.- Reasoning:
This is done for consistency reasons.
- Solution:
Omit unnecessary operators.
Example:
# Correct: profit = 3.33 profit = -3.33 inverse = ~5 complement = not foo # Wrong: profit = +3.33 profit = --3.33 profit = ---3.33 number = ~~42 bar = not not foo
Added in version 0.8.0.
- full_code: ClassVar[str] = 'WPS330'¶
- summary: ClassVar[str] = 'Forbid unnecessary operators in your code.'¶
- InconsistentReturnVariableViolation[source]¶
WPS331 — Forbid local variables that are only used in
returnstatements.We also allow cases when a variable is assigned, then there are some other statements without direct variable access and the variable is returned. We reserve this use-case to be able to do some extra work before the function returns.
We also allow the return of partial, sorted, or modified tuple items that are defined just above.
- Reasoning:
This is done for consistency and more readable source code.
- Solution:
Return the expression itself, instead of creating a temporary variable.
Example:
# Correct: def some_function(): return 1 def other_function(): some_value = 1 do_something(some_value) return some_value # Wrong: def some_function(): some_value = 1 return some_value
Added in version 0.9.0.
Changed in version 0.14.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter. SeeRET504.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS331'¶
- summary: ClassVar[str] = 'Forbid local variables that are only used in ``return`` statements.'¶
- WalrusViolation[source]¶
WPS332 — Forbid the use of the walrus operator (:=) in most cases.
- Walrus operator is allowed inside:
comprehensions
top level
whileconditions
- Reasoning:
Code with
:=is hardly readable. It has big problems with scoping and reading order. And it can lead to a huge mess inside your code. Python is not expression-based.- Solution:
Avoid using the walrus operator outside of specific places where it fits. Stick to traditional assignment statements for clarity.
Example:
# Correct: some = call() if some: print(some) # Wrong: if some := call(): print(some)
Added in version 0.14.0.
Changed in version 1.0.0: Allows
:=inside comprehensions.- full_code: ClassVar[str] = 'WPS332'¶
- summary: ClassVar[str] = 'Forbid the use of the walrus operator (`:=`) in most cases.'¶
- ImplicitComplexCompareViolation[source]¶
WPS333 — Forbid implicit complex comparison expressions.
- Reasoning:
Two comparisons in python that are joined with
andoperator mean that you have a complex comparison with tree operators.- Solution:
Refactor your comparison without
andbut with the third operator. Notice that you might have to change the ordering.
Example:
# Correct: if three < two < one: ... # Wrong: if one > two and two > three: ...
Added in version 0.10.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffandpylintlinters. SeePLR1716.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS333'¶
- summary: ClassVar[str] = 'Forbid implicit complex comparison expressions.'¶
- ReversedComplexCompareViolation[source]¶
WPS334 — Forbid reversed order complex comparison expressions.
- Reasoning:
Comparisons where comparators start from the lowest element are easier to read than one that start from the biggest one. It is also possible to write the same expression in two separate way, which is inconsistent.
- Solution:
Reverse the order, so the smallest element comes first and the biggest one comes last.
Example:
# Correct: if three < two < one: ... # Wrong: if one > two > three: ...
Added in version 0.10.0.
- full_code: ClassVar[str] = 'WPS334'¶
- summary: ClassVar[str] = 'Forbid reversed order complex comparison expressions.'¶
- WrongLoopIterTypeViolation[source]¶
WPS335 — Forbid wrong
forloop iter targets.We forbid to use:
Lists and list comprehensions
Sets and set comprehensions
Dicts and dict comprehensions
Generator expressions
Empty tuples
- Reasoning:
Using lists, dicts, and sets do not make much sense. You can use tuples instead. Using comprehensions implicitly creates a two level loop, that is hard to read and deal with.
- Solution:
Use tuples to create explicit iterables for
forloops. In case you are using a comprehension, create a new variable.
Example:
# Correct: for person in ('Kim', 'Nick'): ... # Wrong: for person in ['Kim', 'Nick']: ...
Added in version 0.10.0.
Changed in version 0.12.0.
- full_code: ClassVar[str] = 'WPS335'¶
- summary: ClassVar[str] = 'Forbid wrong ``for`` loop iter targets.'¶
- ExplicitStringConcatViolation[source]¶
WPS336 — Forbid explicit string concatenation in favour of
.formatmethod.However, we still allow multiline string concatenation as a way to write long strings that does not fit the 80-chars rule.
- Reasoning:
When formatting strings one must use
.formatand not any other formatting methods like%,+, orf. This is done for consistency reasons.- Solution:
Join strings together if you can, or use
.formatmethod.
Example:
# Correct: x = 'ab: {0}'.format(some_data) # Wrong: x = 'a' + 'b: ' + some_data
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS336'¶
- summary: ClassVar[str] = 'Forbid explicit string concatenation in favour of ``.format`` method.'¶
- MultilineConditionsViolation[source]¶
WPS337 — Forbid multiline conditions.
- Reasoning:
This way of writing conditions hides the inner complexity this line has and it decreases readability of the code.
- Solution:
Divide multiline conditions to some
ifcondition or use variables.
Example:
# Correct: if isinstance(node.test, ast.UnaryOp): if isinstance(node.test.op, ast.Not): ... # Wrong: if isinstance(node.test, ast.UnaryOp) and isinstance( node.test.op, ast.Not, ): ...
Added in version 0.9.0.
Changed in version 0.11.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS337'¶
- summary: ClassVar[str] = 'Forbid multiline conditions.'¶
- WrongMethodOrderViolation[source]¶
WPS338 — Forbid incorrect order of methods inside a class.
We follow the same ordering:
__init_subclass____new____init____call____await__public and magic methods
protected methods
private methods (we discourage using them)
We follow “Newspaper order” where the most important things come first.
- Reasoning:
It is hard to read classes where API declarations are bloated with implementation details. We need to see the important stuff first, then we can go deeper in case we are interested.
- Solution:
Reorder methods inside your class to match our format.
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS338'¶
- summary: ClassVar[str] = 'Forbid incorrect order of methods inside a class.'¶
- NumberWithMeaninglessZeroViolation[source]¶
WPS339 — Forbid meaningless zeros.
We discourage using meaningless zeros in float, binary, octal, hex, and exponential numbers.
- Reasoning:
There are ~infinite ways to write these numbers by adding meaningless leading zeros to the number itself.
0b1is the same as0b01and0b001. How can a language be called consistent if you can write numbers in an infinite ways? It hurts readability and understanding of your code.- Solution:
Remove meaningless leading zeros.
Example:
# Correct: numbers = [1.5, 0b1, 0o2, 0x5, 10e10] # Wrong: numbers = [1.50, 0b00000001, 0o0002, 0x05, 10e010]
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS339'¶
- summary: ClassVar[str] = 'Forbid meaningless zeros.'¶
- PositiveExponentViolation[source]¶
WPS340 — Forbid extra
+signs in the exponent.- Reasoning:
Positive exponent is positive by default, there’s no need to write an extra
+sign. We enforce consistency with this rule.- Solution:
Remove meaningless
+sign from the exponent.
Example:
# Correct: number = 1e1 + 1e-1 # Wrong: number = 1e+1
Added in version 0.12.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS340'¶
- summary: ClassVar[str] = 'Forbid extra ``+`` signs in the exponent.'¶
- WrongHexNumberCaseViolation[source]¶
WPS341 — Forbid letters as hex numbers.
- Reasoning:
One can write
0xAand0xawhich is inconsistent. This rule enforces upper-case letters in hex numbers.- Solution:
Use uppercase letters in hex numbers.
Example:
# Correct: number = 0xABCDEF # Wrong: number = 0xabcdef
Added in version 0.12.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS341'¶
- summary: ClassVar[str] = 'Forbid letters as hex numbers.'¶
- ImplicitRawStringViolation[source]¶
WPS342 — Forbid
\\escape sequences inside regular strings.- Reasoning:
It is hard to read escape sequences inside regular strings, because they use
\\double backslash for a single character escape.- Solution:
Use raw strings
r''to rewrite the escape sequence with a\single backslash.
Example:
# Correct: escaped = [r'\n', '\n'] # Wrong: escaped = '\\n'
Is not reported for f-strings on python3.12+
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS342'¶
- summary: ClassVar[str] = 'Forbid ``\\\\`` escape sequences inside regular strings.'¶
- BadComplexNumberSuffixViolation[source]¶
WPS343 — Forbid uppercase complex number suffix.
- Reasoning:
Numbers should be consistent.
- Solution:
Use lowercase suffix for imaginary part.
Example:
# Correct: complex_number = 1j # Wrong: complex_number = 1J
Added in version 0.12.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS343'¶
- summary: ClassVar[str] = 'Forbid uppercase complex number suffix.'¶
- ZeroDivisionViolation[source]¶
WPS344 — Forbid explicit division (or modulo) by zero.
- Reasoning:
This will just throw
ZeroDivisionError. If that’s what you need: just throw it. No need to use undefined math behaviours. Or it might be just a typo / mistake, then fix it.- Solution:
Use
ZeroDivisionErroror make your number something besides0.
Example:
# Correct: raise ZeroDivisionError() # Wrong: 1 / 0 1 % 0
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS344'¶
- summary: ClassVar[str] = 'Forbid explicit division (or modulo) by zero.'¶
- MeaninglessNumberOperationViolation[source]¶
WPS345 — Forbid meaningless math operations with
0and1.- Reasoning:
Adding and subtracting zero does not change the value. There’s no need to do that. Multiplying by zero is also redundant: it can be replaced with explicit
0assign. Multiplying and dividing by1is also meaningless. Likewise, using|or^with0, and using the%operator with1are unnecessary.- Solution:
Remove useless operations.
Example:
# Correct: number = 1 zero = 0 one = 1 three = 3 # Wrong: number = 1 + 0 * 1 zero = some * 0 / 1 one = some ** 0 ** 1 three = 3 ^ 0 three = 3 | 0 three = 3 % 1
Added in version 0.12.0.
Changed in version 0.15.0.
- full_code: ClassVar[str] = 'WPS345'¶
- summary: ClassVar[str] = 'Forbid meaningless math operations with ``0`` and ``1``.'¶
- OperationSignNegationViolation[source]¶
WPS346 — Forbid double minus operations.
- Reasoning:
Having two operations is harder than having just one. Two negations are harder than one positive expression. Two negations equal to one positive expression. Positive and negative equal to one negative.
- Solution:
Replace double minus operation to a single one with plus. Replace ‘plus-minus’ operation to a single one with minus.
Example:
# Correct: number = 3 + 1 number += 6 number -= 2 # Wrong: number = 3 - -1 number -= -6 number += -2
Added in version 0.12.0.
- full_code: ClassVar[str] = 'WPS346'¶
- summary: ClassVar[str] = 'Forbid double minus operations.'¶
- VagueImportViolation[source]¶
WPS347 — Forbid imports that may cause confusion outside of the module.
Names that we forbid to import:
Common names like
dumpsandloadsNames starting with
to_andfrom_Too short names like
QorF, but we are fine with_
- Reasoning:
See
datetime.*in code? You know that it’s from datetime. SeeBaseViewin a Django project? You know where it is from. Seeloads? It can be anything:yaml,toml,json, etc. We are also enforcing consistency with our naming too-short rules here.- Solution:
Use package level imports or import aliases.
See
VAGUE_IMPORTS_BLACKLISTfor the full list of bad import names.Example:
# Correct: import json import dumps # package names are not checked from json import loads as json_loads # Wrong: from json import loads
Added in version 0.13.0.
Changed in version 0.14.0.
- full_code: ClassVar[str] = 'WPS347'¶
- summary: ClassVar[str] = 'Forbid imports that may cause confusion outside of the module.'¶
- LineStartsWithDotViolation[source]¶
WPS348 — Forbid starting lines with a dot.
- Reasoning:
We enforce strict consistency rules about how to break lines. We also enforce strict rules about multi-line parameters. Starting new lines with the dot means that this rule is broken.
- Solution:
Use
()to break lines in a complex expression.
Example:
# Correct: some = MyModel.objects.filter( ..., ).exclude( ..., ).annotate( ..., ) # Wrong: some = ( MyModel.objects.filter(...) .exclude(...) .annotate(...) )
Added in version 0.13.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. It conflicted with the
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS348'¶
- summary: ClassVar[str] = 'Forbid starting lines with a dot.'¶
- RedundantSubscriptViolation[source]¶
WPS349 — Forbid redundant components in a subscript’s slice.
- Reasoning:
We do it for consistency reasons.
Example:
# Correct: array[:7] array[3:] # Wrong: x[0:7] x[3:None]
Added in version 0.13.0.
- full_code: ClassVar[str] = 'WPS349'¶
- summary: ClassVar[str] = "Forbid redundant components in a subscript's slice."¶
- AugmentedAssignPatternViolation[source]¶
WPS350 — Enforce using augmented assign pattern.
- Reasoning:
a += bis short and correct version ofa = a + b. Why not using the short version?
Example:
# Correct: a += b # Wrong: a = a + b
Added in version 0.13.0.
- full_code: ClassVar[str] = 'WPS350'¶
- summary: ClassVar[str] = 'Enforce using augmented assign pattern.'¶
- UnnecessaryLiteralsViolation[source]¶
WPS351 — Forbid unnecessary literals in your code.
- Reasoning:
We discourage using primitive calls to get default type values. There are better ways to get these values.
- Solution:
Use direct default values of the given type
Example:
# Correct: default = 0 # Wrong: default = int()
Added in version 0.13.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
rufflinter. SeeUP018andC408.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS351'¶
- summary: ClassVar[str] = 'Forbid unnecessary literals in your code.'¶
- MultilineLoopViolation[source]¶
WPS352 — Forbid multiline loops.
- Reasoning:
It decreased the readability of the code.
- Solution:
Use single line loops and create new variables in case you need to fit too many logic inside the loop definition.
Example:
# Correct: for num in some_function(arg1, arg2): ... # Wrong: for num in range( arg1, arg2, ): ...
Added in version 0.13.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS352'¶
- summary: ClassVar[str] = 'Forbid multiline loops.'¶
- IncorrectYieldFromTargetViolation[source]¶
WPS353 — Forbid
yield fromwith several nodes.We allow to
yield fromtuples, names, attributes, calls, and subscripts.- Reasoning:
We enforce consistency when yielding values from tuple instead of any other types. It also might be an error when you try to
yield fromsomething that is not iterable.- Solution:
Use allowed node types with
yield from.
Example:
# Correct: yield from (1, 2, 3) yield from some # Wrong: yield from [1, 2, 3]
Added in version 0.13.0.
- full_code: ClassVar[str] = 'WPS353'¶
- summary: ClassVar[str] = 'Forbid ``yield from`` with several nodes.'¶
- ConsecutiveYieldsViolation[source]¶
WPS354 — Forbid consecutive
yieldexpressions.We raise this violation when we find at least two consecutive
yieldexpressions.- Reasoning:
One can write multiple
yieldnodes in a row. That’s inconsistent. Because we haveyield fromform.- Solution:
It can be easily changed to
yield from (...)format.
Added in version 0.13.0.
Changed in version 1.6.0: No longer produced, kept here for historic reasons. It is inconsistent with async code.
- disabled_since: ClassVar[str | None] = '1.6.0'¶
- full_code: ClassVar[str] = 'WPS354'¶
- summary: ClassVar[str] = 'Forbid consecutive ``yield`` expressions.'¶
- BracketBlankLineViolation[source]¶
WPS355 — Forbid useless blank lines before and after brackets.
- Reasoning:
We do this for consistency.
- Solution:
Remove blank lines from the start and from the end of a collection.
Example:
# Correct: arr = [ 1, 2, ] # Wrong: arr = [ 1, 2, ]
Added in version 0.13.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS355'¶
- summary: ClassVar[str] = 'Forbid useless blank lines before and after brackets.'¶
- IterableUnpackingViolation[source]¶
WPS356 — Forbid unnecessary iterable unpacking.
- Reasoning:
We do this for consistency.
- Solution:
Do not use iterable unpacking when it’s not necessary.
Example:
# Correct: [1, *numbers, 99] {*iterable, *other_iterable} list(iterable) first, *iterable = other_iterable GenericTuple = tuple[*Shape] # Wrong: [*iterable] *iterable, = other_iterable
Added in version 0.13.0.
Changed in version 0.19.3: Allow using
TypeVarTupleunpacking in generic types. As a side-effect we now allow all unpackings inast.Subscript.- full_code: ClassVar[str] = 'WPS356'¶
- summary: ClassVar[str] = 'Forbid unnecessary iterable unpacking.'¶
- LineCompriseCarriageReturnViolation[source]¶
WPS357 — Forbid using
\r(carriage return) in line breaks.- Reasoning:
We enforce Unix-style newlines. We only use newlines (
\n), not carriage returns. So\rline breaks not allowed in code.- Solution:
Use only
\n(not\r\nor\r) to break lines.
Added in version 0.14.0.
- full_code: ClassVar[str] = 'WPS357'¶
- summary: ClassVar[str] = 'Forbid using ``\\r`` (carriage return) in line breaks.'¶
- FloatZeroViolation[source]¶
WPS358 — Forbid using float zeros:
0.0.- Reasoning:
Float zeros can be used as variable values which may lead to typing bugs when trying to perform an operation between an int number and the float zero.
- Solution:
Use int zeros (0). If a float is needed, it should be cast explicitly.
Example:
# Correct: zero = 0 # Wrong: zero = 0.0
Added in version 0.15.0.
- full_code: ClassVar[str] = 'WPS358'¶
- summary: ClassVar[str] = 'Forbid using float zeros: ``0.0``.'¶
- UnpackingIterableToListViolation[source]¶
WPS359 — Forbids to unpack iterable objects to lists.
- Reasoning:
We do this for consistency.
- Solution:
Do not unpack iterables to lists, use tuples for that.
Example:
# Correct: first, second = (7, 4) first, *iterable = other_iterable # Wrong: [first, second] = (7, 4) [first, *iterable] = other_iterable
Added in version 0.15.0.
- full_code: ClassVar[str] = 'WPS359'¶
- summary: ClassVar[str] = 'Forbids to unpack iterable objects to lists.'¶
- RawStringNotNeededViolation[source]¶
WPS360 — Forbid the use of raw strings when there is no backslash in the string.
- Reasoning:
Raw string are only needed when dealing with
\in the string.- Solution:
Do not prefix the string with
r. Use a normal string instead.
Example:
# Correct: r'This is a correct use \n' # Wrong: r'This string should not be prefixed with r.'
Is not reported for f-strings on python3.12+
Added in version 0.15.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS360'¶
- summary: ClassVar[str] = 'Forbid the use of raw strings when there is no backslash in the string.'¶
- InconsistentComprehensionViolation[source]¶
WPS361 — Forbids inconsistent newlines in comprehensions.
- Reasoning:
We do this for consistency.
- Solution:
Either place comprehension on a single line or ensure that action, for loops, and condition are all on different lines.
Example:
# Correct: list = [some(number) for number in numbers] list = [ some(number) for numbers in matrix for number in numbers if number > 0 ] # Wrong: list = [ some(number) for number in numbers if number > 0 ]
Added in version 0.15.0.
Changed in version 1.0.0: No longer produced, kept here for historic reasons. This is covered with
ruffformatter.- disabled_since: ClassVar[str | None] = '1.0.0'¶
- full_code: ClassVar[str] = 'WPS361'¶
- summary: ClassVar[str] = 'Forbids inconsistent newlines in comprehensions.'¶
- AssignToSliceViolation[source]¶
WPS362 — Forbid assignment to a subscript slice.
- Reasoning:
Assignment to a slice may lead to a list changing its size implicitly and strangely which makes it hard to spot bugs.
- Solution:
Use explicit index assignment in place of slice assignment.
Why you may disable or inline-ignore this rule?
The quite common and useful example which violates this rule is inplace list replacement via
[:]- this helps to keep the same object reference while it content could be completely erased or replaced with the new one.One more thing: slice assignment is the only way for inplace array multiple replacement when you need that.
Example:
# Correct: a[5] = 1 # Wrong: a[1:3] = [1, 2] a[slice(1)] = [1, 3]
Added in version 0.15.0.
- full_code: ClassVar[str] = 'WPS362'¶
- summary: ClassVar[str] = 'Forbid assignment to a subscript slice.'¶
- RaiseSystemExitViolation[source]¶
WPS363 — Forbid raising
SystemExit.- Reasoning:
For consistency.
- Solution:
Use
sys.exit().
Example:
# Correct: sys.exit(code) # Wrong: raise SystemExit(code)
Added in version 1.0.0.
- full_code: ClassVar[str] = 'WPS363'¶
- summary: ClassVar[str] = 'Forbid raising :exc:`SystemExit`.'¶
- NotInWithUnaryOpViolation[source]¶
WPS364 — Forbid using
not a in binstead ofa not in b.- Reasoning:
The expression
not a in bis parsed asnot (a in b)and is equivalent toa not in b. However, it is easy to misread as(not a) in bor require extra parsing effort. Using the explicitnot inoperator is clearer and idiomatic.- Solution:
Replace
not a in b(ornot (a in b)) witha not in b.
Example:
# Correct: if user not in users: ... # Wrong: if not user in users: ... if not (user in users): ...
Added in version 1.5.0.
- full_code: ClassVar[str] = 'WPS364'¶
- summary: ClassVar[str] = 'Forbid using ``not a in b`` instead of ``a not in b``.'¶
- SimplifiableMatchViolation[source]¶
WPS365 — Some
matchstatements can be simplified toifstatements.- Reasoning:
Using
matchfor simple two-case conditions (including wildcard_) is unnecessarily verbose and less performant than a plainif/else. Simple conditions should prefer readability and simplicity.- Solution:
Replace violating
match ... case _statements withif ... else.- When is this violation is raised?
When there are exactly two
casestatementsWhen the first case uses a literal pattern
When the second case is a wildcard:
case _:
Example:
# Correct: if state == EventType.REJECT: user = 'rejected' else: user = 'active' # Wrong: match state: case EventType.REJECT: user = 'rejected' case _: user = 'active'
Added in version 1.5.0.
- full_code: ClassVar[str] = 'WPS365'¶
- summary: ClassVar[str] = 'Some ``match`` statements can be simplified to ``if`` statements.'¶
- MeaninglessBooleanOperationViolation[source]¶
WPS366 — Forbid meaningless boolean operations.
- Reasoning:
Some parts of a boolean expression may be redundant, making the logic difficult to understand.
- Explanation:
comparison of constants can be replaced with a single constant
- comparison with constants in the
andoperator can lead to an implicit conditional assignment, which is better done explicitly
- comparison with constants in the
everything after the first constant in
oroperator can be removedcomparison of duplicated variables can be reduced
- Solution:
Remove useless operations.
Example:
# Correct: cond = condition or -1 cond = condition1 or condition2 cond = condition1 and condition2 and condition3 cond = condition or -condition # Wrong: cond = 10 and 'value' cond = condition and 10 cond = condition or True or 2 cond = condition or 'value' or 0 cond = condition and condition
Added in version 1.6.0.
- full_code: ClassVar[str] = 'WPS366'¶
- summary: ClassVar[str] = 'Forbid meaningless boolean operations.'¶