Description
Feature or enhancement
Function arguments and variables annotated with float
should not allow value of type int.
Pitch
PEP484 suggested that when an argument is annotated as having type float, an argument of type int is acceptable;
. This allows this kind of typing to be valid:
x: float = 2
But int
is not subtype of float
and doesn't provide the same interface. Float provides methods that are not available in int
:
is_integer
fromhex
hex
This violates LSP and is problematic especially with is_integer
:
def method_requiring_whole_number_float(number: float):
if number.is_integer():
...
This method clearly states that it requires float
and as an author of such code, I would expect that is_integer
would be available if my typing is correct.
There are workarounds (if int(number) == number:
) but they render the is_integer
useless as it can never be safely used.
Just adding the missing methods to int
(or removing the extra methods from float
) would not be valid solution as there are other problems stemming from the fact that int
is not float
. Eg.:
def split_whole_and_decimal(number: float) -> tuple[str, str]:
return str(number).split('.') # it's reasonable to expect that the output contains a dot `.` as `float` does but `int` doesn't
I'm proposing an errata to PEP484 that will remove when an argument is annotated as having type float, an argument of type int is acceptable;
.