django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

QuerySet annotations are lost when getting an instance in the queryset (bug with WithAnnotations)

Open felixmeziere opened this issue 3 years ago • 1 comments

Bug report

What's wrong

Even though a queryset is correctly typed with WithAnnotations, this annotation is lost when accessing an instance in the queryset, which means we can't use this typing feature properly. Here is a minimal example:

class SomeQuerySet(QuerySet[Accommodation]):
    pass


queryset = SomeQuerySet().annotate(hello=Value(True)).filter(is_on_shelf=True).annotate(hi=Value(False))
reveal_type(queryset) # CORRECT: Revealed type is "SomeQuerySet[WithAnnotations[Accommodation, TypedDict({'hello': Any, 'hi': Any})]]"
reveal_type(queryset.first()) # INCORRECT: Revealed type is "Union[Accommodation, None]"
reveal_type(queryset.get(pk=1)) # INCORRECT: Revealed type is "Accommodation"
reveal_type(queryset[0]) # INCORRECT: Revealed type is "Accommodation"

How should it be instead:

Revealed types should be:

reveal_type(queryset.first()) # Revealed type is "Union[WithAnnotations[Accommodation, TypedDict({'hello': Any, 'hi': Any})], None]"
reveal_type(queryset.get(pk=1)) # Revealed type is "WithAnnotations[Accommodation, TypedDict({'hello': Any, 'hi': Any})]"
reveal_type(queryset[0]) # Revealed type is "WithAnnotations[Accommodation, TypedDict({'hello': Any, 'hi': Any})]"

System information

  • OS: Mac Os Monterey
  • python version: 10.0.3
  • django version: 4.0.4
  • mypy version: 0.961
  • django-stubs version: current master (just after 1.12.0)
  • django-stubs-ext version: 0.5.0

felixmeziere avatar Jul 04 '22 16:07 felixmeziere

@syastrov I just saw that you have worked on similar topics in the past, any ideas?

felixmeziere avatar Jul 05 '22 15:07 felixmeziere