Python 3.10 – Simplifies Unions in Type Annotations

Python 3.10 has several new typing features. They are given in detail here:

  • PEP 604, Allow writing union types as X | Y
  • PEP 613, Explicit Type Aliases
  • PEP 612, Parameter Specification Variables

The focus of this tutorial is to talk about PEP 604, which makes writing union types easier when adding type annotation (AKA: type hinting) to your codebase.

Unions Ye Olde Way

Before Python 3.10, if you wanted to say that a variable or parameter could be multiple different types, you would need to use Union:

from typing import Union

rate: Union[int, str] = 1

Here’s another example from the Python documentation:

from typing import Union

def square(number: Union[int, float]) -> Union[int, float]:
    return number ** 2

Let’s find out how 3.10 will fix that!

The New Union

In Python 3.10, you no longer need to import Union at all. All the details are in PEP 604. The PEP allows you to replace it entirely with the | operator. Once you have done that, the code above becomes the following:

def square(number: int | float) -> int | float:
    return number ** 2

You can use the new syntax to replace Optional as well, which is what you used for type hinting that an argument could be None:

# Old syntax

from typing import Optional, Union

def f(param: Optional[int]) -> Union[float, str]:
   ...


# New syntax in 3.10

def f(param: int | None) -> float | str:
   ...

You can even use this syntax with isinstance() and issubclass():

>>> isinstance(1, int | str)
True

Wrapping Up

While this isn’t an amazing new feature for the Python language, the addition of using the | operator with type annotations makes your code look cleaner. You don’t need as many imports and it looks nicer this way.

Related Reading