Reputation: 5619
mypy is really handy and catches a lot of bugs, but when I write "scientific" applications, I often end up doing:
def my_func(number: Union[float, int]):
# Do something
number
is either a float or int, depending on the user's input. Is there an official way to do that?
Upvotes: 136
Views: 64386
Reputation: 27436
Python ≥ 3.10
allows you to do the following.
def my_func(number: int | float) -> int | float:
Upvotes: 21
Reputation: 387
You can define your own type to address this and keep your code cleaner.
FloatInt = Union[float, int]
def my_func(number: FloatInt):
# Do something
Upvotes: 12
Reputation: 18693
For people who come to this question for the more general problem of Union typing hints for entities which don't have an existing supertype in common, for example Union[int, numpy.ndarray]
, the solution is to import Union
from typing
.
Example 1:
from typing import Union
def my_func(number: Union[float, int]):
# Do something
Example 2:
from typing import Union
import numpy as np
def my_func(x: Union[float, np.ndarray]):
# do something
# Do something
Upvotes: -2
Reputation: 1121148
Use float
only, as int
is implied in that type:
def my_func(number: float):
PEP 484 Type Hints specifically states that:
Rather than requiring that users write import numbers and then use
numbers.Float
etc., this PEP proposes a straightforward shortcut that is almost as effective: when an argument is annotated as having typefloat
, an argument of typeint
is acceptable; similar, for an argument annotated as having type complex, arguments of type float or int are acceptable.
(Bold emphasis mine).
Ideally you would still use numbers.Real
:
from numbers import Real
def my_func(number: Real):
as that would accept fractions.Fraction()
and decimal.Decimal()
objects as well; the number pyramid is broader than just integers and floating point values.
However, these are not currently working when using mypy
to do your type checking, see Mypy #3186.
Upvotes: 221