Skip to content

Commit 0ce571e

Browse files
authored
fix as manager and from queryset self types (#1788) (#1789)
1 parent 1334efd commit 0ce571e

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

mypy_django_plugin/transformers/managers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ def _process_dynamic_method(
132132
_replace_type_var(arg_type, base_that_has_method.defn.type_vars[0].fullname, manager_instance.args[0])
133133
for arg_type in args_types
134134
]
135+
if base_that_has_method.self_type:
136+
# Manages -> Self returns
137+
ret_type = _replace_type_var(ret_type, base_that_has_method.self_type.fullname, manager_instance)
135138

136139
# Drop any 'self' argument as our manager is already initialized
137140
return method_type.copy_modified(

tests/typecheck/managers/querysets/test_as_manager.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
- case: self_return_management
2+
main: |
3+
from myapp.models import MyModel
4+
reveal_type(MyModel.objects.example_simple()) # N: Revealed type is "myapp.models.ManagerFromMyQuerySet[myapp.models.MyModel]"
5+
reveal_type(MyModel.objects.example_list()) # N: Revealed type is "builtins.list[myapp.models.ManagerFromMyQuerySet[myapp.models.MyModel]]"
6+
reveal_type(MyModel.objects.example_simple().just_int()) # N: Revealed type is "builtins.int"
7+
reveal_type(MyModel.objects.example_dict()) # N: Revealed type is "builtins.dict[builtins.str, myapp.models.ManagerFromMyQuerySet[myapp.models.MyModel]]"
8+
9+
installed_apps:
10+
- myapp
11+
files:
12+
- path: myapp/__init__.py
13+
- path: myapp/models.py
14+
content: |
15+
from django.db import models
16+
from typing import List, Dict
17+
from typing_extensions import Self
18+
19+
class BaseQuerySet(models.QuerySet):
20+
def example_dict(self) -> Dict[str, Self]: ...
21+
22+
class MyQuerySet(BaseQuerySet):
23+
def example_simple(self) -> Self: ...
24+
def example_list(self) -> List[Self]: ...
25+
def just_int(self) -> int: ...
26+
27+
class MyModel(models.Model):
28+
objects = MyQuerySet.as_manager()
129
- case: declares_manager_type_like_django
230
main: |
331
from myapp.models import MyModel

tests/typecheck/managers/querysets/test_from_queryset.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
- case: from_queryset_self_return_management
2+
main: |
3+
from myapp.models import MyModel
4+
reveal_type(MyModel.objects.example_simple()) # N: Revealed type is "myapp.models.BaseManagerFromModelQuerySet[myapp.models.MyModel]"
5+
reveal_type(MyModel.objects.example_list()) # N: Revealed type is "builtins.list[myapp.models.BaseManagerFromModelQuerySet[myapp.models.MyModel]]"
6+
installed_apps:
7+
- myapp
8+
files:
9+
- path: myapp/__init__.py
10+
- path: myapp/models.py
11+
content: |
12+
from django.db import models
13+
from django.db.models.manager import BaseManager
14+
from typing_extensions import Self
15+
from typing import List
16+
17+
class ModelQuerySet(models.QuerySet):
18+
def example_simple(self) -> Self: ...
19+
def example_list(self) -> List[Self]: ...
20+
NewManager = BaseManager.from_queryset(ModelQuerySet)
21+
class MyModel(models.Model):
22+
objects = NewManager()
23+
124
- case: from_queryset_with_base_manager
225
main: |
326
from myapp.models import MyModel

0 commit comments

Comments
 (0)