Propagating options through list comprehensions.
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 19:44:22 +0000 (21:44 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 19:44:22 +0000 (21:44 +0200)
Side-effect: Buffer access starts working within list comprehensions.

Cython/Compiler/ExprNodes.py
tests/run/bufaccess.pyx
tests/run/tnumpy.pyx

index 6439a7e815c0a595809fcb94c4d1b1969801cf04..1aca04bcfcc0acae9b888dec5747003c31afc224 100644 (file)
@@ -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):
index 5d7d32e19f95b4d252027a6a679dcd0a7285953c..c6d9159bb2799f2821360e377a9790e30f32a35e 100644 (file)
@@ -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
index 05b16ba1712b1ae18a638b46944909e4d49fe310..e8937796ec41c4c81589df958a687ee0d044f8a0 100644 (file)
@@ -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])])