Commit 8c7b0f3f authored by da-woods's avatar da-woods Committed by GitHub

Handle function "outer_attrs" more consistently (GH-4375)

A few children of function nodes need to be consistently evaluated
outside the function scope. This PR attempts to do so and thus
fixes https://github.com/cython/cython/issues/4367.
parent 494f517e
......@@ -1750,6 +1750,8 @@ class FuncDefNode(StatNode, BlockNode):
code_object = None
return_type_annotation = None
outer_attrs = None # overridden by some derived classes - to be visited outside the node's scope
def analyse_default_values(self, env):
default_seen = 0
for arg in self.args:
......
......@@ -2054,8 +2054,6 @@ if VALUE is not None:
def visit_DefNode(self, node):
node = self.visit_FuncDefNode(node)
env = self.current_env()
if isinstance(node, Nodes.DefNode) and node.is_wrapper:
env = env.parent_scope
if (not isinstance(node, Nodes.DefNode) or
node.fused_py_func or node.is_generator_body or
not node.needs_assignment_synthesis(env)):
......
......@@ -370,8 +370,10 @@ class EnvTransform(CythonTransform):
self.env_stack.pop()
def visit_FuncDefNode(self, node):
outer_attrs = node.outer_attrs
self.visitchildren(node, attrs=outer_attrs)
self.enter_scope(node, node.local_scope)
self._process_children(node)
self.visitchildren(node, attrs=None, exclude=outer_attrs)
self.exit_scope()
return node
......
......@@ -61,3 +61,23 @@ a = A()
@a.decorate
def i(x):
return x - 1
def append_to_list_decorator(lst):
def do_append_to_list_dec(func):
def new_func():
return lst + func()
return new_func
return do_append_to_list_dec
def outer(arg1, arg2):
"""
ensure decorators are analysed in the correct scope
https://github.com/cython/cython/issues/4367
mainly intended as a compile-time test (but it does run...)
>>> outer(append_to_list_decorator, [1,2,3])
[1, 2, 3, 4]
"""
@arg1([x for x in arg2])
def method():
return [4]
return method()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment