From: Dag Sverre Seljebotn Date: Thu, 25 Sep 2008 09:40:17 +0000 (+0200) Subject: merge X-Git-Tag: 0.9.9.2.beta~63^2~8 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=bbba7ca8251b75654f69a217a4a8cd84df4a4ccd;p=cython.git merge --- bbba7ca8251b75654f69a217a4a8cd84df4a4ccd diff --cc Cython/Compiler/Buffer.py index 10c7e086,aa6d09b0..96767569 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@@ -381,14 -415,16 +415,16 @@@ def put_buffer_lookup_code(entry, index 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): @@@ -557,19 -576,14 +619,19 @@@ def get_getbuffer_code(dtype, code) """ 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); @@@ -581,13 -595,25 +643,25 @@@ __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; diff --cc Cython/Compiler/Code.py index 2b69f484,6fe06d88..bc57c53b --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@@ -168,7 -174,7 +174,8 @@@ class GlobalState(object) self.used_utility_code = set() self.declared_cnames = {} self.pystring_table_needed = False + self.in_utility_code_generation = False + self.emit_linenums = emit_linenums def initwriters(self, rootwriter): self.utilprotowriter = rootwriter.new_writer() diff --cc Cython/Compiler/ExprNodes.py index f8237bee,cd9a5a46..ddf5f618 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@@ -1460,7 -1463,7 +1464,7 @@@ class IndexNode(ExprNode) def is_lvalue(self): return 1 -- ++ def calculate_result_code(self): if self.is_buffer_access: return "" @@@ -1495,9 -1498,9 +1499,10 @@@ def generate_result_code(self, code): if self.is_buffer_access: ++ # buffer_pointer_code is returned by result() ptrcode = self.buffer_lookup_code(code) code.putln("%s = *%s;" % ( - self.result_code, + self.result(), self.buffer_type.buffer_ptr_type.cast_code(ptrcode))) # Must incref the value we pulled out. if self.buffer_type.dtype.is_pyobject: diff --cc tests/run/numpy_test.pyx index 33336ab9,e070d3ce..934e33d4 --- a/tests/run/numpy_test.pyx +++ b/tests/run/numpy_test.pyx @@@ -151,20 -184,17 +182,29 @@@ def put_range_long_1d(np.ndarray[long] 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 @@@ -216,11 -229,18 +256,21 @@@ def inc1_float64_t(np.ndarray[np.float6 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 == data + + def test_bad_cast(): + # This should raise an exception + cdef np.ndarray[long, cast=True] arr = np.array([1], dtype='b') -