diff options
Diffstat (limited to 'Objects/descrobject.c')
-rw-r--r-- | Objects/descrobject.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 076e741481..20c0d36eca 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -210,15 +210,15 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) } static PyObject * -methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) +methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) { - Py_ssize_t argc; - PyObject *self, *func, *result, **stack; + Py_ssize_t nargs; + PyObject *self, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); - argc = PyTuple_GET_SIZE(args); - if (argc < 1) { + nargs = PyTuple_GET_SIZE(args); + if (nargs < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%V' of '%.100s' " "object needs an argument", @@ -239,12 +239,48 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) return NULL; } - func = PyCFunction_NewEx(descr->d_method, self, NULL); - if (func == NULL) + result = _PyMethodDef_RawFastCallDict(descr->d_method, self, + &PyTuple_GET_ITEM(args, 1), nargs - 1, + kwargs); + result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); + return result; +} + +// same to methoddescr_call(), but use FASTCALL convention. +PyObject * +_PyMethodDescr_FastCallKeywords(PyObject *descrobj, + PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) +{ + assert(Py_TYPE(descrobj) == &PyMethodDescr_Type); + PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj; + PyObject *self, *result; + + /* Make sure that the first argument is acceptable as 'self' */ + if (nargs < 1) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); return NULL; - stack = &PyTuple_GET_ITEM(args, 1); - result = _PyObject_FastCallDict(func, stack, argc - 1, kwds); - Py_DECREF(func); + } + self = args[0]; + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' " + "requires a '%.100s' object " + "but received a '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + self->ob_type->tp_name); + return NULL; + } + + result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self, + args+1, nargs-1, kwnames); + result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); return result; } @@ -421,8 +457,7 @@ static PyObject * member_get_doc(PyMemberDescrObject *descr, void *closure) { if (descr->d_member->doc == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return PyUnicode_FromString(descr->d_member->doc); } @@ -437,8 +472,7 @@ static PyObject * getset_get_doc(PyGetSetDescrObject *descr, void *closure) { if (descr->d_getset->doc == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return PyUnicode_FromString(descr->d_getset->doc); } @@ -804,7 +838,8 @@ mappingproxy_get(mappingproxyobject *pp, PyObject *args) if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) return NULL; - return _PyObject_CallMethodId(pp->mapping, &PyId_get, "(OO)", key, def); + return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get, + key, def, NULL); } static PyObject * @@ -1172,7 +1207,7 @@ wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) return (*wk)(self, args, wp->descr->d_wrapped, kwds); } - if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { PyErr_Format(PyExc_TypeError, "wrapper %s doesn't take keyword arguments", wp->descr->d_base->name); @@ -1453,7 +1488,7 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) doc = pold->prop_doc ? pold->prop_doc : Py_None; } - new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); + new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL); Py_DECREF(type); if (new == NULL) return NULL; |