docs: def get_signature(func):
      """
      Gathers information about the call signature of `func`.
      """
      code = func.__code__
  
      # Names of regular parameters
      parameters = tuple(code.co_varnames[:code.co_argcount])
  
      # Flags
      has_varargs = bool(code.co_flags & inspect.CO_VARARGS)
      has_varkw = bool(code.co_flags & inspect.CO_VARKEYWORDS)
      has_kwonly = bool(code.co_kwonlyargcount)
  
      # A mapping of parameter names to default values
      default_values = func.__defaults__ or ()
      defaults = dict(zip(parameters[-len(default_values):], default_values))
  
      # Type annotations for all parameters
      type_hints = typing.get_type_hints(func) if typing else func.__annotations__
      types = tuple(normalize_type(type_hints.get(param, AnyType)) for param in parameters)
  
      # Type annotations for required parameters
      required = types[:-len(defaults)] if defaults else types
  
      # Complexity
      complexity = tuple(map(type_complexity, types)) if typing else None
  
      return Signature(parameters, types, complexity, defaults, required,
                       has_varargs, has_varkw, has_kwonly)