code: def _argspec(func):
      
      assert isinstance(func, collections.Callable), 'Argument must be a callable'
  
      try: sp =  inspect.getargspec(func) if six.PY2 else inspect.getfullargspec(func)
      except TypeError:
          # inspect.getargspec() fails for built-in functions
          return []
  
      # Collect arguments with defaults
      ret = []
      defaults_start = len(sp.args) - len(sp.defaults) if sp.defaults else len(sp.args)
      for i, name in enumerate(sp.args):
          arg = data.ArgumentSpec(name)
          if i >= defaults_start:
              arg['default'] = sp.defaults[i - defaults_start]
          ret.append(arg)
  
      # *args, **kwargs
      if sp.varargs:
          ret.append(data.ArgumentSpec(sp.varargs, varargs=True))
      if six.PY2:
          if sp.keywords:
              ret.append(data.ArgumentSpec(sp.keywords, keywords=True))
      else:
          if sp.varkw:
              ret.append(data.ArgumentSpec(sp.varkw, keywords=True))
  
      # TODO: support Python 3: kwonlyargs, kwonlydefaults, annotations
  
      # Finish
      return ret
docs: For a callable, get the full argument spec
  
      :type func: Callable
      :rtype: list[data.ArgumentSpec]