def walk_down(root, skip=constantly(False), include_self=True): """Yield each node from here downward, myself included, in depth-first pre-order. :arg skip: A predicate decribing nodes to not descend into. We always return ourselves, even if the predicate says to skip us. :arg include_self: A flag for including the root in the walk down. The AST we get from Reflect.parse is somewhat unsatisfying. It's not a uniform tree shape; it seems to have already been turned into more specialized objects. Thus, we have to traverse into different fields depending on node type. """ if include_self: yield root for child in ifilter(is_node, iflatten(root.itervalues())): if skip(child): yield child continue # Just a "yield from": for ret in walk_down(child, skip=skip): yield ret
def iflatmap(func, lst): return fn.iflatten(imap(func, lst))
def fmt_options(options): return fn.iflatten(imap(fmt_option, options))
def aggregate_candidates(state): return fn.iflatten(imap(lambda x: fmt_candidates(x['name'], x['candidates']), state['sources']))