diff options
Diffstat (limited to 'Objects/descrobject.c')
-rw-r--r-- | Objects/descrobject.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 2df5ac5..1a69b6b 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1313,7 +1313,7 @@ static PyMemberDef property_members[] = { {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, - {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY}, + {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0}, {0} }; @@ -1372,6 +1372,9 @@ property_dealloc(PyObject *self) static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { + static PyObject * volatile cached_args = NULL; + PyObject *args; + PyObject *ret; propertyobject *gs = (propertyobject *)self; if (obj == NULL || obj == Py_None) { @@ -1382,7 +1385,29 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL); + args = cached_args; + if (!args || Py_REFCNT(args) != 1) { + Py_CLEAR(cached_args); + if (!(cached_args = args = PyTuple_New(1))) + return NULL; + } + Py_INCREF(args); + assert (Py_REFCNT(args) == 2); + Py_INCREF(obj); + PyTuple_SET_ITEM(args, 0, obj); + ret = PyObject_Call(gs->prop_get, args, NULL); + if (args == cached_args) { + if (Py_REFCNT(args) == 2) { + obj = PyTuple_GET_ITEM(args, 0); + PyTuple_SET_ITEM(args, 0, NULL); + Py_XDECREF(obj); + } + else { + Py_CLEAR(cached_args); + } + } + Py_DECREF(args); + return ret; } static int @@ -1584,6 +1609,14 @@ property_traverse(PyObject *self, visitproc visit, void *arg) return 0; } +static int +property_clear(PyObject *self) +{ + propertyobject *pp = (propertyobject *)self; + Py_CLEAR(pp->prop_doc); + return 0; +} + PyTypeObject PyProperty_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "property", /* tp_name */ @@ -1609,7 +1642,7 @@ PyTypeObject PyProperty_Type = { Py_TPFLAGS_BASETYPE, /* tp_flags */ property_doc, /* tp_doc */ property_traverse, /* tp_traverse */ - 0, /* tp_clear */ + (inquiry)property_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ |