Check a variable against Union type at runtime in Python 3.6 Check a variable against Union type at runtime in Python 3.6 python python

Check a variable against Union type at runtime in Python 3.6


In Python 3.8 and later, the approach suggested by MSeifert and Richard Xia can be improved by not using the undocumented attributes __origin__ and __args__. This functionality is provided by the new functions typing.get_args(tp) and typing.get_origin(tp):

>> from typing import Union, get_origin, get_args>> x = Union[int, str]>> get_origin(x), get_args(x)(typing.Union, (<class 'int'>, <class 'str'>))>> get_origin(x) is UnionTrue>> isinstance(3, get_args(x))True>> isinstance('a', get_args(x))True>> isinstance([], get_args(x))False

P.S.: I know that the question is about Python 3.6 (probably because this was the newest version at the time), but I arrived here when I searched for a solution as a Python 3.8 user. I guess that others might be in the same situation, so I thought that adding a new answer here makes sense.


You could use the __args__ attribute of Union which holds a tuple of the "possible contents:

>>> from typing import Union>>> x = Union[int, str]>>> x.__args__(int, str)>>> isinstance(3, x.__args__)True>>> isinstance('a', x.__args__)True

The __args__ argument is not documented so it could be considered "messing with implementation details" but it seems like a better way than parsing the repr.


The existing accepted answer by MSeifert (https://stackoverflow.com/a/45959000/7433423) does not distinguish Unions from other generic types, and it is difficult to determine at runtime whether a type annotation is a Union or some other generic type like Mapping due to the behavior of isinstance() and issubclass() on parameterized Union types.

It appears that generic types will have an undocumented __origin__ attribute which will contain a reference to the original generic type used to create it. Once you have confirmed that the type annotation is a parameterized Union, you can then use the also undocumented __args__ attribute to get the type parameters.

>>> from typing import Union>>> type_anno = Union[int, str]>>> type_anno.__origin__ is UnionTrue>>> isinstance(3, type_anno.__args__)True>>> isinstance('a', type_anno.__args__)True