summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cython/Compiler/Nodes.py2
-rw-r--r--tests/run/exceptionrefcount.pyx55
2 files changed, 57 insertions, 0 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 5c985202a..119e5d4fe 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 000000000..4c8d645b0
--- /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