Skip to content

Commit 8c7b0f3

Browse files
authored
Handle function "outer_attrs" more consistently (cythonGH-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 cython#4367.
1 parent 494f517 commit 8c7b0f3

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

Cython/Compiler/Nodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,8 @@ class FuncDefNode(StatNode, BlockNode):
17501750
code_object = None
17511751
return_type_annotation = None
17521752

1753+
outer_attrs = None # overridden by some derived classes - to be visited outside the node's scope
1754+
17531755
def analyse_default_values(self, env):
17541756
default_seen = 0
17551757
for arg in self.args:

Cython/Compiler/ParseTreeTransforms.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,8 +2054,6 @@ def visit_FuncDefNode(self, node):
20542054
def visit_DefNode(self, node):
20552055
node = self.visit_FuncDefNode(node)
20562056
env = self.current_env()
2057-
if isinstance(node, Nodes.DefNode) and node.is_wrapper:
2058-
env = env.parent_scope
20592057
if (not isinstance(node, Nodes.DefNode) or
20602058
node.fused_py_func or node.is_generator_body or
20612059
not node.needs_assignment_synthesis(env)):

Cython/Compiler/Visitor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,10 @@ def exit_scope(self):
370370
self.env_stack.pop()
371371

372372
def visit_FuncDefNode(self, node):
373+
outer_attrs = node.outer_attrs
374+
self.visitchildren(node, attrs=outer_attrs)
373375
self.enter_scope(node, node.local_scope)
374-
self._process_children(node)
376+
self.visitchildren(node, attrs=None, exclude=outer_attrs)
375377
self.exit_scope()
376378
return node
377379

tests/run/decorators.pyx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,23 @@ a = A()
6161
@a.decorate
6262
def i(x):
6363
return x - 1
64+
65+
def append_to_list_decorator(lst):
66+
def do_append_to_list_dec(func):
67+
def new_func():
68+
return lst + func()
69+
return new_func
70+
return do_append_to_list_dec
71+
72+
def outer(arg1, arg2):
73+
"""
74+
ensure decorators are analysed in the correct scope
75+
https://github.com/cython/cython/issues/4367
76+
mainly intended as a compile-time test (but it does run...)
77+
>>> outer(append_to_list_decorator, [1,2,3])
78+
[1, 2, 3, 4]
79+
"""
80+
@arg1([x for x in arg2])
81+
def method():
82+
return [4]
83+
return method()

0 commit comments

Comments
 (0)