Commit 73133f68 authored by Noam Hershtig's avatar Noam Hershtig

Create run tests for conditional GILStatNode

parent 5ff75cda
......@@ -7794,7 +7794,7 @@ class GILStatNode(NogilTryFinallyStatNode):
#
# state string 'gil' or 'nogil'
child_attrs = ["body", "condition", "finally_clause", "finally_except_clause"]
child_attrs = ["condition"] + NogilTryFinallyStatNode.child_attrs
state_temp = None
def __init__(self, pos, state, body, condition=None):
......
......@@ -4700,7 +4700,7 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
node.condition = None
# Condition is False - the body of the GILStatNode
# should run without changing changing the state of the gil
# should run without changing the state of the gil
# return the body of the GILStatNode
else:
return node.body
......
......@@ -2916,8 +2916,9 @@ class GilCheck(VisitorTransform):
def visit_GILStatNode(self, node):
if node.condition is not None:
error(node.pos, "Non-constant condition in a "
"`with %s(<condition>)` statement" % node.state)
error(node.condition.pos,
"Non-constant condition in a "
"`with %s(<condition>)` statement" % node.state)
return node
if self.nogil and node.nogil_check:
......@@ -3259,6 +3260,13 @@ class ReplaceFusedTypeChecks(VisitorTransform):
self.visitchildren(node)
return self.transform(node)
def visit_GILStatNode(self, node):
"""
Fold constant condition of GILStatNode.
"""
self.visitchildren(node)
return self.transform(node)
def visit_PrimaryCmpNode(self, node):
with Errors.local_errors(ignore=True):
type1 = node.operand1.analyse_as_type(self.local_scope)
......
# 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() nogil except? -1:
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() 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 test_nested_condition_false():
"""
>>> test_nested_condition_false()
220
"""
cdef int res = 0
with gil(False):
res = f_gil(res)
with nogil(False):
res = f_gil(res)
with nogil(True):
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
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