nodes: 0, module; 1, function_definition; 2, function_name:pipe_sort; 3, parameters; 4, block; 5, default_parameter; 6, default_parameter; 7, default_parameter; 8, dictionary_splat_pattern; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, return_statement; 21, identifier:context; 22, None; 23, identifier:_INPUT; 24, None; 25, identifier:conf; 26, None; 27, identifier:kwargs; 28, comment:"""An operator that sorts the input source according to the specified key.
      Not loopable. Not lazy.
  
      Parameters
      ----------
      context : pipe2py.Context object
      _INPUT : pipe2py.modules pipe like object (iterable of items)
      kwargs -- other inputs, e.g. to feed terminals for rule values
      conf : {
          'KEY': [
              {
                  'field': {'type': 'text', 'value': 'title'},
                  'dir': {'type': 'text', 'value': 'DESC'}
              }
          ]
      }
  
      Returns
      -------
      _OUTPUT : generator of sorted items
      """; 29, assignment; 30, assignment; 31, assignment; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, assignment; 38, assignment; 39, identifier:_OUTPUT; 40, identifier:test; 41, call; 42, identifier:_pass; 43, call; 44, identifier:key_defs; 45, call; 46, identifier:get_value; 47, call; 48, identifier:parse_conf; 49, call; 50, identifier:keys; 51, call; 52, identifier:order; 53, generator_expression; 54, identifier:comparers; 55, call; 56, identifier:cmp_func; 57, call; 58, identifier:_OUTPUT; 59, conditional_expression:_INPUT if _pass else iter(sorted(_INPUT, cmp=cmp_func)); 60, attribute; 61, argument_list; 62, attribute; 63, argument_list; 64, identifier:imap; 65, argument_list; 66, identifier:partial; 67, argument_list; 68, identifier:partial; 69, argument_list; 70, identifier:imap; 71, argument_list; 72, binary_operator:'%s%s' % ('-' if k.dir == 'DESC' else '', k.field); 73, for_in_clause; 74, identifier:map; 75, argument_list; 76, identifier:partial; 77, argument_list; 78, identifier:_INPUT; 79, identifier:_pass; 80, call; 81, identifier:kwargs; 82, identifier:pop; 83, string; 84, None; 85, identifier:utils; 86, identifier:get_pass; 87, keyword_argument; 88, identifier:DotDict; 89, call; 90, attribute; 91, dictionary_splat; 92, attribute; 93, keyword_argument; 94, dictionary_splat; 95, identifier:parse_conf; 96, identifier:key_defs; 97, string; 98, tuple; 99, identifier:k; 100, identifier:keys; 101, identifier:get_comparer; 102, identifier:order; 103, identifier:multikeysort; 104, keyword_argument; 105, identifier:iter; 106, argument_list; 107, string_content:pass_if; 108, identifier:test; 109, identifier:test; 110, attribute; 111, argument_list; 112, identifier:utils; 113, identifier:get_value; 114, identifier:kwargs; 115, identifier:utils; 116, identifier:parse_conf; 117, identifier:parse_func; 118, identifier:get_value; 119, identifier:kwargs; 120, string_content:%s%s; 121, conditional_expression:'-' if k.dir == 'DESC' else ''; 122, attribute; 123, identifier:comparers; 124, identifier:comparers; 125, call; 126, identifier:utils; 127, identifier:listize; 128, subscript; 129, string; 130, comparison_operator:k.dir == 'DESC'; 131, string; 132, identifier:k; 133, identifier:field; 134, identifier:sorted; 135, argument_list; 136, identifier:conf; 137, string; 138, string_content:-; 139, attribute; 140, string; 141, identifier:_INPUT; 142, keyword_argument; 143, string_content:KEY; 144, identifier:k; 145, identifier:dir; 146, string_content:DESC; 147, identifier:cmp; 148, identifier:cmp_func
code: def pipe_sort(context=None, _INPUT=None, conf=None, **kwargs):
      """An operator that sorts the input source according to the specified key.
      Not loopable. Not lazy.
  
      Parameters
      ----------
      context : pipe2py.Context object
      _INPUT : pipe2py.modules pipe like object (iterable of items)
      kwargs -- other inputs, e.g. to feed terminals for rule values
      conf : {
          'KEY': [
              {
                  'field': {'type': 'text', 'value': 'title'},
                  'dir': {'type': 'text', 'value': 'DESC'}
              }
          ]
      }
  
      Returns
      -------
      _OUTPUT : generator of sorted items
      """
      test = kwargs.pop('pass_if', None)
      _pass = utils.get_pass(test=test)
      key_defs = imap(DotDict, utils.listize(conf['KEY']))
      get_value = partial(utils.get_value, **kwargs)
      parse_conf = partial(utils.parse_conf, parse_func=get_value, **kwargs)
      keys = imap(parse_conf, key_defs)
      order = ('%s%s' % ('-' if k.dir == 'DESC' else '', k.field) for k in keys)
      comparers = map(get_comparer, order)
      cmp_func = partial(multikeysort, comparers=comparers)
      _OUTPUT = _INPUT if _pass else iter(sorted(_INPUT, cmp=cmp_func))
      return _OUTPUT