-
-
Notifications
You must be signed in to change notification settings - Fork 466
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
Self
typed custom queryset methods incompatible with base queryset type
#1840
Comments
I've been investigating this. It arises from #1789 , fixing #1788, where it was specified that queryset method return types of |
I do not think this is realy an error. Since Log.objects is not realy a LogQuerySet[Log, Log]. It is a generated manager by Django that derivates from LogQuerySet, but is not a LogQuerySet. So self should not rersolve a But maybe the issue here is more global (cf @flaeppe) that ManagerFromLogQuerySet is not detected has a subclass of LogQuerySet, which I think it is. |
Hi @moranabadie, thanks for taking a look. The manager that Django creates in Perhaps the plugin's current application of |
This stems from the fact that Django dynamically adds queryset methods as attributes of a manager. The mypy plugin simulates that behaviour as well. There's a note hinting towards that happening, which is also slightly relevant: django-stubs/django-stubs/db/models/manager.pyi Lines 37 to 38 in 82c394f
We probably need to help mypy resolve You would probably also find the incorrectness by printing out the return type of I happen to know that the plugin strips the first argument ( Stripping happens here via the django-stubs/mypy_django_plugin/transformers/managers.py Lines 143 to 150 in 82c394f
If we try to simulate the plugin behaviour manually in playground, we see that mypy emits an error for the Inlining playground contents for clarity from typing_extensions import Self
class QuerySet:
def method(self) -> Self:
return self
class Manager:
method = QuerySet.method
reveal_type(Manager.method)
reveal_type(Manager().method)
reveal_type(Manager().method()) I'll just keep going here, mostly for notes to self. But the issues emitted from the above snippet can instead of stripping be fixed by e.g. annotate every manager method as: +from typing import Any, Callable, ClassVar
from typing_extensions import Self
class QuerySet:
def method(self) -> Self:
return self
class Manager:
- method = QuerySet.method
+ method: ClassVar[Callable[[Any], QuerySet]] = QuerySet.method
reveal_type(Manager.method)
reveal_type(Manager().method)
reveal_type(Manager().method()) Notes:
|
Oups, you seem to be right. I will try to fix it in a pull request |
Bug report
What's wrong
Custom queryset methods with a return type of
Self
have a return type incompatible with the baseQuerySet
class.mypy reports:
How is that should be
It would be great if the return type was inferred to be a sub-type of
QuerySet
with the correct type, eg,QuerySet[Log]
.System information
python
version: 3.11.6/3.8.18django
version: 3.2.23mypy
version: 1.6.1django-stubs
version: 4.2.6django-stubs-ext
version: 4.2.5The text was updated successfully, but these errors were encountered: