django-stubs
django-stubs copied to clipboard
var-annotated error with imported BaseModel, related to namespace module
As a followup to https://github.com/typeddjango/django-stubs/issues/68 I've noticed that it would not work with:
from django.db import models
from ...base.models import BaseModelMixin
# class BaseModelMixin(models.Model):
# class Meta:
# abstract = True
class TestModel(BaseModelMixin):
foo = models.CharField(max_length=123)
error: Need type annotation for "foo" [var-annotated]
The imported model is the same as the commented one.
If not importing it, but defining it there (uncommenting it), it works:
from django.db import models
# from ...base.models import BaseModelMixin
class BaseModelMixin(models.Model):
class Meta:
abstract = True
class TestModel(BaseModelMixin):
foo = models.CharField(max_length=123)
Note that it also fails when overwriting the import:
from django.db import models
# from ...base.models import BaseModelMixin
class BaseModelMixin(models.Model):
class Meta:
abstract = True
class TestModel(BaseModelMixin):
foo = models.CharField(max_length=123)
…/models.py:5: error: Name "BaseModelMixin" already defined (possibly by an import) [no-redef]
…/models.py:11: error: Need type annotation for "foo" [var-annotated]
I've not investigated much yet, but it appears to be caused by the models fullname not containing the first part of the (namespaced) module name: app.models.TestModel
vs project.app.models.TestModel
(via django_context.all_registered_model_class_fullnames
)..!
This results in the is_model_subclass_info
check only working if it is defined in the same file (via info.has_base
check - shouldn't that work better maybe in general?): https://github.com/typeddjango/django-stubs/blob/cf6952c9df385a699dd63054b6753eb924b0c68c/mypy_django_plugin/lib/helpers.py#L304-L307
Note that the namespace ("project") is added/used via AppConfig
:
class MyAppConfig(AppConfig):
name = "project.app"
project/__init__.py
does not exist, but creating it and/or changing ProductConfig.name
to not include the namespace changes the behavior.
System information
- OS: Arch Linux
-
python
version: 3.9.5 -
django
version: 4.0.dev20210602105309 -
mypy
version: 0.910 -
django-stubs
version: 1.8.0 -
django-stubs-ext
version: 0.2.0
@blueyed thanks for the report! Do you have a solution in mind? I would love to merge a fix for this.
Any updates on this one?
Any updates?
Monkey-patching as following seems to be fixing the issue:
import mypy_django_plugin.lib.helpers
from mypy_django_plugin.lib.helpers import is_model_subclass_info as patch
PREFIX = "project." # name of your namespace module
def is_model_subclass_info(info, django_context):
if info.fullname.startswith(PREFIX):
name = info.fullname[len(PREFIX) :] # use removeprefix if py>=39
if name in django_context.all_registered_model_class_fullnames:
return True
return patch(info, django_context)
mypy_django_plugin.lib.helpers.is_model_subclass_info = is_model_subclass_info
running mypy like so:
mypy -p project
@sobolevn I'm guessing we need to prefix namespace modules in all_registered_model_class_fullnames
property? I'm not sure if how would we fetch that information in that context.