nodes: 0, module; 1, function_definition; 2, function_name:toposort; 3, parameters; 4, block; 5, identifier:graph; 6, default_parameter; 7, expression_statement; 8, expression_statement; 9, for_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, while_statement; 14, comment:# Nodes may not be walked because they don't reach in degree 0.; 15, if_statement; 16, return_statement; 17, identifier:pick_first; 18, string; 19, comment:"""Toplogically sorts a list match graph.
  
      Tries to perform a topological sort using as tiebreaker the pick_first
      argument. If the graph contains cycles, raise ValueError.
      """; 20, assignment; 21, pattern_list; 22, call; 23, block; 24, assignment; 25, assignment; 26, assignment; 27, identifier:stk; 28, block; 29, comparison_operator:len(ordered) != len(graph) - 1; 30, block; 31, identifier:ordered; 32, string_content:head; 33, identifier:in_deg; 34, dictionary; 35, identifier:node; 36, identifier:next_nodes; 37, attribute; 38, argument_list; 39, for_statement; 40, identifier:stk; 41, list; 42, identifier:ordered; 43, list; 44, identifier:visited; 45, call; 46, expression_statement; 47, expression_statement; 48, if_statement; 49, expression_statement; 50, for_statement; 51, call; 52, binary_operator:len(graph) - 1; 53, raise_statement; 54, identifier:six; 55, identifier:iteritems; 56, identifier:graph; 57, identifier:next_node; 58, list; 59, block; 60, identifier:FIRST; 61, identifier:set; 62, argument_list; 63, assignment; 64, call; 65, comparison_operator:node != FIRST; 66, block; 67, assignment; 68, identifier:next_node; 69, identifier:traversal; 70, block; 71, identifier:len; 72, argument_list; 73, call; 74, integer:1; 75, call; 76, attribute; 77, attribute; 78, if_statement; 79, expression_statement; 80, identifier:node; 81, call; 82, attribute; 83, argument_list; 84, identifier:node; 85, identifier:FIRST; 86, expression_statement; 87, identifier:traversal; 88, call; 89, if_statement; 90, if_statement; 91, expression_statement; 92, if_statement; 93, identifier:ordered; 94, identifier:len; 95, argument_list; 96, identifier:ValueError; 97, argument_list; 98, identifier:next_nodes; 99, identifier:head_node; 100, identifier:next_nodes; 101, identifier:update_node; 102, comparison_operator:next_node is None; 103, block; 104, assignment; 105, attribute; 106, argument_list; 107, identifier:visited; 108, identifier:add; 109, identifier:node; 110, call; 111, identifier:_get_traversal; 112, argument_list; 113, comparison_operator:next_node is None; 114, block; 115, comparison_operator:next_node in visited; 116, block; 117, augmented_assignment; 118, comparison_operator:in_deg[next_node] == 0; 119, block; 120, identifier:graph; 121, string; 122, identifier:next_node; 123, None; 124, continue_statement; 125, subscript; 126, binary_operator:in_deg.get(next_node, 0) + 1; 127, identifier:stk; 128, identifier:pop; 129, attribute; 130, argument_list; 131, call; 132, identifier:pick_first; 133, identifier:next_node; 134, None; 135, continue_statement; 136, identifier:next_node; 137, identifier:visited; 138, raise_statement; 139, subscript; 140, integer:1; 141, subscript; 142, integer:0; 143, expression_statement; 144, string_content:Graph has a cycle; 145, identifier:in_deg; 146, identifier:next_node; 147, call; 148, integer:1; 149, identifier:ordered; 150, identifier:append; 151, identifier:node; 152, attribute; 153, argument_list; 154, call; 155, identifier:in_deg; 156, identifier:next_node; 157, identifier:in_deg; 158, identifier:next_node; 159, call; 160, attribute; 161, argument_list; 162, identifier:graph; 163, identifier:get; 164, identifier:node; 165, call; 166, identifier:ValueError; 167, argument_list; 168, attribute; 169, argument_list; 170, identifier:in_deg; 171, identifier:get; 172, identifier:next_node; 173, integer:0; 174, identifier:BeforeNodes; 175, argument_list; 176, string; 177, identifier:stk; 178, identifier:append; 179, identifier:next_node; 180, string_content:Graph has a cycle
code: def toposort(graph, pick_first='head'):
      """Toplogically sorts a list match graph.
  
      Tries to perform a topological sort using as tiebreaker the pick_first
      argument. If the graph contains cycles, raise ValueError.
      """
      in_deg = {}
      for node, next_nodes in six.iteritems(graph):
          for next_node in [next_nodes.head_node, next_nodes.update_node]:
              if next_node is None:
                  continue
              in_deg[next_node] = in_deg.get(next_node, 0) + 1
  
      stk = [FIRST]
      ordered = []
      visited = set()
      while stk:
          node = stk.pop()
          visited.add(node)
          if node != FIRST:
              ordered.append(node)
          traversal = _get_traversal(graph.get(node, BeforeNodes()), pick_first)
          for next_node in traversal:
              if next_node is None:
                  continue
              if next_node in visited:
                  raise ValueError('Graph has a cycle')
  
              in_deg[next_node] -= 1
              if in_deg[next_node] == 0:
                  stk.append(next_node)
  
      # Nodes may not be walked because they don't reach in degree 0.
      if len(ordered) != len(graph) - 1:
          raise ValueError('Graph has a cycle')
      return ordered