diff options
author | Benjamin Peterson <benjamin@python.org> | 2012-05-01 13:51:46 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2012-05-01 13:51:46 (GMT) |
commit | 8fbd2954583cbf252999991d7c58e4deacb2688c (patch) | |
tree | ff64dc8a51441dc21961c04a69b1e80fa759c254 /Objects | |
parent | 49a69e4d48d68a36325ba9098e1962e8c2195339 (diff) | |
parent | 7295c6a871f9cc42a4209a8eebe2e0974194a2a3 (diff) | |
download | cpython-8fbd2954583cbf252999991d7c58e4deacb2688c.zip cpython-8fbd2954583cbf252999991d7c58e4deacb2688c.tar.gz cpython-8fbd2954583cbf252999991d7c58e4deacb2688c.tar.bz2 |
merge 3.2 (#14699)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/descrobject.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index b679c4bc..abcc002 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -257,14 +257,52 @@ static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) { - PyObject *func, *result; + Py_ssize_t argc; + PyObject *self, *func, *result; - func = PyCFunction_New(descr->d_method, (PyObject *)PyDescr_TYPE(descr)); - if (func == NULL) + /* Make sure that the first argument is acceptable as 'self' */ + assert(PyTuple_Check(args)); + argc = PyTuple_GET_SIZE(args); + if (argc < 1) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); return NULL; + } + self = PyTuple_GET_ITEM(args, 0); + if (!PyType_Check(self)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' requires a type " + "but received a '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + self->ob_type->tp_name); + return NULL; + } + if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' " + "requires a subtype of '%.100s' " + "but received '%.100s", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + self->ob_type->tp_name); + return NULL; + } + func = PyCFunction_New(descr->d_method, self); + if (func == NULL) + return NULL; + args = PyTuple_GetSlice(args, 1, argc); + if (args == NULL) { + Py_DECREF(func); + return NULL; + } result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(func); + Py_DECREF(args); return result; } |