What is the best way to check if a field from a class is typing.Optional?
Example code:
from typing import Optional
import re
from dataclasses import
Note: typing.Optional[x]
is an alias for typing.Union[x, None]
Now, one could inspect the attributes of your input field annotation to check if it is defined like Union[x, None]:
You can read its attributes __module__
, __args__
and __origin__
:
from typing import *
def print_meta_info(x):
print(x.__module__, x.__args__, x.__origin__)
x = Optional[int]
print_meta_info(x) # 'typing', (class Int,), typing.Union
x = Union[int, float]
print_meta_info(x) # 'typing', (class int, class float), typing.Union
x = Iterable[str]
print_meta_info(x) # 'typing', (class int,), typing.Iterable
You need to take this steps to define your checker:
__module__
, __args__
and __origin__
__module__
must be set to 'typing'. If not, the annotation is not an object defined by the typing module__origin__
value is equal to typing.Union__args__
must be a tuple with 2 items where the second one is the class NoneType (type(None)
)
If all conditions are evaluated to true, you have typing.Optional[x]
You may also need to know what is the optional class in the annotation:
x = Optional[int].__args__[0]
print(x) # class int