nodes: 0, module; 1, function_definition; 2, function_name:sort; 3, parameters; 4, block; 5, identifier:self; 6, identifier:key; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, default_parameter; 15, expression_statement; 16, if_statement; 17, expression_statement; 18, if_statement; 19, if_statement; 20, if_statement; 21, if_statement; 22, if_statement; 23, if_statement; 24, if_statement; 25, expression_statement; 26, return_statement; 27, identifier:start; 28, None; 29, identifier:num; 30, None; 31, identifier:by; 32, None; 33, identifier:get; 34, None; 35, identifier:desc; 36, False; 37, identifier:alpha; 38, False; 39, identifier:store; 40, None; 41, identifier:groups; 42, False; 43, string:'''Sort and return the list, set or sorted set at ``key``.
  
          ``start`` and ``num`` allow for paging through the sorted data
  
          ``by`` allows using an external key to weight and sort the items.
              Use an "*" to indicate where in the key the item value is located
  
          ``get`` allows for returning items from external keys rather than the
              sorted data itself.  Use an "*" to indicate where int he key
              the item value is located
  
          ``desc`` allows for reversing the sort
  
          ``alpha`` allows for sorting lexicographically rather than numerically
  
          ``store`` allows for storing the result of the sort into
              the key ``store``
  
          ``groups`` if set to True and if ``get`` contains at least two
              elements, sort will return a list of tuples, each containing the
              values fetched from the arguments to ``get``.
  
          '''; 44, parenthesized_expression; 45, block; 46, assignment; 47, comparison_operator:by is not None; 48, block; 49, boolean_operator; 50, block; 51, comparison_operator:get is not None; 52, comment:# If get is a string assume we want to get a single value.; 53, comment:# Otherwise assume it's an interable and we want to get multiple; 54, comment:# values. We can't just iterate blindly because strings are; 55, comment:# iterable.; 56, block; 57, identifier:desc; 58, block; 59, identifier:alpha; 60, block; 61, comparison_operator:store is not None; 62, block; 63, identifier:groups; 64, block; 65, assignment; 66, call; 67, boolean_operator; 68, raise_statement; 69, identifier:pieces; 70, list; 71, identifier:by; 72, None; 73, expression_statement; 74, expression_statement; 75, comparison_operator:start is not None; 76, comparison_operator:num is not None; 77, expression_statement; 78, expression_statement; 79, expression_statement; 80, identifier:get; 81, None; 82, if_statement; 83, expression_statement; 84, expression_statement; 85, identifier:store; 86, None; 87, expression_statement; 88, expression_statement; 89, if_statement; 90, identifier:options; 91, dictionary; 92, attribute; 93, argument_list; 94, parenthesized_expression; 95, parenthesized_expression; 96, call; 97, identifier:key; 98, call; 99, call; 100, identifier:start; 101, None; 102, identifier:num; 103, None; 104, call; 105, call; 106, call; 107, call; 108, block; 109, else_clause; 110, call; 111, call; 112, call; 113, call; 114, boolean_operator; 115, block; 116, pair; 117, identifier:self; 118, identifier:execute_command; 119, string; 120, list_splat; 121, dictionary_splat; 122, boolean_operator; 123, boolean_operator; 124, identifier:CommandError; 125, argument_list; 126, attribute; 127, argument_list; 128, attribute; 129, argument_list; 130, attribute; 131, argument_list; 132, attribute; 133, argument_list; 134, attribute; 135, argument_list; 136, identifier:isinstance; 137, argument_list; 138, expression_statement; 139, expression_statement; 140, block; 141, attribute; 142, argument_list; 143, attribute; 144, argument_list; 145, attribute; 146, argument_list; 147, attribute; 148, argument_list; 149, boolean_operator; 150, comparison_operator:len(get) < 2; 151, raise_statement; 152, string; 153, conditional_expression:len(get) if groups else None; 154, string_content:SORT; 155, identifier:pieces; 156, identifier:options; 157, comparison_operator:start is not None; 158, comparison_operator:num is None; 159, comparison_operator:num is not None; 160, comparison_operator:start is None; 161, string:"``start`` and ``num`` must both be specified"; 162, identifier:pieces; 163, identifier:append; 164, string; 165, identifier:pieces; 166, identifier:append; 167, identifier:by; 168, identifier:pieces; 169, identifier:append; 170, string; 171, identifier:pieces; 172, identifier:append; 173, identifier:start; 174, identifier:pieces; 175, identifier:append; 176, identifier:num; 177, identifier:get; 178, identifier:str; 179, call; 180, call; 181, for_statement; 182, identifier:pieces; 183, identifier:append; 184, string; 185, identifier:pieces; 186, identifier:append; 187, string; 188, identifier:pieces; 189, identifier:append; 190, string; 191, identifier:pieces; 192, identifier:append; 193, identifier:store; 194, not_operator; 195, call; 196, call; 197, integer:2; 198, call; 199, string_content:groups; 200, call; 201, identifier:groups; 202, None; 203, identifier:start; 204, None; 205, identifier:num; 206, None; 207, identifier:num; 208, None; 209, identifier:start; 210, None; 211, string_content:BY; 212, string_content:LIMIT; 213, attribute; 214, argument_list; 215, attribute; 216, argument_list; 217, identifier:g; 218, identifier:get; 219, block; 220, string_content:DESC; 221, string_content:ALPHA; 222, string_content:STORE; 223, identifier:get; 224, identifier:isinstance; 225, argument_list; 226, identifier:len; 227, argument_list; 228, identifier:CommandError; 229, argument_list; 230, identifier:len; 231, argument_list; 232, identifier:pieces; 233, identifier:append; 234, string; 235, identifier:pieces; 236, identifier:append; 237, identifier:get; 238, expression_statement; 239, expression_statement; 240, identifier:get; 241, identifier:str; 242, identifier:get; 243, concatenated_string; 244, identifier:get; 245, string_content:GET; 246, call; 247, call; 248, string:'when using "groups" the "get" argument '; 249, string; 250, string; 251, attribute; 252, argument_list; 253, attribute; 254, argument_list; 255, string_content:must be specified and contain at least; 256, string_content:two keys; 257, identifier:pieces; 258, identifier:append; 259, string; 260, identifier:pieces; 261, identifier:append; 262, identifier:g; 263, string_content:GET
code: def sort(self, key, start=None, num=None, by=None, get=None,
               desc=False, alpha=False, store=None, groups=False):
          '''Sort and return the list, set or sorted set at ``key``.
  
          ``start`` and ``num`` allow for paging through the sorted data
  
          ``by`` allows using an external key to weight and sort the items.
              Use an "*" to indicate where in the key the item value is located
  
          ``get`` allows for returning items from external keys rather than the
              sorted data itself.  Use an "*" to indicate where int he key
              the item value is located
  
          ``desc`` allows for reversing the sort
  
          ``alpha`` allows for sorting lexicographically rather than numerically
  
          ``store`` allows for storing the result of the sort into
              the key ``store``
  
          ``groups`` if set to True and if ``get`` contains at least two
              elements, sort will return a list of tuples, each containing the
              values fetched from the arguments to ``get``.
  
          '''
          if ((start is not None and num is None) or
                  (num is not None and start is None)):
              raise CommandError("``start`` and ``num`` must both be specified")
  
          pieces = [key]
          if by is not None:
              pieces.append('BY')
              pieces.append(by)
          if start is not None and num is not None:
              pieces.append('LIMIT')
              pieces.append(start)
              pieces.append(num)
          if get is not None:
              # If get is a string assume we want to get a single value.
              # Otherwise assume it's an interable and we want to get multiple
              # values. We can't just iterate blindly because strings are
              # iterable.
              if isinstance(get, str):
                  pieces.append('GET')
                  pieces.append(get)
              else:
                  for g in get:
                      pieces.append('GET')
                      pieces.append(g)
          if desc:
              pieces.append('DESC')
          if alpha:
              pieces.append('ALPHA')
          if store is not None:
              pieces.append('STORE')
              pieces.append(store)
  
          if groups:
              if not get or isinstance(get, str) or len(get) < 2:
                  raise CommandError('when using "groups" the "get" argument '
                                     'must be specified and contain at least '
                                     'two keys')
  
          options = {'groups': len(get) if groups else None}
          return self.execute_command('SORT', *pieces, **options)