nodes: 0, module; 1, function_definition; 2, function_name:sort; 3, parameters; 4, block; 5, identifier:self; 6, list_splat_pattern; 7, dictionary_splat_pattern; 8, expression_statement; 9, expression_statement; 10, for_statement; 11, expression_statement; 12, return_statement; 13, identifier:columns; 14, identifier:options; 15, comment:"""
          Return a new query which will produce results sorted by
          one or more metrics or dimensions. You may use plain
          strings for the columns, or actual `Column`, `Metric`
          and `Dimension` objects.
  
          Add a minus in front of the metric (either the string or
          the object) to sort in descending order.
  
          ```python
          # sort using strings
          query.sort('pageviews', '-device type')
          # alternatively, ask for a descending sort in a keyword argument
          query.sort('pageviews', descending=True)
  
          # sort using metric, dimension or column objects
          pageviews = profile.core.metrics['pageviews']
          query.sort(-pageviews)
          ```
          """; 16, assignment; 17, identifier:column; 18, identifier:columns; 19, block; 20, assignment; 21, identifier:self; 22, identifier:sorts; 23, call; 24, if_statement; 25, if_statement; 26, expression_statement; 27, subscript; 28, call; 29, attribute; 30, argument_list; 31, call; 32, block; 33, elif_clause; 34, else_clause; 35, identifier:descending; 36, block; 37, else_clause; 38, call; 39, attribute; 40, string; 41, attribute; 42, argument_list; 43, attribute; 44, identifier:setdefault; 45, string; 46, list; 47, identifier:isinstance; 48, argument_list; 49, expression_statement; 50, call; 51, block; 52, block; 53, expression_statement; 54, block; 55, attribute; 56, argument_list; 57, identifier:self; 58, identifier:raw; 59, string_content:sort; 60, string:","; 61, identifier:join; 62, identifier:sorts; 63, identifier:self; 64, identifier:meta; 65, string_content:sort; 66, identifier:column; 67, identifier:Column; 68, assignment; 69, identifier:isinstance; 70, argument_list; 71, expression_statement; 72, expression_statement; 73, raise_statement; 74, assignment; 75, expression_statement; 76, identifier:sorts; 77, identifier:append; 78, binary_operator:sign + identifier; 79, identifier:identifier; 80, attribute; 81, identifier:column; 82, attribute; 83, assignment; 84, assignment; 85, call; 86, identifier:sign; 87, string; 88, assignment; 89, identifier:sign; 90, identifier:identifier; 91, identifier:column; 92, identifier:id; 93, identifier:utils; 94, identifier:basestring; 95, identifier:descending; 96, boolean_operator; 97, identifier:identifier; 98, attribute; 99, identifier:ValueError; 100, argument_list; 101, string_content:-; 102, identifier:sign; 103, string; 104, call; 105, call; 106, subscript; 107, identifier:id; 108, call; 109, attribute; 110, argument_list; 111, attribute; 112, argument_list; 113, attribute; 114, call; 115, attribute; 116, argument_list; 117, identifier:column; 118, identifier:startswith; 119, string; 120, identifier:options; 121, identifier:get; 122, string; 123, False; 124, attribute; 125, identifier:columns; 126, attribute; 127, argument_list; 128, string:"Can only sort on columns or column strings. Received: {}"; 129, identifier:format; 130, identifier:column; 131, string_content:-; 132, string_content:descending; 133, identifier:self; 134, identifier:api; 135, identifier:column; 136, identifier:lstrip; 137, string; 138, string_content:-
code: def sort(self, *columns, **options):
          """
          Return a new query which will produce results sorted by
          one or more metrics or dimensions. You may use plain
          strings for the columns, or actual `Column`, `Metric`
          and `Dimension` objects.
  
          Add a minus in front of the metric (either the string or
          the object) to sort in descending order.
  
          ```python
          # sort using strings
          query.sort('pageviews', '-device type')
          # alternatively, ask for a descending sort in a keyword argument
          query.sort('pageviews', descending=True)
  
          # sort using metric, dimension or column objects
          pageviews = profile.core.metrics['pageviews']
          query.sort(-pageviews)
          ```
          """
  
          sorts = self.meta.setdefault('sort', [])
  
          for column in columns:
              if isinstance(column, Column):
                  identifier = column.id
              elif isinstance(column, utils.basestring):
                  descending = column.startswith('-') or options.get('descending', False)
                  identifier = self.api.columns[column.lstrip('-')].id
              else:
                  raise ValueError("Can only sort on columns or column strings. Received: {}".format(column))
  
              if descending:
                  sign = '-'
              else:
                  sign = ''
  
              sorts.append(sign + identifier)
  
          self.raw['sort'] = ",".join(sorts)
          return self