diff options
author | Guido van Rossum <guido@python.org> | 2001-08-24 15:23:20 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-24 15:23:20 (GMT) |
commit | 271410ad189d9482274a4acba44ae29059ae2b55 (patch) | |
tree | 4a0240aa66eb4f10a76715649bb9e1df55012b53 | |
parent | 833a8d86417f4832f5e3ad742f21fe10378388bb (diff) | |
download | cpython-271410ad189d9482274a4acba44ae29059ae2b55.zip cpython-271410ad189d9482274a4acba44ae29059ae2b55.tar.gz cpython-271410ad189d9482274a4acba44ae29059ae2b55.tar.bz2 |
Change the getset type to take an optional third function argument:
the delete function. (Question: should the attribute name also be
recorded in the getset object? That makes the protocol more work, but
may give us better error messages.)
-rw-r--r-- | Objects/descrobject.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index c29dd83..efed1c0 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -868,6 +868,7 @@ typedef struct { PyObject_HEAD PyObject *get; PyObject *set; + PyObject *del; } getsetobject; static void @@ -877,6 +878,7 @@ getset_dealloc(PyObject *self) Py_XDECREF(gs->get); Py_XDECREF(gs->set); + Py_XDECREF(gs->del); self->ob_type->tp_free(self); } @@ -900,16 +902,23 @@ static int getset_descr_set(PyObject *self, PyObject *obj, PyObject *value) { getsetobject *gs = (getsetobject *)self; - PyObject *res; + PyObject *func, *res; - if (gs->set == NULL) { - PyErr_SetString(PyExc_AttributeError, "unsettable attribute"); + if (value == NULL) + func = gs->del; + else + func = gs->set; + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, + value == NULL ? + "can't delete attribute" : + "can't set attribute"); return -1; } if (value == NULL) - res = PyObject_CallFunction(gs->set, "(O)", obj); + res = PyObject_CallFunction(func, "(O)", obj); else - res = PyObject_CallFunction(gs->set, "(OO)", obj, value); + res = PyObject_CallFunction(func, "(OO)", obj, value); if (res == NULL) return -1; Py_DECREF(res); @@ -919,10 +928,10 @@ getset_descr_set(PyObject *self, PyObject *obj, PyObject *value) static int getset_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *get = NULL, *set = NULL; + PyObject *get = NULL, *set = NULL, *del = NULL; getsetobject *gs = (getsetobject *)self; - if (!PyArg_ParseTuple(args, "|OO:getset.__init__", &get, &set)) + if (!PyArg_ParseTuple(args, "|OOO:getset.__init__", &get, &set, &del)) return -1; if (get == Py_None) get = NULL; @@ -930,18 +939,21 @@ getset_init(PyObject *self, PyObject *args, PyObject *kwds) set = NULL; Py_XINCREF(get); Py_XINCREF(set); + Py_XINCREF(del); gs->get = get; gs->set = set; + gs->del = del; return 0; } static char getset_doc[] = -"getset([getfunc[, setfunc]]) -> getset attribute\n" +"getset([getfunc[, setfunc[, delfunc]]]) -> getset attribute\n" "Typical use to define a managed attribute x of C instances:\n" "class C(object):\n" " def getx(self): return self.__x\n" " def setx(self, value): self.__x = value\n" -" x = getset(getx, setx)"; +" def delx(self): del self.__x\n" +" x = getset(getx, setx, delx)"; PyTypeObject PyGetSet_Type = { PyObject_HEAD_INIT(&PyType_Type) |