def _traverse(obj: Any, root: bool=False) -> Node:
    'Walk the object depth first.'
    obj_type = type(obj)
    py_version = (sys.version_info.major, sys.version_info.minor)
    children: List[Node]

    def iter_rich_args(rich_args) -> Iterable[Union[(Any, Tuple[(str, Any)])]]:
        for arg in rich_args:
            if isinstance(arg, tuple):
                if (len(arg) == 3):
                    (key, child, default) = arg
                    if (default == child):
                        continue
                    (yield (key, child))
                elif (len(arg) == 2):
                    (key, child) = arg
                    (yield (key, child))
                elif (len(arg) == 1):
                    (yield arg[0])
            else:
                (yield arg)
    if hasattr(obj, '__rich_repr__'):
        args = list(iter_rich_args(obj.__rich_repr__()))
        if args:
            children = []
            append = children.append
            node = Node(open_brace=f'{obj.__class__.__name__}(', close_brace=')', children=children, last=root)
            for (last, arg) in loop_last(args):
                if isinstance(arg, tuple):
                    (key, child) = arg
                    child_node = _traverse(child)
                    child_node.last = last
                    child_node.key_repr = key
                    child_node.last = last
                    child_node.key_separator = '='
                    append(child_node)
                else:
                    child_node = _traverse(arg)
                    child_node.last = last
                    append(child_node)
        else:
            node = Node(value_repr=f'{obj.__class__.__name__}()', children=[], last=root)
    elif (is_dataclass(obj) and (not isinstance(obj, type)) and (('__create_fn__' in obj.__repr__.__qualname__) or (py_version == (3, 6)))):
        obj_id = id(obj)
        if (obj_id in visited_ids):
            return Node(value_repr='...')
        push_visited(obj_id)
        children = []
        append = children.append
        node = Node(open_brace=f'{obj.__class__.__name__}(', close_brace=')', children=children, last=root)
        for (last, field) in loop_last(fields(obj)):
            if field.repr:
                child_node = _traverse(getattr(obj, field.name))
                child_node.key_repr = field.name
                child_node.last = last
                child_node.key_separator = '='
                append(child_node)
        pop_visited(obj_id)
    elif (obj_type in _CONTAINERS):
        obj_id = id(obj)
        if (obj_id in visited_ids):
            return Node(value_repr='...')
        push_visited(obj_id)
        (open_brace, close_brace, empty) = _BRACES[obj_type](obj)
        if obj:
            children = []
            node = Node(open_brace=open_brace, close_brace=close_brace, children=children, last=root)
            append = children.append
            num_items = len(obj)
            last_item_index = (num_items - 1)
            if isinstance(obj, _MAPPING_CONTAINERS):
                iter_items = iter(obj.items())
                if (max_length is not None):
                    iter_items = islice(iter_items, max_length)
                for (index, (key, child)) in enumerate(iter_items):
                    child_node = _traverse(child)
                    child_node.key_repr = to_repr(key)
                    child_node.last = (index == last_item_index)
                    append(child_node)
            else:
                iter_values = iter(obj)
                if (max_length is not None):
                    iter_values = islice(iter_values, max_length)
                for (index, child) in enumerate(iter_values):
                    child_node = _traverse(child)
                    child_node.last = (index == last_item_index)
                    append(child_node)
            if ((max_length is not None) and (num_items > max_length)):
                append(Node(value_repr=f'... +{(num_items - max_length)}', last=True))
        else:
            node = Node(empty=empty, children=[], last=root)
        pop_visited(obj_id)
    else:
        node = Node(value_repr=to_repr(obj), last=root)
    node.is_tuple = isinstance(obj, tuple)
    return node
Walk the object depth first.
def _traverse(obj: Any, root: bool=False) -> Node:
    
    obj_type = type(obj)
    py_version = (sys.version_info.major, sys.version_info.minor)
    children: List[Node]

    def iter_rich_args(rich_args) -> Iterable[Union[(Any, Tuple[(str, Any)])]]:
        for arg in rich_args:
            if isinstance(arg, tuple):
                if (len(arg) == 3):
                    (key, child, default) = arg
                    if (default == child):
                        continue
                    (yield (key, child))
                elif (len(arg) == 2):
                    (key, child) = arg
                    (yield (key, child))
                elif (len(arg) == 1):
                    (yield arg[0])
            else:
                (yield arg)
    if hasattr(obj, '__rich_repr__'):
        args = list(iter_rich_args(obj.__rich_repr__()))
        if args:
            children = []
            append = children.append
            node = Node(open_brace=f'{obj.__class__.__name__}(', close_brace=')', children=children, last=root)
            for (last, arg) in loop_last(args):
                if isinstance(arg, tuple):
                    (key, child) = arg
                    child_node = _traverse(child)
                    child_node.last = last
                    child_node.key_repr = key
                    child_node.last = last
                    child_node.key_separator = '='
                    append(child_node)
                else:
                    child_node = _traverse(arg)
                    child_node.last = last
                    append(child_node)
        else:
            node = Node(value_repr=f'{obj.__class__.__name__}()', children=[], last=root)
    elif (is_dataclass(obj) and (not isinstance(obj, type)) and (('__create_fn__' in obj.__repr__.__qualname__) or (py_version == (3, 6)))):
        obj_id = id(obj)
        if (obj_id in visited_ids):
            return Node(value_repr='...')
        push_visited(obj_id)
        children = []
        append = children.append
        node = Node(open_brace=f'{obj.__class__.__name__}(', close_brace=')', children=children, last=root)
        for (last, field) in loop_last(fields(obj)):
            if field.repr:
                child_node = _traverse(getattr(obj, field.name))
                child_node.key_repr = field.name
                child_node.last = last
                child_node.key_separator = '='
                append(child_node)
        pop_visited(obj_id)
    elif (obj_type in _CONTAINERS):
        obj_id = id(obj)
        if (obj_id in visited_ids):
            return Node(value_repr='...')
        push_visited(obj_id)
        (open_brace, close_brace, empty) = _BRACES[obj_type](obj)
        if obj:
            children = []
            node = Node(open_brace=open_brace, close_brace=close_brace, children=children, last=root)
            append = children.append
            num_items = len(obj)
            last_item_index = (num_items - 1)
            if isinstance(obj, _MAPPING_CONTAINERS):
                iter_items = iter(obj.items())
                if (max_length is not None):
                    iter_items = islice(iter_items, max_length)
                for (index, (key, child)) in enumerate(iter_items):
                    child_node = _traverse(child)
                    child_node.key_repr = to_repr(key)
                    child_node.last = (index == last_item_index)
                    append(child_node)
            else:
                iter_values = iter(obj)
                if (max_length is not None):
                    iter_values = islice(iter_values, max_length)
                for (index, child) in enumerate(iter_values):
                    child_node = _traverse(child)
                    child_node.last = (index == last_item_index)
                    append(child_node)
            if ((max_length is not None) and (num_items > max_length)):
                append(Node(value_repr=f'... +{(num_items - max_length)}', last=True))
        else:
            node = Node(empty=empty, children=[], last=root)
        pop_visited(obj_id)
    else:
        node = Node(value_repr=to_repr(obj), last=root)
    node.is_tuple = isinstance(obj, tuple)
    return node