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

reveal_type(User.objects.filter) returns UserManager rather than QuerySet[User] #635

Closed
kracekumar opened this issue Jun 5, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@kracekumar
Copy link

kracekumar commented Jun 5, 2021

Bug report

from django.contrib.auth.models import User

reveal_type(User.objects.filter(
  email='[email protected]'))

output

# mypy filename.py
note: Revealed type is 
  'django.contrib.auth.models.UserManager
  [django.contrib.auth.models.User]'

What's wrong

The output should QuerySet[django.contrib.auth.models.User]

I don't know this is mypy bug or stubs bug.

How is that should be

QuerySet[django.contrib.auth.models.User]

System information

  • OS: OSX
  • python version: 3.9.4
  • django version: 3.2
  • mypy version: 0.812
  • django-stubs version: 1.8.0

Mypy config

[mypy]
strict = True
disallow_any_explicit = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
pretty = True
warn_return_any = False

plugins =
        mypy_django_plugin.main,
        mypy_drf_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = "koans.dj_koans.mysite.mysite.settings"
@kracekumar kracekumar added the bug Something isn't working label Jun 5, 2021
@kracekumar kracekumar changed the title reveal_type(User.objects.filter) is return UserManager rather than QuerySet[User] reveal_type(User.objects.filter) returns UserManager rather than QuerySet[User] Jun 5, 2021
@sobolevn
Copy link
Member

sobolevn commented Jun 5, 2021

@kracekumar does this happen with other models? Or only with User?

@kracekumar
Copy link
Author

kracekumar commented Jun 5, 2021

@sobolevn It happens for all the models.

from django.db import models
from django.utils import timezone

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

reveal_type(Question.objects.filter(id=1))
reveal_type(Choice.objects.filter(id=1))

output

note: Revealed type is 'django.db.models.manager.BaseManager[Any]'
note: Revealed type is 'django.db.models.manager.BaseManager[Any]'

sobolevn added a commit that referenced this issue Jun 5, 2021
@sobolevn
Copy link
Member

sobolevn commented Jun 5, 2021

Yes, I can confirm: https://github.com/typeddjango/django-stubs/pull/636/checks?check_run_id=2754398770#step:7:249

In [5]: type(ApplicationSubmission.objects.filter(id__gt=0))
Out[5]: django.db.models.query.QuerySet

@p7g
Copy link
Contributor

p7g commented Jun 15, 2021

I think this is because the stub for QuerySet has filter (and other methods) typed like def filter(self: _QS, *args: Any, **kwargs: Any) -> _QS: ..., and these queryset method types are copied verbatim to the generated Manager class type. The result is that any chain of QuerySet methods off of the Manager is typed as a Manager, even though at runtime queryset methods on managers return a queryset.

@sobolevn
Copy link
Member

Yes, this is exactly the cause!

syastrov added a commit to syastrov/django-stubs that referenced this issue Jul 7, 2021
This currently has the drawback that error messages display the internal type _QuerySet, with both type arguments.

See also discussion on typeddjango#661 and typeddjango#608.

Fixes typeddjango#635: QuerySet methods on Managers (like .all()) now return QuerySets rather than Managers.

Address code review by @sobolevn.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

3 participants