django-stubs
django-stubs copied to clipboard
Related Manager lose typing
Bug report
Hi, not sure if this is a bug or my having wrong declarations.
What's wrong
The typing of related_manager.all is off when I share a QuerySet between multiple models :
- case: related
main: |
from myapp.models import MyModel
reveal_type(MyModel.objects.all()) # N: Revealed type is "myapp.models.MyQuerySet[myapp.models.MyModel]"
reveal_type(list(MyModel.objects.all())[0]) # N: Revealed type is "myapp.models.MyModel"
for x in MyModel.objects.all():
reveal_type(x) # N: Revealed type is "myapp.models.MyModel"
reveal_type(x.relatedobject_set.all()) # N: Revealed type is "myapp.models.MyQuerySet[myapp.models.RelatedObject]"
reveal_type(list(x.relatedobject_set.all())[0]) # N: Revealed type is "myapp.models.RelatedObject"
for y in x.relatedobject_set.all():
reveal_type(y) # N: Revealed type is "myapp.models.RelatedObject"
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
from django.db.models.manager import BaseManager
from typing import List, Dict
from typing_extensions import Self
from typing import TypeVar, Generic
T = TypeVar("T", bound=models.Model)
class MyQuerySet(models.QuerySet[T], Generic[T]): ...
class MyModel(models.Model):
objects = MyQuerySet.as_manager()
class RelatedObject(models.Model):
objects = MyQuerySet.as_manager()
parent = models.ForeignKey(MyModel, models.PROTECT)
E Actual:
E ...
E main:6: note: Revealed type is "myapp.models.MyQuerySet" (diff)
E main:7: note: Revealed type is "T`1" (diff)
E main:9: note: Revealed type is "T`1" (diff)
E myapp/models:15: error: Need type annotation for "objects" [var-annotated] (diff)
E myapp/models:20: error: Need type annotation for "objects" [var-annotated] (diff)
E Expected:
E ...
E main:6: note: Revealed type is "myapp.models.MyQuerySet[myapp.models.RelatedObject]" (diff)
E main:7: note: Revealed type is "myapp.models.RelatedObject" (diff)
E main:9: note: Revealed type is "myapp.models.RelatedObject" (diff)
- case: related_subclassing
main: |
from myapp.models import MyModel
reveal_type(MyModel.objects.all()) # N: Revealed type is "myapp.models.BaseQuerySet[myapp.models.MyModel]"
reveal_type(list(MyModel.objects.all())[0]) # N: Revealed type is "myapp.models.MyModel"
for x in MyModel.objects.all():
reveal_type(x) # N: Revealed type is "myapp.models.MyModel"
reveal_type(x.relatedobject_set.all()) # N: Revealed type is "myapp.models.BaseQuerySet[myapp.models.RelatedObject]"
reveal_type(list(x.relatedobject_set.all())[0]) # N: Revealed type is "myapp.models.RelatedObject"
for y in x.relatedobject_set.all():
reveal_type(y) # N: Revealed type is "myapp.models.RelatedObject"
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
from django.db.models.manager import BaseManager
from typing import List, Dict
from typing_extensions import Self
from typing import TypeVar, Generic
T = TypeVar("T", bound=models.Model)
class BaseQuerySet(models.QuerySet[T], Generic[T]): ...
class BaseModel(models.Model):
objects = BaseQuerySet.as_manager()
class Meta:
abstract = True
class MyModel(BaseModel):
pass
class RelatedObjectQuerySet(BaseQuerySet["RelatedObject"]):
pass
class RelatedObject(BaseModel):
parent = models.ForeignKey(MyModel, models.PROTECT)
E Actual:
E ...
E main:6: note: Revealed type is "myapp.models.BaseQuerySet" (diff)
E main:7: note: Revealed type is "T`1" (diff)
E main:9: note: Revealed type is "T`1" (diff)
E myapp/models:13: error: Need type annotation for "objects" [var-annotated] (diff)
E Expected:
E ...
E main:6: note: Revealed type is "myapp.models.BaseQuerySet[myapp.models.RelatedObject]" (diff)
E main:7: note: Revealed type is "myapp.models.RelatedObject" (diff)
E main:9: note: Revealed type is "myapp.models.RelatedObject" (diff)
How is that should be
The types should be MyModel
or RelatedObject
instead of T
.
Note: If I remove the Generic I get Any
instead of T
.
System information
- OS: osx
-
python
version: 3.11.3 -
django
version: Django==4.2.9 -
mypy
version: mypy==1.7.1 -
django-stubs
version: django-stubs==4.2.7 -
django-stubs-ext
version: django-stubs-ext==4.2.7