[Numpy-discussion] Another reference count leak: ticket #848

Michael Abbott michael@araneidae.co...
Wed Jul 9 04:33:53 CDT 2008


On Wed, 9 Jul 2008, Michael Abbott wrote:
> Well then, I need to redo my patch.  Here's the new patch for 
> ..._arrtype_new:

I'm sorry about this, I posted too early.  Here is the final patch (and 
I'll update the ticket accordingly).



commit a1ff570cbd3ca6c28f87c55cebf2675b395c6fa0
Author: Michael Abbott <michael.abbott@diamond.ac.uk>
Date:   Tue Jul 8 10:10:59 2008 +0100

    Another reference leak using PyArray_DescrFromType
    
    This change fixes the following issues resulting in reference count
    leaks: a spurious ADDREF on a typecode returned from
    PyArray_DescrFromType, an awkward interaction with PyArray_FromAny, and
    a couple of early returns which need DECREFs.

diff --git a/numpy/core/src/scalartypes.inc.src b/numpy/core/src/scalartypes.inc.src
index 3feefc0..d54ae1b 100644
--- a/numpy/core/src/scalartypes.inc.src
+++ b/numpy/core/src/scalartypes.inc.src
@@ -1886,7 +1886,6 @@ static PyObject *
         if (!PyArg_ParseTuple(args, "|O", &obj)) return NULL;
 
     typecode = PyArray_DescrFromType(PyArray_@TYPE@);
-    Py_INCREF(typecode);
     if (obj == NULL) {
 #if @default@ == 0
         char *mem;
@@ -1903,19 +1902,30 @@ static PyObject *
         goto finish;
     }
 
+    Py_XINCREF(typecode);
     arr = PyArray_FromAny(obj, typecode, 0, 0, FORCECAST, NULL);
-    if ((arr==NULL) || (PyArray_NDIM(arr) > 0)) return arr;
+    if ((arr==NULL) || (PyArray_NDIM(arr) > 0)) {
+        Py_XDECREF(typecode);
+        return arr;
+    }
     robj = PyArray_Return((PyArrayObject *)arr);
 
 finish:
-    if ((robj==NULL) || (robj->ob_type == type)) return robj;
+    if ((robj==NULL) || (robj->ob_type == type)) {
+        Py_XDECREF(typecode);
+        return robj;
+    }
     /* Need to allocate new type and copy data-area over */
     if (type->tp_itemsize) {
         itemsize = PyString_GET_SIZE(robj);
     }
     else itemsize = 0;
     obj = type->tp_alloc(type, itemsize);
-    if (obj == NULL) {Py_DECREF(robj); return NULL;}
+    if (obj == NULL) {
+        Py_XDECREF(typecode);
+        Py_DECREF(robj);
+        return NULL;
+    }
     if (typecode==NULL)
         typecode = PyArray_DescrFromType(PyArray_@TYPE@);
     dest = scalar_value(obj, typecode);


The corresponding test case is (sorry it's crude):

	import sys
	from numpy import float32
	
	refs = 0
	refs = sys.gettotalrefcount()
	float32()
	print sys.gettotalrefcount() - refs

I'm afraid I haven't tested all the possible paths through this routine.  
I need to get back to chasing my other leaks.


More information about the Numpy-discussion mailing list