|
|
|
|
|
by aleksanb
978 days ago
|
|
It's quite useful on ci, and as a `make mypy` can run before pushing up your code, but for interactive errors we all use pyright, which is a bit of a letdown because you don't get autocomplete for fields and models accessed through reverse relation managers etc, pyright doesn't know about them. Many packages ship types nowadays, so the type coverage isn't too bad for us right now. Here's our plugin setup in mypy.ini in case this helps (Django 4.2 + drf 3.14) [mypy]
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
ignore_missing_imports = True
follow_imports = silent
no_implicit_optional = True
warn_unused_ignores = True
check_untyped_defs = True
disallow_untyped_defs = True
disallow_untyped_calls = True
warn_unreachable = True
strict_equality = True
allow_redefinition = True
show_error_codes = True
mypy_path = stubs
[mypy.plugins.django-stubs]
django_settings_module = 'mycompany.settings'
with packages: mypy==1.6.0
django-stubs==4.2.4
django-stubs-ext==4.2.2
djangorestframework-stubs==3.14.3
with this horror of a regex in make (because you'll get drowned in wrong type errors in all of the untype files, and errors get shown from imports even if you don't care about that imported file), add more file targets as necessary: FILES_TO_MYPY = $(shell ls mycompany/\*/validators.py mycompany/\*/services.py mycompany/\*/selectors.py mycompany/\*/managers.py | sort | uniq)
# 1)We have to grep out django-manager-missing like this until the following bug
# is fixed: https://github.com/python/mypy/issues/12987.
# 2) We grep out the line of `Found 95 errors in 16 files (checked 83 source
# files)` that now appears as we use follow-imports: silent, because there's a
# bug where errors from imported modules are counted against the total even
# though they aren't emitted. If any real errors appear we get them as a
# separate line anyways.
.PHONY: mypy
mypy:
@{ MYPY_FORCE_COLOR=${NOT_CI} $(VENV)/bin/mypy --config-file mypy.ini $(FILES_TO_MYPY) 2>&3 | grep -v 'django-manager-missing\|errors in'; } 3>&1 | tee $(HYRE_TESTS_OUTPUT_PATH)/mypy.stdout.txt
This allows you to get proper errors for things like model = MyModel.objects.get()
othermodel = model.othermodel_set.first()
reveal_type(othermodel) # correctly revealed to note: Revealed type is "Union[mycompany.importpath.models.OtherModel None]"
and even errors on typos like model = MyModel.objects.get()
othermodel = model.ooooothermodel_set.first() # revealed as MyModel has no attribute ooooothermodel_set, perhaps you ment othermodel_set
.
|
|