Open kracekumar opened 3 years ago
I would love to see it rebased and merged! 👍
@sidmitra saw the PR previously and since it was not updated, felt opening a bug report to understand overall picture.
I rebased the PR :) I am not sure if it will actually fix your issue, though.
.annotate
previously is typed as returning QuerySet[Any]
.
But the problem is that get_book_counts_for_author
is returning a QuerySet where .values
was called on it.
The type in django-stubs for this is called "ValuesQuerySet", but it doesn't exist in reality.
But you might be able to use return type Collection[AuthorCount]
if you don't really need to use QuerySet
methods on the return value.
Thank you @syastrov and a good catch on Collection. Since the return result can be used for any filtering, annotated as Union[QuerySet[Book], AuthorCount]
. When it's a dictionary-like access either Collection[AuthorCount]
or Iterable[Authorcount]
works
For anyone interested, I just want to leave an update here that since #2319 the closest way of defining a return type is probably:
def get_book_counts_for_author() -> QuerySet[WithAnnotations[Book, AuthorCount], AuthorCount]:
That would still trigger a "Incompatible return type" error. But we need an improvement of .annotate
to consider a .values
having been called before we get rid of that.
Bug report
What's wrong
Iterating over the
annotate
result and accessing the aggregated item throwsModel
is not indexable.Mypy error
What should be the proper way to annotate the code here other than
type: ignore
?Failed Approaches
get_book_counts_for_author() -> QuerySet[AuthorCount]:
Output:
polls/models.py:69: error: Type argument "TypedDict('polls.models.AuthorCount', {'author': builtins.int})" of "QuerySet" must be a subtype of "django.db.models.base.Model"
get_book_counts_for_author() -> Union[QuerySet[Book], AuthorCount]:
Output:
__getitem__
,__iter__
likeBut output was
polls/models.py:65: error: Return type "Iterator[AuthorCount]" of "__iter__" incompatible with return type "Iterator[_T]" in supertype "QuerySet"
. The same problem happens with__getittem__
. AlsoQuerySet[AuthorType]
fails since it's not a instance ofModel
.Working approach
Is there a better way to annotate the code for the
annotate
return value. The bad part of the code is to keep checking the instance type in the consuming function and adding optional throughout the code.How is that should be
I don't know
System information
python
version:3.9.4
django
version:3.2
mypy
version:0.812
django-stubs
version:1.8.0