diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-02-28 21:13:49 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-02-28 21:13:49 +0000 |
commit | fc064db275032fa5c2b0f9d86945988051cfa11c (patch) | |
tree | 9a74de8807870517095663129568100012673d1a /numpy/core | |
parent | 1bf01888151e1e6c28b2eb3b8ccb482148d55402 (diff) | |
download | numpy-fc064db275032fa5c2b0f9d86945988051cfa11c.tar.gz |
Add refcheck keyword argument to resize method to allow override of reference count check. Allow 0-stride arrays to be created and allow setting of strides even when we create the memory.
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/arraymethods.c | 23 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 44 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 2 |
3 files changed, 45 insertions, 24 deletions
diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index 6109252c9..175e1d4d5 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -642,18 +642,29 @@ array_copy(PyArrayObject *self, PyObject *args) return PyArray_NewCopy(self, fortran); } -static char doc_resize[] = "self.resize(new_shape). "\ +static char doc_resize[] = "self.resize(new_shape, refcheck=True). "\ "Change size and shape of self inplace.\n"\ "\n Array must own its own memory and not be referenced by other " \ "arrays\n Returns None."; static PyObject * -array_resize(PyArrayObject *self, PyObject *args) +array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds) { PyArray_Dims newshape; PyObject *ret; int n; - + int refcheck = 1; + + if (kwds != NULL) { + PyObject *ref; + ref = PyDict_GetItemString(kwds, "refcheck"); + if (ref) { + refcheck = PyInt_AsLong(ref); + if (refcheck==-1 && PyErr_Occurred()) { + return NULL; + } + } + } n = PyTuple_Size(args); if (n <= 1) { if (!PyArg_ParseTuple(args, "O&", PyArray_IntpConverter, @@ -668,7 +679,8 @@ array_resize(PyArrayObject *self, PyObject *args) return NULL; } } - ret = PyArray_Resize(self, &newshape); + + ret = PyArray_Resize(self, &newshape, refcheck); PyDimMem_FREE(newshape.ptr); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1563,7 +1575,8 @@ static PyMethodDef array_methods[] = { {"setfield", (PyCFunction)array_setfield, METH_VARARGS | METH_KEYWORDS, doc_setfield}, {"copy", (PyCFunction)array_copy, 1, doc_copy}, - {"resize", (PyCFunction)array_resize, 1, doc_resize}, + {"resize", (PyCFunction)array_resize, + METH_VARARGS | METH_KEYWORDS, doc_resize}, /* for subtypes */ {"__array__", (PyCFunction)array_getarray, 1, doc_array_getarray}, diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index eed01f93a..b48489f12 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3845,7 +3845,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, self->nd = nd; self->dimensions = NULL; self->data = NULL; - if (data == NULL) { /* strides is NULL too */ + if (data == NULL) { self->flags = DEFAULT_FLAGS; if (flags) { self->flags |= FORTRAN; @@ -3872,14 +3872,9 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, sd = _array_fill_strides(self->strides, dims, nd, sd, flags, &(self->flags)); } - else { - if (data == NULL) { - PyErr_SetString(PyExc_ValueError, - "if 'strides' is given in " \ - "array creation, data must " \ - "be given too"); - goto fail; - } + else { /* we allow strides even when we create + the memory, but be careful with this... + */ memcpy(self->strides, strides, sizeof(intp)*nd); } } @@ -3922,17 +3917,17 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /* call the __array_finalize__ method if a subtype and some object passed in */ - if ((subtype != &PyArray_Type) && - (subtype != &PyBigArray_Type)) { + if ((subtype != &PyArray_Type) && (subtype != &PyBigArray_Type)) { PyObject *res, *func, *args; static PyObject *str=NULL; if (str == NULL) { str = PyString_InternFromString("__array_finalize__"); } - if (!(self->flags & OWNDATA)) { /* did not allocate own data */ - /* update flags before calling back into - Python */ + if (strides != NULL) { /* did not allocate own data + or funny strides */ + /* update flags before calling back into + Python */ PyArray_UpdateFlags(self, UPDATE_ALL_FLAGS); } func = PyObject_GetAttr((PyObject *)self, str); @@ -3961,9 +3956,13 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /*OBJECT_API Resize (reallocate data). Only works if nothing else is referencing this array and it is contiguous. + If refcheck is 0, then the reference count is not checked + and assumed to be 1. + You still must own this data and have no weak-references and no base + object. */ static PyObject * -PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) +PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) { intp oldsize, newsize; int new_nd=newshape->len, k, n, elsize; @@ -3991,7 +3990,8 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) return NULL; } - refcnt = REFCOUNT(self); + if (refcheck) refcnt = REFCOUNT(self); + else refcnt = 1; if ((refcnt > 2) || (self->base != NULL) || \ (self->weakreflist != NULL)) { PyErr_SetString(PyExc_ValueError, @@ -4177,6 +4177,13 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) type_num = descr->type_num; itemsize = descr->elsize; + if (itemsize == 0) { + PyErr_SetString(PyExc_ValueError, + "data-type with unspecified variable length"); + Py_DECREF(descr); + return NULL; + } + if (buffer.ptr == NULL) { ret = (PyArrayObject *)\ PyArray_NewFromDescr(subtype, descr, @@ -4190,9 +4197,10 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) } else { /* buffer given -- use it */ if (dims.len == 1 && dims.ptr[0] == -1) { - dims.ptr[offset] = buffer.len / itemsize; + dims.ptr[0] = (buffer.len-offset) / itemsize; } - else if (buffer.len < itemsize* \ + else if ((strides.ptr == NULL) && \ + buffer.len < itemsize* \ PyArray_MultiplyList(dims.ptr, dims.len)) { PyErr_SetString(PyExc_TypeError, "buffer is too small for " \ diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index d85ed6890..25bd98a45 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -73,7 +73,7 @@ class test_attributes(ScipyTestCase): self.failUnlessRaises(ValueError, make_array, 4, 2, -1) self.failUnlessRaises(ValueError, make_array, 8, 3, 1) #self.failUnlessRaises(ValueError, make_array, 8, 3, 0) - self.failUnlessRaises(ValueError, lambda: ndarray([1], strides=4)) + #self.failUnlessRaises(ValueError, lambda: ndarray([1], strides=4)) def check_set_stridesattr(self): |