for i, s in zip(index_cnames, bufaux.stridevars):
params.append(i)
params.append(s.cname)
- funcname = "__Pyx_BufPtrStrided%dd" % nd
- funcgen = buf_lookup_strided_code
# Make sure the utility code is available
- code.globalstate.use_generated_code(funcgen, name=funcname, nd=nd)
+ code.globalstate.use_code_from(funcgen, name=funcname, nd=nd)
- ptrcode = "%s(%s.buf, %s)" % (funcname, bufstruct, ", ".join(params))
- return entry.type.buffer_ptr_type.cast_code(ptrcode)
+ ptr_type = entry.type.buffer_ptr_type
+ ptrcode = "%s(%s, %s.buf, %s)" % (funcname,
+ ptr_type.declaration_code(""),
+ bufstruct,
+ ", ".join(params))
+ return ptrcode
def use_empty_bufstruct_code(env, max_ndim):
"""
name = "__Pyx_GetBuffer_%s" % mangle_dtype_name(dtype)
- if not code.globalstate.has_utility_code(name):
+ if not code.globalstate.has_code(name):
code.globalstate.use_utility_code(acquire_utility_code)
-
- itemchecker = get_ts_check_item(dtype, code)
+ typestringchecker = "__Pyx_CheckTypestring_%s" % mangle_dtype_name(dtype)
+ code.globalstate.use_code_from(create_typestringchecker,
+ typestringchecker,
+ dtype=dtype)
+
+ dtype_name = str(dtype)
+ dtype_cname = dtype.declaration_code("")
utilcode = [dedent("""
- static int %s(PyObject* obj, Py_buffer* buf, int flags, int nd); /*proto*/
+ static int %s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/
""") % name, dedent("""
- static int %(name)s(PyObject* obj, Py_buffer* buf, int flags, int nd) {
+ static int %(name)s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
const char* ts;
if (obj == Py_None) {
__Pyx_ZeroBuffer(buf);
__Pyx_BufferNdimError(buf, nd);
goto fail;
}
- ts = buf->format;
- ts = %(typestringchecker)s(ts); if (!ts) goto fail;
- ts = __Pyx_ConsumeWhitespace(ts);
- if (*ts != 0) {
- PyErr_Format(PyExc_ValueError,
- "Buffer format string specifies more data than '%(dtype_name)s' can hold (expected end, got '%%s')", ts);
- goto fail;
+ if (!cast) {
+ ts = buf->format;
+ ts = __Pyx_ConsumeWhitespace(ts);
+ if (!ts) goto fail;
- ts = %(itemchecker)s(ts);
++ ts = %(typestringchecker)s(ts);
+ if (!ts) goto fail;
+ ts = __Pyx_ConsumeWhitespace(ts);
+ if (!ts) goto fail;
+ if (*ts != 0) {
+ PyErr_Format(PyExc_ValueError,
- "Expected non-struct buffer data type (expected end, got '%%s')", ts);
++ "Buffer format string specifies more data than '%(dtype_name)s' can hold (expected end, got '%%s')", ts);
+ goto fail;
+ }
+ } else {
+ if (buf->itemsize != sizeof(%(dtype_cname)s)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Attempted cast of buffer to datatype of different size.");
+ goto fail;
+ }
}
if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
return 0;
arr[i] = value
value += 1
+ def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr):
+ cdef int i, j
+ for i in range(arr.shape[0]):
+ print " ".join([str(arr[i, j]) for j in range(arr.shape[1])])
+
+ def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr):
+ cdef int i, j
+ for i in range(arr.shape[0]):
+ print " ".join([str(arr[i, j]) for j in range(arr.shape[1])])
-# Exhaustive dtype tests -- increments element [1] by 1 for all dtypes
+cdef struct cfloat:
+ float real
+ float imag
+
+cdef struct cdouble:
+ double real
+ double imag
+
+cdef struct clongdouble:
+ long double real
+ long double imag
+
+# Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes
def inc1_byte(np.ndarray[char] arr): arr[1] += 1
def inc1_ubyte(np.ndarray[unsigned char] arr): arr[1] += 1
def inc1_short(np.ndarray[short] arr): arr[1] += 1
def test_dtype(dtype, inc1):
- a = np.array([0, 10], dtype=dtype)
- inc1(a)
- if a[1] != 11: print "failed!"
-
+ if dtype in ('F', 'D', 'G'):
+ a = np.array([0, 10+10j], dtype=dtype)
+ inc1(a)
+ if a[1] != (11 + 11j): print "failed!", a[1]
+ else:
+ a = np.array([0, 10], dtype=dtype)
+ inc1(a)
+ if a[1] != 11: print "failed!"
+
+ def test_good_cast():
+ # Check that a signed int can round-trip through casted unsigned int access
+ cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i')
+ cdef unsigned int data = arr[0]
+ return -100 == <int>data
+
+ def test_bad_cast():
+ # This should raise an exception
+ cdef np.ndarray[long, cast=True] arr = np.array([1], dtype='b')
-