support for lambda inside of generator expressions
authorStefan Behnel <scoder@users.berlios.de>
Thu, 21 Apr 2011 20:23:19 +0000 (22:23 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Thu, 21 Apr 2011 20:23:19 +0000 (22:23 +0200)
Cython/Compiler/Symtab.py
tests/run/cython3.pyx
tests/run/generator_expressions.pyx [new file with mode: 0644]

index 70e6a002e63e49d7a37935cf2583ac1a8faa13e7..8fe2e8da5877ff6e7f86bc81cb3bc706cc57110e 100644 (file)
@@ -558,8 +558,7 @@ class Scope(object):
 
     def declare_lambda_function(self, func_cname, pos):
         # Add an entry for an anonymous Python function.
-        entry = self.declare_var(None, py_object_type, pos,
-                                 cname=func_cname, visibility='private')
+        entry = self.declare(None, func_cname, py_object_type, pos, 'private')
         entry.name = EncodedString(func_cname)
         entry.func_cname = func_cname
         entry.signature = pyfunction_signature
@@ -1401,6 +1400,12 @@ class GeneratorExpressionScope(Scope):
         self.entries[name] = entry
         return entry
 
+    def declare_lambda_function(self, func_cname, pos):
+        return self.outer_scope.declare_lambda_function(func_cname, pos)
+
+    def add_lambda_def(self, def_node):
+        return self.outer_scope.add_lambda_def(def_node)
+
 
 class ClosureScope(LocalScope):
 
index d3f416e8384524a9e0e8b9da8759e00880835feb..475a3deb22088cd7bea472ad58857c89f66d1a24 100644 (file)
@@ -1,4 +1,6 @@
 # cython: language_level=3
+# mode: run
+# tag: generators, python3
 
 cimport cython
 
@@ -89,6 +91,16 @@ def list_comp():
     assert x == 'abc' # don't leak in Py3 code
     return result
 
+def list_comp_with_lambda():
+    """
+    >>> list_comp_with_lambda()
+    [0, 4, 8]
+    """
+    x = 'abc'
+    result = [x*2 for x in range(5) if (lambda x:x % 2)(x) == 0]
+    assert x == 'abc' # don't leak in Py3 code
+    return result
+
 module_level_lc = [ module_level_loopvar*2 for module_level_loopvar in range(4) ]
 def list_comp_module_level():
     """
diff --git a/tests/run/generator_expressions.pyx b/tests/run/generator_expressions.pyx
new file mode 100644 (file)
index 0000000..f525da7
--- /dev/null
@@ -0,0 +1,39 @@
+# mode: run
+# tag: generators, lambda
+
+def genexpr():
+    """
+    >>> genexpr()
+    [0, 2, 4, 6, 8]
+    """
+    x = 'abc'
+    result = list( x*2 for x in range(5) )
+    assert x == 'abc' # don't leak
+    return result
+
+def genexpr_if():
+    """
+    >>> genexpr_if()
+    [0, 4, 8]
+    """
+    x = 'abc'
+    result = list( x*2 for x in range(5) if x % 2 == 0 )
+    assert x == 'abc' # don't leak
+    return result
+
+def genexpr_with_lambda():
+    """
+    >>> genexpr_with_lambda()
+    [0, 4, 8]
+    """
+    x = 'abc'
+    result = list( x*2 for x in range(5) if (lambda x:x % 2)(x) == 0 )
+    assert x == 'abc' # don't leak
+    return result
+
+def genexpr_of_lambdas(int N):
+    """
+    >>> [ (f(), g()) for f,g in genexpr_of_lambdas(5) ]
+    [(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)]
+    """
+    return ( ((lambda : x), (lambda : x*2)) for x in range(N) )