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 = \ ...@@ -123,8 +123,6 @@ overflowcheck.fold = optimization.use_switch = \
final = internal = type_version_tag = no_gc_clear = no_gc = _empty_decorator final = internal = type_version_tag = no_gc_clear = no_gc = _empty_decorator
gil = nogil = _EmptyDecoratorAndManager()
_cython_inline = None _cython_inline = None
def inline(f, *args, **kwds): def inline(f, *args, **kwds):
...@@ -187,6 +185,25 @@ def declare(type=None, value=_Unspecified, **kwds): ...@@ -187,6 +185,25 @@ def declare(type=None, value=_Unspecified, **kwds):
else: else:
return value 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 # Emulated types
......
...@@ -18,19 +18,40 @@ def cdef_nogil(x): ...@@ -18,19 +18,40 @@ def cdef_nogil(x):
return x + 1 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) @cython.locals(x=cython.int)
def test_cdef_nogil(x): def test_cdef_nogil(x):
cdef_nogil(x) # ok cdef_nogil(x) # ok
cdef_nogil_false(x) # ok
cdef_nogil_true(x) # ok
with cython.nogil: with cython.nogil:
cdef_nogil_true(x) # ok
cdef_needs_gil(x) # not ok cdef_needs_gil(x) # not ok
cdef_nogil_false(x) # not ok
@cython.nogil @cython.nogil
def pyfunc(x): def pyfunc(x): # invalid
return x + 1 return x + 1
_ERRORS = """ _ERRORS = """
25:22: Calling gil-requiring function not allowed without gil 44:22: Calling gil-requiring function not allowed without gil
29:0: Python functions cannot be declared 'nogil' 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): ...@@ -275,14 +275,33 @@ def cdef_nogil(x):
return x + 1 return x + 1
@cython.cfunc
@cython.nogil(True)
@cython.locals(x=cython.int) @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): def test_cdef_nogil(x):
""" """
>>> test_cdef_nogil(5) >>> test_cdef_nogil(5)
6 18
""" """
with cython.nogil: with cython.nogil:
result = cdef_nogil(x) result = cdef_nogil(x)
with cython.nogil(True):
result += cdef_nogil_true(x)
result += cdef_nogil_false(x)
return result 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