1

I have a function that returns a number but it's not obvious what the user enters. It could accept a str, int or float. So I've type-hinted it as follows:

from numbers import Number


def to_number(value: Union[str, Number]) -> Number:
    if isinstance(value, Number) and math.isnan(value):
        raise ValueError(f"No NaNsense")

    try:
        return int(value)
    except ValueError:
        try:
            return float(value)
        except ValueError as exc:
            raise ValueError(f"'{value}' is not a number") from exc

Upon running pytype on the file I get the following error:

File "whatever.py", line 8, in evaluate: bad return type [bad-return-type]
           Expected: numbers.Number
  Actually returned: int
File "whatever.py", line 11, in evaluate: bad return type [bad-return-type]
           Expected: numbers.Number
  Actually returned: float

But in the REPL

>>> isinstance(int(5), numbers.Number)
True
>>> isinstance(float(5), numbers.Number)
True

What's the resolution here? I'm on CPython 3.7.13, PyType 2022.12.15

  • Does this answer your question? [How to type hint a generic numeric type in Python?](https://stackoverflow.com/questions/60616802/how-to-type-hint-a-generic-numeric-type-in-python) Ignore first answer, it's incorrect (at least still certainly doesn't work with `mypy`), read other answers. TL;DR: don't use Number, use regular `float` instead (`Union[int, float]` reduces to `float` for type checkers). – STerliakov Dec 23 '22 at 08:42
  • Please take a look here: https://github.com/python/mypy/issues/3186 **Summary**: float(int included) is not understood as numbers.Number in mypy. – Immature trader Dec 23 '22 at 09:06
  • Yeah, that discourse is quite involved. I think I'll go without the `Union` type hint option: I don't plan to create any new number systems that inherit `Number` anyway. – Syafiq Kamarul Azman Dec 26 '22 at 04:54

0 Answers0