From: Vitja Makarov Date: Sat, 27 Nov 2010 16:09:38 +0000 (+0300) Subject: Support lambda in module scope #603 X-Git-Tag: 0.14.alpha0~53 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=175f08eb86aaff0bc53089be3b6b79c967067140;p=cython.git Support lambda in module scope #603 --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 10706766..ae557f73 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -2215,6 +2215,8 @@ class DefNode(FuncDefNode): def needs_assignment_synthesis(self, env, code=None): # Should enable for module level as well, that will require more testing... + if self.entry.is_lambda: + return True if env.is_module_scope: if code is None: return env.directives['binding'] diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index d0443def..3ab87d03 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -181,9 +181,6 @@ class PostParse(ScopeTrackingTransform): def visit_LambdaNode(self, node): # unpack a lambda expression into the corresponding DefNode - if self.scope_type != 'function': - error(node.pos, - "lambda functions are currently only supported in functions") lambda_id = self.lambda_counter self.lambda_counter += 1 node.lambda_name = EncodedString(u'lambda%d' % lambda_id) @@ -1366,7 +1363,7 @@ class CreateClosureClasses(CythonTransform): while cscope.is_py_class_scope or cscope.is_c_class_scope: cscope = cscope.outer_scope - if not from_closure and self.path: + if not from_closure and (self.path or inner_node): if not inner_node: if not node.assmt: raise InternalError, "DefNode does not have assignment node" diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 1f62c06f..1dec2321 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -75,6 +75,7 @@ class Entry(object): # is_cfunction boolean Is a C function # is_cmethod boolean Is a C method of an extension type # is_unbound_cmethod boolean Is an unbound C method of an extension type + # is_lambda boolean Is a lambda function # is_type boolean Is a type definition # is_cclass boolean Is an extension class # is_cpp_class boolean Is a C++ class @@ -137,6 +138,7 @@ class Entry(object): is_cfunction = 0 is_cmethod = 0 is_unbound_cmethod = 0 + is_lambda = 0 is_type = 0 is_cclass = 0 is_cpp_class = 0 @@ -530,7 +532,7 @@ class Scope(object): entry.name = EncodedString(func_cname) entry.func_cname = func_cname entry.signature = pyfunction_signature - self.pyfunc_entries.append(entry) + entry.is_lambda = True return entry def add_lambda_def(self, def_node): diff --git a/tests/run/lambda_module.pyx b/tests/run/lambda_module.pyx new file mode 100644 index 00000000..8bc3ef0b --- /dev/null +++ b/tests/run/lambda_module.pyx @@ -0,0 +1,25 @@ +# Module scope lambda functions +__doc__ = """ +>>> pow2(16) +256 +>>> with_closure(0) +0 +>>> typed_lambda(1)(2) +3 +>>> typed_lambda(1.5)(1.5) +2 +>>> cdef_const_lambda() +123 +>>> const_lambda() +321 +""" + +pow2 = lambda x: x * x +with_closure = lambda x:(lambda: x)() +typed_lambda = lambda int x : (lambda int y: x + y) + +cdef int xxx = 123 +cdef_const_lambda = lambda: xxx + +yyy = 321 +const_lambda = lambda: yyy