let generator expressions inherit type declarations from surrounding scope
authorStefan Behnel <scoder@users.berlios.de>
Tue, 25 May 2010 07:30:19 +0000 (09:30 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Tue, 25 May 2010 07:30:19 +0000 (09:30 +0200)
Cython/Compiler/Symtab.py
tests/run/all.pyx
tests/run/any.pyx

index 3f33b9666749c4fdb13b39c3a1b455b810049030..b7b3d65578afb29355fb319bcf045099b08cab00 100644 (file)
@@ -1275,6 +1275,11 @@ class GeneratorExpressionScope(LocalScope):
 
     def declare_var(self, name, type, pos,
                     cname = None, visibility = 'private', is_cdef = True):
+        if type is unspecified_type:
+            # if the outer scope defines a type for this variable, inherit it
+            outer_entry = self.outer_scope.lookup(name)
+            if outer_entry and not outer_entry.is_builtin:
+                type = outer_entry.type # may still be 'unspecified_type' !
         # the outer scope needs to generate code for the variable, but
         # this scope must hold its name exclusively
         cname = '%s%s' % (self.genexp_prefix, self.outer_scope.mangle(Naming.var_prefix, name))
index f87ea293753eacd5fe900eed93604f00dc95a156..29b7561403027623549ed8605192e39c6f0111e3 100644 (file)
@@ -166,9 +166,11 @@ def all_lower_case_characters(unicode ustring):
     return all(uchar.islower() for uchar in ustring)
 
 @cython.test_assert_path_exists("//ForInStatNode",
-                                "//InlinedGeneratorExpressionNode")
+                                "//InlinedGeneratorExpressionNode",
+                                "//InlinedGeneratorExpressionNode//IfStatNode")
 @cython.test_fail_if_path_exists("//SimpleCallNode",
-                                 "//YieldExprNode")
+                                 "//YieldExprNode",
+                                 "//IfStatNode//CoerceToBooleanNode")
 def all_in_typed_gen(seq):
     """
     >>> all_in_typed_gen([1,1,1])
@@ -192,15 +194,15 @@ def all_in_typed_gen(seq):
     4
     False
     """
-    # FIXME: this isn't really supposed to work, but it currently does
-    # due to incorrect scoping - this should be fixed!!
     cdef int x
     return all(x for x in seq)
 
 @cython.test_assert_path_exists("//ForInStatNode",
-                                "//InlinedGeneratorExpressionNode")
+                                "//InlinedGeneratorExpressionNode",
+                                "//InlinedGeneratorExpressionNode//IfStatNode")
 @cython.test_fail_if_path_exists("//SimpleCallNode",
-                                 "//YieldExprNode")
+                                 "//YieldExprNode",
+                                 "//IfStatNode//CoerceToBooleanNode")
 def all_in_nested_gen(seq):
     """
     >>> all(x for L in [[1,1,1],[1,1,1],[1,1,1]] for x in L)
@@ -243,7 +245,5 @@ def all_in_nested_gen(seq):
     2
     False
     """
-    # FIXME: this isn't really supposed to work, but it currently does
-    # due to incorrect scoping - this should be fixed!!
     cdef int x
     return all(x for L in seq for x in L)
index 1a1d5898fc8b00c571b9a5898d9d1aeca69f685c..1621e66d7b2598c5c1cdb049c95177a8a0be2c54 100644 (file)
@@ -143,7 +143,8 @@ lower_ustring = mixed_ustring.lower()
 upper_ustring = mixed_ustring.upper()
 
 @cython.test_assert_path_exists('//PythonCapiCallNode',
-                                '//ForFromStatNode')
+                                '//ForFromStatNode',
+                                "//InlinedGeneratorExpressionNode")
 @cython.test_fail_if_path_exists('//SimpleCallNode',
                                  '//ForInStatNode')
 def any_lower_case_characters(unicode ustring):
@@ -158,9 +159,11 @@ def any_lower_case_characters(unicode ustring):
     return any(uchar.islower() for uchar in ustring)
 
 @cython.test_assert_path_exists("//ForInStatNode",
-                                "//InlinedGeneratorExpressionNode")
+                                "//InlinedGeneratorExpressionNode",
+                                "//InlinedGeneratorExpressionNode//IfStatNode")
 @cython.test_fail_if_path_exists("//SimpleCallNode",
-                                 "//YieldExprNode")
+                                 "//YieldExprNode",
+                                 "//IfStatNode//CoerceToBooleanNode")
 def any_in_typed_gen(seq):
     """
     >>> any_in_typed_gen([0,1,0])
@@ -182,15 +185,15 @@ def any_in_typed_gen(seq):
     5
     False
     """
-    # FIXME: this isn't really supposed to work, but it currently does
-    # due to incorrect scoping - this should be fixed!!
     cdef int x
     return any(x for x in seq)
 
 @cython.test_assert_path_exists("//ForInStatNode",
-                                "//InlinedGeneratorExpressionNode")
+                                "//InlinedGeneratorExpressionNode",
+                                "//InlinedGeneratorExpressionNode//IfStatNode")
 @cython.test_fail_if_path_exists("//SimpleCallNode",
-                                 "//YieldExprNode")
+                                 "//YieldExprNode",
+                                 "//IfStatNode//CoerceToBooleanNode")
 def any_in_nested_gen(seq):
     """
     >>> any(x for L in [[0,0,0],[0,0,1],[0,0,0]] for x in L)
@@ -226,7 +229,5 @@ def any_in_nested_gen(seq):
     3
     False
     """
-    # FIXME: this isn't really supposed to work, but it currently does
-    # due to incorrect scoping - this should be fixed!!
     cdef int x
     return any(x for L in seq for x in L)