summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-02-28 21:13:49 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-02-28 21:13:49 +0000
commitfc064db275032fa5c2b0f9d86945988051cfa11c (patch)
tree9a74de8807870517095663129568100012673d1a /numpy/core
parent1bf01888151e1e6c28b2eb3b8ccb482148d55402 (diff)
downloadnumpy-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.c23
-rw-r--r--numpy/core/src/arrayobject.c44
-rw-r--r--numpy/core/tests/test_multiarray.py2
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):