diff options
Diffstat (limited to 'Objects/descrobject.c')
-rw-r--r-- | Objects/descrobject.c | 125 |
1 files changed, 78 insertions, 47 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 9eda4bdd7d..9934f23387 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -92,7 +92,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) "descriptor '%V' for type '%s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } } @@ -101,16 +101,16 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) "descriptor '%V' for type '%s' " "needs a type, not a '%s' as arg 2", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, type->ob_type->tp_name); return NULL; } - if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { + if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for type '%s' " "doesn't apply to type '%s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, ((PyTypeObject *)type)->tp_name); return NULL; } @@ -149,7 +149,7 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } @@ -204,7 +204,7 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return -1; } @@ -222,18 +222,18 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) "descriptor '%V' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)(descr->d_type))) { + (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); return NULL; } @@ -256,14 +256,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 *)descr->d_type); - 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; } @@ -281,18 +319,18 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) "descriptor '%V' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)(descr->d_type))) { + (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); return NULL; } @@ -712,19 +750,19 @@ proxy_get(proxyobject *pp, PyObject *args) static PyObject * proxy_keys(proxyobject *pp) { - return PyMapping_Keys(pp->dict); + return PyObject_CallMethod(pp->dict, "keys", NULL); } static PyObject * proxy_values(proxyobject *pp) { - return PyMapping_Values(pp->dict); + return PyObject_CallMethod(pp->dict, "values", NULL); } static PyObject * proxy_items(proxyobject *pp) { - return PyMapping_Items(pp->dict); + return PyObject_CallMethod(pp->dict, "items", NULL); } static PyObject * @@ -846,16 +884,13 @@ PyDictProxy_New(PyObject *dict) /* This has no reason to be in this file except that adding new files is a bit of a pain */ -/* forward */ -static PyTypeObject wrappertype; - typedef struct { PyObject_HEAD PyWrapperDescrObject *descr; PyObject *self; } wrapperobject; -#define Wrapper_Check(v) (Py_TYPE(v) == &wrappertype) +#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type) static void wrapper_dealloc(wrapperobject *wp) @@ -924,10 +959,10 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op) return v; } -static long +static Py_hash_t wrapper_hash(wrapperobject *wp) { - int x, y; + Py_hash_t x, y; x = _Py_HashPointer(wp->descr); if (x == -1) return -1; @@ -957,7 +992,7 @@ static PyMemberDef wrapper_members[] = { static PyObject * wrapper_objclass(wrapperobject *wp) { - PyObject *c = (PyObject *)wp->descr->d_type; + PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); Py_INCREF(c); return c; @@ -1021,7 +1056,7 @@ wrapper_traverse(PyObject *self, visitproc visit, void *arg) return 0; } -static PyTypeObject wrappertype = { +PyTypeObject _PyMethodWrapper_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "method-wrapper", /* tp_name */ sizeof(wrapperobject), /* tp_basicsize */ @@ -1068,9 +1103,9 @@ PyWrapper_New(PyObject *d, PyObject *self) assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); descr = (PyWrapperDescrObject *)d; assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)(descr->d_type))); + (PyObject *)PyDescr_TYPE(descr))); - wp = PyObject_GC_New(wrapperobject, &wrappertype); + wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); if (wp != NULL) { Py_INCREF(descr); wp->descr = descr; @@ -1124,7 +1159,7 @@ typedef struct { } propertyobject; static PyObject * property_copy(PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *); + PyObject *); static PyMemberDef property_members[] = { {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, @@ -1141,7 +1176,7 @@ PyDoc_STRVAR(getter_doc, static PyObject * property_getter(PyObject *self, PyObject *getter) { - return property_copy(self, getter, NULL, NULL, NULL); + return property_copy(self, getter, NULL, NULL); } @@ -1151,7 +1186,7 @@ PyDoc_STRVAR(setter_doc, static PyObject * property_setter(PyObject *self, PyObject *setter) { - return property_copy(self, NULL, setter, NULL, NULL); + return property_copy(self, NULL, setter, NULL); } @@ -1161,7 +1196,7 @@ PyDoc_STRVAR(deleter_doc, static PyObject * property_deleter(PyObject *self, PyObject *deleter) { - return property_copy(self, NULL, NULL, deleter, NULL); + return property_copy(self, NULL, NULL, deleter); } @@ -1199,7 +1234,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - return PyObject_CallFunction(gs->prop_get, "(O)", obj); + return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL); } static int @@ -1220,9 +1255,9 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) return -1; } if (value == NULL) - res = PyObject_CallFunction(func, "(O)", obj); + res = PyObject_CallFunctionObjArgs(func, obj, NULL); else - res = PyObject_CallFunction(func, "(OO)", obj, value); + res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); if (res == NULL) return -1; Py_DECREF(res); @@ -1230,11 +1265,10 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) } static PyObject * -property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del, - PyObject *doc) +property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) { propertyobject *pold = (propertyobject *)old; - PyObject *new, *type; + PyObject *new, *type, *doc; type = PyObject_Type(old); if (type == NULL) @@ -1252,15 +1286,12 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del, Py_XDECREF(del); del = pold->prop_del ? pold->prop_del : Py_None; } - if (doc == NULL || doc == Py_None) { - Py_XDECREF(doc); - if (pold->getter_doc && get != Py_None) { - /* make _init use __doc__ from getter */ - doc = Py_None; - } - else { - doc = pold->prop_doc ? pold->prop_doc : Py_None; - } + if (pold->getter_doc && get != Py_None) { + /* make _init use __doc__ from getter */ + doc = Py_None; + } + else { + doc = pold->prop_doc ? pold->prop_doc : Py_None; } new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); |