On the one hand, I have learned that numbers that can be int
or float
should be type annotated as float
(sources: PEP 484 Type Hints and this stackoverflow question):
def add(a: float, b: float):
return a + b
On the other hand, an int
is not an instance of float
:
issubclass(int, float)
returns False
isinstance(42, float)
returns False
I would thus have expected Union[int, float]
to be the correct annotation for this use case.
Questions:
int
/float
a special case in type annotations? Are there other examples like this?Union[float, int]
if this is an unintended use?On the other hand, an int is not an instance of float : issubclass(int, float) returns False. isinstance(42, float) returns False.
In his excellent article The State of Type Hints in Python Bernát Gábor recommends that “type hints should be used whenever unit tests are worth writing.” Indeed, type hints play a similar role as tests in your code: they help you as a developer write better code.
Type hinting is a formal solution to statically indicate the type of a value within your Python code. It was specified in PEP 484 and introduced in Python 3.5.
New in version 3.5. The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.
- Are int/float a special case in type annotations?
float
is a special case. int
is not. PEP 484 says, in the paragraph below the one referenced by the link in your question:
when an argument is annotated as having type
float
, an argument of typeint
is acceptable;
So accepting int
where float
is annotated is explicitly a special case, independent of the way annotations generally deal with a class hierarchy.
Are there other examples like this?
Yes, there's at least one other special case. In that same paragraph PEP 484 goes on to say:
for an argument annotated as having type
complex
, arguments of typefloat
orint
are acceptable.
- Is there any linter that would warn me about
Union[float, int]
if this is an unintended use?
Union[float, int]
is perfectly fine.
The special treatment of a float
annotation is just a convenience (PEP 484 calls it a "shortcut") to allow people to avoid writing out the long-winded Union[float, int]
annotation, because arguments that can be a float
or an int
are very common.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With