docs: def tracer(frame, event, arg):
      """This is an internal function that is called every time a call is made
      during a trace. It keeps track of relationships between calls.
      """
      global func_count_max
      global func_count
      global trace_filter
      global time_filter
      global call_stack
      global func_time
      global func_time_max
  
      if event == 'call':
          keep = True
          code = frame.f_code
  
          # Stores all the parts of a human readable name of the current call.
          full_name_list = []
  
          # Work out the module name
          module = inspect.getmodule(code)
          if module:
              module_name = module.__name__
              module_path = module.__file__
              if not settings['include_stdlib'] \
                  and is_module_stdlib(module_path):
                  keep = False
              if module_name == '__main__':
                  module_name = ''
          else:
              module_name = ''
          if module_name:
              full_name_list.append(module_name)
  
          # Work out the class name.
          try:
              class_name = frame.f_locals['self'].__class__.__name__
              full_name_list.append(class_name)
          except (KeyError, AttributeError):
              class_name = ''
  
          # Work out the current function or method
          func_name = code.co_name
          if func_name == '?':
              func_name = '__main__'
          full_name_list.append(func_name)
  
          # Create a readable representation of the current call
          full_name = '.'.join(full_name_list)
  
          # Load the trace filter, if any. 'keep' determines if we should ignore
          # this call
          if keep and trace_filter:
              keep = trace_filter(call_stack, module_name, class_name,
                  func_name, full_name)
  
          # Store the call information
          if keep:
  
              if call_stack:
                  fr = call_stack[-1]
              else:
                  fr = None
              if fr not in call_dict:
                  call_dict[fr] = {}
              if full_name not in call_dict[fr]:
                  call_dict[fr][full_name] = 0
              call_dict[fr][full_name] += 1
  
              if full_name not in func_count:
                  func_count[full_name] = 0
              func_count[full_name] += 1
              if func_count[full_name] > func_count_max:
                  func_count_max = func_count[full_name]
  
              call_stack.append(full_name)
              call_stack_timer.append(time.time())
  
          else:
              call_stack.append('')
              call_stack_timer.append(None)
  
      if event == 'return':
          if call_stack:
              full_name = call_stack.pop(-1)
              if call_stack_timer:
                  t = call_stack_timer.pop(-1)
              else:
                  t = None
              if t and time_filter(stack=call_stack, full_name=full_name):
                  if full_name not in func_time:
                      func_time[full_name] = 0
                  call_time = (time.time() - t)
                  func_time[full_name] += call_time
                  if func_time[full_name] > func_time_max:
                      func_time_max = func_time[full_name]
  
      return tracer