31 new autofixes added in the Python analyzer

PTC-W0041: Not using the min built-in

Fixes this code:

if value >= 10:
    value = 10

to this:

value = min(value, 10)

PTC-W0042: Not using the max built-in:

Fixes this code:

if value <= 10:
    value = 10

to this:

value = max(value, 10)

PYL-W0711: Exception to catch is the result of a binary operation

Fixes this code:

try:
    something()
except Exc1 or Exc2:
    print("caught!")

to this:

try:
    something()
except (Exc1, Exc2):
    print("caught!")

PYL-R1701: Consider merging isinstance calls

Changes this:

if isinstance(i, int) or isinstance(i, float):
    print('A number')

to this:

if isinstance(i, (int, float)):
    print('A number')

FLK-W601: Use of deprecated has_key

Changes this:

if my_dict.has_key("my key"):
   # do something
   ...

to this:

if "my key" in my_dict:
   # do something
   ...

FLK-E401: Multiple imports on a line

Changes this:

import os, sys

to this:

import os
import sys

PYL-E0211: Method has no argument

This issue complaints of method which should have the bound instance as the first argument has no argument defined.

The fixer will detect if it is a classmethod or a regular method and add the required argument.
So, this:

class Cls:
    def some_method():
        ...

    @classmethod
    def something():
        ...

Will be changed to:

class Cls:
    def some_method(self):
        ...

    @classmethod
    def something(cls):
        ...

PTC-W0039: Unnecessary None provided as default

It is unnecessary to provide None as the default value when the key is not present in the dictionary as get implicitly returns None.

So, the fixer will change this:

value = some_dict.get("key", None)

to this:

value = some_dict.get("key")

PYL-C0414: Import alias same as the original package name

Import alias is the same as the original package name, thus making the alias unnecessary.

So, this:

import my_package as my_package

Will be automatically fixed to:

import my_package

PYL-W0107: Unnecessary pass statement

Changes this:

class Docstring:
    '''This is a dummy class with docstring.'''
    pass

to this:

class Docstring:
    '''This is a dummy class with docstring.'''

PYL-R1707: Trailing comma tuple

Changes this:

fruits = apple,

to this:

fruits = (apple,)

PYL-R1703: if statement can be simplified

Changes this:

def simplifiable_if(arg, arg2):
    if arg and not arg2:
        var = True
    else:
        var = False

    return var

to this:

def simplifiable_if(arg, arg2):
    var = bool(arg and not arg2)

    return var

PYL-R1719: if expression can be simplified

value = True if arg else False

will be simplified into:

value = bool(arg)

PYL-R1706: consider using if expression

This fixer will replace the use of pre-Python 2.5 ternary syntax with an if expression.
So, the following code:

def get_val(condition, fallback, on_truth=None):
    if on_truth is None:
        on_truth = []

    return condition and on_truth or fallback

will be refactored as:

def get_val(condition, fallback, on_truth=None):
    if on_truth is None:
        on_truth = []

    return on_truth if condition else fallback

PYL-R1712: Use tuple unpacking to swap variables

The following code:

temp = a
a = b
b = temp

will be refactored as:

a, b = b, a

PYL-E0113: Invalid star assignment target

Changes this:

*var = [1, 2, 3, 4]

to this:

(*var, ) = [1, 2, 3, 4]

PYL-R0205: Useless inheritance from object

Changes this:

class Foo(object):
    """Foo bar baz"""

to this:

class Foo:
    """Foo bar baz"""

PYL-W0235: Useless super delegation

Any method in a child class which is only calling the overridden method of any of its base class using super and doing nothing else is unnecessary.

So, this:

class Egg:
    def __init__(self, first, second):
        pass


class Spam(Egg):
    def __init__(self, first, second):
        super().__init__(first, second)

will be refactored as:

class Egg:
    def __init__(self, first, second):
        pass


class Spam(Egg):
    ...

PYL-R1705: Unnecessary else / elif used after return

Changes this:

def classify_number(x):
    if x % 2 == 0:
        return 'Even'
    else:
        return 'Odd'


def what_is_this_number(x):
    if x % 2 == 0 and x >= 0:
        return 'Even'
    elif x % 2 == 0 and x < 0:
        return 'Even and Negative'
    elif x % 2 != 0 and x < 0:
        return 'Odd and Negative.'
    else:
        return 'Odd'

to this:

def classify_number(x):
    if x % 2 == 0:
        return 'Even'
    return 'Odd'


def what_is_this_number(x):
    if x % 2 == 0 and x >= 0:
        return 'Even'

    if x % 2 == 0 and x < 0:
        return 'Even and Negative'

    if x % 2 != 0 and x < 0:
        return 'Odd and Negative'

    return 'Odd'

PYL-R1724: Unnecessary elif / else block after continue

Refactors this:

def classify_number(x):
    for num in range(x):
        if x % 2 == 0:
            continue
        else:
            print(f"{num} is Odd}")

as this:

def classify_number(x):
    for num in range(x):
        if x % 2 == 0:
            continue
        print(f"{num} is Odd}")

PYL-R1723: Unnecessary else / elif used after break

Refactors this:

def changing_denominators(p, q):
    while True:
        if q == 0:
            break
        else:
            print(p/q)
            q = q - 1

To this:

def changing_denominators(p, q):
    while True:
        if q == 0:
            break
        print(p/q)
        q = q - 1

PYL-R1720: Unnecessary else/elif used after raise

Refactors this:

def check_magic_generator(attribute):

    magic = get_magic_number(attribute)

    if magic < 0:
        raise ValueError(f"{attribute} looks invalid")
    elif magic > 100
        raise ValueError(f"{attribute} is very magical")
    else:
        return magic

To this:

def check_magic_generator(attribute):

    magic = get_magic_number(attribute)

    if magic < 0:
        raise ValueError(f"{attribute} looks invalid")
    if magic > 100
        raise ValueError(f"{attribute} is very magical")

    return magic

PYL-W0126: Missing parentheses for call in the test

Changes this:

def bool_function():
    return True

def nonbool_function():
    return 42

if bool_function:
    pass

if nonbool_function:
    pass

To this:

def bool_function():
    return True

def nonbool_function():
    return 42

if bool_function():
    pass

if nonbool_function():
    pass

PYL-W0705: Catching previously caught exception

Changes this:

try:
    1 / 0
except ZeroDivisionError:
    print("Divided by zero")
except (OSError, ZeroDivisionError):
    print("Handles an exception which was caught before.")

To this:

try:
    1 / 0
except ZeroDivisionError:
    print("Divided by zero")
except OSError:
    print("Handles a unique exception")

PYL-E0237: Assigning to an attribute not defined in class slots

During autofix, DeepSource will add the missing names in slots
So, this:

class E:
    __slots__ = "foo"

    def __init__(self):
        self.not_foo = "Not foo"
        self.not_bar = "Not Bar"

Will be changed to:

class E:
    __slots__ = ["foo", "not_foo", "not_bar"]

    def __init__(self):
        self.not_foo = "Not foo"
        self.not_bar = "Not Bar"

PYL-W1403: Implicit string concatenation

The autofix will add the missing comma in the sequence.
So, this:

sample_seq = ['A', 'B' 'C', 'D']

will be changed to:

sample_seq = ['A', 'B', 'C', 'D']

PYL-W0108: Unnecessary lambda expression

During autofix, the lambda function is removed and the callable is assigned directly to the variable to avoid any breakage.

PYL-E0238: Invalid __slots__ object

During autofix, DeepSource will replace the invalid object with []
So, this:

class Bad:
    __slots__ = list

will be changed to:

class Bad:
    __slots__ = []

PYL-W0404: Multiple imports for an import name

import os
from os import path
from sys import path
import os

will be refactored as:

import os
from os import path

PYL-W1507: Shallow copy of os.environ

os.environ is not a dict but proxy object.
The use of copy.copy(os.environ) will make a shallow copy of os.environ therefore, any changes made in the copy would be reflected in os.environ as well.

During the autofix, DeepSource will replace copy.copy(os.environ) with os.environ.copy() calls.

PYL-E0241: Class has duplicate bases

DeepSource will remove the duplicate bases during the autofix.
i.e.,

class SomeClass(SomeBase, Unique, SomeBase):
    ...

will be refactored to:

class SomeClass(SomeBase, Unique):
    ...
1 Like