Skip to content

Commit 3830fa9

Browse files
authored
fix handling of explicit objects annotation (#2241)
* fix handling of explicit `objects` annotation * adjust test
1 parent f3d9703 commit 3830fa9

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

mypy_django_plugin/transformers/querysets.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,14 @@ def determine_proper_manager_type(ctx: FunctionContext) -> MypyType:
3333
assert isinstance(default_return_type, Instance)
3434

3535
outer_model_info = helpers.get_typechecker_api(ctx).scope.active_class()
36-
if outer_model_info is None or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
36+
if (
37+
outer_model_info is None
38+
or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME)
39+
or outer_model_info.self_type is None
40+
):
3741
return default_return_type
3842

39-
return helpers.reparametrize_instance(default_return_type, [Instance(outer_model_info, [])])
43+
return helpers.reparametrize_instance(default_return_type, [outer_model_info.self_type])
4044

4145

4246
def get_field_type_from_lookup(

tests/typecheck/managers/querysets/test_from_queryset.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,31 @@
4343
class MyModelWithoutSelf(models.Model):
4444
objects = ManagerWithoutSelf()
4545
46+
- case: from_queryset_model_inheritance
47+
main: |
48+
from myapp.models import Base, Sub
49+
reveal_type(Base.objects) # N: Revealed type is "myapp.models.MyManager[myapp.models.Base]"
50+
reveal_type(Sub.objects) # N: Revealed type is "myapp.models.MyManager[myapp.models.Sub]"
51+
installed_apps:
52+
- myapp
53+
files:
54+
- path: myapp/__init__.py
55+
- path: myapp/models.py
56+
content: |
57+
from typing import ClassVar
58+
from typing_extensions import Self
59+
from django.db.models import Model
60+
from django.db.models.manager import BaseManager
61+
from django.db.models.query import QuerySet
62+
63+
MyManager = BaseManager.from_queryset(QuerySet, "MyManager")
64+
65+
class Base(Model):
66+
objects: ClassVar[MyManager[Self]] = MyManager()
67+
68+
class Sub(Base):
69+
pass
70+
4671
- case: from_queryset_with_base_manager
4772
main: |
4873
from myapp.models import MyModel

tests/typecheck/managers/test_managers.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
- path: myapp/models.py
584584
content: |
585585
from typing import ClassVar, TypeVar
586+
from typing_extensions import Self
586587
from django.db import models
587588
588589
T = TypeVar("T", bound="MyModel")
@@ -597,7 +598,7 @@
597598
pass
598599
599600
class MySubModel(MyModel):
600-
objects: ClassVar[MySubManager["MySubModel"]] = MySubManager()
601+
objects: ClassVar[MySubManager[Self]] = MySubManager()
601602
602603
- case: subclass_manager_without_type_parameters_disallow_any_generics
603604
main: |

0 commit comments

Comments
 (0)