Python bug detection

Code Review Doctor suggests fixes if your code appears to introduce a bug, or if it looks like the code is not doing what your intended.

This gives you another line of defense against human error because if one human can commit a bug then another human certainly can miss it during code review.

Money
code-review-doctorbotsuggested changes just now
async.py
1
+
async def task():
2
+
    download_files()

Calling a coroutine without the await statement just returns the coroutine without actually running the function.

Read more
Suggested changes
-
    download_files()
+
    await download_files()
Expand 3 lines ...
Commit suggestion
3
+
	
4
+
async def download_files():
5
+
    pass
models.py
1
+
class FooBarClass:
2
+
    @classmethod
3
+
    def from_dict(self):

Class methods should take cls as the first argument.

Read more
Suggested changes
-
    def from_dict(self):
+
    def from_dict(cls):
Commit suggestion
4
+
        pass
mail.py
1
+
if value is 1:

Primitive data types such as strings and integers should be compared using == and != rather than is and is not.

Read more
Suggested changes
-
if value is 1:
+
if value == 1:
Commit suggestion
2
+
    pass
helpers.py
1
+
if value == False:

Singleton data types such as booleans should be compared using is and is not rather than == and !=.

Read more
Suggested changes
-
if value == False:
+
if value is False:
Commit suggestion
2
+
    pass
models.py
1
+
from dataclasses import dataclass
2
+
	
3
+
@dataclass

Use frozen=True to make the dataclasses immutable and hashable.

Read more
Suggested changes
-
@dataclass
+
@dataclass(frozen=True)
Expand 2 lines ...
Commit suggestion
4
+
class FooBarClass:
5
+
    pass
validation.py
1
+
values = (
2
+
    'yes',
3
+
    'correct'

Missing commas in tuples results in implicit string concatenation. Probably not what you intended to do.

Read more
Suggested changes
-
    'correct'
+
    'correct',
Expand 2 lines ...
Commit suggestion
4
+
    'agreed',
5
+
)
helpers.py
1
+
if value == 1 and False:
2
+
    foo_bar()

This code will always evaluate the same value regardless of the inputs.

Read more
helpers.py
1
+
try:
2
+
    foo()
3
+
except ValueError or TypeError:

Catch multiple exception types using a tuple, not with or operator.

Read more
Suggested changes
-
except ValueError or TypeError:
+
except (ValueError, TypeError):
Commit suggestion
4
+
    pass
views.py
1
+
class HomeView(View):
2
+
    def get(self, request):
3
+
        import pdb; pdb.set_trace()

Don't commit breakpoints. This will pause execution in prod and break the app.

Read more
Suggested changes
-
        import pdb; pdb.set_trace()
Commit suggestion
4
+
        ...
settings.py
1
+
REST_FRAMEWORK = {
2
+
    'DEFAULT_PERMISSION_CLASSES': (
3
+
        'rest_framework.permissions.IsAuthenticated'

A tuple with only one element must end with a comma. Python won't know it's a tuple without the comma. Probably not what you intended to do.

Read more
Suggested changes
-
        'rest_framework.permissions.IsAuthenticated'
+
        'rest_framework.permissions.IsAuthenticated',
Expand 2 lines ...
Commit suggestion
4
+
    )
5
+
}
utils.py
1
+
title = 'Hello world',

A comma after a value turns it into tuple. Probably not what you intended to do.

Read more
Suggested changes
-
title = 'Hello world',
+
title = 'Hello world'
Commit suggestion
catalogue.py
1
+
content = open('some/path.txt').read()

Leaving files open degrades application performance and increases the risk of unexpected side effects. Using open as a context manager will close it automatically for you.

Read more
Suggested changes
-
content = open('some/path.txt').read()
+
with open('some/path.txt') as f:
+
    content = f.read()
Commit suggestion
catalogue.py
1
+
with open('some/path.txt') as f:

Read and write calls will fail at runtime if open is called with incorrect modes.

Read more
Suggested changes
-
with open('some/path.txt') as f:
+
with open('some/path.txt', 'w') as f:
Commit suggestion
2
+
    content = f.write('foo')
catalogue.py
1
+
with open('some/path.txt') as f:
2
+
    line_one = f.readline()
3
+
4
+
line_two = f.readline()

Accidentally trying to read or write files that are closed will cause a ValueError at runtime.

Read more
catalogue.py
1
+
with open('some/path.txt') as f:

Not specifying encoding when reading a file can cause UnicodeDecodeError because Python assumes the file is encoded with the OS's default text encoding, but that's often an invalid assumption.

Read more
Suggested changes
-
with open('some/path.txt') as f:
+
with open('some/path.txt', encoding='utf_8') as f:
Commit suggestion
2
+
    line_one = f.read()
catalogue.py
1
+
with open('some/path.txt', 'w') as f:

Not specifying encoding when writing a file can cause UnicodeEncodeError because Python assumes the string's characters can fit in the OS's default text encoding, but that's often an invalid assumption.

Read more
Suggested changes
-
with open('some/path.txt', 'w') as f:
+
with open('some/path.txt', 'w', encoding='utf-8') as f:
Commit suggestion
2
+
    f.write('foo')
catalogue.py
1
+
with open('sample-chinese.txt', encoding='utf_8') as f:

Specifying incorrect encoding when reading a file can cause UnicodeDecodeError if the contents of the file is incompatible with the specified encoding.

Read more
Suggested changes
-
with open('sample-chinese.txt', encoding='utf_8') as f:
+
with open('sample-chinese.txt', encoding='big5') as f:
Commit suggestion
2
+
    content = f.read()
settings.py
1
+
raise ValidationError('{value} is not allowed')

An f-string will not work if the f prefix is missing.

Read more
Suggested changes
-
raise ValidationError('{value} is not allowed')
+
raise ValidationError(f'{value} is not allowed')
Commit suggestion
Update settings.py

Are you ready to improve your team agility through lower tech debt? Add Code Review Doctor to GitHub.