diff -r 2df7c958974e Objects/descrobject.c --- a/Objects/descrobject.c Sat May 23 18:08:55 2015 -0700 +++ b/Objects/descrobject.c Sun May 24 15:42:18 2015 +0300 @@ -1372,7 +1372,8 @@ property_dealloc(PyObject *self) static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { - static PyObject *args = NULL; + static PyObject * volatile cached_args = NULL; + PyObject *args; PyObject *ret; propertyobject *gs = (propertyobject *)self; @@ -1384,12 +1385,28 @@ property_descr_get(PyObject *self, PyObj PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - if (!args && !(args = PyTuple_New(1))) { - return 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); - PyTuple_SET_ITEM(args, 0, 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; }