Source code for noob.introspection

"""
Utilities for working with python type annotations
"""

from types import NoneType, UnionType
from typing import Annotated, Any, Union, get_args, get_origin


[docs] def unwrap_optional(typ: type) -> type: if get_origin(typ) in (Union, UnionType): args = [unwrap_optional(arg) for arg in get_args(typ)] for arg in args: if arg is not None: return arg return typ
[docs] def unwrap_annotated(typ: type) -> type: if get_origin(typ) is Annotated: return get_args(typ)[0] return typ
[docs] def unwrap(typ: type) -> type: """ Unwrap all 'extra' type wrappers to get to the actual type """ typ = unwrap_annotated(typ) typ = unwrap_optional(typ) return typ
[docs] def is_union(dtype: Any) -> bool: """ Check if a dtype is a union """ if UnionType is None: return get_origin(dtype) is Union else: return get_origin(dtype) in (Union, UnionType)
[docs] def is_optional(dtype: Any) -> bool: dtype = unwrap_annotated(dtype) if not is_union(dtype): return False args = get_args(dtype) return None in args or NoneType in args