In a big library, I had a ‘bug’ because a function which accept only float but not int
def foo(penalty: float):
if not isinstance(penalty, float):
raise ValueError(f"`penalty` has to be a float, but is {penalty}")
# some instruction
I would like to open a PR with the following :
def foo(penalty: int | float):
if not isinstance(penalty, (int,float)):
raise ValueError(f"`penalty` has to be a float or int, but is {penalty}")
# some instruction
but before this, I ask myself :
are there good reason, in Python to accept float but not int ?
>Solution :
A few reasons might exist:
-
Floats have methods that integers don’t. For example the
fromhexorhexmethods exist onfloatobjects, but notintobjects. If the function makes use of such methods, accepting an int will cause it to fail. -
Sometimes, floats are specifically needed when dealing with foreign functions, for example, a function expecting a C
double, afloatworks for this purpose, but anintdoes not. -
Other types are accepted by
isinstancechecks ofint, for exampleboolobjects, which may be undesirable. -
In Python2, arithmetic with integers can sometimes produce different results than when a float is used. If the library is (or was) backwards compatible to Python2, it could be an artifact of that fact
-
A function may expect a value explicitly between (non-inclusive) 0 and 1, meaning an int will never make sense.
Presumably, a function could just upcast the integer to a float as-needed:
if isinstance(arg, int):
arg = float(arg)
But for performance, it may be better to error out and inform the user a float is needed (so perhaps the user can use a float to begin with).