Get the argument from an Optional[...] annotation, or None if it is no such annotation.
(annotation: typing.Any)
| 15 | |
| 16 | |
| 17 | def get_optional_arg(annotation: typing.Any) -> typing.Any: |
| 18 | """Get the argument from an Optional[...] annotation, or None if it is no such annotation.""" |
| 19 | origin = typing.get_origin(annotation) |
| 20 | if origin != typing.Union and (sys.version_info >= (3, 10) and origin != types.UnionType): |
| 21 | return None |
| 22 | |
| 23 | union_args = typing.get_args(annotation) |
| 24 | if len(union_args) != 2: # Union does _not_ have two members, so it's not an Optional |
| 25 | return None |
| 26 | |
| 27 | has_none_arg = any(is_none_type(arg) for arg in union_args) |
| 28 | # There will always be at least one type arg, as we have already established that this is a Union with exactly |
| 29 | # two members, and both cannot be None (`Union[None, None]` does not work). |
| 30 | type_arg = next(arg for arg in union_args if not is_none_type(arg)) # pragma: no branch |
| 31 | |
| 32 | if has_none_arg: |
| 33 | return type_arg |
| 34 | return None |
| 35 | |
| 36 | |
| 37 | def annotation_is_class(annotation: typing.Any) -> bool: |