I would like to use typing's get_type_hints
method to get argument annotations. However I encountered this problem in Python3.6.8
a = typing.Optional[int]
type(a)
Out[13]: typing.Union
type(a) == typing.Union
Out[14]: False
type(a) == type(typing.Optional)
Out[23]: False
type(a) == type(typing.Optional[int])
Out[24]: True
repr(type(a))
Out[25]: 'typing.Union'
repr(typing.Union)
Out[26]: 'typing.Union'
It seems that there's no generic way to judge whether a type is typing.Optional
or not beside comparing the repr
which is not very pythonic. Is there a hack to it?
P.S. in 3.7 there's typing._GenericAlias
and it works perfectly fine.
Directly from mypy typing module docs. Optional[str] is just a shorthand or alias for Union[str, None] . It exists mostly as a convenience to help function signatures look a little cleaner. Update for Python 3.10+ you can now use the pipe operator as well.
Python will always remain a dynamically typed language. However, PEP 484 introduced type hints, which make it possible to also do static type checking of Python code. Unlike how types work in most other statically typed languages, type hints by themselves don't cause Python to enforce types.
The type() function is used to get the type of an object. When a single argument is passed to the type() function, it returns the type of the object. Its value is the same as the object. __class__ instance variable.
What Are Type Annotations? Type annotations — also known as type signatures — are used to indicate the datatypes of variables and input/outputs of functions and methods. In many languages, datatypes are explicitly stated. In these languages, if you don't declare your datatype — the code will not run.
I believe this is being answered in this post Check if a field is typing.Optional.
I also pasted it below:
Optional[X]
is equivalent to Union[X, None]
. So you could do,
import re
from typing import Optional
from dataclasses import dataclass, fields
@dataclass(frozen=True)
class TestClass:
required_field_1: str
required_field_2: int
optional_field: Optional[str]
def get_optional_fields(klass):
class_fields = fields(klass)
for field in class_fields:
if (
hasattr(field.type, "__args__")
and len(field.type.__args__) == 2
and field.type.__args__[-1] is type(None)
):
# Check if exactly two arguments exists and one of them are None type
yield field.name
print(list(get_optional_fields(TestClass)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With