code: def varnames(func):
      """Return tuple of positional and keywrord argument names for a function,
      method, class or callable.
  
      In case of a class, its ``__init__`` method is considered.
      For methods the ``self`` parameter is not included.
      """
      cache = getattr(func, "__dict__", {})
      try:
          return cache["_varnames"]
      except KeyError:
          pass
  
      if inspect.isclass(func):
          try:
              func = func.__init__
          except AttributeError:
              return (), ()
      elif not inspect.isroutine(func):  # callable object?
          try:
              func = getattr(func, "__call__", func)
          except Exception:
              return (), ()
  
      try:  # func MUST be a function or method here or we won't parse any args
          spec = _getargspec(func)
      except TypeError:
          return (), ()
  
      args, defaults = tuple(spec.args), spec.defaults
      if defaults:
          index = -len(defaults)
          args, kwargs = args[:index], tuple(args[index:])
      else:
          kwargs = ()
  
      # strip any implicit instance arg
      # pypy3 uses "obj" instead of "self" for default dunder methods
      implicit_names = ("self",) if not _PYPY3 else ("self", "obj")
      if args:
          if inspect.ismethod(func) or (
              "." in getattr(func, "__qualname__", ())
              and args[0] in implicit_names
          ):
              args = args[1:]
  
      try:
          cache["_varnames"] = args, kwargs
      except TypeError:
          pass
      return args, kwargs
  
imports: import inspect
  import sys
  import warnings
  from .callers import _legacymulticall, _multicall
label_desc: Use image node_id 2 for calling a global function with example usage: varnames(func) and returns: args,  kwargs, cache, ,  , ,  , ,  