diff options
author | Guido van Rossum <guido@python.org> | 2003-04-14 21:46:03 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2003-04-14 21:46:03 (GMT) |
commit | 4dcdb78c6ffd203c9d72ef41638cc4a0e3857adf (patch) | |
tree | 8004c2c85681d2379d1a0c8d319e4506517666bb /Objects | |
parent | 2fd02eb80fdfd7b651d3df7e09a0b076e126cc03 (diff) | |
download | cpython-4dcdb78c6ffd203c9d72ef41638cc4a0e3857adf.zip cpython-4dcdb78c6ffd203c9d72ef41638cc4a0e3857adf.tar.gz cpython-4dcdb78c6ffd203c9d72ef41638cc4a0e3857adf.tar.bz2 |
Close off the "Verre Carlo hack" as discussed on python-dev.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a900f55..91c40b9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3574,6 +3574,24 @@ wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped) return PyInt_FromLong((long)res); } +/* Helper to check for object.__setattr__ or __delattr__ applied to a type. + This is called the Verre Carlo hack after its discoverer. */ +static int +hackcheck(PyObject *self, setattrofunc func, char *what) +{ + PyTypeObject *type = self->ob_type; + while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE) + type = type->tp_base; + if (type->tp_setattro != func) { + PyErr_Format(PyExc_TypeError, + "can't apply this %s to %s object", + what, + type->tp_name); + return 0; + } + return 1; +} + static PyObject * wrap_setattr(PyObject *self, PyObject *args, void *wrapped) { @@ -3583,6 +3601,8 @@ wrap_setattr(PyObject *self, PyObject *args, void *wrapped) if (!PyArg_ParseTuple(args, "OO", &name, &value)) return NULL; + if (!hackcheck(self, func, "__setattr__")) + return NULL; res = (*func)(self, name, value); if (res < 0) return NULL; @@ -3599,6 +3619,8 @@ wrap_delattr(PyObject *self, PyObject *args, void *wrapped) if (!PyArg_ParseTuple(args, "O", &name)) return NULL; + if (!hackcheck(self, func, "__delattr__")) + return NULL; res = (*func)(self, name, NULL); if (res < 0) return NULL; |