Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python what is the type of typing.Optional [duplicate]

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.

like image 859
Kevin Fang Avatar asked Mar 13 '19 23:03

Kevin Fang


People also ask

What is optional typing in Python?

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.

Which type of typing is identified with Python?

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.

What does type () return in Python?

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 is type annotation in Python?

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.


1 Answers

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)))
like image 157
Tekill Avatar answered Oct 10 '22 10:10

Tekill