'Perform a depth-first search on the given DiGraph, with a limit on maximum steps.
:param networkx.DiGraph graph:  The graph to traverse.
:param Any source:              The source to begin traversal.
:param int max_steps:           Maximum steps of the traversal, or None if not limiting steps.
:return: An iterator of edges.'

@staticmethod
def _dfs_edges(graph, source, max_steps=None):

    if (max_steps is None):
        (yield networkx.dfs_edges(graph, source))
    else:
        steps_map = defaultdict(int)
        traversed = {source}
        stack = [source]
        while stack:
            src = stack.pop()
            for dst in graph.successors(src):
                if (dst in traversed):
                    continue
                traversed.add(dst)
                dst_steps = max((steps_map[src] + 1), steps_map[dst])
                if (dst_steps > max_steps):
                    continue
                (yield (src, dst))
                steps_map[dst] = dst_steps
                stack.append(dst)
