[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