Skip to content

var-annotated error with imported BaseModel, related to namespace module #658

@blueyed

Description

@blueyed

As a followup to #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?):

def is_model_subclass_info(info: TypeInfo, django_context: "DjangoContext") -> bool:
return info.fullname in django_context.all_registered_model_class_fullnames or info.has_base(
fullnames.MODEL_CLASS_FULLNAME
)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions