Search code examples
pythonpython-typingmypy

mypy handle type errors once optional type is guaranteed not None


I have some method that returns an optional float/None. I use the output of that conditionally, if None I do one thing, if truthy (a float) I pass through later methods.

Currently mypy raises errors that those later methods don't suport a None. How do I either change the type or create a new variable that is guaranteed to be a float and not optional?

Example:

def method(args) -> Optional[float]:
    if some_case:
        return numerical_value: float
    return None


def next_step(val: float) -> Any:
    return do_more_stuff


result = method(stuff)

if result is None:
    exit_early()

# otherwise we are guaranteed dealing with a float
next_step(result)

Solution

  • Even though exit_early() ensures that the rest of the code can't be reached, that's a dynamic property of the function, not a static property. There are two options (as recommended by @barmar):

    1. You can declare exit_early to have a return type of typing.NoReturn, which mypy can use to infer that the only way to reach the call to next_step is if result is None is false, implying result has type float.

    2. Use an else, which syntactically implies that result will have type float when calling next_step, no matter what exit_early does.

      if result is None:
          exit_early()
      else:
          next_step(result)