summaryrefslogtreecommitdiff
path: root/Objects/descrobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/descrobject.c')
-rw-r--r--Objects/descrobject.c69
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;