summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-02-24 15:41:21 +0000
committerStefan Behnel <stefan_ml@behnel.de>2022-02-24 16:42:28 +0100
commit01bca8285cb2f5caf9ddf49a8ec33a2581898402 (patch)
tree4a9bcd2a99228e94f1bac396db771b842011ce52
parent3b721b32380529360106071c89ce9b75120aa968 (diff)
downloadcython-01bca8285cb2f5caf9ddf49a8ec33a2581898402.tar.gz
Correctly generate function definions in finally clauses (GH-4652)
This creates two copies of the function, one for the exception case and one for the non-exception case. It's probably inefficient but the simplest solution. Fixes https://github.com/cython/cython/issues/4651.
-rw-r--r--Cython/Compiler/Nodes.py2
-rw-r--r--tests/run/tryfinally.pyx18
2 files changed, 20 insertions, 0 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index aebc5dc0e..76a9833ca 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -7702,6 +7702,8 @@ class TryFinallyStatNode(StatNode):
def generate_function_definitions(self, env, code):
self.body.generate_function_definitions(env, code)
self.finally_clause.generate_function_definitions(env, code)
+ if self.finally_except_clause:
+ self.finally_except_clause.generate_function_definitions(env, code)
def put_error_catcher(self, code, temps_to_clean_up, exc_vars,
exc_lineno_cnames=None, exc_filename_cname=None):
diff --git a/tests/run/tryfinally.pyx b/tests/run/tryfinally.pyx
index 7ff545308..072019a99 100644
--- a/tests/run/tryfinally.pyx
+++ b/tests/run/tryfinally.pyx
@@ -549,3 +549,21 @@ def complex_finally_clause(x, obj):
del l[0], lobj[0]
assert all(i == 3 for i in l), l
return 99
+
+def function_in_finally():
+ """
+ https://github.com/cython/cython/issues/4651 - function definitions in the
+ except copy of the finally clause weren't generated
+
+ >>> function_in_finally()
+ in try
+ in func()
+ finished
+ """
+ try:
+ print('in try')
+ finally:
+ def func():
+ print('in func()')
+ func()
+ print('finished')