[Zope3-checkins] CVS: Zope3/src/zope/proxy/context - wrapper.c:1.6
Steve Alexander
steve@cat-box.net
Wed, 9 Apr 2003 10:51:23 -0400
Update of /cvs-repository/Zope3/src/zope/proxy/context
In directory cvs.zope.org:/tmp/cvs-serv13331/src/zope/proxy/context
Modified Files:
wrapper.c
Log Message:
Fixed various reference leaks.
Reworked some tests that created new types on each run through not to
do so.
Fixed various cases where an error raised in __get__ might have resulted
in a NULL exposed to python code.
=== Zope3/src/zope/proxy/context/wrapper.c 1.5 => 1.6 ===
--- Zope3/src/zope/proxy/context/wrapper.c:1.5 Wed Apr 9 09:00:19 2003
+++ Zope3/src/zope/proxy/context/wrapper.c Wed Apr 9 10:50:52 2003
@@ -675,7 +675,7 @@
#define FILLSLOTDEFS \
PyObject *wrapped; \
PyObject *descriptor; \
- PyObject *name;
+ PyObject *wrapped_type;
#define FILLSLOT(NAME, IDX, BADVAL) \
wrapped = Proxy_GET_OBJECT(self); \
@@ -685,13 +685,27 @@
(NAME)); \
return (BADVAL); \
} \
- name = SlotStrings[IDX]; \
- descriptor = _PyType_Lookup(wrapped->ob_type, name);\
+ descriptor = _PyType_Lookup(wrapped->ob_type, SlotStrings[IDX]);\
if (descriptor != NULL && \
descriptor->ob_type->tp_descr_get != NULL && \
(PyObject_TypeCheck(descriptor, &ContextDescriptorType) || \
PyObject_TypeCheck(wrapped, &ContextAwareType))\
- )
+ ) { \
+ wrapped_type = PyObject_Type(wrapped); \
+ if (wrapped_type == NULL) \
+ return (BADVAL); \
+ descriptor = descriptor->ob_type->tp_descr_get( \
+ descriptor, self, wrapped_type); \
+ if (descriptor == NULL) \
+ return (BADVAL);
+
+/* Concerning the last two lines of the above macro:
+ * Calling tp_descr_get returns a new reference.
+ * We need to decref it once we've finished using it.
+ * It will be available in the 'descriptor' variable.
+ * tp_descr_get should never return NULL. So, we can use
+ * Py_DECREF on the new value of 'descriptor'.
+ */
#define FILLSLOTBASE(NAME, IDX) \
FILLSLOTDEFS \
@@ -701,10 +715,6 @@
FILLSLOTDEFS \
FILLSLOT(NAME, IDX, -1)
-#define REBOUNDDESCRIPTOR \
- descriptor->ob_type->tp_descr_get( \
- descriptor, self, PyObject_Type(wrapped))
-
/* Sequence/mapping protocol: __len__, __getitem__, __setitem__
*/
@@ -714,8 +724,9 @@
{
PyObject *res;
int len;
- FILLSLOTBASEINT("__len__", LEN_IDX) {
- res = PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, NULL);
+ FILLSLOTBASEINT("__len__", LEN_IDX)
+ res = PyObject_CallFunctionObjArgs(descriptor, NULL);
+ Py_DECREF(descriptor);
if (res == NULL)
return -1;
len = (int)PyInt_AsLong(res);
@@ -727,8 +738,12 @@
static PyObject *
wrap_getitem(PyObject *self, PyObject *v) {
+ PyObject *retval;
FILLSLOTBASE("__getitem__", GETITEM_IDX)
- return PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, v, NULL);
+ retval = PyObject_CallFunctionObjArgs(descriptor, v, NULL);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyObject_GetItem(wrapped, v);
}
@@ -739,8 +754,9 @@
FILLSLOTDEFS
if (value == NULL) {
- FILLSLOT("__delitem__", DELITEM_IDX, -1) {
- res = PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, key, NULL);
+ FILLSLOT("__delitem__", DELITEM_IDX, -1)
+ res = PyObject_CallFunctionObjArgs(descriptor, key, NULL);
+ Py_DECREF(descriptor);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -748,9 +764,9 @@
}
return PyObject_DelItem(wrapped, key);
} else {
- FILLSLOT("__setitem__", SETITEM_IDX, -1) {
- res = PyObject_CallFunctionObjArgs(
- REBOUNDDESCRIPTOR, key, value, NULL);
+ FILLSLOT("__setitem__", SETITEM_IDX, -1)
+ res = PyObject_CallFunctionObjArgs(descriptor, key, value, NULL);
+ Py_DECREF(descriptor);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -766,16 +782,24 @@
static PyObject *
wrap_iter(PyObject *self)
{
+ PyObject *retval;
FILLSLOTBASE("__iter__", ITER_IDX)
- return PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, NULL);
+ retval = PyObject_CallFunctionObjArgs(descriptor, NULL);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyObject_GetIter(wrapped);
}
static PyObject *
wrap_iternext(PyObject *self)
{
+ PyObject *retval;
FILLSLOTBASE("next", NEXT_IDX)
- return PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, NULL);
+ retval = PyObject_CallFunctionObjArgs(descriptor, NULL);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyIter_Next(Proxy_GET_OBJECT(self));
}
@@ -787,8 +811,9 @@
{
PyObject *res;
int result;
- FILLSLOTBASEINT("__contains__", CONTAINS_IDX) {
- res = PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, value, NULL);
+ FILLSLOTBASEINT("__contains__", CONTAINS_IDX)
+ res = PyObject_CallFunctionObjArgs(descriptor, value, NULL);
+ Py_DECREF(descriptor);
if (res == NULL)
return -1;
result = PyObject_IsTrue(res);
@@ -804,23 +829,35 @@
static PyObject *
wrap_call(PyObject *self, PyObject *args, PyObject *kw)
{
+ PyObject *retval;
FILLSLOTDEFS
if (kw) {
FILLSLOT("__call__", CALL_IDX, NULL)
- return PyEval_CallObjectWithKeywords(REBOUNDDESCRIPTOR, args, kw);
+ retval = PyEval_CallObjectWithKeywords(descriptor, args, kw);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyEval_CallObjectWithKeywords(wrapped, args, kw);
} else {
FILLSLOT("__call__", CALL_IDX, NULL)
- return PyObject_CallObject(REBOUNDDESCRIPTOR, args);
+ retval = PyObject_CallObject(descriptor, args);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyObject_CallObject(wrapped, args);
}
}
static PyObject *
wrap_str(PyObject *self) {
+ PyObject *retval;
+
FILLSLOTBASE("__str__", STR_IDX)
- return PyObject_CallFunctionObjArgs(REBOUNDDESCRIPTOR, NULL);
+ retval =PyObject_CallFunctionObjArgs(descriptor, NULL);
+ Py_DECREF(descriptor);
+ return retval;
+ }
return PyObject_Str(wrapped);
}