nodes: 0, module; 1, function_definition; 2, function_name:traceParseAction; 3, parameters; 4, block; 5, identifier:f; 6, expression_statement; 7, expression_statement; 8, function_definition; 9, try_statement; 10, return_statement; 11, comment:"""Decorator for debugging parse actions.
  
      When the parse action is called, this decorator will print
      ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``.
      When the parse action completes, the decorator will print
      ``"<<"`` followed by the returned value, or any exception that the parse action raised.
  
      Example::
  
          wd = Word(alphas)
  
          @traceParseAction
          def remove_duplicate_chars(tokens):
              return ''.join(sorted(set(''.join(tokens))))
  
          wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
          print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
  
      prints::
  
          >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
          <<leaving remove_duplicate_chars (ret: 'dfjkls')
          ['dfjkls']
      """; 12, assignment; 13, function_name:z; 14, parameters; 15, block; 16, block; 17, except_clause; 18, identifier:z; 19, identifier:f; 20, call; 21, list_splat_pattern; 22, expression_statement; 23, expression_statement; 24, if_statement; 25, expression_statement; 26, try_statement; 27, expression_statement; 28, return_statement; 29, expression_statement; 30, identifier:AttributeError; 31, block; 32, identifier:_trim_arity; 33, argument_list; 34, identifier:paArgs; 35, assignment; 36, assignment; 37, comparison_operator:len(paArgs)>3; 38, block; 39, call; 40, block; 41, except_clause; 42, call; 43, identifier:ret; 44, assignment; 45, pass_statement; 46, identifier:f; 47, identifier:thisFunc; 48, attribute; 49, pattern_list; 50, subscript; 51, call; 52, integer:3; 53, expression_statement; 54, attribute; 55, argument_list; 56, expression_statement; 57, as_pattern; 58, block; 59, attribute; 60, argument_list; 61, attribute; 62, attribute; 63, identifier:f; 64, identifier:__name__; 65, identifier:s; 66, identifier:l; 67, identifier:t; 68, identifier:paArgs; 69, slice; 70, identifier:len; 71, argument_list; 72, assignment; 73, attribute; 74, identifier:write; 75, binary_operator:">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t); 76, assignment; 77, identifier:Exception; 78, as_pattern_target; 79, expression_statement; 80, raise_statement; 81, attribute; 82, identifier:write; 83, binary_operator:"<<leaving %s (ret: %r)\n" % (thisFunc,ret); 84, identifier:z; 85, identifier:__name__; 86, identifier:f; 87, identifier:__name__; 88, unary_operator; 89, identifier:paArgs; 90, identifier:thisFunc; 91, binary_operator:paArgs[0].__class__.__name__ + '.' + thisFunc; 92, identifier:sys; 93, identifier:stderr; 94, string:">>entering %s(line: '%s', %d, %r)\n"; 95, tuple; 96, identifier:ret; 97, call; 98, identifier:exc; 99, call; 100, identifier:sys; 101, identifier:stderr; 102, string:"<<leaving %s (ret: %r)\n"; 103, tuple; 104, integer:3; 105, binary_operator:paArgs[0].__class__.__name__ + '.'; 106, identifier:thisFunc; 107, identifier:thisFunc; 108, call; 109, identifier:l; 110, identifier:t; 111, identifier:f; 112, argument_list; 113, attribute; 114, argument_list; 115, identifier:thisFunc; 116, identifier:ret; 117, attribute; 118, string; 119, identifier:line; 120, argument_list; 121, list_splat; 122, attribute; 123, identifier:write; 124, binary_operator:"<<leaving %s (exception: %s)\n" % (thisFunc,exc); 125, attribute; 126, identifier:__name__; 127, string_content:.; 128, identifier:l; 129, identifier:s; 130, identifier:paArgs; 131, identifier:sys; 132, identifier:stderr; 133, string:"<<leaving %s (exception: %s)\n"; 134, tuple; 135, subscript; 136, identifier:__class__; 137, identifier:thisFunc; 138, identifier:exc; 139, identifier:paArgs; 140, integer:0
code: def traceParseAction(f):
      """Decorator for debugging parse actions.
  
      When the parse action is called, this decorator will print
      ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``.
      When the parse action completes, the decorator will print
      ``"<<"`` followed by the returned value, or any exception that the parse action raised.
  
      Example::
  
          wd = Word(alphas)
  
          @traceParseAction
          def remove_duplicate_chars(tokens):
              return ''.join(sorted(set(''.join(tokens))))
  
          wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
          print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
  
      prints::
  
          >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
          <<leaving remove_duplicate_chars (ret: 'dfjkls')
          ['dfjkls']
      """
      f = _trim_arity(f)
      def z(*paArgs):
          thisFunc = f.__name__
          s,l,t = paArgs[-3:]
          if len(paArgs)>3:
              thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
          sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
          try:
              ret = f(*paArgs)
          except Exception as exc:
              sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
              raise
          sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
          return ret
      try:
          z.__name__ = f.__name__
      except AttributeError:
          pass
      return z