Skip to content

Resolve queryset annotate types for expressions with static ClassVar#3221

Open
federicobond wants to merge 2 commits intotypeddjango:masterfrom
federicobond:feat/annotate-output-field-types
Open

Resolve queryset annotate types for expressions with static ClassVar#3221
federicobond wants to merge 2 commits intotypeddjango:masterfrom
federicobond:feat/annotate-output-field-types

Conversation

@federicobond
Copy link
Contributor

Instead of always typing annotated fields as Any, resolve the concrete Python type when the expression has a static ClassVar output_field (e.g. Count → int, Exists → bool, Length → int, Now → datetime).

The current implementation introduces some unsoundness, since functions like Length can return None for nullable fields. This is not the case for Count or Exists, for example. Setting is_nullable=True here is theoretically safer but would make the types wrong in the other direction, and is more annoying in practice.

The real solution is to query the Django runtime for the type of the requested field argument, but it introduces quite a bit of complexity, and I'm not sure if it's worth pursuing before agreeing this is a desirable feature.

For now, I'm happy to discuss and gather more feedback.

@federicobond federicobond force-pushed the feat/annotate-output-field-types branch from 35848bd to d87fa61 Compare March 25, 2026 02:00
Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

This looks super cool! cc @UnknownPlatypus

@UnknownPlatypus
Copy link
Contributor

I'll check this this week, it looks promising !


# For now, we don't try to resolve the output_field of the field would be, but use Any.
# Try to resolve the output_field type for each expression. For expressions
# with a static ClassVar output_field (e.g. Count → IntegerField → int),
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use the return type of the property/cached_property when applicable ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what you mean, which property?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nvm, got it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added resolution via property return type in a separate commit.

Instead of always typing annotated fields as Any, resolve the concrete
Python type when the expression has a static ClassVar output_field
(e.g. Count → int, Exists → bool, Length → int, Now → datetime).
@federicobond federicobond force-pushed the feat/annotate-output-field-types branch from d87fa61 to 247f89b Compare March 27, 2026 00:45
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