python / typeshed

Collection of library stubs for Python, with static types
Other
4.18k stars 1.69k forks source link

math.prod typing incorrect #11913

Open karolinepauls opened 2 months ago

karolinepauls commented 2 months ago

Test file (decimal_prod.py):

from decimal import Decimal
from math import prod
from typing import TYPE_CHECKING

result = prod([Decimal(1), Decimal(2)])

if TYPE_CHECKING:
    reveal_type(result)
else:
    print(type(result))

Test:

$ mypy --version
mypy 1.10.0 (compiled: yes)
$ mypy decimal_prod.py
decimal_prod.py:8: note: Revealed type is "builtins.float"
Success: no issues found in 1 source file
$ python decimal_prod.py
<class 'decimal.Decimal'>

defined here: https://github.com/python/typeshed/blob/main/stdlib/math.pyi#L102-L105

srittau commented 2 months ago

It sounds as if we should use a TypeVar here, but the existing overload makes me a bit anxious. Any fix should include tests to check a few use cases. (But as always: PR welcome!)

Akuli commented 2 months ago

Presumably all non-int return types should be a union with Literal[1]. No matter what type the sequence elements are, it is possible to get the integer 1 with an empty sequence:

>>> import math
>>> math.prod([])
1
real-or-random commented 2 months ago

Presumably all non-int return types should be a union with Literal[1]. No matter what type the sequence elements are, it is possible to get the integer 1 with an empty sequence:

>>> import math
>>> math.prod([])
1

And now try:

>>> math.prod([], start=17)
> 17