django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

[5.0.3 regression] `GenericRelation` has no attribute

Open andersk opened this issue 6 months ago • 2 comments

In 5.0.3, the value of a GenericRelation field is given the useless type _ST (an unbound type variable), and trying to do anything with it gives errors like error: "_ST" has no attribute "all" [attr-defined].

This was introduced with b2b1afac196e622ec725248cad1c22a6557253d0 (#2261, cc @rafonseca).

https://github.com/typeddjango/django-stubs/blob/d60e31ed0ac4e4115f9ef20041521c201391d592/django-stubs/contrib/contenttypes/fields.pyi#L69

ForeignObject is generic and requires generic arguments. Without these generic arguments, it was previously interpreted as ForeignObject[Any, Any] but now it’s interpreted as the invalid ForeignObject[Any, _ST].

https://github.com/typeddjango/django-stubs/blob/d60e31ed0ac4e4115f9ef20041521c201391d592/django-stubs/db/models/fields/related.pyi#L29-L34

Complete test case

pyproject.toml

[tool.django-stubs]
django_settings_module = "my_settings"

[tool.mypy]
plugins = ["mypy_django_plugin.main"]

my_settings.py

INSTALLED_APPS = ["django.contrib.contenttypes", "my_app"]

my_app/__init__.py

# empty

my_app/models.py

from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models

class TaggedItem(models.Model):
    tag = models.SlugField()
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

class Bookmark(models.Model):
    url = models.URLField()
    tags = GenericRelation(TaggedItem)

def test(b: Bookmark) -> None:
    b.tags.all()  # error: "_ST" has no attribute "all"  [attr-defined]
$ mypy .
my_app/models.py:16: error: "_ST" has no attribute "all"  [attr-defined]
Found 1 error in 1 file (checked 3 source files)

andersk avatar Jul 31 '24 20:07 andersk