pythonpython-typingunions

Why does a type hint `float` accept `int` while it is not even a subclass?


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:

I would thus have expected Union[int, float] to be the correct annotation for this use case.

Questions:


Solution

    • 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 type int 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 type float or int 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.