Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type Annotation Errors in Models Inheriting from 3rd Party Packages #2341

Open
Dresdn opened this issue Aug 15, 2024 · 6 comments · May be fixed by #2440
Open

Type Annotation Errors in Models Inheriting from 3rd Party Packages #2341

Dresdn opened this issue Aug 15, 2024 · 6 comments · May be fixed by #2440
Labels
3rd party Presence of a third party dependency has been mentioned bug Something isn't working

Comments

@Dresdn
Copy link

Dresdn commented Aug 15, 2024

Bug report

What's wrong

With the latest django-stubs v5.0.4, I've noticed strange behavior when using models that inherit from 3rd party packages. Specifically, mypy throws a "Need type annotation for <field_name>" error on model fields.

Here’s the scenario:

  • I created a new project using django-cookiecutter.
  • I added mypy v1.11.1, django-stubs v5.0.4, and tested with Django 4.2.11 and 5.0.8.
  • I have the following model classes:
class FooBase(models.Model):
    name = models.CharField(max_length=255)

    class Meta:
        abstract = True

class Bar(FooBase):
    updated_at = models.DateTimeField(auto_now=True)
  • When both classes are defined in local_app/models.py, there are no errors.
  • However, if I move the FooBase class to a 3rd party package’s models.py (e.g., site-packages/django_extensions/models.py since that came with the cookiecutter install), I get a mypy error on the updated_at field of Bar.

This issue only started occurring with django-stubs v5.0.3 or v5.0.4 and mypy v1.11.0 or v1.11.1. It was working correctly with the previous versions (django-stubs v5.0.2 and mypy v1.10.1).

I am aware of issue #2011, which has been closed. However, the difference here is that the code was working fine with the prior django-stubs and mypy versions, but the error occurs after updating to the latest versions.

How is that should be

Type checking should pass without errors when using models that inherit from 3rd party packages, just as it did with previous versions of django-stubs and mypy.

System information

  • OS: yes
  • python version: 3.11.9
  • django version: 5.0.8 & 4.2.11
  • mypy version: 1.11.1
  • django-stubs version: 5.0.4
  • django-stubs-ext version: 5.0.4

mypy Settings

[tool.mypy]
python_version = "3.11"
check_untyped_defs = true
ignore_missing_imports = true
warn_unused_ignores = true
warn_redundant_casts = true
warn_unused_configs = true
plugins = [
    "mypy_django_plugin.main",
]
@Dresdn Dresdn added the bug Something isn't working label Aug 15, 2024
@Dresdn
Copy link
Author

Dresdn commented Aug 16, 2024

One other fun tidbit of information: not all fields throw an error.

models.FileField(), models.ImageField(), and models.JSONField() don't throw a type error. As far as I can tell, all the others do (IntegerField(), TextField(), etc.)

@YPCrumble
Copy link
Contributor

I believe I'm getting the same issue - it asks for var-annotated on nearly every field in a model that inherits from django extensions' TimeStampedModel, for instance. I believe it was introduced in django-stubs 5.0.3.

@ivan-klass
Copy link

I get similar issue with related managers - many of them are not resolved with update to 5.0.4, but a couple of them could be fixed if a model inherited from TimeStampedModel using workaround described here.

#1354 seems relevant.

@Alexerson
Copy link
Contributor

It tried to do a bisect and it seems the issue was maybe introduced in ac36393.

@flaeppe flaeppe added the 3rd party Presence of a third party dependency has been mentioned label Sep 26, 2024
@elnygren
Copy link

Getting this with:

mypy==1.13.0
django-stubs==5.1.1
django-extensions==3.2.3

@realsuayip
Copy link
Contributor

Here is a monkeypatch workaround:

import mypy_django_plugin.lib.helpers
from mypy_django_plugin.lib.helpers import is_model_type as patch

allowlist = {
    "dotted.path.to.your.ModelClass",
}


def is_model_type(info):
    if info.fullname in allowlist:
        return True
    return patch(info)


mypy_django_plugin.lib.helpers.is_model_type = is_model_type

It seems that for models inherited from 3rd party apps, info.metaclass_type is None for some reason rather than being model metaclass.

@Niicck Niicck linked a pull request Nov 10, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3rd party Presence of a third party dependency has been mentioned bug Something isn't working
Development

Successfully merging a pull request may close this issue.

7 participants