From: Stefan Behnel Date: Wed, 3 Nov 2010 13:06:10 +0000 (+0100) Subject: in pure mode: rename 'with nogil' to 'with cython.nogil', test 'real' pure mode by... X-Git-Tag: 0.14.alpha0~250 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cfb1d64a147a867032d9e488a14cf629a1543a76;p=cython.git in pure mode: rename 'with nogil' to 'with cython.nogil', test 'real' pure mode by compiling .py file instead of .pyx file --HG-- rename : tests/run/pure.pyx => tests/run/pure_py.py --- diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index e04b28bf..753dfb42 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -854,6 +854,10 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): PostParseError(node.pos, "Compiler directive with statements cannot contain 'as'")) else: name, value = directive + if name == 'nogil': + # special case: in pure mode, "with nogil" spells "with cython.nogil" + node = GILStatNode(node.pos, state = "nogil", body = node.body) + return self.visit_Node(node) if self.check_directive_scope(node.pos, name, 'with statement'): directive_dict[name] = value if directive_dict: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 10cc16cd..c79465d5 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1512,7 +1512,7 @@ def p_with_statement(s): def p_with_items(s): pos = s.position() - if s.sy == 'IDENT' and s.systring == 'nogil': + if not s.in_python_file and s.sy == 'IDENT' and s.systring == 'nogil': state = s.systring s.next() if s.sy == ',': diff --git a/Cython/Shadow.py b/Cython/Shadow.py index 72b864bd..48278c03 100644 --- a/Cython/Shadow.py +++ b/Cython/Shadow.py @@ -58,6 +58,17 @@ def declare(type=None, value=None, **kwds): else: return value +class _nogil(object): + """Support for 'with nogil' statement + """ + def __enter__(self): + pass + def __exit__(self, exc_class, exc, tb): + return exc_class is None + +nogil = _nogil() +del _nogil + # Emulated types class CythonType(object): diff --git a/tests/run/pure_py.py b/tests/run/pure_py.py new file mode 100644 index 00000000..26fb3107 --- /dev/null +++ b/tests/run/pure_py.py @@ -0,0 +1,193 @@ +import cython + +def test_sizeof(): + """ + >>> test_sizeof() + True + True + True + True + True + """ + x = cython.declare(cython.bint) + print sizeof(x) == sizeof(cython.bint) + print sizeof(cython.char) <= sizeof(cython.short) <= sizeof(cython.int) <= sizeof(cython.long) <= sizeof(cython.longlong) + print sizeof(cython.uint) == sizeof(cython.int) + print sizeof(cython.p_int) == sizeof(cython.p_double) + if cython.compiled: + print sizeof(cython.char) < sizeof(cython.longlong) + else: + print sizeof(cython.char) == 1 + +def test_declare(n): + """ + >>> test_declare(100) + (100, 100) + >>> test_declare(100.5) + (100, 100) + >>> test_declare(None) + Traceback (most recent call last): + ... + TypeError: an integer is required + """ + x = cython.declare(cython.int) + y = cython.declare(cython.int, n) + if cython.compiled: + cython.declare(xx=cython.int, yy=cython.long) + i = sizeof(xx) + ptr = cython.declare(cython.p_int, cython.address(y)) + return y, ptr[0] + +@cython.locals(x=cython.double, n=cython.int) +def test_cast(x): + """ + >>> test_cast(1.5) + 1 + >>> test_cast(None) + Traceback (most recent call last): + ... + TypeError: a float is required + """ + n = cython.cast(cython.int, x) + return n + +@cython.locals(x=cython.int, y=cython.p_int) +def test_address(x): + """ + >>> test_address(39) + 39 + """ + y = cython.address(x) + return y[0] + +@cython.locals(x=cython.int) +@cython.locals(y=cython.bint) +def test_locals(x): + """ + >>> test_locals(5) + True + """ + y = x + return y + +@cython.test_assert_path_exists("//TryFinallyStatNode", + "//TryFinallyStatNode//GILStatNode") +@cython.test_fail_if_path_exists("//TryFinallyStatNode//TryFinallyStatNode") +def test_with_nogil(nogil): + """ + >>> raised = [] + >>> class nogil(object): + ... def __enter__(self): + ... pass + ... def __exit__(self, exc_class, exc, tb): + ... raised.append(exc) + ... return exc_class is None + + >>> test_with_nogil(nogil()) + WORKS + True + >>> raised + [None] + """ + result = False + with nogil: + print "WORKS" + with cython.nogil: + result = True + return result + +@cython.test_assert_path_exists("//TryFinallyStatNode", + "//TryFinallyStatNode//GILStatNode") +@cython.test_fail_if_path_exists("//TryFinallyStatNode//TryFinallyStatNode") +def test_with_nogil_multiple(nogil): + """ + >>> raised = [] + >>> class nogil(object): + ... def __enter__(self): + ... pass + ... def __exit__(self, exc_class, exc, tb): + ... raised.append(exc) + ... return exc_class is None + + >>> test_with_nogil_multiple(nogil()) + True + >>> raised + [None] + """ + result = False + with nogil, cython.nogil: + result = True + return result + +MyUnion = cython.union(n=cython.int, x=cython.double) +MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion) +MyStruct2 = cython.typedef(MyStruct[2]) + +def test_struct(n, x): + """ + >>> test_struct(389, 1.64493) + (389, 1.64493) + """ + a = cython.declare(MyStruct2) + a[0] = MyStruct(True, data=MyUnion(n=n)) + a[1] = MyStruct(is_integral=False, data={'x': x}) + return a[0].data.n, a[1].data.x + +import cython as cy +from cython import declare, cast, locals, address, typedef, p_void, compiled +from cython import declare as my_declare, locals as my_locals, p_void as my_void_star, typedef as my_typedef, compiled as my_compiled + +@my_locals(a=cython.p_void) +def test_imports(): + """ + >>> test_imports() + True + """ + a = cython.NULL + b = declare(p_void, cython.NULL) + c = my_declare(my_void_star, cython.NULL) + d = cy.declare(cy.p_void, cython.NULL) + return a == d and compiled and my_compiled + +MyStruct3 = typedef(MyStruct[3]) +MyStruct4 = my_typedef(MyStruct[4]) +MyStruct5 = cy.typedef(MyStruct[5]) + +def test_declare_c_types(n): + """ + >>> test_declare_c_types(0) + >>> test_declare_c_types(1) + >>> test_declare_c_types(2) + """ + # + b00 = cython.declare(cython.bint, 0) + b01 = cython.declare(cython.bint, 1) + b02 = cython.declare(cython.bint, 2) + # + i00 = cython.declare(cython.uchar, n) + i01 = cython.declare(cython.char, n) + i02 = cython.declare(cython.schar, n) + i03 = cython.declare(cython.ushort, n) + i04 = cython.declare(cython.short, n) + i05 = cython.declare(cython.sshort, n) + i06 = cython.declare(cython.uint, n) + i07 = cython.declare(cython.int, n) + i08 = cython.declare(cython.sint, n) + i09 = cython.declare(cython.slong, n) + i10 = cython.declare(cython.long, n) + i11 = cython.declare(cython.ulong, n) + i12 = cython.declare(cython.slonglong, n) + i13 = cython.declare(cython.longlong, n) + i14 = cython.declare(cython.ulonglong, n) + + i20 = cython.declare(cython.Py_ssize_t, n) + i21 = cython.declare(cython.size_t, n) + # + f00 = cython.declare(cython.float, n) + f01 = cython.declare(cython.double, n) + f02 = cython.declare(cython.longdouble, n) + # + #z00 = cython.declare(cython.complex, n+1j) + #z01 = cython.declare(cython.floatcomplex, n+1j) + #z02 = cython.declare(cython.doublecomplex, n+1j) + #z03 = cython.declare(cython.longdoublecomplex, n+1j)