nodes: 0, module; 1, function_definition; 2, function_name:cycles; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, function_definition; 8, comment:# First, let's get a iterable of all known cycles.; 9, expression_statement; 10, expression_statement; 11, comment:# Now, let's go through and sift through the cycles, finding; 12, comment:# the shortest unique cycle known, ignoring cycles which contain; 13, comment:# already known cycles.; 14, for_statement; 15, comment:# And return that unique list.; 16, return_statement; 17, comment:"""
          Fairly expensive cycle detection algorithm. This method
          will return the shortest unique cycles that were detected.
  
          Debug usage may look something like:
  
          print("The following cycles were found:")
          for cycle in network.cycles():
              print("    ", " -> ".join(cycle))
          """; 18, function_name:walk_node; 19, parameters; 20, block; 21, assignment; 22, assignment; 23, identifier:cycle; 24, call; 25, block; 26, identifier:shortest; 27, identifier:node; 28, identifier:seen; 29, expression_statement; 30, if_statement; 31, expression_statement; 32, for_statement; 33, identifier:cycles; 34, call; 35, identifier:shortest; 36, call; 37, identifier:sorted; 38, argument_list; 39, for_statement; 40, comment:"""
              Walk each top-level node we know about, and recurse
              along the graph.
              """; 41, comparison_operator:node in seen; 42, block; 43, call; 44, identifier:edge; 45, subscript; 46, block; 47, attribute; 48, argument_list; 49, identifier:set; 50, argument_list; 51, identifier:cycles; 52, keyword_argument; 53, identifier:el; 54, identifier:shortest; 55, block; 56, else_clause; 57, identifier:node; 58, identifier:seen; 59, expression_statement; 60, return_statement; 61, attribute; 62, argument_list; 63, attribute; 64, identifier:node; 65, for_statement; 66, identifier:chain; 67, identifier:from_iterable; 68, generator_expression; 69, identifier:key; 70, identifier:len; 71, if_statement; 72, block; 73, yield; 74, identifier:seen; 75, identifier:add; 76, identifier:node; 77, identifier:self; 78, identifier:edges; 79, identifier:cycle; 80, call; 81, block; 82, call; 83, for_in_clause; 84, call; 85, block; 86, expression_statement; 87, tuple; 88, identifier:walk_node; 89, argument_list; 90, expression_statement; 91, identifier:walk_node; 92, argument_list; 93, identifier:node; 94, attribute; 95, attribute; 96, argument_list; 97, break_statement; 98, call; 99, identifier:node; 100, identifier:edge; 101, call; 102, yield; 103, identifier:node; 104, call; 105, identifier:self; 106, identifier:nodes; 107, call; 108, identifier:issubset; 109, call; 110, attribute; 111, argument_list; 112, identifier:set; 113, argument_list; 114, binary_operator:(node,) + cycle; 115, identifier:set; 116, argument_list; 117, identifier:set; 118, argument_list; 119, identifier:set; 120, argument_list; 121, identifier:shortest; 122, identifier:add; 123, identifier:cycle; 124, identifier:seen; 125, tuple; 126, identifier:cycle; 127, identifier:el; 128, identifier:cycle; 129, identifier:node
code: def cycles(self):
          """
          Fairly expensive cycle detection algorithm. This method
          will return the shortest unique cycles that were detected.
  
          Debug usage may look something like:
  
          print("The following cycles were found:")
          for cycle in network.cycles():
              print("    ", " -> ".join(cycle))
          """
  
          def walk_node(node, seen):
              """
              Walk each top-level node we know about, and recurse
              along the graph.
              """
              if node in seen:
                  yield (node,)
                  return
              seen.add(node)
              for edge in self.edges[node]:
                  for cycle in walk_node(edge, set(seen)):
                      yield (node,) + cycle
  
          # First, let's get a iterable of all known cycles.
          cycles = chain.from_iterable(
              (walk_node(node, set()) for node in self.nodes))
  
          shortest = set()
          # Now, let's go through and sift through the cycles, finding
          # the shortest unique cycle known, ignoring cycles which contain
          # already known cycles.
          for cycle in sorted(cycles, key=len):
              for el in shortest:
                  if set(el).issubset(set(cycle)):
                      break
              else:
                  shortest.add(cycle)
          # And return that unique list.
          return shortest