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

Fix inaccurate math.prod Typing #12041

Closed
wants to merge 14 commits into from
Closed

Conversation

max-muoto
Copy link
Contributor

@max-muoto max-muoto commented May 27, 2024

This PR fixes the issues detailed in #11913. One of the main strategies for accommodating the fact that an empty list inherently changes the result of the return-type, is having the first overloads be that of Iterable[Never], which will match an empty iterable first. Since the typing was fairly inaccurate before, I'm presuming a lot of repos will have new typing errors as a result of this change.

Let's walk through some examples (all with Pyright) of the new behavior:

Empty list will always evaluate to 1

res = math.prod([])
reveal_type(res) # Revealed type is Literal[1]

Given an empty list, but a start, the result will always be the type of the start:

res = math.prod([], start=Decimal(1))
reveal_type(res) # Revealed type is `Decimal`

Another example, where the list is filled out:

res = math.prod([Decimal(1)], start=Decimal(1))
reveal_type(res) # Revealed type is `Decimal`

With multiple types:

res = math.prod([Decimal(1), 1, 2.23], start=Decimal(1))
# Obviously this will actually be Decimal, but not sure we can get any better than this.
reveal_type(res) # Revealed type is Decimal | int | float 

@max-muoto max-muoto changed the title Fix Inaccurate math.prod Typing Fix inaccurate math.prod Typing May 27, 2024
@max-muoto max-muoto marked this pull request as draft May 27, 2024 02:03
@max-muoto max-muoto force-pushed the fix-prod-typing branch 4 times, most recently from ce23a94 to a089dd5 Compare May 27, 2024 02:29

This comment has been minimized.

@max-muoto
Copy link
Contributor Author

max-muoto commented May 27, 2024

The test cases seem to work for Pyright, but have issues with MyPy since it seems MyPy doesn't match an empty list to list[Never], while Pyright does, for the overloading.

@Akuli
Copy link
Collaborator

Akuli commented May 27, 2024

This is still not perfect, but it's probably the best we can do reasonably. Consider this code:

from decimal import Decimal
from math import prod

reveal_type(prod([Decimal(1), Decimal(2)], start=3.4))

Mypy says: note: Revealed type is "Union[typing.SupportsFloat, typing.SupportsIndex] (not error)
Runtime says: TypeError: unsupported operand type(s) for *: 'float' and 'decimal.Decimal

Copy link
Contributor

github-actions bot commented Sep 8, 2024

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@max-muoto max-muoto closed this Sep 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants