Commit 5ea5a0f5 authored by Stefan Behnel's avatar Stefan Behnel

Generally allow the "nogil" decorator and context manager to accept boolean...

Generally allow the "nogil" decorator and context manager to accept boolean arguments like "@nogil(False)".
See #2579.
parent 4fc2fd38
......@@ -123,8 +123,6 @@ overflowcheck.fold = optimization.use_switch = \
final = internal = type_version_tag = no_gc_clear = no_gc = _empty_decorator
gil = nogil = _EmptyDecoratorAndManager()
_cython_inline = None
def inline(f, *args, **kwds):
......@@ -187,6 +185,25 @@ def declare(type=None, value=_Unspecified, **kwds):
else:
return value
class _nogil(object):
"""Support for 'with nogil' statement and @nogil decorator.
"""
def __call__(self, x):
if callable(x):
# Used as function decorator => return the function unchanged.
return x
# Used as conditional context manager or to create an "@nogil(True/False)" decorator => keep going.
return self
def __enter__(self):
pass
def __exit__(self, exc_class, exc, tb):
return exc_class is None
nogil = _nogil()
gil = _nogil()
del _nogil
# Emulated types
......
......@@ -18,19 +18,40 @@ def cdef_nogil(x):
return x + 1
@cython.cfunc
@cython.nogil(True)
@cython.locals(x=cython.int)
@cython.returns(cython.int)
def cdef_nogil_true(x):
return x + 1
@cython.cfunc
@cython.nogil(False)
@cython.locals(x=cython.int)
@cython.returns(cython.int)
def cdef_nogil_false(x):
return x + 1
@cython.locals(x=cython.int)
def test_cdef_nogil(x):
cdef_nogil(x) # ok
cdef_nogil_false(x) # ok
cdef_nogil_true(x) # ok
with cython.nogil:
cdef_nogil_true(x) # ok
cdef_needs_gil(x) # not ok
cdef_nogil_false(x) # not ok
@cython.nogil
def pyfunc(x):
def pyfunc(x): # invalid
return x + 1
_ERRORS = """
25:22: Calling gil-requiring function not allowed without gil
29:0: Python functions cannot be declared 'nogil'
44:22: Calling gil-requiring function not allowed without gil
45:24: Calling gil-requiring function not allowed without gil
49:0: Python functions cannot be declared 'nogil'
"""
......@@ -275,14 +275,33 @@ def cdef_nogil(x):
return x + 1
@cython.cfunc
@cython.nogil(True)
@cython.locals(x=cython.int)
@cython.returns(cython.int)
def cdef_nogil_true(x):
return x + 1
@cython.cfunc
@cython.nogil(False)
@cython.locals(x=cython.int)
@cython.returns(cython.int)
def cdef_nogil_false(x):
return x + 1
@cython.locals(x=cython.int, result=cython.int)
def test_cdef_nogil(x):
"""
>>> test_cdef_nogil(5)
6
18
"""
with cython.nogil:
result = cdef_nogil(x)
with cython.nogil(True):
result += cdef_nogil_true(x)
result += cdef_nogil_false(x)
return result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment