code: def getargspec(method):
      
  
      argspec = _getargspec(method)
      args = argspec[0]
      if args and args[0] == 'self':
          return argspec
      if hasattr(method, '__func__'):
          method = method.__func__
  
      func_closure = six.get_function_closure(method)
  
      # NOTE(sileht): if the closure is None we cannot look deeper,
      # so return actual argspec, this occurs when the method
      # is static for example.
      if not func_closure:
          return argspec
  
      closure = None
      # In the case of deeply nested decorators (with arguments), it's possible
      # that there are several callables in scope;  Take a best guess and go
      # with the one that looks most like a pecan controller function
      # (has a __code__ object, and 'self' is the first argument)
      func_closure = filter(
          lambda c: (
              six.callable(c.cell_contents) and
              hasattr(c.cell_contents, '__code__')
          ),
          func_closure
      )
      func_closure = sorted(
          func_closure,
          key=lambda c: 'self' in c.cell_contents.__code__.co_varnames,
          reverse=True
      )
  
      closure = func_closure[0]
  
      method = closure.cell_contents
      return getargspec(method)
docs: Drill through layers of decorators attempting to locate the actual argspec
      for a method.