Description
This evening I decided to try out mypy on a large existing Django codebase. Hundreds of .py files.
Surprisingly, I found no actual tutorial on the documentation on how to use mypy on a large existing project as opposed to single file. Therefore I will enumerate a number of issues that I have encountered so far. Perhaps such an enumeration will be useful in writing new documentation, fixing issues, or other improvements.
- No documented way to run mypy on anything except single files.
I tried invoking mypy on a directory rather than a single .py file. This appears to work, however the documentation does not appear to mention this usage as a possiblity.
error: Cannot find module named 'FOO.BAR.BAZ'
I receive the following error when there certainly exists a file ./FOO/BAR/BAZ.py
. Therefore this error makes no sense to me. I invoked mypy with MYPYPATH=. mypy .
.
error: Need type annotation for variable
Why? This points to a line that looks like dependencies = []
. Error message should be improved to indicate why it is demanding a type annotation.
error: Method must have at least one argument
Well done. This was flagging a number of unittest methods marked with @skip
that took no arguments. Such as the following:
class BeaconBasicTests(SimpleTestCase):
@skip('not yet automated')
def test_given_beacons_exist_when_page_reloaded_then_beacons_still_exist():
pass
It was expecting (self)
as the signature, which seems reasonable.
error: Result type of + incompatible in assignment
Appears to be a mypy bug. Was complaining about the following construction:
INSTALLED_APPS = (
'django.contrib.admin',
...
)
if USE_DEBUG_TOOLBAR:
INSTALLED_APPS += ('debug_toolbar',) # error here
error: Value of type "object" is not indexable
Appears to be a mypy bug. Was complaining about the following construction:
LESSON_OBJECT_TYPES = {
'warm_up': dict(
title='Warm Up',
...=...,
),
...
)
x = LESSON_OBJECT_TYPES['teacher_coding_exercise']['expected_file_types'] # error here
error: Callable[[Any, Any, Any], Any] has no attribute "short_description"
Appears to be a mypy bug. Was complaining about the following construction:
def upload_deck(modeladmin, request, queryset):
...
upload_deck.short_description = 'Upload slides to selected deck' # error here
It is legal (albeit advanced) to annotate a function object (including a lambda) with additional attributes.
error: Name 'Foo' already defined
Common to receive this kind of error when using star-imports. For example:
=== A.py
from B import *
import C
=== B.py
import C
In the above scenario mypy will complain that C is already defined in A.
Recommend altering there to be an error only if Foo is defined more than once and is defined to be something different.
That's all folks. I suppose I'll wait to add my own type annotations until mypy gives my current unannotated code a clean bill of health.