in uberpoet/dotreader.py [0:0]
def find_roots_in_dep_map(self, dep_map):
# type: (Dict[str, List[str]]) -> List[str]
"""
Finds the roots in the DAG represented by a outgoing edge map.
If it returns empty, then you have cycles and thus don't have a DAG.
"""
incoming = self.incoming_edge_map_from_dep_map(dep_map)
# A node with no incoming edges and some outgoing edges is a root in a DAG
# Nodes with no edges are not really part of a graph, so we ignore them
return [node for node, incoming_edges in incoming.iteritems() if not incoming_edges and dep_map[node]]