[Numpy-svn] r2931 - in trunk/numpy: core/include/numpy core/src lib

numpy-svn at scipy.org numpy-svn at scipy.org
Mon Jul 31 16:17:34 EDT 2006


Author: oliphant
Date: 2006-07-31 15:17:29 -0500 (Mon, 31 Jul 2006)
New Revision: 2931

Modified:
   trunk/numpy/core/include/numpy/arrayobject.h
   trunk/numpy/core/src/arrayobject.c
   trunk/numpy/core/src/multiarraymodule.c
   trunk/numpy/lib/index_tricks.py
Log:
Fix ticket #216.  Also fix uses of DATA_RENEW so that object arrays will raise an error instead of possibly memory-leak when reference counts aren't freed.  Fix uses of longlong to Py_ssize_t and apppropriate FORMAT string.

Modified: trunk/numpy/core/include/numpy/arrayobject.h
===================================================================
--- trunk/numpy/core/include/numpy/arrayobject.h	2006-07-31 19:34:57 UTC (rev 2930)
+++ trunk/numpy/core/include/numpy/arrayobject.h	2006-07-31 20:17:29 UTC (rev 2931)
@@ -654,7 +654,6 @@
 #elif SIZEOF_PY_INTPTR_T == SIZEOF_LONG
 	#define NPY_INTP NPY_LONG
 	#define NPY_UINTP NPY_ULONG
-        #define PyIntpArrType_Type PyLongArrType_Type
         #define PyUIntpArrType_Type PyULongArrType_Type
 	#define NPY_MAX_INTP NPY_MAX_LONG
 	#define NPY_MIN_INTP MIN_LONG

Modified: trunk/numpy/core/src/arrayobject.c
===================================================================
--- trunk/numpy/core/src/arrayobject.c	2006-07-31 19:34:57 UTC (rev 2930)
+++ trunk/numpy/core/src/arrayobject.c	2006-07-31 20:17:29 UTC (rev 2931)
@@ -5226,6 +5226,12 @@
                                 "resize only works on single-segment arrays");
                 return NULL;
         }
+        
+        if (self->descr->hasobject) {
+                PyErr_SetString(PyExc_ValueError, 
+                                "cannot resize an object-array like this");
+                return NULL;
+        }
 
         if (fortran == PyArray_ANYORDER)
                 fortran = PyArray_CORDER;

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2006-07-31 19:34:57 UTC (rev 2930)
+++ trunk/numpy/core/src/multiarraymodule.c	2006-07-31 20:17:29 UTC (rev 2931)
@@ -4239,7 +4239,7 @@
 
 /* new reference in *at */
 /*MULTIARRAY_API
- Get typenum from an object -- None goes to &LONG_descr
+ Get typenum from an object -- None goes to PyArray_DEFAULT
 */
 static int
 PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
@@ -4894,6 +4894,14 @@
 	PyArrayObject *ret;
 	Bool binary;
 
+        if (dtype->hasobject) {
+                PyErr_SetString(PyExc_ValueError, 
+                                "Cannot create an object array from"    \
+                                " a string");
+                Py_DECREF(dtype);
+                return NULL;
+        }		
+
 	if (dtype == NULL)
 		dtype=PyArray_DescrFromType(PyArray_DEFAULT);
 	
@@ -4907,13 +4915,6 @@
 	binary = ((sep == NULL) || (strlen(sep) == 0));	
 
 	if (binary) {
-		if (dtype->hasobject) {
-			PyErr_SetString(PyExc_ValueError, 
-					"Cannot create an object array from" \
-					" a binary string");
-			Py_DECREF(dtype);
-			return NULL;
-		}		
 		if (n < 0 ) {
 			if (slen % itemsize != 0) {
 				PyErr_SetString(PyExc_ValueError, 
@@ -5040,13 +5041,14 @@
 array_fromString(PyObject *ignored, PyObject *args, PyObject *keywds)
 {
 	char *data;
-	longlong nin=-1;
+	Py_ssize_t nin=-1;
 	char *sep=NULL;
 	Py_ssize_t s;
 	static char *kwlist[] = {"string", "dtype", "count", "sep", NULL};
 	PyArray_Descr *descr=NULL;
 
-	if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#|O&Ls", kwlist, 
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#|O&" 
+                                         NPY_SSIZE_T_PYFMT "s", kwlist, 
 					 &data, &s, 
 					 PyArray_DescrConverter, &descr,
 					 &nin, &sep)) {
@@ -5057,7 +5059,7 @@
 }
 
 
-/* steals a reference to dtype */
+/* steals a reference to dtype (which cannot be NULL) */
 /*OBJECT_API */
 static PyObject *
 PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, intp count)
@@ -5072,14 +5074,24 @@
 
         elcount = (count < 0) ? 0 : count;
         elsize = dtype->elsize;
+        
+        /* We would need to alter the memory RENEW code to decrement any
+           reference counts before just throwing away the memory. 
+         */
+        if (dtype->hasobject) {
+                PyErr_SetString(PyExc_ValueError, "cannot create "\
+                                "object arrays from iterator");
+                goto done;
+        }
 
         ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1,
                                     &elcount, NULL,NULL, 0, NULL);
         dtype = NULL;
         if (ret == NULL) goto done;
 
-        for (i = 0; (i < count || count == -1) && (value = PyIter_Next(iter)); i++) {
-
+        for (i = 0; (i < count || count == -1) && 
+                     (value = PyIter_Next(iter)); i++) {
+                
             if (i >= elcount) {
                 /* 
                    Grow ret->data:
@@ -5094,6 +5106,7 @@
                 if (new_data == NULL) {
                     PyErr_SetString(PyExc_MemoryError, 
                                     "cannot allocate array memory");
+                    Py_DECREF(value);
                     goto done;
                 }
                 ret->data = new_data;
@@ -5101,9 +5114,10 @@
             ret->dimensions[0] = i+1;
 
             if (((item = index2ptr(ret, i)) == NULL) ||
-                    (ret->descr->f->setitem(value, item, ret) == -1)) {
-                        goto done;
-                }
+                (ret->descr->f->setitem(value, item, ret) == -1)) {
+                    Py_DECREF(value);
+                    goto done;
+            }
             Py_DECREF(value);
 
         }
@@ -5117,12 +5131,12 @@
             Realloc the data so that don't keep extra memory tied up
             (assuming realloc is reasonably good about reusing space...)
         */
-        new_data = PyDataMem_RENEW(ret->data, i * elsize);
-        if (new_data == NULL) {
+        if (i==0) i = 1;
+        ret->data = PyDataMem_RENEW(ret->data, i * elsize);
+        if (ret->data == NULL) {
             PyErr_SetString(PyExc_MemoryError, "cannot allocate array memory");
             goto done;
         }
-        ret->data = new_data;
 
 done:
         Py_XDECREF(iter);
@@ -5138,11 +5152,13 @@
 array_fromIter(PyObject *ignored, PyObject *args, PyObject *keywds)
 {
 	PyObject *iter;
-	longlong nin=-1;
+	Py_ssize_t nin=-1;
 	static char *kwlist[] = {"iter", "dtype", "count", NULL};
 	PyArray_Descr *descr=NULL;
 
-	if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO&|L", kwlist, 
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, 
+                                         "OO&|" NPY_SSIZE_T_PYFMT, 
+                                         kwlist, 
 					 &iter,
 					 PyArray_DescrConverter, &descr,
 					 &nin)) {
@@ -5174,6 +5190,12 @@
 	PyArray_ScanFunc *scan;
 	Bool binary;
 
+        if (typecode->hasobject) {
+                PyErr_SetString(PyExc_ValueError, "cannot read into"
+                                "object array");
+                Py_DECREF(typecode);
+                return NULL;
+        }
 	if (typecode->elsize == 0) {
 		PyErr_SetString(PyExc_ValueError, "0-sized elements.");
 		Py_DECREF(typecode);
@@ -5314,11 +5336,13 @@
 	PyObject *file=NULL, *ret;
 	FILE *fp;
 	char *sep="";
-	longlong nin=-1;
+	Py_ssize_t nin=-1;
 	static char *kwlist[] = {"file", "dtype", "count", "sep", NULL};
 	PyArray_Descr *type=NULL;
 	
-	if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|O&Ls", kwlist, 
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, 
+                                         "O|O&" NPY_SSIZE_T_PYFMT "s", 
+                                         kwlist, 
 					 &file,
 					 PyArray_DescrConverter, &type,
 					 &nin, &sep)) {
@@ -5448,11 +5472,13 @@
 array_frombuffer(PyObject *ignored, PyObject *args, PyObject *keywds)
 {
 	PyObject *obj=NULL;
-	longlong nin=-1, offset=0;
+	Py_ssize_t nin=-1, offset=0;
 	static char *kwlist[] = {"buffer", "dtype", "count", "offset", NULL};
 	PyArray_Descr *type=NULL;
 
-	if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|O&LL", kwlist, 
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|O&"
+                                         NPY_SSIZE_T_PYFMT 
+                                         NPY_SSIZE_T_PYFMT, kwlist, 
 					 &obj,
 					 PyArray_DescrConverter, &type,
 					 &nin, &offset)) {

Modified: trunk/numpy/lib/index_tricks.py
===================================================================
--- trunk/numpy/lib/index_tricks.py	2006-07-31 19:34:57 UTC (rev 2930)
+++ trunk/numpy/lib/index_tricks.py	2006-07-31 20:17:29 UTC (rev 2931)
@@ -336,6 +336,8 @@
     """
 
     def __init__(self, *args):
+        if len(args) == 1 and isinstance(args[0], tuple):
+            args = args[0]
         self.nd = len(args)
         self.ind = [0]*self.nd
         self.index = 0




More information about the Numpy-svn mailing list