diff options
Diffstat (limited to 'tests/run/pure_py.py')
-rw-r--r-- | tests/run/pure_py.py | 202 |
1 files changed, 192 insertions, 10 deletions
diff --git a/tests/run/pure_py.py b/tests/run/pure_py.py index 89139155c..0cacf6429 100644 --- a/tests/run/pure_py.py +++ b/tests/run/pure_py.py @@ -1,3 +1,5 @@ +# mode: run + import sys IS_PY2 = sys.version_info[0] < 3 @@ -33,21 +35,18 @@ def test_sizeof(): def test_declare(n): """ >>> test_declare(100) - (100, 100) + (100, 100, 100) >>> test_declare(100.5) - (100, 100) - >>> test_declare(None) #doctest: +ELLIPSIS - Traceback (most recent call last): - ... - TypeError: ... + (100, 100, 100) """ x = cython.declare(cython.int) y = cython.declare(cython.int, n) + z = cython.declare(int, n) # C int if cython.compiled: cython.declare(xx=cython.int, yy=cython.long) i = cython.sizeof(xx) ptr = cython.declare(cython.p_int, cython.address(y)) - return y, ptr[0] + return y, z, ptr[0] @cython.locals(x=cython.double, n=cython.int) @@ -144,16 +143,22 @@ def test_with_nogil(nogil, should_raise=False): MyUnion = cython.union(n=cython.int, x=cython.double) MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion) MyStruct2 = cython.typedef(MyStruct[2]) +MyStruct3 = cython.typedef(MyStruct[3]) def test_struct(n, x): """ >>> test_struct(389, 1.64493) - (389, 1.64493) + (389, 1.64493, False) """ - a = cython.declare(MyStruct2) + a = cython.declare(MyStruct3) a[0] = MyStruct(is_integral=True, data=MyUnion(n=n)) a[1] = MyStruct(is_integral=False, data={'x': x}) - return a[0].data.n, a[1].data.x + if sys.version_info >= (3, 6): + # dict is ordered => struct creation via keyword arguments above was deterministic! + a[2] = MyStruct(False, MyUnion(x=x)) + else: + a[2] = MyStruct(is_integral=False, data=MyUnion(x=x)) + return a[0].data.n, a[1].data.x, a[2].is_integral import cython as cy from cython import declare, cast, locals, address, typedef, p_void, compiled @@ -221,6 +226,8 @@ def test_declare_c_types(n): @cython.ccall @cython.returns(cython.double) def c_call(x): + if x == -2.0: + raise RuntimeError("huhu!") return x @@ -239,6 +246,10 @@ def call_ccall(x): 1.0 >>> (is_compiled and 1) or result 1 + + >>> call_ccall(-2) + Traceback (most recent call last): + RuntimeError: huhu! """ ret = c_call(x) return ret, cython.typeof(ret) @@ -248,6 +259,8 @@ def call_ccall(x): @cython.inline @cython.returns(cython.double) def cdef_inline(x): + if x == -2.0: + raise RuntimeError("huhu!") return x + 1 @@ -262,6 +275,10 @@ def call_cdef_inline(x): 'int' >>> result == 2.0 or result True + + >>> call_cdef_inline(-2) + Traceback (most recent call last): + RuntimeError: huhu! """ ret = cdef_inline(x) return ret, cython.typeof(ret) @@ -305,6 +322,25 @@ def test_cdef_nogil(x): return result +@cython.cfunc +@cython.inline +def has_inner_func(x): + # the inner function must remain a Python function + # (and inline must not be applied to it) + @cython.test_fail_if_path_exists("//CFuncDefNode") + def inner(): + return x + return inner + + +def test_has_inner_func(): + """ + >>> test_has_inner_func() + 1 + """ + return has_inner_func(1)() + + @cython.locals(counts=cython.int[10], digit=cython.int) def count_digits_in_carray(digits): """ @@ -396,6 +432,23 @@ def ccall_except_check_always(x): return x+1 +@cython.test_fail_if_path_exists("//CFuncDeclaratorNode//IntNode[@value = '-1']") +@cython.test_assert_path_exists("//CFuncDeclaratorNode") +@cython.ccall +@cython.returns(cython.long) +@cython.exceptval(check=False) +def ccall_except_no_check(x): + """ + >>> ccall_except_no_check(41) + 42 + >>> try: _ = ccall_except_no_check(0) # no exception propagated! + ... except ValueError: assert not is_compiled + """ + if x == 0: + raise ValueError + return x+1 + + @cython.final @cython.cclass class CClass(object): @@ -422,3 +475,132 @@ class TestUnboundMethod: True """ def meth(self): pass + +@cython.cclass +class Foo: + a = cython.declare(cython.double) + b = cython.declare(cython.double) + c = cython.declare(cython.double) + + @cython.locals(a=cython.double, b=cython.double, c=cython.double) + def __init__(self, a, b, c): + self.a = a + self.b = b + self.c = c + +@cython.cclass +class EmptyClass(object): + def __init__(self, *args): + pass + +def same_type_cast(): + """ + >>> same_type_cast() + True + """ + + f = EmptyClass() + return f is cython.cast(EmptyClass, f) + +def multi_args_init_cast(): + """ + >>> multi_args_init_cast() + True + """ + f = Foo(10, 20, 30) + return cython.cast(Foo, f) is f + +def multi_args_init_declare(): + """ + >>> multi_args_init_declare() is None + True + """ + f = cython.declare(Foo) + + if cython.compiled: + f = None + + return f + +EmptyClassSyn = cython.typedef(EmptyClass) + +def empty_declare(): + """ + >>> empty_declare() + [] + """ + + r0 = cython.declare(EmptyClass) + r1 = cython.declare(EmptyClassSyn) + r2 = cython.declare(MyStruct) + r3 = cython.declare(MyUnion) + r4 = cython.declare(MyStruct2) + r5 = cython.declare(cython.int[2]) + + if cython.compiled: + r0 = None + r1 = None + + res = [ + r0 is None, + r1 is None, + r2 is not None, + r3 is not None, + r4 is not None, + r5 is not None + ] + + r2.is_integral = True + assert r2.is_integral == True + + r3.x = 12.3 + assert r3.x == 12.3 + + #It generates a correct C code, but raises an exception when interpreted + if cython.compiled: + r4[0].is_integral = True + assert r4[0].is_integral == True + + r5[0] = 42 + assert r5[0] == 42 + + return [i for i, x in enumerate(res) if not x] + +def same_declare(): + """ + >>> same_declare() + True + """ + + f = EmptyClass() + f2 = cython.declare(EmptyClass, f) + return f2 is f + +def none_cast(): + """ + >>> none_cast() is None + True + """ + + f = None + return cython.cast(EmptyClass, f) + +def none_declare(): + """ + >>> none_declare() is None + True + """ + + f = None + f2 = cython.declare(Foo, f) + return f2 + +def array_init_with_list(): + """ + >>> array_init_with_list() + [10, 42] + """ + x = cython.declare(cython.int[20], list(range(20))) + x[12] = 42 + + return [x[10], x[12]] |