nodes: 0, module; 1, function_definition; 2, function_name:attribute_crawl; 3, parameters; 4, block; 5, identifier:self; 6, identifier:key; 7, expression_statement; 8, expression_statement; 9, for_statement; 10, return_statement; 11, comment:"""
          Grab all attribute values associated with the given feature.
  
          Traverse the given feature (and all of its descendants) to find all
          values associated with the given attribute key.
  
          >>> import tag
          >>> reader = tag.GFF3Reader(tag.pkgdata('otau-no-seqreg.gff3'))
          >>> features = tag.select.features(reader)
          >>> for feature in features:
          ...     names = feature.attribute_crawl('Name')
          ...     print(sorted(list(names)))
          ['Ot01g00060', 'XM_003074019.1', 'XP_003074065.1']
          ['Ot01g00070', 'XM_003074020.1', 'XP_003074066.1']
          ['Ot01g00080', 'XM_003074021.1', 'XP_003074067.1']
          ['Ot01g00090', 'XM_003074022.1', 'XP_003074068.1']
          ['Ot01g00100', 'XM_003074023.1', 'XP_003074069.1']
          ['Ot01g00110', 'XM_003074024.1', 'XP_003074070.1']
          """; 12, assignment; 13, identifier:feature; 14, identifier:self; 15, block; 16, identifier:union; 17, identifier:union; 18, call; 19, expression_statement; 20, if_statement; 21, identifier:set; 22, argument_list; 23, assignment; 24, comparison_operator:values is not None; 25, block; 26, identifier:values; 27, call; 28, identifier:values; 29, None; 30, expression_statement; 31, attribute; 32, argument_list; 33, call; 34, identifier:feature; 35, identifier:get_attribute; 36, identifier:key; 37, keyword_argument; 38, attribute; 39, argument_list; 40, identifier:as_list; 41, True; 42, identifier:union; 43, identifier:update; 44, call; 45, identifier:set; 46, argument_list; 47, identifier:values
code: def attribute_crawl(self, key):
          """
          Grab all attribute values associated with the given feature.
  
          Traverse the given feature (and all of its descendants) to find all
          values associated with the given attribute key.
  
          >>> import tag
          >>> reader = tag.GFF3Reader(tag.pkgdata('otau-no-seqreg.gff3'))
          >>> features = tag.select.features(reader)
          >>> for feature in features:
          ...     names = feature.attribute_crawl('Name')
          ...     print(sorted(list(names)))
          ['Ot01g00060', 'XM_003074019.1', 'XP_003074065.1']
          ['Ot01g00070', 'XM_003074020.1', 'XP_003074066.1']
          ['Ot01g00080', 'XM_003074021.1', 'XP_003074067.1']
          ['Ot01g00090', 'XM_003074022.1', 'XP_003074068.1']
          ['Ot01g00100', 'XM_003074023.1', 'XP_003074069.1']
          ['Ot01g00110', 'XM_003074024.1', 'XP_003074070.1']
          """
          union = set()
          for feature in self:
              values = feature.get_attribute(key, as_list=True)
              if values is not None:
                  union.update(set(values))
          return union