summaryrefslogtreecommitdiff
path: root/scipy/base/src/arrayobject.c
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-09-15 08:55:17 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-09-15 08:55:17 +0000
commit76f6dbd300d38b121a5efca9eb5181de83ab039d (patch)
tree16ed34273fa06d78082c72c04feed187529be19e /scipy/base/src/arrayobject.c
parent7257a82db2316aaf815cc65f045e8ea7e2dc5861 (diff)
downloadnumpy-76f6dbd300d38b121a5efca9eb5181de83ab039d.tar.gz
Added PyArray_ArrayType
Diffstat (limited to 'scipy/base/src/arrayobject.c')
-rw-r--r--scipy/base/src/arrayobject.c159
1 files changed, 123 insertions, 36 deletions
diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c
index 7e90358da..05dfc35ed 100644
--- a/scipy/base/src/arrayobject.c
+++ b/scipy/base/src/arrayobject.c
@@ -4309,86 +4309,163 @@ discover_dimensions(PyObject *s, int nd, intp *d, int check_it)
return 0;
}
+static void
+_array_small_type(int chktype, int mintype, int chksize, int minsize,
+ PyArray_Typecode *outtype)
+{
+ outtype->type_num = MAX(chktype, mintype);
+ if (PyTypeNum_ISFLEXIBLE(outtype->type_num) && \
+ PyTypeNum_ISFLEXIBLE(mintype)) {
+ /* Handle string->unicode case separately
+ because string itemsize is twice as large */
+ if (outtype->type_num == PyArray_UNICODE &&
+ mintype == PyArray_STRING) {
+ outtype->itemsize = MAX(chksize, 2*minsize);
+ }
+ else {
+ outtype->itemsize = MAX(chksize, minsize);
+ }
+ }
+ else {
+ outtype->itemsize = chksize;
+ }
+ return;
+}
-static int
-array_objecttype(PyObject *op, int minimum_type, int max)
+static void
+_array_find_type(PyObject *op, PyArray_Typecode *minitype,
+ PyArray_Typecode *outtype, int max)
{
int l;
PyObject *ip;
- int result;
-
- if (minimum_type == -1) return -1;
+ int chktype=0;
+ int chksize=0;
+ int mintype, minsize;
+
+ if (minitype == NULL) {
+ mintype = PyArray_BOOL;
+ minsize = sizeof(bool);
+ }
+ else {
+ mintype = minitype->type_num;
+ minsize = minitype->itemsize;
+ }
- if (max < 0) return PyArray_OBJECT;
+
+ if (max < 0 || mintype == -1) goto deflt;
- if (PyArray_Check(op))
- return MAX(PyArray_TYPE(op), minimum_type);
+ if (PyArray_Check(op)) {
+ chktype = PyArray_TYPE(op);
+ chksize = PyArray_ITEMSIZE(op);
+ goto finish;
+ }
+
+ if (PyArray_IsScalar(op, Generic)) {
+ PyArray_TypecodeFromScalar(op, outtype);
+ chktype = outtype->type_num;
+ chksize = outtype->itemsize;
+ goto finish;
+ }
+
if (PyObject_HasAttrString(op, "__array__")) {
ip = PyObject_CallMethod(op, "__array__", NULL);
- if(ip != NULL) {
- result = MAX(minimum_type, PyArray_TYPE(ip));
- Py_DECREF(ip);
- return result;
+ if(ip && PyArray_Check(ip)) {
+ chktype = PyArray_TYPE(ip);
+ chksize = PyArray_ITEMSIZE(ip);
+ goto finish;
}
}
-
+
if (PyObject_HasAttrString(op, "__array_typestr__")) {
- PyArray_Typecode type = {PyArray_NOTYPE, 0, 0};
int swap=0, res;
ip = PyObject_GetAttrString(op, "__array_typestr__");
if (ip && PyString_Check(ip)) {
res = _array_typecode_fromstr(PyString_AS_STRING(ip),
- &swap, &type);
+ &swap, outtype);
if (res >= 0) {
Py_DECREF(ip);
- return MAX(minimum_type, type.type_num);
+ chktype = outtype->type_num;
+ chksize = outtype->itemsize;
+ goto finish;
}
}
Py_XDECREF(ip);
}
-
+
if (PyString_Check(op)) {
- return MAX(minimum_type, (int)PyArray_STRING);
+ chktype = PyArray_STRING;
+ chksize = PyString_GET_SIZE(op);
+ goto finish;
}
if (PyUnicode_Check(op)) {
- return MAX(minimum_type, (int)PyArray_UNICODE);
+ chktype = PyArray_UNICODE;
+ chksize = PyUnicode_GET_DATA_SIZE(op);
+ goto finish;
}
- if (PyInstance_Check(op)) return PyArray_OBJECT;
+ if (PyBuffer_Check(op)) {
+ chktype = PyArray_VOID;
+ chksize = op->ob_type->tp_as_sequence->sq_length(op);
+ PyErr_Clear();
+ goto finish;
+ }
+ if (PyInstance_Check(op)) goto deflt;
+
if (PySequence_Check(op)) {
+ PyArray_Typecode newtype = {mintype, minsize, 0};
l = PyObject_Length(op);
if (l < 0 && PyErr_Occurred()) {
PyErr_Clear();
- return (int)PyArray_OBJECT;
+ goto deflt;
+ }
+ if (l == 0 && mintype == 0) {
+ newtype.type_num = PyArray_INTP;
+ newtype.itemsize = sizeof(intp);
}
- if (l == 0 && minimum_type == 0)
- minimum_type = PyArray_INTP;
while (--l >= 0) {
ip = PySequence_GetItem(op, l);
if (ip==NULL) {
PyErr_Clear();
- return (int) PyArray_OBJECT;
+ goto deflt;
}
- minimum_type = array_objecttype(ip, minimum_type,
- max-1);
+ _array_find_type(ip, &newtype, outtype, max-1);
+ _array_small_type(outtype->type_num,
+ newtype.type_num,
+ outtype->itemsize,
+ newtype.itemsize,
+ &newtype);
Py_DECREF(ip);
}
- return minimum_type;
+ chktype = newtype.type_num;
+ chksize = newtype.itemsize;
+ goto finish;
}
- if (PyInt_Check(op) || PyLong_Check(op)) {
- return MAX(minimum_type, (int) (PyArray_INTP));
+ if (PyInt_Check(op)) {
+ chktype = PyArray_LONG;
+ chksize = sizeof(long);
+ goto finish;
} else if (PyFloat_Check(op)) {
- return MAX(minimum_type, (int) (PyArray_DOUBLE));
+ chktype = PyArray_DOUBLE;
+ chksize = sizeof(double);
+ goto finish;
} else if (PyComplex_Check(op)) {
- return MAX(minimum_type,
- (int)(PyArray_CDOUBLE));
- } else {
- return (int)PyArray_OBJECT;
+ chktype = PyArray_CDOUBLE;
+ chksize = sizeof(cdouble);
+ goto finish;
}
+
+ deflt:
+ chktype = PyArray_OBJECT;
+ chksize = sizeof(void *);
+
+ finish:
+ _array_small_type(chktype, mintype, chksize, minsize,
+ outtype);
+ return;
}
static int
@@ -5059,7 +5136,7 @@ array_fromobject(PyObject *op, PyArray_Typecode *typecode, int min_depth,
}
else {
if (type == PyArray_NOTYPE) {
- typecode->type_num = array_objecttype(op, 0, MAX_DIMS);
+ _array_find_type(op, NULL, typecode, MAX_DIMS);
}
if (PySequence_Check(op))
r = Array_FromSequence(op, typecode,
@@ -5096,11 +5173,21 @@ array_fromobject(PyObject *op, PyArray_Typecode *typecode, int min_depth,
return r;
}
+static void
+PyArray_ArrayType(PyObject *op, PyArray_Typecode *intype,
+ PyArray_Typecode *outtype)
+{
+ _array_find_type(op, intype, outtype, MAX_DIMS);
+ return;
+}
static int
PyArray_ObjectType(PyObject *op, int minimum_type)
{
- return array_objecttype(op, minimum_type, MAX_DIMS);
+ PyArray_Typecode intype, outtype;
+ intype.type_num = minimum_type;
+ _array_find_type(op, &intype, &outtype, MAX_DIMS);
+ return outtype.type_num;
}