Check A Variable Against Union Type At Runtime In Python 3.6


Answer :

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 Union True >>> isinstance(3, type_anno.__args__) True >>> isinstance('a', type_anno.__args__) True 

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 Union True >> 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.


Comments

Popular posts from this blog

Are Regular VACUUM ANALYZE Still Recommended Under 9.1?

Can Feynman Diagrams Be Used To Represent Any Perturbation Theory?