'Generic traversal of the DAG represented by this spec.
This will yield each node in the spec.  Options:
order    [=pre|post]
Order to traverse spec nodes. Defaults to preorder traversal.
Options are:
\'pre\':  Pre-order traversal; each node is yielded before its
children in the dependency DAG.
\'post\': Post-order  traversal; each node is yielded after its
children in the dependency DAG.
cover    [=nodes|edges|paths]
Determines how extensively to cover the dag.  Possible values:
\'nodes\': Visit each node in the dag only once.  Every node
yielded by this function will be unique.
\'edges\': If a node has been visited once but is reached along a
new path from the root, yield it but do not descend
into it.  This traverses each \'edge\' in the DAG once.
\'paths\': Explore every unique path reachable from the root.
This descends into visited subtrees and will yield
nodes twice if they\'re reachable by multiple paths.
depth    [=False]
Defaults to False.  When True, yields not just nodes in the
spec, but also their depth from the root in a (depth, node)
tuple.
key   [=id]
Allow a custom key function to track the identity of nodes
in the traversal.
root     [=True]
If False, this won\'t yield the root node, just its descendents.
direction [=children|parents]
If \'children\', does a traversal of this spec\'s children.  If
\'parents\', traverses upwards in the DAG towards the root.'

def traverse_edges(self, visited=None, d=0, deptype=None, deptype_query=None, dep_spec=None, **kwargs):

    depth = kwargs.get('depth', False)
    key_fun = kwargs.get('key', id)
    if isinstance(key_fun, string_types):
        key_fun = attrgetter(key_fun)
    yield_root = kwargs.get('root', True)
    cover = kwargs.get('cover', 'nodes')
    direction = kwargs.get('direction', 'children')
    order = kwargs.get('order', 'pre')
    deptype = canonical_deptype(deptype)
    if (deptype_query is None):
        deptype_query = ('link', 'run')
    def validate(name, val, allowed_values):
        if (val not in allowed_values):
            raise ValueError(('Invalid    value    for    %s:    %s.        Choices    are    %s' % (name, val, ','.join(allowed_values))))
    validate('cover', cover, ('nodes', 'edges', 'paths'))
    validate('direction', direction, ('children', 'parents'))
    validate('order', order, ('pre', 'post'))
    if (visited is None):
        visited = set()
    key = key_fun(self)
    if ((key in visited) and (cover == 'nodes')):
        return
    def return_val(dspec):
        if (not dspec):
            if (direction == 'parents'):
                dspec = DependencySpec(self, None, ())
            else:
                dspec = DependencySpec(None, self, ())
        return ((d, dspec) if depth else dspec)
    yield_me = (yield_root or (d > 0))
    if (yield_me and (order == 'pre')):
        (yield return_val(dep_spec))
    if (not ((key in visited) and (cover == 'edges'))):
        if (direction == 'children'):
            successors = self.dependencies_dict(deptype)
            succ = (lambda s: s.spec)
        elif (direction == 'parents'):
            successors = self.dependents_dict(deptype)
            succ = (lambda s: s.parent)
        else:
            raise ValueError(('Invalid    traversal    direction:    %s' % direction))
        visited.add(key)
        for (name, dspec) in sorted(successors.items()):
            child = successors[name]
            children = succ(child).traverse_edges(visited, d=(d + 1), deptype=deptype, deptype_query=deptype_query, dep_spec=dspec, **kwargs)
            for elt in children:
                (yield elt)
    if (yield_me and (order == 'post')):
        (yield return_val(dep_spec))
