in pure mode: rename 'with nogil' to 'with cython.nogil', test 'real' pure mode by...
authorStefan Behnel <scoder@users.berlios.de>
Wed, 3 Nov 2010 13:06:10 +0000 (14:06 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 3 Nov 2010 13:06:10 +0000 (14:06 +0100)
--HG--
rename : tests/run/pure.pyx => tests/run/pure_py.py

Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.py
Cython/Shadow.py
tests/run/pure_py.py [new file with mode: 0644]

index e04b28bfc186fb0e1a5ddae678160c11304e0741..753dfb4244d4c27d4a7ebaedfcf792ff8fa7e219 100644 (file)
@@ -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:
index 10cc16cddc244aa806257a302d9cec5c900278f8..c79465d57168fd0d9cdbb728e3f1d4ff5c08aec2 100644 (file)
@@ -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 == ',':
index 72b864bd7515565d2a11efed9b8232fa6705730e..48278c0382d7a3bb9e7a56ed80209c3070329b1a 100644 (file)
@@ -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 (file)
index 0000000..26fb310
--- /dev/null
@@ -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)