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)
returnsFalse
isinstance(42, float)
returnsFalse
I would thus have expected Union[int, float]
to be the correct annotation for this use case.
Questions:
- What is the reason for that counter-intuitive behaviour? Does type hinting follow different mechanics than class comparisons (for instance in some case a "lossless casting" rule or so)?
- Are
int
/float
a special case in type annotations? Are there other examples like this? - Is there any linter that would warn me about
Union[float, int]
if this is an unintended use?
None
when it should beNoneType
or something – Curcio