nodes: 0, module; 1, function_definition; 2, function_name:sort_by; 3, parameters; 4, block; 5, identifier:self; 6, identifier:attr_or_key; 7, default_parameter; 8, expression_statement; 9, comment:# work out the direction; 10, if_statement; 11, if_statement; 12, expression_statement; 13, expression_statement; 14, identifier:direction; 15, string; 16, comment:"""Sort the view by an attribute or key
  
          :param attr_or_key: The attribute or key to sort by
          :param direction: Either `asc` or `desc` indicating the direction of
                            sorting
          """; 17, comparison_operator:direction in ('+', 'asc', gtk.SORT_ASCENDING); 18, block; 19, elif_clause; 20, else_clause; 21, call; 22, comment:# is a key; 23, block; 24, else_clause; 25, call; 26, call; 27, string_content:asc; 28, identifier:direction; 29, tuple; 30, expression_statement; 31, comparison_operator:direction in ('-', 'desc', gtk.SORT_DESCENDING); 32, block; 33, block; 34, identifier:callable; 35, argument_list; 36, expression_statement; 37, comment:# it's an attribute; 38, block; 39, attribute; 40, argument_list; 41, attribute; 42, argument_list; 43, string; 44, string; 45, attribute; 46, assignment; 47, identifier:direction; 48, tuple; 49, expression_statement; 50, raise_statement; 51, identifier:attr_or_key; 52, assignment; 53, expression_statement; 54, attribute; 55, identifier:set_default_sort_func; 56, identifier:sort_func; 57, identifier:attr_or_key; 58, attribute; 59, identifier:set_sort_column_id; 60, unary_operator; 61, identifier:direction; 62, string_content:+; 63, string_content:asc; 64, identifier:gtk; 65, identifier:SORT_ASCENDING; 66, identifier:direction; 67, attribute; 68, string; 69, string; 70, attribute; 71, assignment; 72, call; 73, identifier:sort_func; 74, attribute; 75, assignment; 76, identifier:self; 77, identifier:model; 78, identifier:self; 79, identifier:model; 80, integer:1; 81, identifier:gtk; 82, identifier:SORT_ASCENDING; 83, string_content:-; 84, string_content:desc; 85, identifier:gtk; 86, identifier:SORT_DESCENDING; 87, identifier:direction; 88, attribute; 89, identifier:AttributeError; 90, argument_list; 91, identifier:self; 92, identifier:_key_sort_func; 93, identifier:sort_func; 94, attribute; 95, identifier:gtk; 96, identifier:SORT_DESCENDING; 97, string; 98, identifier:self; 99, identifier:_attr_sort_func; 100, string_content:unrecognised direction
code: def sort_by(self, attr_or_key, direction='asc'):
          """Sort the view by an attribute or key
  
          :param attr_or_key: The attribute or key to sort by
          :param direction: Either `asc` or `desc` indicating the direction of
                            sorting
          """
          # work out the direction
          if direction in ('+', 'asc', gtk.SORT_ASCENDING):
              direction = gtk.SORT_ASCENDING
          elif direction in ('-', 'desc', gtk.SORT_DESCENDING):
              direction = gtk.SORT_DESCENDING
          else:
              raise AttributeError('unrecognised direction')
          if callable(attr_or_key):
              # is a key
              sort_func = self._key_sort_func
          else:
              # it's an attribute
              sort_func = self._attr_sort_func
          self.model.set_default_sort_func(sort_func, attr_or_key)
          self.model.set_sort_column_id(-1, direction)