def getargspec(obj):
    argnames, varargs, varkw, _defaults = None, None, None, None
    if inspect.isfunction(obj) or inspect.ismethod(obj):
        argnames, varargs, varkw, _defaults = inspect.getargspec(obj)
    elif inspect.isclass(obj):
        if inspect.ismethoddescriptor(obj.__init__):
            argnames, varargs, varkw, _defaults = [], False, False, None
        else:
            argnames, varargs, varkw, _defaults = inspect.getargspec(obj.__init__)
    elif hasattr(obj, '__call__'):
        argnames, varargs, varkw, _defaults = inspect.getargspec(obj.__call__)
    else:
        raise TypeError("Object not callable?")
    if argnames and argnames[0] == 'self':
        del argnames[0]
    if _defaults is None:
        _defaults = []
        defaults = dict()
    else:
        defaults = dict()
        _defaults = list(_defaults)
        _defaults.reverse()
        argnames.reverse()
        for i, default in enumerate(_defaults):
            defaults[argnames[i]] = default
        argnames.reverse()
    return argnames, defaults, True if varargs else False, True if varkw else False