nodes: 0, module; 1, function_definition; 2, function_name:sort_topologically; 3, parameters; 4, block; 5, identifier:dag; 6, expression_statement; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, while_statement; 11, if_statement; 12, return_statement; 13, comment:"""Sort the dag breath first topologically.
  
      Only the nodes inside the dag are returned, i.e. the nodes that are also keys.
  
      Returns:
           a topological ordering of the DAG.
      Raises:
           an error if this is not possible (graph is not valid).
      """; 14, assignment; 15, assignment; 16, assignment; 17, identifier:independent_nodes; 18, block; 19, comparison_operator:len(sorted_nodes) != len(dag.keys()); 20, block; 21, identifier:sorted_nodes; 22, identifier:dag; 23, call; 24, identifier:sorted_nodes; 25, list; 26, identifier:independent_nodes; 27, call; 28, expression_statement; 29, expression_statement; 30, comment:# this alters the dag so that we are sure we are visiting the nodes only once; 31, expression_statement; 32, while_statement; 33, call; 34, call; 35, raise_statement; 36, attribute; 37, argument_list; 38, identifier:deque; 39, argument_list; 40, assignment; 41, call; 42, assignment; 43, identifier:downstream_nodes; 44, block; 45, identifier:len; 46, argument_list; 47, identifier:len; 48, argument_list; 49, call; 50, identifier:copy; 51, identifier:deepcopy; 52, identifier:dag; 53, call; 54, identifier:node; 55, call; 56, attribute; 57, argument_list; 58, identifier:downstream_nodes; 59, subscript; 60, expression_statement; 61, if_statement; 62, if_statement; 63, identifier:sorted_nodes; 64, call; 65, identifier:ValueError; 66, argument_list; 67, identifier:get_independent_nodes; 68, argument_list; 69, attribute; 70, argument_list; 71, identifier:sorted_nodes; 72, identifier:append; 73, identifier:node; 74, identifier:dag; 75, identifier:node; 76, assignment; 77, comparison_operator:downstream_node not in dag; 78, block; 79, not_operator; 80, block; 81, attribute; 82, argument_list; 83, string; 84, identifier:dag; 85, identifier:independent_nodes; 86, identifier:popleft; 87, identifier:downstream_node; 88, call; 89, identifier:downstream_node; 90, identifier:dag; 91, continue_statement; 92, call; 93, expression_statement; 94, identifier:dag; 95, identifier:keys; 96, string_content:graph is not acyclic; 97, attribute; 98, argument_list; 99, identifier:has_dependencies; 100, argument_list; 101, call; 102, identifier:downstream_nodes; 103, identifier:pop; 104, integer:0; 105, identifier:downstream_node; 106, identifier:dag; 107, attribute; 108, argument_list; 109, identifier:independent_nodes; 110, identifier:append; 111, identifier:downstream_node
code: def sort_topologically(dag):
      """Sort the dag breath first topologically.
  
      Only the nodes inside the dag are returned, i.e. the nodes that are also keys.
  
      Returns:
           a topological ordering of the DAG.
      Raises:
           an error if this is not possible (graph is not valid).
      """
      dag = copy.deepcopy(dag)
      sorted_nodes = []
      independent_nodes = deque(get_independent_nodes(dag))
      while independent_nodes:
          node = independent_nodes.popleft()
          sorted_nodes.append(node)
          # this alters the dag so that we are sure we are visiting the nodes only once
          downstream_nodes = dag[node]
          while downstream_nodes:
              downstream_node = downstream_nodes.pop(0)
              if downstream_node not in dag:
                  continue
              if not has_dependencies(downstream_node, dag):
                  independent_nodes.append(downstream_node)
  
      if len(sorted_nodes) != len(dag.keys()):
          raise ValueError('graph is not acyclic')
      return sorted_nodes