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

fix handling of explicit objects annotation #2241

Merged
merged 2 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions mypy_django_plugin/transformers/querysets.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ def determine_proper_manager_type(ctx: FunctionContext) -> MypyType:
assert isinstance(default_return_type, Instance)

outer_model_info = helpers.get_typechecker_api(ctx).scope.active_class()
if outer_model_info is None or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
if (
outer_model_info is None
or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME)
or outer_model_info.self_type is None
):
return default_return_type

return helpers.reparametrize_instance(default_return_type, [Instance(outer_model_info, [])])
return helpers.reparametrize_instance(default_return_type, [outer_model_info.self_type])


def get_field_type_from_lookup(
Expand Down
25 changes: 25 additions & 0 deletions tests/typecheck/managers/querysets/test_from_queryset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@
class MyModelWithoutSelf(models.Model):
objects = ManagerWithoutSelf()

- case: from_queryset_model_inheritance
main: |
from myapp.models import Base, Sub
reveal_type(Base.objects) # N: Revealed type is "myapp.models.MyManager[myapp.models.Base]"
reveal_type(Sub.objects) # N: Revealed type is "myapp.models.MyManager[myapp.models.Sub]"
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from typing import ClassVar
from typing_extensions import Self
from django.db.models import Model
from django.db.models.manager import BaseManager
from django.db.models.query import QuerySet

MyManager = BaseManager.from_queryset(QuerySet, "MyManager")

class Base(Model):
objects: ClassVar[MyManager[Self]] = MyManager()
flaeppe marked this conversation as resolved.
Show resolved Hide resolved

class Sub(Base):
pass

- case: from_queryset_with_base_manager
main: |
from myapp.models import MyModel
Expand Down
3 changes: 2 additions & 1 deletion tests/typecheck/managers/test_managers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@
- path: myapp/models.py
content: |
from typing import ClassVar, TypeVar
from typing_extensions import Self
from django.db import models

T = TypeVar("T", bound="MyModel")
Expand All @@ -597,7 +598,7 @@
pass

class MySubModel(MyModel):
objects: ClassVar[MySubManager["MySubModel"]] = MySubManager()
objects: ClassVar[MySubManager[Self]] = MySubManager()

- case: subclass_manager_without_type_parameters_disallow_any_generics
main: |
Expand Down
Loading