code: def getargspec(obj):
      """Get the names and default values of a callable's
         arguments
  
      A tuple of four things is returned: (args, varargs,
      varkw, defaults).
        - args is a list of the argument names (it may
          contain nested lists).
        - varargs and varkw are the names of the * and
          ** arguments or None.
        - defaults is a tuple of default argument values
          or None if there are no default arguments; if
          this tuple has n elements, they correspond to
          the last n elements listed in args.
  
      Unlike inspect.getargspec(), can return argument
      specification for functions, methods, callable
      objects, and classes.  Does not support builtin
      functions or methods.
      """
      if not callable(obj):
          raise TypeError("%s is not callable" % type(obj))
      try:
          if inspect.isfunction(obj):
              return inspect.getargspec(obj)
          elif hasattr(obj, "im_func"):
              # For methods or classmethods drop the first
              # argument from the returned list because
              # python supplies that automatically for us.
              # Note that this differs from what
              # inspect.getargspec() returns for methods.
              # NB: We use im_func so we work with
              #     instancemethod objects also.
              spec = list(inspect.getargspec(obj.im_func))
              spec[0] = spec[0][1:]
              return spec
          elif inspect.isclass(obj):
              return getargspec(obj.__init__)
          # elif isinstance(obj, object) and \
          #     not isinstance(obj, type(arglist.__get__)): # TODO: what does this clause do?
          elif isinstance(obj, object):
              # We already know the instance is callable,
              # so it must have a __call__ method defined.
              # Return the arguments it expects.
              return getargspec(obj.__call__)
      except NotImplementedError:
          # If a nested call to our own getargspec()
          # raises NotImplementedError, re-raise the
          # exception with the real object type to make
          # the error message more meaningful (the caller
          # only knows what they passed us; they shouldn't
          # care what aspect(s) of that object we actually
          # examined).
          pass
      raise NotImplementedError(
          "do not know how to get argument list for %s" % type(obj)
      )
  
imports: import collections
  import itertools
  import inspect
label_desc: Use image node_id 4 for calling a global function with example usage: getargspec(obj) and returns: inspect, spec, getargspec, getargspec