Refactoring

These checks ensure that you don’t have patterns that can be refactored.

There are so many ways of doing the same thing in Python. Here we collect know patterns that can be rewritten into much easier or just more pythonic version.

Summary

UselessLoopElseViolation

Forbid else without break in a loop.

UselessFinallyViolation

Forbid finally in try block without except block.

SimplifiableIfViolation

Forbid simplifiable if conditions.

UselessReturningElseViolation

Forbid useless else cases in returning functions.

NegatedConditionsViolation

Forbid negated conditions together with else clause.

NestedTryViolation

Forbid nested try blocks.

UselessLambdaViolation

Forbid useless proxy lambda expressions.

UselessLenCompareViolation

Forbid unpythonic zero-length compare.

NotOperatorWithCompareViolation

Forbid not with compare expressions.

NestedTernaryViolation

Forbid nesting ternary expressions in certain places.

WrongInCompareTypeViolation

Forbid in with static containers except set nodes.

UnmergedIsinstanceCallsViolation

Forbid multiple isinstance calls on the same variable.

WrongIsinstanceWithTupleViolation

Forbid multiple isinstance calls with single-item tuples.

ImplicitElifViolation

Forbid implicit elif conditions.

ImplicitInConditionViolation

Forbid multiple equality comparisons with the same variable.

OpenWithoutContextManagerViolation

Forbid open() without a context manager.

TypeCompareViolation

Forbid comparing types with type() function.

PointlessStarredViolation

Forbid useless starred expressions.

ImplicitEnumerateViolation

Forbid implicit enumerate() calls.

ImplicitSumViolation

Forbid implicit sum() calls.

FalsyConstantCompareViolation

Forbid comparing with explicit falsy constants.

WrongIsCompareViolation

Forbid comparing values with constants using is or is not.

ImplicitPrimitiveViolation

Forbid implicit primitives in the form of lambda functions.

AlmostSwappedViolation

Forbid unpythonic variable swaps.

MisrefactoredAssignmentViolation

Forbid misrefactored self assignment.

InCompareWithSingleItemContainerViolation

Forbid comparisons where in is compared with single item container.

ImplicitYieldFromViolation

Forbid yield inside for loop instead of yield from.

NotATupleArgumentViolation

Require tuples as arguments for certain functions.

ImplicitItemsIteratorViolation

Forbid implicit .items() iterator.

ImplicitDictGetViolation

Forbid implicit .get() dict method.

ImplicitNegativeIndexViolation

Forbid implicit negative indexes.

SimplifiableReturningIfViolation

Forbid if statements that simply return booleans in functions or methods.

Refactoring opportunities

class UselessLoopElseViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid else without break in a loop.

We use the same logic for for and while loops.

Reasoning:

When there’s no break keyword in loop’s body it means that else will always be called. This rule will reduce complexity, improve readability, and protect from possible errors.

Solution:

Refactor your else case logic to be inside the loop’s body. Or right after it.

Example:

# Correct:
for letter in 'abc':
    if letter == 'b':
        break
else:
    print('"b" is not found')

for letter in 'abc':
    print(letter)
print('always called')

# Wrong:
for letter in 'abc':
    print(letter)
else:
    print('always called')

New in version 0.3.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found `else` in a loop without `break`'
code: ClassVar[int] = 500
previous_codes: ClassVar[Set[int]] = {436}
class UselessFinallyViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid finally in try block without except block.

However, we allow to use try with just finally block when function or method is decorated. Because we cannot control what is going on in this decorator. It might be @contextmanager or similar thing that requires this API.

Reasoning:

This rule will reduce complexity and improve readability.

Solution:

Refactor your try logic. Replace the try-finally statement with a with statement.

Example:

# Correct:
with open("filename") as f:
    f.write(...)

# Wrong:
try:
    f = open("filename")
    f.write(...)
finally:
    f.close()

New in version 0.3.0.

Changed in version 0.11.0.

Changed in version 0.14.0.

error_template: ClassVar[str] = 'Found `finally` in `try` block without `except`'
code: ClassVar[int] = 501
previous_codes: ClassVar[Set[int]] = {437}
class SimplifiableIfViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid simplifiable if conditions.

Reasoning:

These complex constructions can cause frustration among other developers. They are longer, more verbose, and more complex.

Solution:

Either use bool() to convert test values to boolean values, or just leave it as it is in case your test already returns a boolean value. Use can also use not keyword to switch boolean values.

Example:

# Correct:
my_bool = bool(some_call())
other_value = 8 if some_call() else None

# Wrong:
my_bool = True if some_call() else False

We only check if nodes where True and False values are used. We check both if nodes and if expressions.

New in version 0.7.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found simplifiable `if` condition'
code: ClassVar[int] = 502
previous_codes: ClassVar[Set[int]] = {451}
class UselessReturningElseViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid useless else cases in returning functions.

We check single if statements that all contain return or raise or break statements with this rule. We do not check if statements with elif cases.

Reasoning:

Using extra else creates a situation when the whole node could and should be dropped without any changes in logic. So, we prefer to have less code than more code.

Solution:

Remove useless else case.

Example:

# Correct:
def some_function():
    if some_call():
        return 'yeap'
    return 'nope'

# Wrong:
def some_function():
    if some_call():
        raise ValueError('yeap')
    else:
        raise ValueError('nope')

New in version 0.7.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found useless returning `else` statement'
code: ClassVar[int] = 503
previous_codes: ClassVar[Set[int]] = {457}
class NegatedConditionsViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid negated conditions together with else clause.

Reasoning:

It easier to read and name regular conditions. Not negated ones.

Solution:

Move actions from the negated if condition to the else condition.

Example:

# Correct:
if some == 1:
     ...
else:
     ...

if not some:
     ...

if not some:
    ...
elif other:
    ...

# Wrong:
if not some:
     ...
else:
     ...

New in version 0.8.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found negated condition'
code: ClassVar[int] = 504
previous_codes: ClassVar[Set[int]] = {463}
class NestedTryViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid nested try blocks.

Notice, we check all possible slots for try block: 1. the try block itself 2. all except cases 3. else case 4. and finally case

Reasoning:

Nesting try blocks indicates that something really bad happens to your logic. Why does it require two separate exception handlers? It is a perfect case to refactor your code.

Solution:

Collapse two exception handlers together. Or create a separate function that will handle this second nested case.

Example:

# Wrong:
try:
    try:
        ...
    except SomeException:
        ...
except SomeOtherException:
    ...

try:
    ...
except SomeOtherException:
    try:
        ...
    except SomeException:
        ...

New in version 0.8.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found nested `try` block'
code: ClassVar[int] = 505
previous_codes: ClassVar[Set[int]] = {464}
class UselessLambdaViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid useless proxy lambda expressions.

Reasoning:

Sometimes developers tend to overuse lambda expressions and they wrap code that can be passed as is, without extra wrapping. The code without extra lambda is easier to read and is more performant.

Solution:

Remove wrapping lambda declaration, use just the internal function.

Example:

# Correct:
numbers = map(int, ['1', '2'])

# Wrong:
numbers = map(lambda string: int(string), ['1', '2'])

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found useless lambda declaration'
code: ClassVar[int] = 506
previous_codes: ClassVar[Set[int]] = {467}
class UselessLenCompareViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid unpythonic zero-length compare.

Note, that we allow to check arbitrary length, like len(arr) == 3.

Reasoning:

Python’s structures like dicts, lists, sets, and tuples all have __bool__ method to checks their length. So, there’s no point in wrapping them into len(...) and checking that it is bigger that 0 or less then 1, etc.

Solution:

Remove extra len() call.

Example:

# Correct:
if some_array or not other_array or len(third_array) == 1:
    ...

# Wrong:
if len(some_array) > 0 or len(other_array) < 1:
    ...

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found useless `len()` compare'
code: ClassVar[int] = 507
previous_codes: ClassVar[Set[int]] = {468}
class NotOperatorWithCompareViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid not with compare expressions.

Reasoning:

This version of not operator is unreadable.

Solution:

Refactor the expression without not operator. Change the compare signs.

Example:

# Correct:
if x <= 5:
    ...

# Wrong:
if not x > 5:
    ...

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found incorrect `not` with compare usage'
code: ClassVar[int] = 508
previous_codes: ClassVar[Set[int]] = {470}
class NestedTernaryViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid nesting ternary expressions in certain places.

Note, that we restrict to nest ternary expressions inside:

  • if conditions

  • boolean and binary operations like and or +

  • unary operators

Reasoning:

Nesting ternary in random places can lead to very hard debug and testing problems.

Solution:

Refactor the ternary expression to be either a new variable, or nested if statement, or a new function.

Example:

# Correct:
some = x if cond() else y

# Wrong:
if x if cond() else y:
    ...

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found incorrectly nested ternary'
code: ClassVar[int] = 509
previous_codes: ClassVar[Set[int]] = {472}
class WrongInCompareTypeViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid in with static containers except set nodes.

We enforce people to use sets as a static containers. You can also use variables, calls, methods, etc. Dynamic values are not checked.

Reasoning:

Using static list, tuple, or dict elements to check that some element is inside the container is a bad practice. Because we need to iterate all over the container to find the element. Sets are the best suit for this task. Moreover, it makes your code consistent.

Solution:

Use set elements or comprehensions to check that something is contained in a container.

Example:

# Correct:
print(needle in {'one', 'two'})

# Wrong:
print(needle in ['one', 'two'])

New in version 0.10.0.

Changed in version 0.11.0.

Changed in version 0.14.0.

error_template: ClassVar[str] = 'Found `in` used with a non-set container'
code: ClassVar[int] = 510
previous_codes: ClassVar[Set[int]] = {473}
class UnmergedIsinstanceCallsViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid multiple isinstance calls on the same variable.

Reasoning:

The best practice is to use isinstance with tuple as the second argument, instead of multiple conditions joined with or.

Solution:

Use tuple of types as the second argument.

Example:

# Correct:
isinstance(some, (int, float))

# Wrong:
isinstance(some, int) or isinstance(some, float)

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found separate `isinstance` calls that can be merged for: {0}'
code: ClassVar[int] = 511
previous_codes: ClassVar[Set[int]] = {474}
class WrongIsinstanceWithTupleViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid multiple isinstance calls with single-item tuples.

Reasoning:

There’s no need to use tuples with single elements. You can use single variables or tuples with multiple elements.

Solution:

Use tuples with multiple elements or a single varaible.

Example:

# Correct:
isinstance(some, (int, float))
isinstance(some, int)

# Wrong:
isinstance(some, (int, ))

See: https://docs.python.org/3/library/functions.html#isinstance

New in version 0.10.0.

Changed in version 0.11.0.

error_template: ClassVar[str] = 'Found `isinstance` call with a single element tuple'
code: ClassVar[int] = 512
previous_codes: ClassVar[Set[int]] = {475}
class ImplicitElifViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.TokenizeViolation

Forbid implicit elif conditions.

Reasoning:

Nested if in else cases are bad for readability because of the nesting level.

Solution:

Use elif on the same level.

Example:

# Correct:
if some:
    ...
elif other:
    ...

# Wrong:
if some:
    ...
else:
    if other:
        ...

New in version 0.12.0.

error_template: ClassVar[str] = 'Found implicit `elif` condition'
code: ClassVar[int] = 513
class ImplicitInConditionViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid multiple equality comparisons with the same variable.

Reasoning:

Using double+ equality compare with or or double+ non-equality compare with and indicates that you have implicit in or not in condition. It is just hidden from you.

Solution:

Refactor compares to use in or not in clauses.

Example:

# Correct:
print(some in {'first', 'second'})
print(some not in {'first', 'second'})

# Wrong:
print(some == 'first' or some == 'second')
print(some != 'first' and some != 'second')

New in version 0.10.0.

Changed in version 0.12.0.

code: ClassVar[int] = 514
error_template: ClassVar[str] = 'Found implicit `in` condition'
previous_codes: ClassVar[Set[int]] = {336}
class OpenWithoutContextManagerViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid open() without a context manager.

Reasoning:

When you open() something, you need to close it. When using a context manager - it is automatically done for you. When not using it - you might find yourself in a situation when file is not closed and is not accessable anymore.

Solution:

Refactor open() call to use with.

Example:

# Correct:
with open(filename) as file_obj:
    ...

# Wrong:
file_obj = open(filename)

New in version 0.12.0.

code: ClassVar[int] = 515
error_template: ClassVar[str] = 'Found `open()` used without a context manager'
class TypeCompareViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid comparing types with type() function.

Reasoning:

When you compare types with type() function call it means that you break polymorphism and dissallow child classes of a node to work here. That’s incorrect.

Solution:

Use isinstance to compare types.

Example:

# Correct:
print(something, type(something))

# Wrong:
if type(something) == int:
    ...

New in version 0.12.0.

code: ClassVar[int] = 516
error_template: ClassVar[str] = 'Found `type()` used to compare types'
class PointlessStarredViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid useless starred expressions.

Reasoning:

Using starred expression with constants is useless. This piece of code can be rewritten to be flat. Eg.: print(*[1, 2, 3]) is print(1, 2, 3).

Solution:

Refactor your code not to use starred expressions with list, dict, tuple, and set constants. Use regular argument passing instead.

Example:

# Correct:
my_list = [1, 2, 3, *other_iterable]

# Wrong:
print(*[1, 2, 3], **{{}})

New in version 0.12.0.

code: ClassVar[int] = 517
error_template: ClassVar[str] = 'Found pointless starred expression'
class ImplicitEnumerateViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit enumerate() calls.

Reasoning:

Using range(len(...)) is not pythonic. Python uses collection iterators, not index-based loops.

Solution:

Use enumerate(...) instead of range(len(...)).

Example:

# Correct:
for index, person in enumerate(people):
    ...

# Wrong:
for index in range(len(people)):
    ...

New in version 0.12.0.

code: ClassVar[int] = 518
error_template: ClassVar[str] = 'Found implicit `enumerate()` call'
class ImplicitSumViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit sum() calls.

When summing types different from numbers, you might need to provide the second argument to the sum function: sum([[1], [2], [3]], [])

You might also use str.join to join iterable of strings.

Reasoning:

Using for loops with += assign inside indicates that you iteratively sum things inside your collection. That’s what sum() builtin function does.

Solution:

Use sum(...) instead of a loop with += operation.

Example:

# Correct:
sum_result = sum(get_elements())

# Wrong:
sum_result = 0
for to_sum in get_elements():
    sum_result += to_sum

New in version 0.12.0.

code: ClassVar[int] = 519
error_template: ClassVar[str] = 'Found implicit `sum()` call'
class FalsyConstantCompareViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid comparing with explicit falsy constants.

We allow to compare with falsy numbers, strings, booleans, None. We disallow complex constants like tuple, dicts, and lists.

Reasoning:

When comparing something with explicit falsy constants what we really mean is not something.

Solution:

Use not with your variable. Fix your data types.

Example:

# Correct:
if not my_check:
    ...

if some_other is None:
    ...

if some_num == 0:
    ...

# Wrong:
if my_check == []:
    ...

New in version 0.12.0.

code: ClassVar[int] = 520
error_template: ClassVar[str] = 'Found compare with falsy constant'
class WrongIsCompareViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid comparing values with constants using is or is not.

However, we allow to compare with None and booleans.

Reasoning:

is compares might not do what you want them to do. Firstly, they check for the same object, not equality. Secondly, they behave unexpectedly even with the simple values like 257.

Solution:

Use == to compare with constants.

Example:

# Correct:
if my_check == [1, 2, 3]:
    ...

# Wrong:
if my_check is [1, 2, 3]:
    ...

New in version 0.12.0.

code: ClassVar[int] = 521
error_template: ClassVar[str] = 'Found wrong `is` compare'
class ImplicitPrimitiveViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit primitives in the form of lambda functions.

Reasoning:

When you use lambda that returns a primitive value and takes no arguments, it means that you should use a primitive type instead.

Solution:

Replace lambda with int, float, list, or any other primitive.

Example:

# Correct:
defaultdict(int)

# Wrong:
defaultdict(lambda: 0)

New in version 0.13.0.

code: ClassVar[int] = 522
error_template: ClassVar[str] = 'Found implicit primitive in a form of `lambda`'
class AlmostSwappedViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid unpythonic variable swaps.

We check for a = b; b = a sequences.

Reasoning:

This looks like a failed attempt to swap.

Solution:

Use standard way to swap two variables.

Example:

# Correct:
a, b = b, a

# Wrong:
a = b
b = a

temp = a
a = b
b = temp

New in version 0.13.0.

error_template: ClassVar[str] = 'Found incorrectly swapped variables'
code: ClassVar[int] = 523
class MisrefactoredAssignmentViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid misrefactored self assignment.

Reasoning:

Self assignment does not need to have the same operand on the left hand side and on the right hand side.

Solution:

Refactor you code to use multiple self assignments or fix your code.

Example:

# Correct:
test += 1
test *= 2

# Wrong:
test += test + 1

See MATH_APPROXIMATE_CONSTANTS for full list of math constants that we check for.

New in version 0.13.0.

error_template: ClassVar[str] = 'Found self assignment with refactored assignment'
code: ClassVar[int] = 524
class InCompareWithSingleItemContainerViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid comparisons where in is compared with single item container.

Reasoning:

in comparison with a container which contains only one item looks like overhead and unneeded complexity.

Solution:

Refactor your code to use == instead in.

Example:

# Correct:
a == 's'

# Wrong:
a in {'s'}

New in version 0.13.0.

error_template: ClassVar[str] = 'Found wrong `in` compare with single item container'
code: ClassVar[int] = 525
class ImplicitYieldFromViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid yield inside for loop instead of yield from.

Reasoning:

It is known that yield from is a semantically identical to a for loop with a yield inside. But, it is way more readable.

Solution:

Use yield from some iterable directly instead iterating over it inside a loop and yield it one by one.

Example:

# Correct:
yield from some()

yield from (
    value[index:index + chunk_size]
    for index in range(0, len(value), chunk_size)
)

# Wrong:
for index in chunk:
    yield index

New in version 0.13.0.

error_template: ClassVar[str] = 'Found implicit `yield from` usage'
code: ClassVar[int] = 526
class NotATupleArgumentViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Require tuples as arguments for certain functions.

Reasoning:

For some functions, it is better to use tuples instead of another iterable types (list, sets,…) as arguments.

Solution:

Use tuples as arguments.

Example:

# Correct:
a = frozenset((2,))

# Wrong:
a = frozenset([2])

See TUPLE_ARGUMENTS_METHODS for full list of methods that we check for.

New in version 0.13.0.

error_template: ClassVar[str] = 'Found not a tuple used as an argument'
code: ClassVar[int] = 527
class ImplicitItemsIteratorViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit .items() iterator.

Reasoning:

When iterating over collection it is easy to forget to use .items() when you need to access both keys and values. So, when you access the iterable with the key inside a for loop, that’s a sign to refactor your code.

Solution:

Use .items() with direct keys and values when you need them.

Example:

# Correct:
for some_key, some_value in collection.items():
    print(some_key, some_value)

# Wrong:
for some_key in collection:
    print(some_key, collection[some_key])

New in version 0.13.0.

error_template: ClassVar[str] = 'Found implicit `.items()` usage'
code: ClassVar[int] = 528
class ImplicitDictGetViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit .get() dict method.

Reasoning:

When using in with a dict key it is hard to keep the code clean. It is more convinient to use .get() and check for None later.

Solution:

Use .get() with the key you need. Check for None in case you need it, or just act with the default value of the same type.

Example:

# Correct:
value = collection.get(key)
if value is not None:
    print(value)

# Wrong:
if key in collection:
    print(collection[key])

New in version 0.13.0.

error_template: ClassVar[str] = 'Found implicit `.get()` dict usage'
code: ClassVar[int] = 529
class ImplicitNegativeIndexViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid implicit negative indexes.

Reasoning:

There’s no need in getting the length of an iterable and then having a negative offset, when you can specify negative indexes in the first place.

Solution:

Use negative indexes.

Example:

# Correct:
some_list[-1]

# Wrong:
some_list[len(some_list) - 1]

New in version 0.13.0.

error_template: ClassVar[str] = 'Found implicit negative index'
code: ClassVar[int] = 530
class SimplifiableReturningIfViolation(node, text=None, baseline=None)[source]

Bases: wemake_python_styleguide.violations.base.ASTViolation

Forbid if statements that simply return booleans in functions or methods.

Reasoning:

There is no need to test a condition and simply return a boolean depending on its outcome if there is not going to be any additional code.

Solution:

Instead of testing the condition and returning a boolean, return the condition itself. This applies to early returning ifs too.

Example:

# Correct:
def some_function():
    return some_condition

# Wrong:
def some_function():
    if some_condition:
        return True
    else:
        return False

New in version 0.15.0.

error_template: ClassVar[str] = 'Found simplifiable returning `if` condition in a function'
code: ClassVar[int] = 531