Skip to content

Resolve .values() field types on annotated querysets#3232

Open
federicobond wants to merge 1 commit intotypeddjango:masterfrom
federicobond:feat/resolve-annotated-field-types
Open

Resolve .values() field types on annotated querysets#3232
federicobond wants to merge 1 commit intotypeddjango:masterfrom
federicobond:feat/resolve-annotated-field-types

Conversation

@federicobond
Copy link
Copy Markdown
Contributor

Previously, extract_proper_type_queryset_values bailed out early for annotated models, returning dict[str, Any] instead of a precise TypedDict. Now it resolves annotation fields from the model's TypedDict type arg and model fields from Django's field metadata.

I've been working on values_list too but this changeset ended up quite neat that I didn't want to introduce more friction.


values_no_params = Blog.objects.annotate(foo=F('id')).values().get()
reveal_type(values_no_params) # N: Revealed type is "builtins.dict[builtins.str, Any]"
reveal_type(values_no_params) # N: Revealed type is "TypedDict({'id': builtins.int, 'num_posts': builtins.int, 'text': builtins.str, 'foo': Any})"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove these lines since type broadening no longer applies to .values() calls?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand your question :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test name is annotate_values_or_values_list_before_or_after_annotate_broadens_type, but with the latest changes, annotate no longer causes the type of .values() to widen to dict[builtins.str, Any].

Now this code is covered by the new test_values_on_with_annotations_queryset test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can probably remove it ye


values_no_params = Blog.objects.annotate(foo=F('id')).values().get()
reveal_type(values_no_params) # N: Revealed type is "builtins.dict[builtins.str, Any]"
reveal_type(values_no_params) # N: Revealed type is "TypedDict({'id': builtins.int, 'num_posts': builtins.int, 'text': builtins.str, 'foo': Any})"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand your question :)

Previously, extract_proper_type_queryset_values bailed out early for
annotated models, returning dict[str, Any] instead of a precise TypedDict.
Now it resolves annotation fields from the model's TypedDict type arg and
model fields from Django's field metadata.
@federicobond federicobond force-pushed the feat/resolve-annotated-field-types branch from 9eb8e04 to 041a3ab Compare March 28, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants