Skip to content
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

Update django.db.models.functions: allow Combinable as parameter, add Round function #2195

Merged
merged 2 commits into from
May 31, 2024

Conversation

noamkush
Copy link
Contributor

@noamkush noamkush commented May 29, 2024

I have made things!

This fixes the annotation for database functions which can take F objects and field names, not just an Expression. Also added annotation for the specialized Round constructor.

@intgr
Copy link
Collaborator

intgr commented May 29, 2024

Per stubtest output, please also remove these entries from allowlist:

note: unused allowlist entry django.db.models.functions.Round.__init__
note: unused allowlist entry django.db.models.functions.math.Round.__init__

@intgr intgr changed the title Fix database function annotations. Update django.db.models.functions: allow Combinable parameters, add Round function May 29, 2024
@intgr intgr changed the title Update django.db.models.functions: allow Combinable parameters, add Round function Update django.db.models.functions: allow Combinable as parameter, add Round function May 29, 2024
@intgr intgr self-assigned this May 29, 2024
@noamkush
Copy link
Contributor Author

Done

asottile-sentry pushed a commit to getsentry/sentry-forked-django-stubs that referenced this pull request May 29, 2024
@@ -41,14 +41,14 @@ class TruncBase(TimezoneMixin, Transform):
tzinfo: Any

def __init__(
self, expression: Expression, output_field: Field | None = ..., tzinfo: tzinfo | None = ..., **extra: Any
self, expression: Combinable | str, output_field: Field | None = ..., tzinfo: tzinfo | None = ..., **extra: Any
Copy link
Collaborator

@intgr intgr May 29, 2024

Choose a reason for hiding this comment

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

I'm not very familiar QuerySet operators/functions.

Most Combinables seem to inherit from Expression. Can you give an example of something that is Combinable but not Expression?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also some PostgreSQL functions are typehinted as BaseExpression | Combinable | str. I wonder if there's a reason for that, or in practice all useful expressions already inherit from Combinable.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sry, you already answered the first question in PR description. F() objects inherit from Combinable but not Expression.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if there's a reason for that, or in practice all useful expressions already inherit from Combinable.

But unless someone can think of a use case for BaseExpression, I'm inclined to go with Combinable | str. Let's not complicate things unless we know it's necessary.

Copy link
Collaborator

@intgr intgr left a comment

Choose a reason for hiding this comment

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

Thanks, looks good to me.

Leaving open for a bit, in case someone has thoughts on BaseExpression: #2195 (comment)

asottile-sentry added a commit to getsentry/sentry-forked-django-stubs that referenced this pull request May 29, 2024
@mkurnikov
Copy link
Member

mkurnikov commented May 30, 2024

Looks good to me, I checked, all possible BaseExpression children also inherit Combinable, either directly, or via Expression base class.
I'd advise to add one test where you could pass every possible Expression child class to one of the places you've annotated as Combinable | str, so we won't miss this in the future.
But it's up to you, could be too much to add every single case. Maybe not every single case, but just one per "unique inheritance chain", like one of the LessThan / GreaterThan and so on.

@intgr
Copy link
Collaborator

intgr commented May 31, 2024

Thanks for confirming the class hierarchy wrt BaseExpression.

I'm not against adding simple tests, but our usual policy is to not require tests for simple stubs, I'd just merge this as is. Once these hints are fixed, it's very unlikely they will regress again. (The bigger challenge is remembering to use the correct types when new classes are added, but that can't really be covered with current test infra)

@intgr intgr merged commit d05c7c3 into typeddjango:master May 31, 2024
36 checks passed
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.

4 participants