def VisitUnionType(self, union):
    'Push unions down into containers.\n\n    This collects similar container types in unions and merges them into\n    single instances with the union type pushed down to the element_type level.\n\n    Arguments:\n      union: A pytd.Union instance. Might appear in a parameter, a return type,\n        a constant type, etc.\n\n    Returns:\n      A simplified pytd.Union.\n    '
    if (not any((isinstance(t, pytd.GenericType) for t in union.type_list))):
        return union
    union = pytd_utils.JoinTypes(union.type_list)
    if (not isinstance(union, pytd.UnionType)):
        union = pytd.UnionType((union,))
    merge_tuples = self._should_merge(pytd.TupleType, union)
    merge_callables = self._should_merge(pytd.CallableType, union)
    if (merge_tuples or merge_callables):
        type_list = []
        for t in union.type_list:
            if (merge_tuples and isinstance(t, pytd.TupleType)):
                t = pytd.GenericType(base_type=t.base_type, parameters=(pytd.UnionType(t.parameters),))
            elif (merge_callables and isinstance(t, pytd.CallableType)):
                t = pytd.GenericType(base_type=t.base_type, parameters=(pytd.AnythingType(), t.ret))
            type_list.append(t)
        union = union.Replace(type_list=tuple(type_list))
    collect = {}
    has_redundant_base_types = False
    for t in union.type_list:
        if isinstance(t, pytd.GenericType):
            key = self._key(t)
            if (key in collect):
                has_redundant_base_types = True
                collect[key] = tuple((pytd_utils.JoinTypes([p1, p2]) for (p1, p2) in zip(collect[key], t.parameters)))
            else:
                collect[key] = t.parameters
    if (not has_redundant_base_types):
        return union
    result = pytd.NothingType()
    done = set()
    for t in union.type_list:
        if isinstance(t, pytd.GenericType):
            key = self._key(t)
            if (key in done):
                continue
            parameters = collect[key]
            add = t.Replace(parameters=tuple((p.Visit(CombineContainers()) for p in parameters)))
            done.add(key)
        else:
            add = t
        result = pytd_utils.JoinTypes([result, add])
    return result
Push unions down into containers.

This collects similar container types in unions and merges them into
single instances with the union type pushed down to the element_type level.

Arguments:
  union: A pytd.Union instance. Might appear in a parameter, a return type,
    a constant type, etc.

Returns:
  A simplified pytd.Union.
def VisitUnionType(self, union):
    'Push unions down into containers.\n\n    This collects similar container types in unions and merges them into\n    single instances with the union type pushed down to the element_type level.\n\n    Arguments:\n      union: A pytd.Union instance. Might appear in a parameter, a return type,\n        a constant type, etc.\n\n    Returns:\n      A simplified pytd.Union.\n    '
    if (not any((isinstance(t, pytd.GenericType) for t in union.type_list))):
        return union
    union = pytd_utils.JoinTypes(union.type_list)
    if (not isinstance(union, pytd.UnionType)):
        union = pytd.UnionType((union,))
    merge_tuples = self._should_merge(pytd.TupleType, union)
    merge_callables = self._should_merge(pytd.CallableType, union)
    if (merge_tuples or merge_callables):
        type_list = []
        for t in union.type_list:
            if (merge_tuples and isinstance(t, pytd.TupleType)):
                t = pytd.GenericType(base_type=t.base_type, parameters=(pytd.UnionType(t.parameters),))
            elif (merge_callables and isinstance(t, pytd.CallableType)):
                t = pytd.GenericType(base_type=t.base_type, parameters=(pytd.AnythingType(), t.ret))
            type_list.append(t)
        union = union.Replace(type_list=tuple(type_list))
    collect = {}
    has_redundant_base_types = False
    for t in union.type_list:
        if isinstance(t, pytd.GenericType):
            key = self._key(t)
            if (key in collect):
                has_redundant_base_types = True
                collect[key] = tuple((pytd_utils.JoinTypes([p1, p2]) for (p1, p2) in zip(collect[key], t.parameters)))
            else:
                collect[key] = t.parameters
    if (not has_redundant_base_types):
        return union
    result = pytd.NothingType()
    done = set()
    for t in union.type_list:
        if isinstance(t, pytd.GenericType):
            key = self._key(t)
            if (key in done):
                continue
            parameters = collect[key]
            add = t.Replace(parameters=tuple((p.Visit(CombineContainers()) for p in parameters)))
            done.add(key)
        else:
            add = t
        result = pytd_utils.JoinTypes([result, add])
    return result