From ce0cf9b5cf19b1b06bb0d7ac65600120865f2398 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Fri, 15 Aug 2008 21:44:22 +0200 Subject: [PATCH] Propagating options through list comprehensions. Side-effect: Buffer access starts working within list comprehensions. --- Cython/Compiler/ExprNodes.py | 7 +++++++ tests/run/bufaccess.pyx | 11 ++++++++++- tests/run/tnumpy.pyx | 34 +++++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 6439a7e8..1aca04bc 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1595,6 +1595,9 @@ class IndexNode(ExprNode): code.putln("%s = %s;" % (temp, index.result_code)) # Generate buffer access code using these temps import Buffer + assert self.options is not None + # The above could happen because child_attrs is wrong somewhere so that + # options are not propagated. return Buffer.put_buffer_lookup_code(entry=self.base.entry, index_signeds=[i.type.signed for i in self.indices], index_cnames=index_temps, @@ -2577,6 +2580,8 @@ class ListComprehensionNode(SequenceNode): subexprs = [] is_sequence_constructor = 0 # not unpackable + child_attrs = ["loop", "append"] + def analyse_types(self, env): self.type = list_type self.is_temp = 1 @@ -2602,6 +2607,8 @@ class ListComprehensionNode(SequenceNode): class ListComprehensionAppendNode(ExprNode): + # Need to be careful to avoid infinite recursion: + # target must not be in child_attrs/subexprs subexprs = ['expr'] def analyse_types(self, env): diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx index 5d7d32e1..c6d9159b 100644 --- a/tests/run/bufaccess.pyx +++ b/tests/run/bufaccess.pyx @@ -331,7 +331,7 @@ def explicitly_release_buffer(): print "After release" # -# Index bounds checking +# Getting items and index bounds checking # @testcase def get_int_2d(object[int, 2] buf, int i, int j): @@ -436,6 +436,15 @@ def set_int_2d(object[int, 2] buf, int i, int j, int value): """ buf[i, j] = value +@testcase +def list_comprehension(object[int] buf, len): + """ + >>> list_comprehension(IntMockBuffer(None, [1,2,3]), 3) + 1|2|3 + """ + cdef int i + print "|".join([str(buf[i]) for i in range(len)]) + # # Buffer type mismatch examples. Varying the type and access # method simultaneously, the odds of an interaction is virtually diff --git a/tests/run/tnumpy.pyx b/tests/run/tnumpy.pyx index 05b16ba1..e8937796 100644 --- a/tests/run/tnumpy.pyx +++ b/tests/run/tnumpy.pyx @@ -1,9 +1,9 @@ # cannot be named "numpy" in order to not clash with the numpy module! -cimport numpy +cimport numpy as np try: - import numpy + import numpy as np __doc__ = """ >>> basic() @@ -25,21 +25,45 @@ try: >>> obj_array() [a 1 {}] a 1 {} + + Test various forms of slicing, picking etc. + >>> a = np.arange(10, dtype=np.long).reshape(2, 5) + >>> print_long_2d(a) + 0 1 2 3 4 + 5 6 7 8 9 + >>> print_long_2d(a[::-1, ::-1]) + 9 8 7 6 5 + 4 3 2 1 0 + >>> print_long_2d(a[1:2, 1:3]) + 6 7 + >>> print_long_2d(a[::2, ::2]) + 0 2 4 + >>> print_long_2d(a[::4, :]) + 0 1 2 3 4 + >>> print_long_2d(a[4:1:-1, :]) + 4 3 2 + """ except: __doc__ = "" def basic(): - cdef object[int, 2] buf = numpy.arange(10, dtype='i').reshape((2, 5)) + cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5)) print buf print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0] def three_dim(): - cdef object[double, 3] buf = numpy.arange(24, dtype='d').reshape((3,2,4)) + cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4)) print buf print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0] def obj_array(): - cdef object[object, 1] buf = numpy.array(["a", 1, {}]) + cdef object[object, ndim=1] buf = np.array(["a", 1, {}]) print buf print buf[0], buf[1], buf[2] + + +def print_long_2d(np.ndarray[long, 2] arr): + cdef int i, j + for i in range(arr.shape[0]): + print " ".join([arr[i, j] for j in range(arr.shape[1])]) -- 2.26.2