or func_type.exception_check:
self.is_temp = 1
# C++ exception handler
+ self.nogil = env.nogil
if func_type.exception_check == '+':
if func_type.exception_value is None:
env.use_utility_code(cpp_exception_utility_code)
func_type.exception_value.entry.cname)
else:
raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
+ if self.nogil:
+ raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
code.putln(
"try {%s%s;} catch(...) {%s; %s}" % (
lhs,
--- /dev/null
+cdef int raise_TypeError() except *:
+ raise TypeError("custom")
+
+cdef extern from "cpp_exceptions_nogil_helper.h" nogil:
+ cdef void foo "foo"(int i) except +
+ cdef void bar "foo"(int i) except +ValueError
+ cdef void spam"foo"(int i) except +raise_TypeError
+
+def test_foo():
+ """
+ >>> test_foo()
+ """
+ #
+ foo(0)
+ foo(0)
+ with nogil:
+ foo(0)
+ foo(0)
+ #
+ try:
+ with nogil:
+ foo(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ with nogil:
+ foo(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ with nogil:
+ foo(1)
+ except:
+ with nogil:
+ foo(0)
+ finally:
+ with nogil:
+ foo(0)
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ foo(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ foo(1)
+ except:
+ with nogil:
+ foo(0)
+ finally:
+ with nogil:
+ foo(0)
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ try:
+ with nogil:
+ foo(1)
+ except:
+ with nogil:
+ foo(1)
+ finally:
+ with nogil:
+ foo(0)
+ pass
+ except:
+ with nogil:
+ foo(0)
+ finally:
+ with nogil:
+ foo(0)
+ pass
+ #
+ try:
+ with nogil:
+ foo(0)
+ try:
+ with nogil:
+ foo(1)
+ except:
+ with nogil:
+ foo(1)
+ finally:
+ with nogil:
+ foo(1)
+ pass
+ except:
+ with nogil:
+ foo(0)
+ finally:
+ with nogil:
+ foo(0)
+ pass
+ #
+
+def test_bar():
+ """
+ >>> test_bar()
+ """
+ #
+ bar(0)
+ bar(0)
+ with nogil:
+ bar(0)
+ bar(0)
+ #
+ try:
+ with nogil:
+ bar(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ with nogil:
+ bar(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ with nogil:
+ bar(1)
+ except ValueError:
+ with nogil:
+ bar(0)
+ finally:
+ with nogil:
+ bar(0)
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ bar(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ bar(1)
+ except ValueError:
+ with nogil:
+ bar(0)
+ finally:
+ with nogil:
+ bar(0)
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ try:
+ with nogil:
+ bar(1)
+ except ValueError:
+ with nogil:
+ bar(1)
+ finally:
+ with nogil:
+ bar(0)
+ pass
+ except ValueError:
+ with nogil:
+ bar(0)
+ finally:
+ with nogil:
+ bar(0)
+ pass
+ #
+ try:
+ with nogil:
+ bar(0)
+ try:
+ with nogil:
+ bar(1)
+ except ValueError:
+ with nogil:
+ bar(1)
+ finally:
+ with nogil:
+ bar(1)
+ pass
+ except ValueError:
+ with nogil:
+ bar(0)
+ finally:
+ with nogil:
+ bar(0)
+ pass
+ #
+
+def test_spam():
+ """
+ >>> test_spam()
+ """
+ #
+ spam(0)
+ spam(0)
+ with nogil:
+ spam(0)
+ spam(0)
+ #
+ try:
+ with nogil:
+ spam(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ with nogil:
+ spam(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ with nogil:
+ spam(1)
+ except TypeError:
+ with nogil:
+ spam(0)
+ finally:
+ with nogil:
+ spam(0)
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ spam(0)
+ finally:
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ spam(1)
+ except TypeError:
+ with nogil:
+ spam(0)
+ finally:
+ with nogil:
+ spam(0)
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ try:
+ with nogil:
+ spam(1)
+ except TypeError:
+ with nogil:
+ spam(1)
+ finally:
+ with nogil:
+ spam(0)
+ pass
+ except TypeError:
+ with nogil:
+ spam(0)
+ finally:
+ with nogil:
+ spam(0)
+ pass
+ #
+ try:
+ with nogil:
+ spam(0)
+ try:
+ with nogil:
+ spam(1)
+ except TypeError:
+ with nogil:
+ spam(1)
+ finally:
+ with nogil:
+ spam(1)
+ pass
+ except TypeError:
+ with nogil:
+ spam(0)
+ finally:
+ with nogil:
+ spam(0)
+ pass
+ #