There are many cases in which a variable can be empty, or more correctly can contain the value None in Python.

The same with the return value of a function. We might have a function that would normally return a floating point number, but sometimes it might return None. How can you give type-checking hints so mypy will accept the situation?

In another article we already saw how to handle the case when a function parameter can have more than one type. Now we'll see a special case of that, when one of the potential values is None.

In other words, when the value is optional.

Function that returns either float or None

In this example we have function (admittedly a bit contrived example, but syntactically correct). We add type-hinting that suggests the function is expected to always return a float.

examples/python/mypy/return_might_be_none.py

import random

def get_something() -> float:
    rnd = random.random()
    if rnd < 0.5:
        return rnd
    return None

print(get_something())

Obviously it does not, so when we run mypy it will complain:

$ mypy return_might_be_none.py

return_might_be_none.py:7: error: Incompatible return value type (got "None", expected "float")

Using Union

Using the Union keyword from the typing module allows us to declare that a variable, or in this case the return value of the function can be either one of 2 or more values. In our case it is either float or None

examples/python/mypy/return_might_be_none_union.py

import random
from typing import Union

def get_something() -> Union[float, None]:
    rnd = random.random()
    if rnd < 0.5:
        return rnd
    return None

print(get_something())

Running mypy on it will be without complaints.

Using Optional

While Union can be used, an even better option for this case is to use the Optional keyword:

examples/python/mypy/return_might_be_none_optional.py

import random
from typing import Optional

def get_something() -> Optional[float]:
    rnd = random.random()
    if rnd < 0.5:
        return rnd
    return None

print(get_something())