def get_args(tp, evaluate=None):
if NEW_TYPING:<EOL><INDENT>if evaluate is not None and not evaluate:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if isinstance(tp, _GenericAlias):<EOL><INDENT>res = tp.__args__<EOL>if get_origin(tp) is collections.abc.Callable and res[<NUM_LIT:0>] is not Ellipsis:<EOL><INDENT>res = (list(res[:-<NUM_LIT:1>]), res[-<NUM_LIT:1>])<EOL><DEDENT>return res<EOL><DEDENT>return ()<EOL><DEDENT>if is_classvar(tp):<EOL><INDENT>return (tp.__type__,)<EOL><DEDENT>if (<EOL>is_generic_type(tp) or is_union_type(tp) or<EOL>is_callable_type(tp) or is_tuple_type(tp)<EOL>):<EOL><INDENT>tree = tp._subs_tree()<EOL>if isinstance(tree, tuple) and len(tree) > <NUM_LIT:1>:<EOL><INDENT>if not evaluate:<EOL><INDENT>return tree[<NUM_LIT:1>:]<EOL><DEDENT>res = _eval_args(tree[<NUM_LIT:1>:])<EOL>if get_origin(tp) is Callable and res[<NUM_LIT:0>] is not Ellipsis:<EOL><INDENT>res = (list(res[:-<NUM_LIT:1>]), res[-<NUM_LIT:1>])<EOL><DEDENT>return res<EOL><DEDENT><DEDENT>return ()<EOL>
Get type arguments with all substitutions performed. For unions,
    basic simplifications used by Union constructor are performed.
    On versions prior to 3.7 if `evaluate` is False (default),
    report result as nested tuple, this matches
    the internal representation of types. If `evaluate` is True
    (or if Python version is 3.7 or greater), then all
    type parameters are applied (this could be time and memory expensive).
    Examples::

        get_args(int) == ()
        get_args(Union[int, Union[T, int], str][int]) == (int, str)
        get_args(Union[int, Tuple[T, int]][str]) == (int, (Tuple, str, int))

        get_args(Union[int, Tuple[T, int]][str], evaluate=True) == \
                 (int, Tuple[str, int])
        get_args(Dict[int, Tuple[T, T]][Optional[int]], evaluate=True) == \
                 (int, Tuple[Optional[int], Optional[int]])
        get_args(Callable[[], T][int], evaluate=True) == ([], int,)