def test_args_evaluated():
    T = TypeVar('T')
    assert typing_inspect.get_args(Union[int, Tuple[T, int]][str],
                                   evaluate=True) == (int, Tuple[str, int])
    assert typing_inspect.get_args(Dict[int, Tuple[T, T]][Optional[int]],
                                   evaluate=True) == (int,
                                                      Tuple[Optional[int],
                                                            Optional[int]])
    assert typing_inspect.get_args(Callable[[], T][int], evaluate=True) == (
        [],
        int,
    )
    assert typing_inspect.get_args(Union[int, Callable[[Tuple[T, ...]], str]],
                                   evaluate=True) == (int,
                                                      Callable[[Tuple[T, ...]],
                                                               str])

    # ClassVar special-casing
    assert typing_inspect.get_args(ClassVar, evaluate=True) == ()
    assert typing_inspect.get_args(ClassVar[int], evaluate=True) == (int, )

    # Literal special-casing
    assert typing_inspect.get_args(Literal, evaluate=True) == ()
    assert typing_inspect.get_args(Literal["value"],
                                   evaluate=True) == ("value", )
    assert typing_inspect.get_args(Literal[1, 2, 3],
                                   evaluate=True) == (1, 2, 3)
def _from_list(obj: list, type_annotation: Annotation,
               xml_annotation: XMLAnnotation, element: Optional[_Element],
               config: SerializerConfig) -> _Element:
    item_annotation, *_rest = typing_inspect.get_args(type_annotation)
    if typing_inspect.is_annotated_type(item_annotation):
        item_type_annotation, item_xml_annotation = get_xml_annotation(
            item_annotation, DEFAULT_VALUE_ANNOTATION)
    else:
        item_type_annotation = item_annotation
        item_xml_annotation = xml_annotation

    if element is None:
        element = Element(xml_annotation.tag)

    if xml_annotation.tag == item_xml_annotation.tag:
        # siblings
        parent = element
    else:
        parent = _make_element(element, xml_annotation.tag)

    for item in obj:
        _from_obj(item, item_type_annotation, item_xml_annotation, parent,
                  config)

    return parent
def _from_union(obj: Any, type_annotation: Annotation,
                json_annotation: JSONAnnotation,
                config: SerializerConfig) -> Any:
    for element_type in typing_inspect.get_args(type_annotation):
        try:
            return _from_any(obj, element_type, json_annotation, config)
        except:  # pylint: disable=bare-except
            pass
def _from_union(obj: Any, type_annotation: Annotation,
                xml_annotation: XMLAnnotation, element: Optional[_Element],
                config: SerializerConfig) -> _Element:
    for union_type_annotation in typing_inspect.get_args(type_annotation):
        try:
            return _from_obj(obj, union_type_annotation, xml_annotation,
                             element, config)
        except:  # pylint: disable=bare-except
            pass

    raise ValueError('unable to find type that satisfies union')
def _from_list(lst: list, type_annotation: Annotation,
               config: SerializerConfig) -> Any:
    item_annotation, *_rest = typing_inspect.get_args(type_annotation)
    if typing_inspect.is_annotated_type(item_annotation):
        item_type_annotation, item_json_annotation = get_json_annotation(
            item_annotation)
    else:
        item_type_annotation = item_annotation
        item_json_annotation = JSONValue()

    return [
        _from_any(item, item_type_annotation, item_json_annotation, config)
        for item in lst
    ]
def _from_optional(obj: Any, type_annotation: Annotation,
                   json_annotation: JSONAnnotation,
                   config: SerializerConfig) -> Any:
    if obj is None:
        return None

    # An optional is a union where the last element is the None type.
    union_types = typing_inspect.get_args(type_annotation)[:-1]
    if len(union_types) == 1:
        # This was Optional[T]
        return _from_any(obj, union_types[0], json_annotation, config)
    else:
        return _from_union(obj, Union[tuple(union_types)], json_annotation,
                           config)
def _from_optional(obj: Any, type_annotation: Annotation,
                   xml_annotation: XMLAnnotation, element: Optional[_Element],
                   config: SerializerConfig) -> _Element:
    if obj is None:
        return _make_element(element, xml_annotation.tag)

    # An optional is a union where the last element is the None type.
    union_types = typing_inspect.get_args(type_annotation)[:-1]
    if len(union_types) == 1:
        # This was Optional[T]
        return _from_obj(obj, union_types[0], xml_annotation, element, config)
    else:
        return _from_union(
            obj,
            Union[tuple(union_types)],  # type: ignore
            xml_annotation,
            element,
            config)
def _is_typed(annotation: Annotation) -> bool:
    return (typing_inspect.is_typed_dict_type(annotation)
            or (typing_inspect.is_list_type(annotation)
                and _is_typed(typing_inspect.get_args(annotation)[0]))
            or (typing_inspect.is_annotated_type(annotation)
                and _is_typed(typing_inspect.get_origin(annotation))))