Commit c6cf09ee authored by Stefan Behnel's avatar Stefan Behnel

Allow print statements in nogil sections.

Would be nice to allow this also for the print() function, but that's tricky because we have to insert the "GILStatNode" before analysing the declarations, which is when we learn if it's really the builtin print function or something else.
parent 9d528b20
......@@ -2842,20 +2842,21 @@ class InjectGilHandling(VisitorTransform, SkipDeclarations):
Must run before the AnalyseDeclarationsTransform to make sure the GILStatNodes get
set up, parallel sections know that the GIL is acquired inside of them, etc.
"""
def __call__(self, root):
self.nogil = False
return super(InjectGilHandling, self).__call__(root)
nogil = False
# special node handling
def visit_RaiseStatNode(self, node):
"""Allow raising exceptions in nogil sections by wrapping them in a 'with gil' block."""
def _inject_gil_in_nogil(self, node):
"""Allow the (Python statement) node in nogil sections by wrapping it in a 'with gil' block."""
if self.nogil:
node = Nodes.GILStatNode(node.pos, state='gil', body=node)
return node
visit_RaiseStatNode = _inject_gil_in_nogil
visit_PrintStatNode = _inject_gil_in_nogil # sadly, not the function
# further candidates:
# def visit_AssertStatNode(self, node):
# def visit_AssertStatNode(self, node): # -> try to keep the condition GIL-free if possible
# def visit_ReraiseStatNode(self, node):
# nogil tracking
......
......@@ -52,7 +52,7 @@ cdef object m():
x, y = y, x
obj[i] = x
obj.fred = x
print obj
print obj # allowed!
del fred
return obj
raise obj # allowed!
......@@ -151,10 +151,10 @@ _ERRORS = u"""
53:11: Indexing Python object not allowed without gil
54:11: Accessing Python attribute not allowed without gil
54:11: Assignment of Python object not allowed without gil
55:8: Constructing Python tuple not allowed without gil
55:8: Python print statement not allowed without gil
56:8: Deleting Python object not allowed without gil
57:8: Returning Python object not allowed without gil
59:11: Truth-testing Python object not allowed without gil
61:14: Truth-testing Python object not allowed without gil
63:8: For-loop using object bounds or target not allowed without gil
......
# mode: run
# tag: nogil
# cython: language_level=2
cimport cython
@cython.test_assert_path_exists(
"//GILStatNode",
"//GILStatNode//GILStatNode",
"//GILStatNode//GILStatNode//PrintStatNode",
)
def test_print_in_nogil(x):
"""
>>> test_print_in_nogil(123)
--123--
"""
with nogil:
print f"--{x}--"
@cython.test_assert_path_exists(
"//GILStatNode",
"//GILStatNode//GILStatNode",
"//GILStatNode//GILStatNode//RaiseStatNode",
)
def test_raise_in_nogil(x):
"""
>>> try: test_raise_in_nogil(123)
... except ValueError as exc: print(exc)
... else: print("NOT RAISED !")
--123--
"""
with nogil:
raise ValueError(f"--{x}--")
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