def ast_walk(root, dispatcher, debug=False):
    """Walk the given tree and for each node apply the corresponding function
    as defined by the dispatcher.
    
    If one node type does not have any function defined for it, it simply
    returns the node unchanged.
    
    Parameters
    ----------
    root : Node
        top of the tree to walk into.
    dispatcher : Dispatcher
        defines the action for each node type.
    """
    def _walker(par):
        children = []
        for c in par.children:
            children.append(_walker(c))

        par.children = [c for c in children if c is not None]
        try:
            func = dispatcher.action_dict[par.type]
            return func(par)
        except __HOLE__:
            if debug:
                print("no action for type %s" % par.type)
            return par

    # FIXME: we need to copy the dict because the dispatcher modify the dict in
    # place ATM, and we call this often. This is very expensive, and should be
    # removed as it has a huge cost in starting time (~30 % in hot case)
    return _walker(__copy(root))
dataset/ETHPy150Open cournape/Bento/bento/parser/nodes.py/ast_walk