nodes: 0, module; 1, function_definition; 2, function_name:profile; 3, parameters; 4, block; 5, default_parameter; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, expression_statement; 14, if_statement; 15, comment:# @profile syntax -- we are a decorator.; 16, if_statement; 17, for_statement; 18, expression_statement; 19, comment:# fp = HotShotFuncProfile(fn, skip=skip, filename=filename, ...); 20, comment:# or HotShotFuncProfile; 21, comment:# We cannot return fp or fp.__call__ directly as that would break method; 22, comment:# definitions, instead we need to return a plain function.; 23, function_definition; 24, expression_statement; 25, expression_statement; 26, expression_statement; 27, expression_statement; 28, return_statement; 29, identifier:fn; 30, None; 31, identifier:skip; 32, integer:0; 33, identifier:filename; 34, None; 35, identifier:immediate; 36, False; 37, identifier:dirs; 38, False; 39, identifier:sort; 40, None; 41, identifier:entries; 42, integer:40; 43, identifier:profiler; 44, tuple; 45, comment:"""Mark `fn` for profiling.
  
      If `skip` is > 0, first `skip` calls to `fn` will not be profiled.
  
      If `immediate` is False, profiling results will be printed to
      sys.stdout on program termination.  Otherwise results will be printed
      after each call.
  
      If `dirs` is False only the name of the file will be printed.
      Otherwise the full path is used.
  
      `sort` can be a list of sort keys (defaulting to ['cumulative',
      'time', 'calls']).  The following ones are recognized::
  
          'calls'      -- call count
          'cumulative' -- cumulative time
          'file'       -- file name
          'line'       -- line number
          'module'     -- file name
          'name'       -- function name
          'nfl'        -- name/file/line
          'pcalls'     -- call count
          'stdname'    -- standard name
          'time'       -- internal time
  
      `entries` limits the output to the first N entries.
  
      `profiler` can be used to select the preferred profiler, or specify a
      sequence of them, in order of preference.  The default is ('cProfile'.
      'profile', 'hotshot').
  
      If `filename` is specified, the profile stats will be stored in the
      named file.  You can load them pstats.Stats(filename).
  
      Usage::
  
          def fn(...):
              ...
          fn = profile(fn, skip=1)
  
      If you are using Python 2.4, you should be able to use the decorator
      syntax::
  
          @profile(skip=3)
          def fn(...):
              ...
  
      or just ::
  
          @profile
          def fn(...):
              ...
  
      """; 46, comparison_operator:fn is None; 47, comment:# @profile() syntax -- we are a decorator maker; 48, block; 49, call; 50, block; 51, identifier:p; 52, identifier:profiler; 53, block; 54, else_clause; 55, assignment; 56, function_name:new_fn; 57, parameters; 58, block; 59, assignment; 60, assignment; 61, assignment; 62, assignment; 63, identifier:new_fn; 64, string; 65, string; 66, string; 67, identifier:fn; 68, None; 69, function_definition; 70, return_statement; 71, identifier:isinstance; 72, argument_list; 73, expression_statement; 74, if_statement; 75, block; 76, identifier:fp; 77, call; 78, list_splat_pattern; 79, dictionary_splat_pattern; 80, return_statement; 81, attribute; 82, attribute; 83, attribute; 84, attribute; 85, attribute; 86, attribute; 87, attribute; 88, attribute; 89, string_content:cProfile; 90, string_content:profile; 91, string_content:hotshot; 92, function_name:decorator; 93, parameters; 94, block; 95, identifier:decorator; 96, identifier:profiler; 97, identifier:str; 98, assignment; 99, comparison_operator:p in AVAILABLE_PROFILERS; 100, block; 101, raise_statement; 102, identifier:profiler_class; 103, argument_list; 104, identifier:args; 105, identifier:kw; 106, call; 107, identifier:new_fn; 108, identifier:__doc__; 109, identifier:fn; 110, identifier:__doc__; 111, identifier:new_fn; 112, identifier:__name__; 113, identifier:fn; 114, identifier:__name__; 115, identifier:new_fn; 116, identifier:__dict__; 117, identifier:fn; 118, identifier:__dict__; 119, identifier:new_fn; 120, identifier:__module__; 121, identifier:fn; 122, identifier:__module__; 123, identifier:fn; 124, return_statement; 125, identifier:profiler; 126, list; 127, identifier:p; 128, identifier:AVAILABLE_PROFILERS; 129, expression_statement; 130, break_statement; 131, call; 132, identifier:fn; 133, keyword_argument; 134, keyword_argument; 135, keyword_argument; 136, keyword_argument; 137, keyword_argument; 138, keyword_argument; 139, identifier:fp; 140, argument_list; 141, call; 142, identifier:profiler; 143, assignment; 144, identifier:ValueError; 145, argument_list; 146, identifier:skip; 147, identifier:skip; 148, identifier:filename; 149, identifier:filename; 150, identifier:immediate; 151, identifier:immediate; 152, identifier:dirs; 153, identifier:dirs; 154, identifier:sort; 155, identifier:sort; 156, identifier:entries; 157, identifier:entries; 158, list_splat; 159, dictionary_splat; 160, identifier:profile; 161, argument_list; 162, identifier:profiler_class; 163, subscript; 164, binary_operator:'only these profilers are available: %s'
                               % ', '.join(AVAILABLE_PROFILERS); 165, identifier:args; 166, identifier:kw; 167, identifier:fn; 168, keyword_argument; 169, keyword_argument; 170, keyword_argument; 171, keyword_argument; 172, keyword_argument; 173, keyword_argument; 174, keyword_argument; 175, identifier:AVAILABLE_PROFILERS; 176, identifier:p; 177, string; 178, call; 179, identifier:skip; 180, identifier:skip; 181, identifier:filename; 182, identifier:filename; 183, identifier:immediate; 184, identifier:immediate; 185, identifier:dirs; 186, identifier:dirs; 187, identifier:sort; 188, identifier:sort; 189, identifier:entries; 190, identifier:entries; 191, identifier:profiler; 192, identifier:profiler; 193, string_content:only these profilers are available: %s; 194, attribute; 195, argument_list; 196, string; 197, identifier:join; 198, identifier:AVAILABLE_PROFILERS; 199, string_content:,
code: def profile(fn=None, skip=0, filename=None, immediate=False, dirs=False,
              sort=None, entries=40,
              profiler=('cProfile', 'profile', 'hotshot')):
      """Mark `fn` for profiling.
  
      If `skip` is > 0, first `skip` calls to `fn` will not be profiled.
  
      If `immediate` is False, profiling results will be printed to
      sys.stdout on program termination.  Otherwise results will be printed
      after each call.
  
      If `dirs` is False only the name of the file will be printed.
      Otherwise the full path is used.
  
      `sort` can be a list of sort keys (defaulting to ['cumulative',
      'time', 'calls']).  The following ones are recognized::
  
          'calls'      -- call count
          'cumulative' -- cumulative time
          'file'       -- file name
          'line'       -- line number
          'module'     -- file name
          'name'       -- function name
          'nfl'        -- name/file/line
          'pcalls'     -- call count
          'stdname'    -- standard name
          'time'       -- internal time
  
      `entries` limits the output to the first N entries.
  
      `profiler` can be used to select the preferred profiler, or specify a
      sequence of them, in order of preference.  The default is ('cProfile'.
      'profile', 'hotshot').
  
      If `filename` is specified, the profile stats will be stored in the
      named file.  You can load them pstats.Stats(filename).
  
      Usage::
  
          def fn(...):
              ...
          fn = profile(fn, skip=1)
  
      If you are using Python 2.4, you should be able to use the decorator
      syntax::
  
          @profile(skip=3)
          def fn(...):
              ...
  
      or just ::
  
          @profile
          def fn(...):
              ...
  
      """
      if fn is None: # @profile() syntax -- we are a decorator maker
          def decorator(fn):
              return profile(fn, skip=skip, filename=filename,
                             immediate=immediate, dirs=dirs,
                             sort=sort, entries=entries,
                             profiler=profiler)
          return decorator
      # @profile syntax -- we are a decorator.
      if isinstance(profiler, str):
          profiler = [profiler]
      for p in profiler:
          if p in AVAILABLE_PROFILERS:
              profiler_class = AVAILABLE_PROFILERS[p]
              break
      else:
          raise ValueError('only these profilers are available: %s'
                               % ', '.join(AVAILABLE_PROFILERS))
      fp = profiler_class(fn, skip=skip, filename=filename,
                          immediate=immediate, dirs=dirs,
                          sort=sort, entries=entries)
      # fp = HotShotFuncProfile(fn, skip=skip, filename=filename, ...)
           # or HotShotFuncProfile
      # We cannot return fp or fp.__call__ directly as that would break method
      # definitions, instead we need to return a plain function.
      def new_fn(*args, **kw):
          return fp(*args, **kw)
      new_fn.__doc__ = fn.__doc__
      new_fn.__name__ = fn.__name__
      new_fn.__dict__ = fn.__dict__
      new_fn.__module__ = fn.__module__
      return new_fn