From bc07e3397e0305982f985eecb1f73cdac557e60e Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Mon, 17 Nov 2008 14:35:05 +0100 Subject: [PATCH] fixed ref-count bug in try-except handling --- Cython/Compiler/Nodes.py | 2 ++ tests/run/exceptionrefcount.pyx | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/run/exceptionrefcount.pyx diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 5c985202..119e5d4f 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -3882,6 +3882,8 @@ class TryExceptStatNode(StatNode): self.else_clause.generate_execution_code(code) code.putln( "}") + for var in Naming.exc_save_vars: + code.put_xdecref_clear(var, py_object_type) code.put_goto(try_end_label) code.put_label(our_error_label) code.put_var_xdecrefs_clear(self.cleanup_list) diff --git a/tests/run/exceptionrefcount.pyx b/tests/run/exceptionrefcount.pyx new file mode 100644 index 00000000..4c8d645b --- /dev/null +++ b/tests/run/exceptionrefcount.pyx @@ -0,0 +1,55 @@ +__doc__ = u""" +>>> class SampleException(Exception): pass +>>> import sys + +>>> def assert_refcount(rc1, rc2, func): +... # test ref-counts, but allow a bit of freedom +... assert rc2 <= rc1 + 4, "%s, before: %d, after %d" % ( +... func.__name__, rc1, rc2) + +>>> def run_test(repeat, test_func): +... initial_refcount = sys.getrefcount(SampleException) +... for i in range(repeat): +... try: raise SampleException +... except: +... refcount1 = sys.getrefcount(SampleException) +... test_func() +... refcount2 = sys.getrefcount(SampleException) +... +... assert_refcount(refcount1, refcount2, test_func) +... assert_refcount(initial_refcount, refcount2, test_func) +... refcount3 = sys.getrefcount(SampleException) +... assert_refcount(refcount1, refcount3, test_func) +... assert_refcount(initial_refcount, refcount3, test_func) + +>>> run_test(50, test_no_exception_else) +>>> run_test(50, test_no_exception) +>>> run_test(50, test_exception) +>>> run_test(50, test_finally) +""" + +def test_no_exception(): + try: + a = 1+1 + except: + pass + +def test_no_exception_else(): + try: + a = 1+1 + except: + pass + else: + b = 1+1 + +def test_exception(): + try: + raise TypeError + except: + pass + +def test_finally(): + try: + a = 1+1 + finally: + b = 1+1 -- 2.26.2