summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wiebe <mwwiebe@gmail.com>2010-12-21 13:51:38 -0800
committerMark Wiebe <mwwiebe@gmail.com>2011-01-09 01:55:00 -0800
commitba576a7faa8b5c67de4e078dba53f7fd88b0b8a1 (patch)
tree84b874c1b16823017d6f56777deca200cd45e9b6
parentf36566682043e9b2a27f3171c1fc94e63977d494 (diff)
downloadnumpy-ba576a7faa8b5c67de4e078dba53f7fd88b0b8a1.tar.gz
ENH: iter: Move casting flags into a casting= parameter
-rw-r--r--numpy/core/include/numpy/ndarraytypes.h6
-rw-r--r--numpy/core/src/multiarray/new_iterator.c.src62
-rw-r--r--numpy/core/src/multiarray/new_iterator.h39
-rw-r--r--numpy/core/src/multiarray/new_iterator_pywrap.c105
-rw-r--r--numpy/core/tests/test_new_iterator.py97
5 files changed, 209 insertions, 100 deletions
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index a0ae16990..5a552b8e6 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -174,14 +174,18 @@ typedef enum {
} NPY_SCALARKIND;
#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+/* For specifying array memory layout or iteration order */
typedef enum {
+ /* Fortran order if inputs are all Fortran, C otherwise */
NPY_ANYORDER=-1,
+ /* C order */
NPY_CORDER=0,
+ /* Fortran order */
NPY_FORTRANORDER=1,
+ /* An order as close to the inputs as possible */
NPY_KEEPORDER=2
} NPY_ORDER;
-
typedef enum {
NPY_CLIP=0,
NPY_WRAP=1,
diff --git a/numpy/core/src/multiarray/new_iterator.c.src b/numpy/core/src/multiarray/new_iterator.c.src
index e853d9df0..2ede07943 100644
--- a/numpy/core/src/multiarray/new_iterator.c.src
+++ b/numpy/core/src/multiarray/new_iterator.c.src
@@ -51,7 +51,7 @@
/* The operand never needs buffering */
#define NPY_OP_ITFLAG_BUFNEVER 0x20
/* The operand is aligned */
-#define NPY_OP_ITFLAG_ALIGNED 0x80
+#define NPY_OP_ITFLAG_ALIGNED 0x40
/* Internal flag, for the type of operands */
#define NPY_ITER_OP_ARRAY 0
@@ -189,7 +189,7 @@ pyiter_prepare_operand(PyArrayObject **op, PyArray_Descr *op_request_dtype,
static int
npyiter_check_casting(npy_intp niter, PyArrayObject **op,
PyArray_Descr **op_dtype,
- npy_uint32 *op_flags,
+ NPY_CASTING casting,
char *op_itflags);
static int
npyiter_fill_axisdata(NpyIter *iter, PyArrayObject **op,
@@ -222,6 +222,8 @@ npyiter_get_common_dtype(npy_intp niter, PyArrayObject **op, npy_intp *op_ndim,
int only_inputs);
static int
npyiter_promote_types(int type1, int type2);
+static int
+npyiter_can_cast(PyArray_Descr *from, PyArray_Descr *to, NPY_CASTING casting);
static PyArrayObject *
npyiter_new_temp_array(NpyIter *iter, PyTypeObject *subtype,
@@ -240,7 +242,8 @@ npyiter_copy_to_buffers(NpyIter *iter);
/* The constructor for an iterator over multiple objects */
NpyIter*
NpyIter_MultiNew(npy_intp niter, PyArrayObject **op_in, npy_uint32 flags,
- NPY_ORDER order, npy_uint32 *op_flags,
+ NPY_ORDER order, NPY_CASTING casting,
+ npy_uint32 *op_flags,
PyArray_Descr **op_request_dtypes,
npy_intp oa_ndim, npy_intp **op_axes, npy_intp buffersize)
{
@@ -611,7 +614,7 @@ NpyIter_MultiNew(npy_intp niter, PyArrayObject **op_in, npy_uint32 flags,
* to check that data type conversions are following the
* casting rules.
*/
- if (!npyiter_check_casting(niter, op, op_dtype, op_flags, op_itflags)) {
+ if (!npyiter_check_casting(niter, op, op_dtype, casting, op_itflags)) {
NpyIter_Deallocate(iter);
return NULL;
}
@@ -848,7 +851,8 @@ NpyIter_MultiNew(npy_intp niter, PyArrayObject **op_in, npy_uint32 flags,
/* The constructor for an iterator over one object */
NpyIter*
NpyIter_New(PyArrayObject *op, npy_uint32 flags,
- NPY_ORDER order, PyArray_Descr* dtype,
+ NPY_ORDER order, NPY_CASTING casting,
+ PyArray_Descr* dtype,
npy_intp a_ndim, npy_intp *axes, npy_intp buffersize)
{
/* Split the flags into separate global and op flags */
@@ -856,11 +860,13 @@ NpyIter_New(PyArrayObject *op, npy_uint32 flags,
flags &= NPY_ITER_GLOBAL_FLAGS;
if (a_ndim > 0) {
- return NpyIter_MultiNew(1, &op, flags, order, &op_flags, &dtype,
+ return NpyIter_MultiNew(1, &op, flags, order, casting,
+ &op_flags, &dtype,
a_ndim, &axes, buffersize);
}
else {
- return NpyIter_MultiNew(1, &op, flags, order, &op_flags, &dtype,
+ return NpyIter_MultiNew(1, &op, flags, order, casting,
+ &op_flags, &dtype,
0, NULL, buffersize);
}
}
@@ -1970,22 +1976,27 @@ npyiter_check_per_op_flags(npy_uint32 op_flags, char *op_itflags)
/*
* Returns 1 if the from -> to cast can be done, based on the casting
* flags provided in op_flags, and 0 otherwise.
+ *
+ * TODO: Maybe this approach, with the NPY_CASTING enum, should replace
+ * the PyArray_CanCastTo code for NumPy 2.0?
*/
static int
-npyiter_can_cast(npy_uint32 op_flags, PyArray_Descr *from, PyArray_Descr *to)
+npyiter_can_cast(PyArray_Descr *from, PyArray_Descr *to, NPY_CASTING casting)
{
/* If unsafe casts are allowed */
- if (op_flags&NPY_ITER_UNSAFE_CASTS) {
+ if (casting == NPY_UNSAFE_CASTING) {
return 1;
}
- /* Equivalent types can be cast even with no casting flags */
+ /* Equivalent types can be cast with any value of 'casting' */
else if (PyArray_EquivTypenums(from->type_num, to->type_num)) {
/* If the types are extended, convert to NBO and compare */
if (PyTypeNum_ISEXTENDED(from->type_num)) {
int ret;
- if (!PyArray_ISNBO(from->byteorder) ||
- !PyArray_ISNBO(to->byteorder)) {
+ /* Only NPY_NO_CASTING prevents byte order conversion */
+ if ((casting != NPY_NO_CASTING) &&
+ (!PyArray_ISNBO(from->byteorder) ||
+ !PyArray_ISNBO(to->byteorder))) {
PyArray_Descr *nbo_from, *nbo_to;
nbo_from = PyArray_DescrNewByteorder(from, NPY_NATIVE);
@@ -2008,19 +2019,22 @@ npyiter_can_cast(npy_uint32 op_flags, PyArray_Descr *from, PyArray_Descr *to)
return 1;
}
/* If safe or same-kind casts are allowed */
- else if (op_flags&(NPY_ITER_SAFE_CASTS|
- NPY_ITER_SAME_KIND_CASTS)) {
+ else if (casting == NPY_SAFE_CASTING || casting == NPY_SAME_KIND_CASTING) {
if (PyArray_CanCastTo(from, to)) {
return 1;
}
- else if(op_flags&NPY_ITER_SAME_KIND_CASTS) {
+ else if(casting == NPY_SAME_KIND_CASTING) {
+ /* TODO: Should also allow casting from "lower" to "higher
+ * kinds, but kind is a char so we need to remap to
+ * an ordered version (like NPY_SCALARKIND is ordered).
+ */
return from->kind == to->kind;
}
else {
return 0;
}
}
- /* No casting flags were specified */
+ /* NPY_NO_CASTING or NPY_EQUIV_CASTING was specified */
else {
return 0;
}
@@ -2143,7 +2157,7 @@ pyiter_prepare_operand(PyArrayObject **op, PyArray_Descr *op_request_dtype,
static int
npyiter_check_casting(npy_intp niter, PyArrayObject **op,
PyArray_Descr **op_dtype,
- npy_uint32 *op_flags,
+ NPY_CASTING casting,
char *op_itflags)
{
npy_intp iiter;
@@ -2154,22 +2168,24 @@ npyiter_check_casting(npy_intp niter, PyArrayObject **op,
op_dtype[iiter])) {
/* Check read (op -> temp) casting */
if ((op_itflags[iiter]&NPY_OP_ITFLAG_READ) &&
- !npyiter_can_cast(op_flags[iiter],
- PyArray_DESCR(op[iiter]), op_dtype[iiter])) {
+ !npyiter_can_cast(PyArray_DESCR(op[iiter]),
+ op_dtype[iiter],
+ casting)) {
PyErr_Format(PyExc_TypeError,
"Iterator operand %d dtype could not be cast "
"to the requested dtype, according to "
- "the casting flags given", (int)iiter);
+ "the casting enabled", (int)iiter);
return 0;
}
/* Check write (temp -> op) casting */
if ((op_itflags[iiter]&NPY_OP_ITFLAG_WRITE) &&
- !npyiter_can_cast(op_flags[iiter],
- op_dtype[iiter], PyArray_DESCR(op[iiter]))) {
+ !npyiter_can_cast(op_dtype[iiter],
+ PyArray_DESCR(op[iiter]),
+ casting)) {
PyErr_Format(PyExc_TypeError,
"Iterator requested dtype could not be cast "
"to the operand %d dtype, according to "
- "the casting flags given", (int)iiter);
+ "the casting enabled", (int)iiter);
return 0;
}
diff --git a/numpy/core/src/multiarray/new_iterator.h b/numpy/core/src/multiarray/new_iterator.h
index 1e551952d..a1071925f 100644
--- a/numpy/core/src/multiarray/new_iterator.h
+++ b/numpy/core/src/multiarray/new_iterator.h
@@ -12,18 +12,33 @@ typedef int (*NpyIter_IterNext_Fn )(NpyIter *iter);
typedef void (*NpyIter_GetCoords_Fn )(NpyIter *iter,
npy_intp *outcoords);
+/* For specifying allowed casting in operations which support it */
+typedef enum {
+ /* Only allow exactly equivalent types */
+ NPY_NO_CASTING=0,
+ /* Allow casts between equivalent types of different byte orders */
+ NPY_EQUIV_CASTING=0,
+ /* Only allow safe casts */
+ NPY_SAFE_CASTING=1,
+ /* Allow safe casts or casts within the same kind */
+ NPY_SAME_KIND_CASTING=2,
+ /* Allow any casts */
+ NPY_UNSAFE_CASTING=3
+} NPY_CASTING;
+
/* Allocate a new iterator over one array object */
NpyIter*
NpyIter_New(PyArrayObject* op, npy_uint32 flags,
- NPY_ORDER order, PyArray_Descr* dtype,
+ NPY_ORDER order, NPY_CASTING casting,
+ PyArray_Descr* dtype,
npy_intp a_ndim, npy_intp *axes, npy_intp buffersize);
/* Allocate a new iterator over multiple array objects */
NpyIter*
NpyIter_MultiNew(npy_intp niter, PyArrayObject **op_in, npy_uint32 flags,
- NPY_ORDER order, npy_uint32 *op_flags,
- PyArray_Descr **op_request_dtypes,
+ NPY_ORDER order, NPY_CASTING casting,
+ npy_uint32 *op_flags, PyArray_Descr **op_request_dtypes,
npy_intp oa_ndim, npy_intp **op_axes, npy_intp buffersize);
/* Removes coords support from an iterator */
@@ -122,20 +137,14 @@ NPY_NO_EXPORT void NpyIter_DebugPrint(NpyIter *iter);
#define NPY_ITER_COPY 0x00100000
/* The operand may be copied with UPDATEIFCOPY to satisfy requirements */
#define NPY_ITER_UPDATEIFCOPY 0x00200000
-/* Allow safe casts to be used when converting data */
-#define NPY_ITER_SAFE_CASTS 0x00400000
-/* Allow casts within types of the same kind to be used when converting data */
-#define NPY_ITER_SAME_KIND_CASTS 0x00800000
-/* Allow any casts when converting data */
-#define NPY_ITER_UNSAFE_CASTS 0x01000000
/* Allow writeable operands to have references or pointers */
-#define NPY_ITER_WRITEABLE_REFERENCES 0x02000000
+#define NPY_ITER_WRITEABLE_REFERENCES 0x00400000
/* Allocate the operand if it is NULL */
-#define NPY_ITER_ALLOCATE 0x04000000
-/* If an operand is allocated, don't use the priority subtype */
-#define NPY_ITER_NO_SUBTYPE 0x08000000
-/* Disallows broadcasting of the dimensions, they must match exactly */
-#define NPY_ITER_NO_BROADCAST 0x10000000
+#define NPY_ITER_ALLOCATE 0x00800000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE 0x01000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST 0x02000000
#define NPY_ITER_GLOBAL_FLAGS 0x0000ffff
#define NPY_ITER_PER_OP_FLAGS 0xffff0000
diff --git a/numpy/core/src/multiarray/new_iterator_pywrap.c b/numpy/core/src/multiarray/new_iterator_pywrap.c
index e37b95417..94c9a04a1 100644
--- a/numpy/core/src/multiarray/new_iterator_pywrap.c
+++ b/numpy/core/src/multiarray/new_iterator_pywrap.c
@@ -79,10 +79,11 @@ static int
npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"op", "flags", "op_flags", "op_dtypes",
- "order", "op_axes", "buffersize"};
+ "order", "casting", "op_axes", "buffersize",
+ NULL};
PyObject *op_in, *flags_in = NULL, *order_in = NULL, *op_flags_in = NULL,
- *op_dtypes_in = NULL, *op_axes_in = NULL;
+ *op_dtypes_in = NULL, *casting_in = NULL, *op_axes_in = NULL;
npy_intp iiter, buffersize = 0;
@@ -90,6 +91,7 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
PyArrayObject *op[NPY_MAXARGS];
npy_uint32 flags = 0;
NPY_ORDER order = NPY_KEEPORDER;
+ NPY_CASTING casting = NPY_NO_CASTING;
npy_uint32 op_flags[NPY_MAXARGS];
PyArray_Descr *op_request_dtypes[NPY_MAXARGS];
npy_intp oa_ndim = 0;
@@ -102,9 +104,9 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
return -1;
}
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOOOOi", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOOOOOi", kwlist,
&op_in, &flags_in, &op_flags_in, &op_dtypes_in,
- &order_in, &op_axes_in, &buffersize)) {
+ &order_in, &casting_in, &op_axes_in, &buffersize)) {
return -1;
}
@@ -239,7 +241,7 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
if (length != 1) {
PyErr_SetString(PyExc_ValueError,
- "order must be 'C', 'F', 'A', or 'K'");
+ "order must be one of 'C', 'F', 'A', or 'K'");
goto fail;
}
switch (str[0]) {
@@ -257,10 +259,72 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
break;
default:
PyErr_SetString(PyExc_ValueError,
- "order must be 'C', 'F', 'A', or 'K'");
+ "order must be one of 'C', 'F', 'A', or 'K'");
goto fail;
}
}
+ /* casting */
+ if (casting_in != NULL) {
+ char *str = NULL;
+ Py_ssize_t length = 0;
+ int bad_cast_input = 0;
+
+ if (PyString_AsStringAndSize(casting_in, &str, &length) == -1) {
+ goto fail;
+ }
+ if (length >= 2) switch (str[2]) {
+ case 0:
+ if (strcmp(str, "no") == 0) {
+ casting = NPY_NO_CASTING;
+ }
+ else {
+ bad_cast_input = 1;
+ }
+ break;
+ case 'u':
+ if (strcmp(str, "equiv") == 0) {
+ casting = NPY_EQUIV_CASTING;
+ }
+ else {
+ bad_cast_input = 1;
+ }
+ break;
+ case 'f':
+ if (strcmp(str, "safe") == 0) {
+ casting = NPY_SAFE_CASTING;
+ }
+ else {
+ bad_cast_input = 1;
+ }
+ break;
+ case 'm':
+ if (strcmp(str, "same_kind") == 0) {
+ casting = NPY_SAME_KIND_CASTING;
+ }
+ else {
+ bad_cast_input = 1;
+ }
+ break;
+ case 's':
+ if (strcmp(str, "unsafe") == 0) {
+ casting = NPY_UNSAFE_CASTING;
+ }
+ else {
+ bad_cast_input = 1;
+ }
+ break;
+ default:
+ bad_cast_input = 1;
+ break;
+
+ }
+ if (bad_cast_input) {
+ PyErr_SetString(PyExc_ValueError,
+ "casting must be one of 'no', 'equiv', 'safe', "
+ "'same_kind', or 'unsafe'");
+ goto fail;
+ }
+ }
/* op_flags */
if (op_flags_in == NULL) {
for (iiter = 0; iiter < niter; ++iiter) {
@@ -350,32 +414,9 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
break;
}
break;
- case 's':
- if (length > 2) switch (str[2]) {
- case 'f':
- if (strcmp(str, "safe_casts") == 0) {
- flag = NPY_ITER_SAFE_CASTS;
- }
- break;
- case 'm':
- if (strcmp(str, "same_kind_casts") == 0) {
- flag = NPY_ITER_SAME_KIND_CASTS;
- }
- break;
- }
- break;
case 'u':
- switch (str[1]) {
- case 'n':
- if (strcmp(str, "unsafe_casts") == 0) {
- flag = NPY_ITER_UNSAFE_CASTS;
- }
- break;
- case 'p':
- if (strcmp(str, "updateifcopy") == 0) {
- flag = NPY_ITER_UPDATEIFCOPY;
- }
- break;
+ if (strcmp(str, "updateifcopy") == 0) {
+ flag = NPY_ITER_UPDATEIFCOPY;
}
break;
case 'w':
@@ -553,7 +594,7 @@ npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
}
}
- self->iter = NpyIter_MultiNew(niter, op, flags, order, op_flags,
+ self->iter = NpyIter_MultiNew(niter, op, flags, order, casting, op_flags,
(PyArray_Descr**)op_request_dtypes,
oa_ndim, oa_ndim > 0 ? op_axes : NULL,
buffersize);
diff --git a/numpy/core/tests/test_new_iterator.py b/numpy/core/tests/test_new_iterator.py
index 50596fd73..37d71e7d9 100644
--- a/numpy/core/tests/test_new_iterator.py
+++ b/numpy/core/tests/test_new_iterator.py
@@ -27,7 +27,8 @@ def test_iter_refcount():
rc_a = sys.getrefcount(a)
rc_dt = sys.getrefcount(dt)
it = newiter(a, [],
- [['readwrite','unsafe_casts','updateifcopy']],
+ [['readwrite','updateifcopy']],
+ casting='unsafe',
op_dtypes=[dt])
assert_(sys.getrefcount(a) > rc_a)
assert_(sys.getrefcount(dt) > rc_dt)
@@ -664,16 +665,26 @@ def test_iter_array_cast():
assert_equal(i.operands[0], a)
assert_equal(i.operands[0].dtype, np.dtype('f4'))
+ # Byte-order cast '<f4' -> '>f4'
+ a = np.arange(6, dtype='<f4').reshape(2,3)
+ i = newiter(a, [], [['readwrite','updateifcopy']],
+ casting='equiv',
+ op_dtypes=[np.dtype('>f4')])
+ assert_equal(i.operands[0], a)
+ assert_equal(i.operands[0].dtype, np.dtype('>f4'))
+
# Safe case 'f4' -> 'f8'
a = np.arange(24, dtype='f4').reshape(2,3,4).swapaxes(1,2)
- i = newiter(a, [], [['readonly','copy','safe_casts']],
+ i = newiter(a, [], [['readonly','copy']],
+ casting='safe',
op_dtypes=[np.dtype('f8')])
assert_equal(i.operands[0], a)
assert_equal(i.operands[0].dtype, np.dtype('f8'))
# The memory layout of the temporary should match a (a is (48,4,16))
assert_equal(i.operands[0].strides, (96,8,32))
a = a[::-1,:,::-1]
- i = newiter(a, [], [['readonly','copy','safe_casts']],
+ i = newiter(a, [], [['readonly','copy']],
+ casting='safe',
op_dtypes=[np.dtype('f8')])
assert_equal(i.operands[0], a)
assert_equal(i.operands[0].dtype, np.dtype('f8'))
@@ -682,7 +693,8 @@ def test_iter_array_cast():
# Same-kind cast 'f8' -> 'f4' -> 'f8'
a = np.arange(24, dtype='f8').reshape(2,3,4).T
i = newiter(a, [],
- [['readwrite','updateifcopy','same_kind_casts']],
+ [['readwrite','updateifcopy']],
+ casting='same_kind',
op_dtypes=[np.dtype('f4')])
assert_equal(i.operands[0], a)
assert_equal(i.operands[0].dtype, np.dtype('f4'))
@@ -696,7 +708,8 @@ def test_iter_array_cast():
# Unsafe cast 'f4' -> 'i4'
a = np.arange(6, dtype='i4')[::-2]
i = newiter(a, [],
- [['writeonly','updateifcopy','unsafe_casts']],
+ [['writeonly','updateifcopy']],
+ casting='unsafe',
op_dtypes=[np.dtype('f4')])
assert_equal(i.operands[0].dtype, np.dtype('f4'))
assert_equal(i.operands[0].strides, (-4,))
@@ -716,19 +729,27 @@ def test_iter_array_cast_errors():
assert_raises(TypeError, newiter, arange(2,dtype='f8'), [],
[['writeonly','updateifcopy']],
op_dtypes=[np.dtype('f4')])
+ # '<f4' -> '>f4' should not work with casting='no'
+ assert_raises(TypeError, newiter, arange(2,dtype='<f4'), [],
+ [['readonly']], casting='no',
+ op_dtypes=[np.dtype('>f4')])
# 'f4' -> 'f8' is a safe cast, but 'f8' -> 'f4' isn't
assert_raises(TypeError, newiter, arange(2,dtype='f4'), [],
- [['readwrite','updateifcopy','safe_casts']],
+ [['readwrite','updateifcopy']],
+ casting='safe',
op_dtypes=[np.dtype('f8')])
assert_raises(TypeError, newiter, arange(2,dtype='f8'), [],
- [['readwrite','updateifcopy','safe_casts']],
+ [['readwrite','updateifcopy']],
+ casting='safe',
op_dtypes=[np.dtype('f4')])
# 'f4' -> 'i4' is neither a safe nor a same-kind cast
assert_raises(TypeError, newiter, arange(2,dtype='f4'), [],
- [['readonly','copy','same_kind_casts']],
+ [['readonly','copy']],
+ casting='same_kind',
op_dtypes=[np.dtype('i4')])
assert_raises(TypeError, newiter, arange(2,dtype='i4'), [],
- [['writeonly','updateifcopy','same_kind_casts']],
+ [['writeonly','updateifcopy']],
+ casting='same_kind',
op_dtypes=[np.dtype('f4')])
def test_iter_scalar_cast():
@@ -742,21 +763,24 @@ def test_iter_scalar_cast():
assert_equal(i.value, 2.5)
# Safe cast 'f4' -> 'f8'
i = newiter(np.float32(2.5), [],
- [['readonly','copy','safe_casts']],
+ [['readonly','copy']],
+ casting='safe',
op_dtypes=[np.dtype('f8')])
assert_equal(i.dtypes[0], np.dtype('f8'))
assert_equal(i.value.dtype, np.dtype('f8'))
assert_equal(i.value, 2.5)
# Same-kind cast 'f8' -> 'f4'
i = newiter(np.float64(2.5), [],
- [['readonly','copy','same_kind_casts']],
+ [['readonly','copy']],
+ casting='same_kind',
op_dtypes=[np.dtype('f4')])
assert_equal(i.dtypes[0], np.dtype('f4'))
assert_equal(i.value.dtype, np.dtype('f4'))
assert_equal(i.value, 2.5)
# Unsafe cast 'f8' -> 'i4'
i = newiter(np.float64(3.0), [],
- [['readonly','copy','unsafe_casts']],
+ [['readonly','copy']],
+ casting='unsafe',
op_dtypes=[np.dtype('i4')])
assert_equal(i.dtypes[0], np.dtype('i4'))
assert_equal(i.value.dtype, np.dtype('i4'))
@@ -772,11 +796,13 @@ def test_iter_scalar_cast_errors():
[['readonly']], op_dtypes=[np.dtype('f4')])
# 'f8' -> 'f4' isn't a safe cast
assert_raises(TypeError, newiter, np.float64(2), [],
- [['readonly','safe_casts']],
+ [['readonly']],
+ casting='safe',
op_dtypes=[np.dtype('f4')])
# 'f4' -> 'i4' is neither a safe nor a same-kind cast
assert_raises(TypeError, newiter, np.float32(2), [],
- [['readonly','same_kind_casts']],
+ [['readonly']],
+ casting='same_kind',
op_dtypes=[np.dtype('i4')])
def test_iter_common_data_type():
@@ -784,17 +810,20 @@ def test_iter_common_data_type():
i = newiter([array([3],dtype='f4'),array([0],dtype='f8')],
['common_data_type'],
- [['readonly','copy','safe_casts']]*2)
+ [['readonly','copy']]*2,
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('f8'));
assert_equal(i.dtypes[1], np.dtype('f8'));
i = newiter([array([3],dtype='i4'),array([0],dtype='f4')],
['common_data_type'],
- [['readonly','copy','safe_casts']]*2)
+ [['readonly','copy']]*2,
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('f8'));
assert_equal(i.dtypes[1], np.dtype('f8'));
i = newiter([array([3],dtype='f4'),array(0,dtype='f8')],
['common_data_type'],
- [['readonly','copy','same_kind_casts']]*2)
+ [['readonly','copy']]*2,
+ casting='same_kind')
assert_equal(i.dtypes[0], np.dtype('f4'));
assert_equal(i.dtypes[1], np.dtype('f4'));
# TODO
@@ -804,18 +833,21 @@ def test_iter_common_data_type():
# be written during iteration, invalidating the scalar kind assumed!
i = newiter([array([3],dtype='u4'),array(0,dtype='i4')],
['common_data_type'],
- [['readonly','copy','unsafe_casts']]*2)
+ [['readonly','copy']]*2,
+ casting='unsafe')
assert_equal(i.dtypes[0], np.dtype('u4'));
assert_equal(i.dtypes[1], np.dtype('u4'));
i = newiter([array([3],dtype='u4'),array(-12,dtype='i4')],
['common_data_type'],
- [['readonly','copy','safe_casts']]*2)
+ [['readonly','copy']]*2,
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('i8'));
assert_equal(i.dtypes[1], np.dtype('i8'));
i = newiter([array([3],dtype='u4'),array(-12,dtype='i4'),
array([2j],dtype='c8'),array([9],dtype='f8')],
['common_data_type'],
- [['readonly','copy','safe_casts']]*4)
+ [['readonly','copy']]*4,
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('c16'));
assert_equal(i.dtypes[1], np.dtype('c16'));
assert_equal(i.dtypes[2], np.dtype('c16'));
@@ -824,18 +856,20 @@ def test_iter_common_data_type():
# When allocating outputs, other outputs aren't factored in
i = newiter([array([3],dtype='i4'),None,array([2j],dtype='c16')], [],
- [['readonly','copy','safe_casts'],
+ [['readonly','copy'],
['writeonly','allocate'],
- ['writeonly']])
+ ['writeonly']],
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('i4'));
assert_equal(i.dtypes[1], np.dtype('i4'));
assert_equal(i.dtypes[2], np.dtype('c16'));
# But, if common data types are requested, they are
i = newiter([array([3],dtype='i4'),None,array([2j],dtype='c16')],
['common_data_type'],
- [['readonly','copy','safe_casts'],
+ [['readonly','copy'],
['writeonly','allocate'],
- ['writeonly']])
+ ['writeonly']],
+ casting='safe')
assert_equal(i.dtypes[0], np.dtype('c16'));
assert_equal(i.dtypes[1], np.dtype('c16'));
assert_equal(i.dtypes[2], np.dtype('c16'));
@@ -1128,7 +1162,8 @@ def test_iter_buffered_cast_simple():
a = np.arange(10, dtype='f4')
i = np.newiter(a, ['buffered','no_inner_iteration'],
- [['readwrite','nbo_aligned','same_kind_casts']],
+ [['readwrite','nbo_aligned']],
+ casting='same_kind',
op_dtypes=[np.dtype('f8')],
buffersize=3)
for v in i:
@@ -1165,7 +1200,8 @@ def test_iter_buffered_cast_byteswapped():
a = np.arange(10, dtype='c8').newbyteorder().byteswap()
a += 2j
i = np.newiter(a, ['buffered','no_inner_iteration'],
- [['readwrite','nbo_aligned','same_kind_casts']],
+ [['readwrite','nbo_aligned']],
+ casting='same_kind',
op_dtypes=[np.dtype('c16')],
buffersize=3)
for v in i:
@@ -1175,7 +1211,8 @@ def test_iter_buffered_cast_byteswapped():
a = np.arange(10, dtype='c8')
a += 2j
i = np.newiter(a, ['buffered','no_inner_iteration'],
- [['readwrite','nbo_aligned','same_kind_casts']],
+ [['readwrite','nbo_aligned']],
+ casting='same_kind',
op_dtypes=[np.dtype('c16').newbyteorder()],
buffersize=3)
for v in i:
@@ -1185,7 +1222,8 @@ def test_iter_buffered_cast_byteswapped():
a = np.arange(10, dtype=np.clongdouble).newbyteorder().byteswap()
a += 2j
i = np.newiter(a, ['buffered','no_inner_iteration'],
- [['readwrite','nbo_aligned','same_kind_casts']],
+ [['readwrite','nbo_aligned']],
+ casting='same_kind',
op_dtypes=[np.dtype('c16')],
buffersize=3)
for v in i:
@@ -1194,7 +1232,8 @@ def test_iter_buffered_cast_byteswapped():
a = np.arange(10, dtype=np.longdouble).newbyteorder().byteswap()
i = np.newiter(a, ['buffered','no_inner_iteration'],
- [['readwrite','nbo_aligned','same_kind_casts']],
+ [['readwrite','nbo_aligned']],
+ casting='same_kind',
op_dtypes=[np.dtype('f4')],
buffersize=7)
for v in i: