summaryrefslogtreecommitdiff
path: root/tests/run/nogil_conditional.pyx
diff options
context:
space:
mode:
Diffstat (limited to 'tests/run/nogil_conditional.pyx')
-rw-r--r--tests/run/nogil_conditional.pyx271
1 files changed, 271 insertions, 0 deletions
diff --git a/tests/run/nogil_conditional.pyx b/tests/run/nogil_conditional.pyx
new file mode 100644
index 000000000..92eff0853
--- /dev/null
+++ b/tests/run/nogil_conditional.pyx
@@ -0,0 +1,271 @@
+# mode: run
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+
+def test(int x):
+ """
+ >>> test(0)
+ 110
+ """
+ with nogil(True):
+ x = f_nogil(x)
+ with gil(True):
+ x = f_gil(x)
+ return x
+
+
+cdef int f_nogil(int x) nogil:
+ cdef int y
+ y = x + 10
+ return y
+
+
+def f_gil(x):
+ y = 0
+ y = x + 100
+ return y
+
+
+cdef int with_gil_func() except? -1 with gil:
+ raise Exception("error!")
+
+
+cdef int nogil_func() except? -1 nogil:
+ with_gil_func()
+
+
+def test_nogil_exception_propagation():
+ """
+ >>> test_nogil_exception_propagation()
+ Traceback (most recent call last):
+ ...
+ Exception: error!
+ """
+ with nogil:
+ with gil:
+ with nogil(True):
+ nogil_func()
+
+
+cdef int write_unraisable() noexcept nogil:
+ with gil:
+ raise ValueError()
+
+
+def test_unraisable():
+ """
+ >>> print(test_unraisable()) # doctest: +ELLIPSIS
+ ValueError
+ Exception...ignored...
+ """
+ import sys
+ old_stderr = sys.stderr
+ stderr = sys.stderr = StringIO()
+ try:
+ write_unraisable()
+ finally:
+ sys.stderr = old_stderr
+ return stderr.getvalue().strip()
+
+
+def test_nested():
+ """
+ >>> test_nested()
+ 240
+ """
+ cdef int res = 0
+
+ with nogil(True):
+ res = f_nogil(res)
+ with gil(1 < 2):
+ res = f_gil(res)
+ with nogil:
+ res = f_nogil(res)
+
+ with gil:
+ res = f_gil(res)
+ with nogil(True):
+ res = f_nogil(res)
+ with nogil:
+ res = f_nogil(res)
+
+ return res
+
+
+DEF FREE_GIL = True
+DEF FREE_GIL_FALSE = False
+
+
+def test_nested_condition_false():
+ """
+ >>> test_nested_condition_false()
+ 220
+ """
+ cdef int res = 0
+
+ with gil(FREE_GIL_FALSE):
+ res = f_gil(res)
+ with nogil(False):
+ res = f_gil(res)
+
+ with nogil(FREE_GIL):
+ res = f_nogil(res)
+ with gil(False):
+ res = f_nogil(res)
+
+ return res
+
+def test_try_finally():
+ """
+ >>> test_try_finally()
+ 113
+ """
+ cdef int res = 0
+
+ try:
+ with nogil(True):
+ try:
+ res = f_nogil(res)
+ with gil(1 < 2):
+ try:
+ res = f_gil(res)
+ finally:
+ res += 1
+ finally:
+ res = res + 1
+ finally:
+ res += 1
+
+ return res
+
+
+ctypedef fused number_or_object:
+ int
+ float
+ object
+
+
+def test_fused(number_or_object x) -> number_or_object:
+ """
+ >>> test_fused[int](1)
+ 2
+ >>> test_fused[float](1.0)
+ 2.0
+ >>> test_fused[object](1)
+ 2
+ >>> test_fused[object](1.0)
+ 2.0
+ """
+ cdef number_or_object res = x
+
+ with nogil(number_or_object is not object):
+ res = res + 1
+
+ return res
+
+
+ctypedef fused int_or_object:
+ int
+ object
+
+
+def test_fused_object(int_or_object x):
+ """
+ >>> test_fused_object[object]("spam")
+ 456
+ >>> test_fused_object[int](1000)
+ 1000
+ """
+ cdef int res = 0
+
+ if int_or_object is object:
+ with nogil(False):
+ res += len(x)
+
+ try:
+ with nogil(int_or_object is object):
+ try:
+ with gil(int_or_object is object):
+ res = f_gil(res)
+ with gil:
+ res = f_gil(res)
+ with gil(False):
+ res = f_nogil(res)
+
+ with gil(int_or_object is not object):
+ res = f_nogil(res)
+ with nogil(False):
+ res = f_nogil(res)
+
+ res = f_nogil(res)
+ finally:
+ res = res + 1
+
+ with nogil(int_or_object is not object):
+ res = f_gil(res)
+
+ with gil(int_or_object is not object):
+ res = f_gil(res)
+
+ with nogil(int_or_object is object):
+ res = f_nogil(res)
+
+ finally:
+ res += 1
+ else:
+ res = x
+
+ return res
+
+
+def test_fused_int(int_or_object x):
+ """
+ >>> test_fused_int[object]("spam")
+ 4
+ >>> test_fused_int[int](1000)
+ 1452
+ """
+ cdef int res = 0
+
+ if int_or_object is int:
+ res += x
+
+ try:
+ with nogil(int_or_object is int):
+ try:
+ with gil(int_or_object is int):
+ res = f_gil(res)
+ with gil:
+ res = f_gil(res)
+ with gil(False):
+ res = f_nogil(res)
+
+ with gil(int_or_object is not int):
+ res = f_nogil(res)
+ with nogil(False):
+ res = f_nogil(res)
+
+ res = f_nogil(res)
+ finally:
+ res = res + 1
+
+ with nogil(int_or_object is not int):
+ res = f_gil(res)
+
+ with gil(int_or_object is not int):
+ res = f_gil(res)
+
+ with nogil(int_or_object is int):
+ res = f_nogil(res)
+
+ finally:
+ res += 1
+ else:
+ with nogil(False):
+ res = len(x)
+
+ return res