[pypy-commit] pypy ffi-backend: (fijal, arigo)
arigo
noreply at buildbot.pypy.org
Thu Jun 21 18:23:02 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55750:8bd00ebe9e89
Date: 2012-06-21 18:21 +0200
http://bitbucket.org/pypy/pypy/changeset/8bd00ebe9e89/
Log: (fijal, arigo) Import all the tests from hg: cffi/c/test_c.py.
Infinite amount of funs fighting various parts of the test running
framework
diff --git a/pypy/module/_ffi_backend/test/_backend_test_c.py b/pypy/module/_ffi_backend/test/_backend_test_c.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_ffi_backend/test/_backend_test_c.py
@@ -0,0 +1,775 @@
+# ____________________________________________________________
+
+def size_of_int():
+ BInt = new_primitive_type("int")
+ return sizeof(BInt)
+
+def size_of_long():
+ BLong = new_primitive_type("long")
+ return sizeof(BLong)
+
+def size_of_ptr():
+ BInt = new_primitive_type("int")
+ BPtr = new_pointer_type(BInt)
+ return sizeof(BPtr)
+
+
+def find_and_load_library(name):
+ import ctypes.util
+ path = ctypes.util.find_library(name)
+ return load_library(path)
+
+def test_load_library():
+ x = find_and_load_library('c')
+ assert repr(x).startswith("<clibrary '")
+
+def test_nonstandard_integer_types():
+ d = nonstandard_integer_types()
+ assert type(d) is dict
+ assert 'char' not in d
+ assert d['size_t'] in (0x1004, 0x1008)
+ assert d['size_t'] == d['ssize_t'] + 0x1000
+
+def test_new_primitive_type():
+ py.test.raises(KeyError, new_primitive_type, "foo")
+ p = new_primitive_type("signed char")
+ assert repr(p) == "<ctype 'signed char'>"
+
+def test_cast_to_signed_char():
+ p = new_primitive_type("signed char")
+ x = cast(p, -65 + 17*256)
+ assert repr(x) == "<cdata 'signed char'>"
+ assert repr(type(x)) == "<type '_ffi_backend.CData'>"
+ assert int(x) == -65
+ x = cast(p, -66 + (1<<199)*256)
+ assert repr(x) == "<cdata 'signed char'>"
+ assert int(x) == -66
+ assert (x == cast(p, -66)) is False
+ assert (x != cast(p, -66)) is True
+ q = new_primitive_type("short")
+ assert (x == cast(q, -66)) is False
+ assert (x != cast(q, -66)) is True
+
+def test_sizeof_type():
+ py.test.raises(TypeError, sizeof, 42.5)
+ p = new_primitive_type("short")
+ assert sizeof(p) == 2
+
+def test_integer_types():
+ for name in ['signed char', 'short', 'int', 'long', 'long long']:
+ p = new_primitive_type(name)
+ size = sizeof(p)
+ min = -(1 << (8*size-1))
+ max = (1 << (8*size-1)) - 1
+ assert int(cast(p, min)) == min
+ assert int(cast(p, max)) == max
+ assert int(cast(p, min - 1)) == max
+ assert int(cast(p, max + 1)) == min
+ assert long(cast(p, min - 1)) == max
+ for name in ['char', 'short', 'int', 'long', 'long long']:
+ p = new_primitive_type('unsigned ' + name)
+ size = sizeof(p)
+ max = (1 << (8*size)) - 1
+ assert int(cast(p, 0)) == 0
+ assert int(cast(p, max)) == max
+ assert int(cast(p, -1)) == max
+ assert int(cast(p, max + 1)) == 0
+ assert long(cast(p, -1)) == max
+
+def test_no_float_on_int_types():
+ p = new_primitive_type('long')
+ py.test.raises(TypeError, float, cast(p, 42))
+
+def test_float_types():
+ INF = 1E200 * 1E200
+ for name in ["float", "double"]:
+ p = new_primitive_type(name)
+ assert bool(cast(p, 0))
+ assert bool(cast(p, INF))
+ assert bool(cast(p, -INF))
+ assert int(cast(p, -150)) == -150
+ assert int(cast(p, 61.91)) == 61
+ assert long(cast(p, 61.91)) == 61L
+ assert type(int(cast(p, 61.91))) is int
+ assert type(int(cast(p, 1E22))) is long
+ assert type(long(cast(p, 61.91))) is long
+ assert type(long(cast(p, 1E22))) is long
+ py.test.raises(OverflowError, int, cast(p, INF))
+ py.test.raises(OverflowError, int, cast(p, -INF))
+ assert float(cast(p, 1.25)) == 1.25
+ assert float(cast(p, INF)) == INF
+ assert float(cast(p, -INF)) == -INF
+ if name == "float":
+ assert float(cast(p, 1.1)) != 1.1 # rounding error
+ assert float(cast(p, 1E200)) == INF # limited range
+
+ assert cast(p, -1.1) != cast(p, -1.1)
+ assert repr(float(cast(p, -0.0))) == '-0.0'
+ assert float(cast(p, '\x09')) == 9.0
+ assert float(cast(p, True)) == 1.0
+ assert float(cast(p, None)) == 0.0
+
+def test_character_type():
+ p = new_primitive_type("char")
+ assert bool(cast(p, '\x00'))
+ assert cast(p, '\x00') != cast(p, -17*256)
+ assert int(cast(p, 'A')) == 65
+ assert long(cast(p, 'A')) == 65L
+ assert type(int(cast(p, 'A'))) is int
+ assert type(long(cast(p, 'A'))) is long
+ assert str(cast(p, 'A')) == 'A'
+
+def test_pointer_type():
+ p = new_primitive_type("int")
+ assert repr(p) == "<ctype 'int'>"
+ p = new_pointer_type(p)
+ assert repr(p) == "<ctype 'int *'>"
+ p = new_pointer_type(p)
+ assert repr(p) == "<ctype 'int * *'>"
+ p = new_pointer_type(p)
+ assert repr(p) == "<ctype 'int * * *'>"
+
+def test_pointer_to_int():
+ BInt = new_primitive_type("int")
+ py.test.raises(TypeError, newp, BInt, None)
+ BPtr = new_pointer_type(BInt)
+ p = newp(BPtr, None)
+ assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int()
+ p = newp(BPtr, 5000)
+ assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int()
+ q = cast(BPtr, p)
+ assert repr(q) == "<cdata 'int *'>"
+ assert p == q
+ assert hash(p) == hash(q)
+
+def test_pointer_to_pointer():
+ BInt = new_primitive_type("int")
+ BPtr = new_pointer_type(BInt)
+ BPtrPtr = new_pointer_type(BPtr)
+ p = newp(BPtrPtr, None)
+ assert repr(p) == "<cdata 'int * *' owning %d bytes>" % size_of_ptr()
+
+def test_reading_pointer_to_int():
+ BInt = new_primitive_type("int")
+ BPtr = new_pointer_type(BInt)
+ p = newp(BPtr, None)
+ assert p[0] == 0
+ p = newp(BPtr, 5000)
+ assert p[0] == 5000
+ py.test.raises(IndexError, "p[1]")
+ py.test.raises(IndexError, "p[-1]")
+
+def test_reading_pointer_to_float():
+ BFloat = new_primitive_type("float")
+ py.test.raises(TypeError, newp, BFloat, None)
+ BPtr = new_pointer_type(BFloat)
+ p = newp(BPtr, None)
+ assert p[0] == 0.0 and type(p[0]) is float
+ p = newp(BPtr, 1.25)
+ assert p[0] == 1.25 and type(p[0]) is float
+ p = newp(BPtr, 1.1)
+ assert p[0] != 1.1 and abs(p[0] - 1.1) < 1E-5 # rounding errors
+
+def test_cast_float_to_int():
+ for type in ["int", "unsigned int", "long", "unsigned long",
+ "long long", "unsigned long long"]:
+ p = new_primitive_type(type)
+ assert int(cast(p, 4.2)) == 4
+ py.test.raises(TypeError, newp, new_pointer_type(p), 4.2)
+
+def test_reading_pointer_to_char():
+ BChar = new_primitive_type("char")
+ py.test.raises(TypeError, newp, BChar, None)
+ BPtr = new_pointer_type(BChar)
+ p = newp(BPtr, None)
+ assert p[0] == '\x00'
+ p = newp(BPtr, 'A')
+ assert p[0] == 'A'
+ py.test.raises(TypeError, newp, BPtr, 65)
+ py.test.raises(TypeError, newp, BPtr, "foo")
+
+def test_hash_differences():
+ BChar = new_primitive_type("char")
+ BInt = new_primitive_type("int")
+ BFloat = new_primitive_type("float")
+ assert (hash(cast(BChar, 'A')) !=
+ hash(cast(BInt, 65)))
+ assert hash(cast(BFloat, 65)) != hash(65.0)
+
+def test_array_type():
+ p = new_primitive_type("int")
+ assert repr(p) == "<ctype 'int'>"
+ #
+ py.test.raises(TypeError, new_array_type, new_pointer_type(p), "foo")
+ py.test.raises(ValueError, new_array_type, new_pointer_type(p), -42)
+ #
+ p1 = new_array_type(new_pointer_type(p), None)
+ assert repr(p1) == "<ctype 'int[]'>"
+ py.test.raises(ValueError, new_array_type, new_pointer_type(p1), 42)
+ #
+ p1 = new_array_type(new_pointer_type(p), 42)
+ p2 = new_array_type(new_pointer_type(p1), 25)
+ assert repr(p2) == "<ctype 'int[25][42]'>"
+ p2 = new_array_type(new_pointer_type(p1), None)
+ assert repr(p2) == "<ctype 'int[][42]'>"
+ #
+ py.test.raises(OverflowError,
+ new_array_type, new_pointer_type(p), sys.maxint+1)
+ py.test.raises(OverflowError,
+ new_array_type, new_pointer_type(p), sys.maxint // 3)
+
+def test_array_instance():
+ LENGTH = 14242
+ p = new_primitive_type("int")
+ p1 = new_array_type(new_pointer_type(p), LENGTH)
+ a = newp(p1, None)
+ assert repr(a) == "<cdata 'int[%d]' owning %d bytes>" % (
+ LENGTH, LENGTH * size_of_int())
+ assert len(a) == LENGTH
+ for i in range(LENGTH):
+ assert a[i] == 0
+ py.test.raises(IndexError, "a[LENGTH]")
+ py.test.raises(IndexError, "a[-1]")
+ for i in range(LENGTH):
+ a[i] = i * i + 1
+ for i in range(LENGTH):
+ assert a[i] == i * i + 1
+ e = py.test.raises(IndexError, "a[LENGTH+100] = 500")
+ assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value)
+
+def test_array_of_unknown_length_instance():
+ p = new_primitive_type("int")
+ p1 = new_array_type(new_pointer_type(p), None)
+ py.test.raises(TypeError, newp, p1, None)
+ py.test.raises(ValueError, newp, p1, -42)
+ a = newp(p1, 42)
+ assert len(a) == 42
+ for i in range(42):
+ a[i] -= i
+ for i in range(42):
+ assert a[i] == -i
+ py.test.raises(IndexError, "a[42]")
+ py.test.raises(IndexError, "a[-1]")
+ py.test.raises(IndexError, "a[42] = 123")
+ py.test.raises(IndexError, "a[-1] = 456")
+
+def test_array_of_unknown_length_instance_with_initializer():
+ p = new_primitive_type("int")
+ p1 = new_array_type(new_pointer_type(p), None)
+ a = newp(p1, range(42))
+ assert len(a) == 42
+ a = newp(p1, tuple(range(142)))
+ assert len(a) == 142
+
+def test_array_initializer():
+ p = new_primitive_type("int")
+ p1 = new_array_type(new_pointer_type(p), None)
+ a = newp(p1, range(100, 142))
+ for i in range(42):
+ assert a[i] == 100 + i
+ #
+ p2 = new_array_type(new_pointer_type(p), 43)
+ a = newp(p2, tuple(range(100, 142)))
+ for i in range(42):
+ assert a[i] == 100 + i
+ assert a[42] == 0 # extra uninitialized item
+
+def test_array_add():
+ p = new_primitive_type("int")
+ p1 = new_array_type(new_pointer_type(p), 5) # int[5]
+ p2 = new_array_type(new_pointer_type(p1), 3) # int[3][5]
+ a = newp(p2, [range(n, n+5) for n in [100, 200, 300]])
+ assert repr(a) == "<cdata 'int[3][5]' owning %d bytes>" % (
+ 3*5*size_of_int(),)
+ assert repr(a + 0) == "<cdata 'int(*)[5]'>"
+ assert repr(a[0]) == "<cdata 'int[5]'>"
+ assert repr((a + 0)[0]) == "<cdata 'int[5]'>"
+ assert repr(a[0] + 0) == "<cdata 'int *'>"
+ assert type(a[0][0]) is int
+ assert type((a[0] + 0)[0]) is int
+
+def test_cast_primitive_from_cdata():
+ p = new_primitive_type("int")
+ n = cast(p, cast(p, -42))
+ assert int(n) == -42
+ #
+ p = new_primitive_type("unsigned int")
+ n = cast(p, cast(p, 42))
+ assert int(n) == 42
+ #
+ p = new_primitive_type("long long")
+ n = cast(p, cast(p, -(1<<60)))
+ assert int(n) == -(1<<60)
+ #
+ p = new_primitive_type("unsigned long long")
+ n = cast(p, cast(p, 1<<63))
+ assert int(n) == 1<<63
+ #
+ p = new_primitive_type("float")
+ n = cast(p, cast(p, 42.5))
+ assert float(n) == 42.5
+ #
+ p = new_primitive_type("char")
+ n = cast(p, cast(p, "A"))
+ assert str(n) == "A"
+
+def test_new_primitive_from_cdata():
+ p = new_primitive_type("int")
+ p1 = new_pointer_type(p)
+ n = newp(p1, cast(p, -42))
+ assert n[0] == -42
+ #
+ p = new_primitive_type("unsigned int")
+ p1 = new_pointer_type(p)
+ n = newp(p1, cast(p, 42))
+ assert n[0] == 42
+ #
+ p = new_primitive_type("float")
+ p1 = new_pointer_type(p)
+ n = newp(p1, cast(p, 42.5))
+ assert n[0] == 42.5
+ #
+ p = new_primitive_type("char")
+ p1 = new_pointer_type(p)
+ n = newp(p1, cast(p, "A"))
+ assert n[0] == "A"
+
+def test_cast_between_pointers():
+ BIntP = new_pointer_type(new_primitive_type("int"))
+ BIntA = new_array_type(BIntP, None)
+ a = newp(BIntA, [40, 41, 42, 43, 44])
+ BShortP = new_pointer_type(new_primitive_type("short"))
+ b = cast(BShortP, a)
+ c = cast(BIntP, b)
+ assert c[3] == 43
+ BLongLong = new_primitive_type("long long")
+ d = cast(BLongLong, c)
+ e = cast(BIntP, d)
+ assert e[3] == 43
+ f = cast(BIntP, int(d))
+ assert f[3] == 43
+ #
+ for null in [0, None]:
+ b = cast(BShortP, null)
+ assert not b
+ c = cast(BIntP, b)
+ assert not c
+ assert int(cast(BLongLong, c)) == 0
+
+def test_alignof():
+ BInt = new_primitive_type("int")
+ assert alignof(BInt) == sizeof(BInt)
+ BPtr = new_pointer_type(BInt)
+ assert alignof(BPtr) == sizeof(BPtr)
+ BArray = new_array_type(BPtr, None)
+ assert alignof(BArray) == alignof(BInt)
+
+def test_new_struct_type():
+ BStruct = new_struct_type("foo")
+ assert repr(BStruct) == "<ctype 'struct foo'>"
+ BPtr = new_pointer_type(BStruct)
+ assert repr(BPtr) == "<ctype 'struct foo *'>"
+
+def test_new_union_type():
+ BUnion = new_union_type("foo")
+ assert repr(BUnion) == "<ctype 'union foo'>"
+ BPtr = new_pointer_type(BUnion)
+ assert repr(BPtr) == "<ctype 'union foo *'>"
+
+def test_complete_struct():
+ BLong = new_primitive_type("long")
+ BChar = new_primitive_type("char")
+ BShort = new_primitive_type("short")
+ BStruct = new_struct_type("foo")
+ assert _getfields(BStruct) is None
+ complete_struct_or_union(BStruct, [('a1', BLong, -1),
+ ('a2', BChar, -1),
+ ('a3', BShort, -1)])
+ d = _getfields(BStruct)
+ assert len(d) == 3
+ assert d[0][0] == 'a1'
+ assert d[0][1].type is BLong
+ assert d[0][1].offset == 0
+ assert d[0][1].bitshift == -1
+ assert d[0][1].bitsize == -1
+ assert d[1][0] == 'a2'
+ assert d[1][1].type is BChar
+ assert d[1][1].offset == sizeof(BLong)
+ assert d[1][1].bitshift == -1
+ assert d[1][1].bitsize == -1
+ assert d[2][0] == 'a3'
+ assert d[2][1].type is BShort
+ assert d[2][1].offset == sizeof(BLong) + sizeof(BShort)
+ assert d[2][1].bitshift == -1
+ assert d[2][1].bitsize == -1
+ assert sizeof(BStruct) == 2 * sizeof(BLong)
+ assert alignof(BStruct) == alignof(BLong)
+
+def test_complete_union():
+ BLong = new_primitive_type("long")
+ BChar = new_primitive_type("char")
+ BUnion = new_union_type("foo")
+ assert _getfields(BUnion) is None
+ complete_struct_or_union(BUnion, [('a1', BLong, -1),
+ ('a2', BChar, -1)])
+ d = _getfields(BUnion)
+ assert len(d) == 2
+ assert d[0][0] == 'a1'
+ assert d[0][1].type is BLong
+ assert d[0][1].offset == 0
+ assert d[1][0] == 'a2'
+ assert d[1][1].type is BChar
+ assert d[1][1].offset == 0
+ assert sizeof(BUnion) == sizeof(BLong)
+ assert alignof(BUnion) == alignof(BLong)
+
+def test_struct_instance():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ p = cast(BStructPtr, None)
+ py.test.raises(AttributeError, "p.a1") # opaque
+ complete_struct_or_union(BStruct, [('a1', BInt, -1),
+ ('a2', BInt, -1)])
+ p = newp(BStructPtr, None)
+ s = p[0]
+ assert s.a1 == 0
+ s.a2 = 123
+ assert s.a1 == 0
+ assert s.a2 == 123
+ py.test.raises(OverflowError, "s.a1 = sys.maxint+1")
+ assert s.a1 == 0
+ py.test.raises(AttributeError, "p.foobar")
+ py.test.raises(AttributeError, "s.foobar")
+
+def test_struct_pointer():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BInt, -1),
+ ('a2', BInt, -1)])
+ p = newp(BStructPtr, None)
+ assert p.a1 == 0 # read/write via the pointer (C equivalent: '->')
+ p.a2 = 123
+ assert p.a1 == 0
+ assert p.a2 == 123
+
+def test_struct_init_list():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BInt, -1),
+ ('a2', BInt, -1),
+ ('a3', BInt, -1)])
+ s = newp(BStructPtr, [123, 456])
+ assert s.a1 == 123
+ assert s.a2 == 456
+ assert s.a3 == 0
+
+def test_array_in_struct():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ BArrayInt5 = new_array_type(new_pointer_type(BInt), 5)
+ complete_struct_or_union(BStruct, [('a1', BArrayInt5, -1)])
+ s = newp(new_pointer_type(BStruct), [[20, 24, 27, 29, 30]])
+ assert s.a1[2] == 27
+ assert repr(s.a1) == "<cdata 'int[5]'>"
+
+def test_offsetof():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ py.test.raises(TypeError, offsetof, BInt, "abc")
+ py.test.raises(TypeError, offsetof, BStruct, "abc")
+ complete_struct_or_union(BStruct, [('abc', BInt, -1), ('def', BInt, -1)])
+ assert offsetof(BStruct, 'abc') == 0
+ assert offsetof(BStruct, 'def') == size_of_int()
+ py.test.raises(KeyError, offsetof, BStruct, "ghi")
+
+def test_function_type():
+ BInt = new_primitive_type("int")
+ BFunc = new_function_type((BInt, BInt), BInt, False)
+ assert repr(BFunc) == "<ctype 'int(*)(int, int)'>"
+ BFunc2 = new_function_type((), BFunc, False)
+ assert repr(BFunc2) == "<ctype 'int(*(*)())(int, int)'>"
+
+def test_function_type_taking_struct():
+ BChar = new_primitive_type("char")
+ BShort = new_primitive_type("short")
+ BStruct = new_struct_type("foo")
+ complete_struct_or_union(BStruct, [('a1', BChar, -1),
+ ('a2', BShort, -1)])
+ BFunc = new_function_type((BStruct,), BShort, False)
+ assert repr(BFunc) == "<ctype 'short(*)(struct foo)'>"
+
+def test_function_void_result():
+ BVoid = new_void_type()
+ BInt = new_primitive_type("int")
+ BFunc = new_function_type((BInt, BInt), BVoid, False)
+ assert repr(BFunc) == "<ctype 'void(*)(int, int)'>"
+
+def test_call_function_0():
+ BSignedChar = new_primitive_type("signed char")
+ BFunc0 = new_function_type((BSignedChar, BSignedChar), BSignedChar, False)
+ f = cast(BFunc0, _testfunc(0))
+ assert f(40, 2) == 42
+ assert f(-100, -100) == -200 + 256
+ py.test.raises(OverflowError, f, 128, 0)
+ py.test.raises(OverflowError, f, 0, 128)
+
+def test_call_function_1():
+ BInt = new_primitive_type("int")
+ BLong = new_primitive_type("long")
+ BFunc1 = new_function_type((BInt, BLong), BLong, False)
+ f = cast(BFunc1, _testfunc(1))
+ assert f(40, 2) == 42
+ assert f(-100, -100) == -200
+ int_max = (1 << (8*size_of_int()-1)) - 1
+ long_max = (1 << (8*size_of_long()-1)) - 1
+ if int_max == long_max:
+ assert f(int_max, 1) == - int_max - 1
+ else:
+ assert f(int_max, 1) == int_max + 1
+
+def test_call_function_2():
+ BLongLong = new_primitive_type("long long")
+ BFunc2 = new_function_type((BLongLong, BLongLong), BLongLong, False)
+ f = cast(BFunc2, _testfunc(2))
+ longlong_max = (1 << (8*sizeof(BLongLong)-1)) - 1
+ assert f(longlong_max - 42, 42) == longlong_max
+ assert f(43, longlong_max - 42) == - longlong_max - 1
+
+def test_call_function_3():
+ BFloat = new_primitive_type("float")
+ BDouble = new_primitive_type("double")
+ BFunc3 = new_function_type((BFloat, BDouble), BDouble, False)
+ f = cast(BFunc3, _testfunc(3))
+ assert f(1.25, 5.1) == 1.25 + 5.1 # exact
+ res = f(1.3, 5.1)
+ assert res != 6.4 and abs(res - 6.4) < 1E-5 # inexact
+
+def test_call_function_4():
+ BFloat = new_primitive_type("float")
+ BDouble = new_primitive_type("double")
+ BFunc4 = new_function_type((BFloat, BDouble), BFloat, False)
+ f = cast(BFunc4, _testfunc(4))
+ res = f(1.25, 5.1)
+ assert res != 6.35 and abs(res - 6.35) < 1E-5 # inexact
+
+def test_call_function_5():
+ BVoid = new_void_type()
+ BFunc5 = new_function_type((), BVoid, False)
+ f = cast(BFunc5, _testfunc(5))
+ f() # did not crash
+
+def test_call_function_6():
+ BInt = new_primitive_type("int")
+ BIntPtr = new_pointer_type(BInt)
+ BFunc6 = new_function_type((BIntPtr,), BIntPtr, False)
+ f = cast(BFunc6, _testfunc(6))
+ x = newp(BIntPtr, 42)
+ res = f(x)
+ assert typeof(res) is BIntPtr
+ assert res[0] == 42 - 1000
+ #
+ BIntArray = new_array_type(BIntPtr, None)
+ BFunc6bis = new_function_type((BIntArray,), BIntPtr, False)
+ f = cast(BFunc6bis, _testfunc(6))
+ #
+ py.test.raises(TypeError, f, [142])
+ #
+ x = newp(BIntArray, [242])
+ res = f(x)
+ assert typeof(res) is BIntPtr
+ assert res[0] == 242 - 1000
+
+def test_call_function_7():
+ BChar = new_primitive_type("char")
+ BShort = new_primitive_type("short")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BChar, -1),
+ ('a2', BShort, -1)])
+ BFunc7 = new_function_type((BStruct,), BShort, False)
+ f = cast(BFunc7, _testfunc(7))
+ res = f({'a1': 'A', 'a2': -4042})
+ assert res == -4042 + ord('A')
+ #
+ x = newp(BStructPtr, {'a1': 'A', 'a2': -4042})
+ res = f(x[0])
+ assert res == -4042 + ord('A')
+
+def test_call_function_9():
+ BInt = new_primitive_type("int")
+ BFunc9 = new_function_type((BInt,), BInt, True) # vararg
+ f = cast(BFunc9, _testfunc(9))
+ assert f(0) == 0
+ assert f(1, cast(BInt, 42)) == 42
+ assert f(2, cast(BInt, 40), cast(BInt, 2)) == 42
+ py.test.raises(TypeError, f, 1, 42)
+
+def test_new_charp():
+ BChar = new_primitive_type("char")
+ BCharP = new_pointer_type(BChar)
+ BCharA = new_array_type(BCharP, None)
+ x = newp(BCharA, 42)
+ assert len(x) == 42
+ x = newp(BCharA, "foobar")
+ assert len(x) == 7
+
+def test_load_and_call_function():
+ BChar = new_primitive_type("char")
+ BCharP = new_pointer_type(BChar)
+ BLong = new_primitive_type("long")
+ BFunc = new_function_type((BCharP,), BLong, False)
+ ll = find_and_load_library('c')
+ strlen = ll.load_function(BFunc, "strlen")
+ input = newp(new_array_type(BCharP, None), "foobar")
+ assert strlen(input) == 6
+ #
+ assert strlen("foobarbaz") == 9
+
+def test_read_variable():
+ if sys.platform == 'win32':
+ py.test.skip("untested")
+ BVoidP = new_pointer_type(new_void_type())
+ ll = find_and_load_library('c')
+ stderr = ll.read_variable(BVoidP, "stderr")
+ assert stderr == cast(BVoidP, _testfunc(8))
+
+def test_write_variable():
+ if sys.platform == 'win32':
+ py.test.skip("untested")
+ BVoidP = new_pointer_type(new_void_type())
+ ll = find_and_load_library('c')
+ stderr = ll.read_variable(BVoidP, "stderr")
+ ll.write_variable(BVoidP, "stderr", None)
+ assert ll.read_variable(BVoidP, "stderr") is None
+ ll.write_variable(BVoidP, "stderr", stderr)
+ assert ll.read_variable(BVoidP, "stderr") == stderr
+
+def test_callback():
+ BInt = new_primitive_type("int")
+ def make_callback():
+ def cb(n):
+ return n + 1
+ BFunc = new_function_type((BInt,), BInt, False)
+ return callback(BFunc, cb) # 'cb' and 'BFunc' go out of scope
+ f = make_callback()
+ assert f(-142) == -141
+
+def test_a_lot_of_callbacks():
+ BInt = new_primitive_type("int")
+ def make_callback(m):
+ def cb(n):
+ return n + m
+ BFunc = new_function_type((BInt,), BInt, False)
+ return callback(BFunc, cb) # 'cb' and 'BFunc' go out of scope
+ #
+ flist = [make_callback(i) for i in range(10000)]
+ for i, f in enumerate(flist):
+ assert f(-142) == -142 + i
+
+def test_enum_type():
+ BEnum = new_enum_type("foo", (), ())
+ assert repr(BEnum) == "<ctype 'enum foo'>"
+ assert _getfields(BEnum) == []
+ #
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ assert _getfields(BEnum) == [(-20, 'ab'), (0, 'def'), (1, 'c')]
+
+def test_cast_to_enum():
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ e = cast(BEnum, 0)
+ assert repr(e) == "<cdata 'enum foo'>"
+ assert str(e) == 'def'
+ assert str(cast(BEnum, -20)) == 'ab'
+ assert str(cast(BEnum, 'c')) == 'c'
+ assert int(cast(BEnum, 'c')) == 1
+ assert int(cast(BEnum, 'def')) == 0
+ assert int(cast(BEnum, -242 + 2**128)) == -242
+ assert str(cast(BEnum, -242 + 2**128)) == '#-242'
+ assert str(cast(BEnum, '#-20')) == 'ab'
+
+def test_enum_in_struct():
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ BStruct = new_struct_type("bar")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BEnum, -1)])
+ p = newp(BStructPtr, [-20])
+ assert p.a1 == "ab"
+ p = newp(BStructPtr, ["c"])
+ assert p.a1 == "c"
+ e = py.test.raises(TypeError, newp, BStructPtr, [None])
+ assert "must be a str or int, not NoneType" in str(e.value)
+
+def test_struct_with_bitfields():
+ BLong = new_primitive_type("long")
+ BStruct = new_struct_type("foo")
+ LONGBITS = 8 * sizeof(BLong)
+ complete_struct_or_union(BStruct, [('a1', BLong, 1),
+ ('a2', BLong, 2),
+ ('a3', BLong, 3),
+ ('a4', BLong, LONGBITS - 5)])
+ d = _getfields(BStruct)
+ assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0
+ assert d[3][1].offset == sizeof(BLong)
+ assert d[0][1].bitshift == 0
+ assert d[0][1].bitsize == 1
+ assert d[1][1].bitshift == 1
+ assert d[1][1].bitsize == 2
+ assert d[2][1].bitshift == 3
+ assert d[2][1].bitsize == 3
+ assert d[3][1].bitshift == 0
+ assert d[3][1].bitsize == LONGBITS - 5
+ assert sizeof(BStruct) == 2 * sizeof(BLong)
+ assert alignof(BStruct) == alignof(BLong)
+
+def test_bitfield_instance():
+ BInt = new_primitive_type("int")
+ BUnsignedInt = new_primitive_type("unsigned int")
+ BStruct = new_struct_type("foo")
+ complete_struct_or_union(BStruct, [('a1', BInt, 1),
+ ('a2', BUnsignedInt, 2),
+ ('a3', BInt, 3)])
+ p = newp(new_pointer_type(BStruct), None)
+ p.a1 = -1
+ assert p.a1 == -1
+ p.a1 = 0
+ py.test.raises(OverflowError, "p.a1 = 2")
+ assert p.a1 == 0
+ #
+ p.a1 = -1
+ p.a2 = 3
+ p.a3 = -4
+ py.test.raises(OverflowError, "p.a3 = 4")
+ e = py.test.raises(OverflowError, "p.a3 = -5")
+ assert str(e.value) == ("value -5 outside the range allowed by the "
+ "bit field width: -4 <= x <= 3")
+ assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4
+ #
+ # special case for convenience: "int x:1", while normally signed,
+ # allows also setting the value "1" (it still gets read back as -1)
+ p.a1 = 1
+ assert p.a1 == -1
+ e = py.test.raises(OverflowError, "p.a1 = -2")
+ assert str(e.value) == ("value -2 outside the range allowed by the "
+ "bit field width: -1 <= x <= 1")
+
+def test_bitfield_instance_init():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ complete_struct_or_union(BStruct, [('a1', BInt, 1)])
+ py.test.raises(NotImplementedError, newp, new_pointer_type(BStruct), [-1])
+
+def test_gc():
+ from gc import collect
+ BInt = new_primitive_type("int")
+ n = cast(BInt, 123)
+ py.test.raises(TypeError, gc, n, 5)
+ destroyed = []
+ m = gc(n, destroyed.append)
+ assert repr(m) == "<cdata 'int' with destructor>"
+ assert destroyed == []
+ del m; collect()
+ assert len(destroyed) == 1
+ assert int(destroyed[0]) == 123
diff --git a/pypy/module/_ffi_backend/test/test_c.py b/pypy/module/_ffi_backend/test/test_c.py
--- a/pypy/module/_ffi_backend/test/test_c.py
+++ b/pypy/module/_ffi_backend/test/test_c.py
@@ -1,786 +1,35 @@
+from __future__ import with_statement
import py
+from pypy.tool.udir import udir
from pypy.conftest import gettestobjspace
+from pypy.module._ffi_backend.test import _backend_test_c
-class AppTestFfiBackend(object):
+class AppTestC(object):
+ """Populated below, hack hack hack."""
- def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('_ffi_backend',))
- #
- import ctypes.util
- path = ctypes.util.find_library('c')
- #
- cls.w_b = cls.space.appexec([cls.space.wrap(path)], '''(path):
- import _ffi_backend
- def size_of_int():
- BInt = _ffi_backend.new_primitive_type("int")
- return _ffi_backend.sizeof(BInt)
- def size_of_long():
- BLong = _ffi_backend.new_primitive_type("long")
- return _ffi_backend.sizeof(BLong)
- def size_of_ptr():
- BInt = _ffi_backend.new_primitive_type("int")
- BPtr = _ffi_backend.new_pointer_type(BInt)
- return _ffi_backend.sizeof(BPtr)
- def find_and_load_library():
- return _ffi_backend.load_library(path)
- _ffi_backend._size_of_int = size_of_int
- _ffi_backend._size_of_long = size_of_long
- _ffi_backend._size_of_ptr = size_of_ptr
- _ffi_backend._find_and_load_library = find_and_load_library
- return _ffi_backend
- ''')
- def test_load_library(self):
- x = self.b._find_and_load_library()
- assert repr(x).startswith("<clibrary '")
+space = gettestobjspace(usemodules=('_ffi_backend',))
+src = py.path.local(__file__).join('..', '_backend_test_c.py').read()
+w_namespace = space.appexec([], "():\n" +
+ src.replace('\n', '\n ') +
+ '\n return locals()\n')
+AppTestC.w_namespace = w_namespace
- def test_nonstandard_integer_types(self):
- d = self.b.nonstandard_integer_types()
- assert type(d) is dict
- assert 'char' not in d
- assert d['size_t'] in (0x1004, 0x1008)
- assert d['size_t'] == d['ssize_t'] + 0x1000
+lst = []
+for name in space.unwrap(space.call_function(space.w_list, w_namespace)):
+ if name.startswith('test_'):
+ lst.append(getattr(_backend_test_c, name))
+lst.sort(key=lambda func: func.func_code.co_firstlineno)
- def test_new_primitive_type(self):
- raises(KeyError, self.b.new_primitive_type, "foo")
- p = self.b.new_primitive_type("signed char")
- assert repr(p) == "<ctype 'signed char'>"
+tmpname = udir.join('_test_c.py')
+with tmpname.open('w') as f:
+ for func in lst:
+ print >> f, 'def %s(self):' % (func.__name__,)
+ print >> f, ' func = self.namespace[%r]' % (func.__name__,)
+ print >> f, ' func()'
- def test_cast_to_signed_char(self):
- p = self.b.new_primitive_type("signed char")
- x = self.b.cast(p, -65 + 17*256)
- assert repr(x) == "<cdata 'signed char'>"
- assert repr(type(x)) == "<type '_ffi_backend.CData'>"
- assert int(x) == -65
- x = self.b.cast(p, -66 + (1<<199)*256)
- assert repr(x) == "<cdata 'signed char'>"
- assert int(x) == -66
- assert (x == self.b.cast(p, -66)) is False
- assert (x != self.b.cast(p, -66)) is True
- q = self.b.new_primitive_type("short")
- assert (x == self.b.cast(q, -66)) is False
- assert (x != self.b.cast(q, -66)) is True
-
- def test_sizeof_type(self):
- raises(TypeError, self.b.sizeof, 42.5)
- p = self.b.new_primitive_type("short")
- assert self.b.sizeof(p) == 2
-
- def test_integer_types(self):
- new_primitive_type = self.b.new_primitive_type
- sizeof = self.b.sizeof
- cast = self.b.cast
- for name in ['signed char', 'short', 'int', 'long', 'long long']:
- p = new_primitive_type(name)
- size = sizeof(p)
- min = -(1 << (8*size-1))
- max = (1 << (8*size-1)) - 1
- assert int(cast(p, min)) == min
- assert int(cast(p, max)) == max
- assert int(cast(p, min - 1)) == max
- assert int(cast(p, max + 1)) == min
- assert long(cast(p, min - 1)) == max
- for name in ['char', 'short', 'int', 'long', 'long long']:
- p = new_primitive_type('unsigned ' + name)
- size = sizeof(p)
- max = (1 << (8*size)) - 1
- assert int(cast(p, 0)) == 0
- assert int(cast(p, max)) == max
- assert int(cast(p, -1)) == max
- assert int(cast(p, max + 1)) == 0
- assert long(cast(p, -1)) == max
-
- def test_no_float_on_int_types(self):
- p = self.b.new_primitive_type('long')
- raises(TypeError, float, self.b.cast(p, 42))
-
- def test_float_types(self):
- new_primitive_type = self.b.new_primitive_type
- cast = self.b.cast
- INF = 1E200 * 1E200
- for name in ["float", "double"]:
- p = new_primitive_type(name)
- assert bool(cast(p, 0))
- assert bool(cast(p, INF))
- assert bool(cast(p, -INF))
- assert int(cast(p, -150)) == -150
- assert int(cast(p, 61.91)) == 61
- assert long(cast(p, 61.91)) == 61L
- assert type(int(cast(p, 61.91))) is int
- assert type(int(cast(p, 1E22))) is long
- assert type(long(cast(p, 61.91))) is long
- assert type(long(cast(p, 1E22))) is long
- raises(OverflowError, int, cast(p, INF))
- raises(OverflowError, int, cast(p, -INF))
- assert float(cast(p, 1.25)) == 1.25
- assert float(cast(p, INF)) == INF
- assert float(cast(p, -INF)) == -INF
- if name == "float":
- assert float(cast(p, 1.1)) != 1.1 # rounding error
- assert float(cast(p, 1E200)) == INF # limited range
-
- assert cast(p, -1.1) != cast(p, -1.1)
- assert repr(float(cast(p, -0.0))) == '-0.0'
-
- def test_character_type(self):
- new_primitive_type = self.b.new_primitive_type
- cast = self.b.cast
- p = new_primitive_type("char")
- assert bool(cast(p, '\x00'))
- assert cast(p, '\x00') != cast(p, -17*256)
- assert int(cast(p, 'A')) == 65
- assert long(cast(p, 'A')) == 65L
- assert type(int(cast(p, 'A'))) is int
- assert type(long(cast(p, 'A'))) is long
- assert str(cast(p, 'A')) == 'A'
-
- def test_pointer_type(self):
- new_primitive_type = self.b.new_primitive_type
- new_pointer_type = self.b.new_pointer_type
- p = new_primitive_type("int")
- assert repr(p) == "<ctype 'int'>"
- p = new_pointer_type(p)
- assert repr(p) == "<ctype 'int *'>"
- p = new_pointer_type(p)
- assert repr(p) == "<ctype 'int * *'>"
- p = new_pointer_type(p)
- assert repr(p) == "<ctype 'int * * *'>"
-
- def test_pointer_to_int(self):
- BInt = new_primitive_type("int")
- py.test.raises(TypeError, newp, BInt, None)
- BPtr = new_pointer_type(BInt)
- p = newp(BPtr, None)
- assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int()
- p = newp(BPtr, 5000)
- assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int()
- q = cast(BPtr, p)
- assert repr(q) == "<cdata 'int *'>"
- assert p == q
- assert hash(p) == hash(q)
-
- def test_pointer_to_pointer(self):
- BInt = new_primitive_type("int")
- BPtr = new_pointer_type(BInt)
- BPtrPtr = new_pointer_type(BPtr)
- p = newp(BPtrPtr, None)
- assert repr(p) == "<cdata 'int * *' owning %d bytes>" % size_of_ptr()
-
- def test_reading_pointer_to_int(self):
- BInt = new_primitive_type("int")
- BPtr = new_pointer_type(BInt)
- p = newp(BPtr, None)
- assert p[0] == 0
- p = newp(BPtr, 5000)
- assert p[0] == 5000
- py.test.raises(IndexError, "p[1]")
- py.test.raises(IndexError, "p[-1]")
-
- def test_reading_pointer_to_float(self):
- BFloat = new_primitive_type("float")
- py.test.raises(TypeError, newp, BFloat, None)
- BPtr = new_pointer_type(BFloat)
- p = newp(BPtr, None)
- assert p[0] == 0.0 and type(p[0]) is float
- p = newp(BPtr, 1.25)
- assert p[0] == 1.25 and type(p[0]) is float
- p = newp(BPtr, 1.1)
- assert p[0] != 1.1 and abs(p[0] - 1.1) < 1E-5 # rounding errors
-
- def test_reading_pointer_to_char(self):
- BChar = new_primitive_type("char")
- py.test.raises(TypeError, newp, BChar, None)
- BPtr = new_pointer_type(BChar)
- p = newp(BPtr, None)
- assert p[0] == '\x00'
- p = newp(BPtr, 'A')
- assert p[0] == 'A'
- py.test.raises(TypeError, newp, BPtr, 65)
- py.test.raises(TypeError, newp, BPtr, "foo")
-
- def test_hash_differences(self):
- BChar = new_primitive_type("char")
- BInt = new_primitive_type("int")
- BFloat = new_primitive_type("float")
- assert (hash(cast(BChar, 'A')) !=
- hash(cast(BInt, 65)))
- assert hash(cast(BFloat, 65)) != hash(65.0)
-
- def test_array_type(self):
- p = new_primitive_type("int")
- assert repr(p) == "<ctype 'int'>"
- #
- py.test.raises(TypeError, new_array_type, new_pointer_type(p), "foo")
- py.test.raises(ValueError, new_array_type, new_pointer_type(p), -42)
- #
- p1 = new_array_type(new_pointer_type(p), None)
- assert repr(p1) == "<ctype 'int[]'>"
- py.test.raises(ValueError, new_array_type, new_pointer_type(p1), 42)
- #
- p1 = new_array_type(new_pointer_type(p), 42)
- p2 = new_array_type(new_pointer_type(p1), 25)
- assert repr(p2) == "<ctype 'int[25][42]'>"
- p2 = new_array_type(new_pointer_type(p1), None)
- assert repr(p2) == "<ctype 'int[][42]'>"
- #
- py.test.raises(OverflowError,
- new_array_type, new_pointer_type(p), sys.maxint+1)
- py.test.raises(OverflowError,
- new_array_type, new_pointer_type(p), sys.maxint // 3)
-
- def test_array_instance(self):
- LENGTH = 14242
- p = new_primitive_type("int")
- p1 = new_array_type(new_pointer_type(p), LENGTH)
- a = newp(p1, None)
- assert repr(a) == "<cdata 'int[%d]' owning %d bytes>" % (
- LENGTH, LENGTH * size_of_int())
- assert len(a) == LENGTH
- for i in range(LENGTH):
- assert a[i] == 0
- py.test.raises(IndexError, "a[LENGTH]")
- py.test.raises(IndexError, "a[-1]")
- for i in range(LENGTH):
- a[i] = i * i + 1
- for i in range(LENGTH):
- assert a[i] == i * i + 1
- e = py.test.raises(IndexError, "a[LENGTH+100] = 500")
- assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value)
-
- def test_array_of_unknown_length_instance(self):
- p = new_primitive_type("int")
- p1 = new_array_type(new_pointer_type(p), None)
- py.test.raises(TypeError, newp, p1, None)
- py.test.raises(ValueError, newp, p1, -42)
- a = newp(p1, 42)
- assert len(a) == 42
- for i in range(42):
- a[i] -= i
- for i in range(42):
- assert a[i] == -i
- py.test.raises(IndexError, "a[42]")
- py.test.raises(IndexError, "a[-1]")
- py.test.raises(IndexError, "a[42] = 123")
- py.test.raises(IndexError, "a[-1] = 456")
-
- def test_array_of_unknown_length_instance_with_initializer(self):
- p = new_primitive_type("int")
- p1 = new_array_type(new_pointer_type(p), None)
- a = newp(p1, range(42))
- assert len(a) == 42
- a = newp(p1, tuple(range(142)))
- assert len(a) == 142
-
- def test_array_initializer(self):
- p = new_primitive_type("int")
- p1 = new_array_type(new_pointer_type(p), None)
- a = newp(p1, range(100, 142))
- for i in range(42):
- assert a[i] == 100 + i
- #
- p2 = new_array_type(new_pointer_type(p), 43)
- a = newp(p2, tuple(range(100, 142)))
- for i in range(42):
- assert a[i] == 100 + i
- assert a[42] == 0 # extra uninitialized item
-
- def test_array_add(self):
- p = new_primitive_type("int")
- p1 = new_array_type(new_pointer_type(p), 5) # int[5]
- p2 = new_array_type(new_pointer_type(p1), 3) # int[3][5]
- a = newp(p2, [range(n, n+5) for n in [100, 200, 300]])
- assert repr(a) == "<cdata 'int[3][5]' owning %d bytes>" % (
- 3*5*size_of_int(),)
- assert repr(a + 0) == "<cdata 'int(*)[5]'>"
- assert repr(a[0]) == "<cdata 'int[5]'>"
- assert repr((a + 0)[0]) == "<cdata 'int[5]'>"
- assert repr(a[0] + 0) == "<cdata 'int *'>"
- assert type(a[0][0]) is int
- assert type((a[0] + 0)[0]) is int
-
- def test_cast_primitive_from_cdata(self):
- p = new_primitive_type("int")
- n = cast(p, cast(p, -42))
- assert int(n) == -42
- #
- p = new_primitive_type("unsigned int")
- n = cast(p, cast(p, 42))
- assert int(n) == 42
- #
- p = new_primitive_type("long long")
- n = cast(p, cast(p, -(1<<60)))
- assert int(n) == -(1<<60)
- #
- p = new_primitive_type("unsigned long long")
- n = cast(p, cast(p, 1<<63))
- assert int(n) == 1<<63
- #
- p = new_primitive_type("float")
- n = cast(p, cast(p, 42.5))
- assert float(n) == 42.5
- #
- p = new_primitive_type("char")
- n = cast(p, cast(p, "A"))
- assert str(n) == "A"
-
- def test_new_primitive_from_cdata(self):
- p = new_primitive_type("int")
- p1 = new_pointer_type(p)
- n = newp(p1, cast(p, -42))
- assert n[0] == -42
- #
- p = new_primitive_type("unsigned int")
- p1 = new_pointer_type(p)
- n = newp(p1, cast(p, 42))
- assert n[0] == 42
- #
- p = new_primitive_type("float")
- p1 = new_pointer_type(p)
- n = newp(p1, cast(p, 42.5))
- assert n[0] == 42.5
- #
- p = new_primitive_type("char")
- p1 = new_pointer_type(p)
- n = newp(p1, cast(p, "A"))
- assert n[0] == "A"
-
- def test_cast_between_pointers(self):
- BIntP = new_pointer_type(new_primitive_type("int"))
- BIntA = new_array_type(BIntP, None)
- a = newp(BIntA, [40, 41, 42, 43, 44])
- BShortP = new_pointer_type(new_primitive_type("short"))
- b = cast(BShortP, a)
- c = cast(BIntP, b)
- assert c[3] == 43
- BLongLong = new_primitive_type("long long")
- d = cast(BLongLong, c)
- e = cast(BIntP, d)
- assert e[3] == 43
- f = cast(BIntP, int(d))
- assert f[3] == 43
- #
- for null in [0, None]:
- b = cast(BShortP, null)
- assert not b
- c = cast(BIntP, b)
- assert not c
- assert int(cast(BLongLong, c)) == 0
-
- def test_alignof(self):
- BInt = new_primitive_type("int")
- assert alignof(BInt) == sizeof(BInt)
- BPtr = new_pointer_type(BInt)
- assert alignof(BPtr) == sizeof(BPtr)
- BArray = new_array_type(BPtr, None)
- assert alignof(BArray) == alignof(BInt)
-
- def test_new_struct_type(self):
- BStruct = new_struct_type("foo")
- assert repr(BStruct) == "<ctype 'struct foo'>"
- BPtr = new_pointer_type(BStruct)
- assert repr(BPtr) == "<ctype 'struct foo *'>"
-
- def test_new_union_type(self):
- BUnion = new_union_type("foo")
- assert repr(BUnion) == "<ctype 'union foo'>"
- BPtr = new_pointer_type(BUnion)
- assert repr(BPtr) == "<ctype 'union foo *'>"
-
- def test_complete_struct(self):
- BLong = new_primitive_type("long")
- BChar = new_primitive_type("char")
- BShort = new_primitive_type("short")
- BStruct = new_struct_type("foo")
- assert _getfields(BStruct) is None
- complete_struct_or_union(BStruct, [('a1', BLong, -1),
- ('a2', BChar, -1),
- ('a3', BShort, -1)])
- d = _getfields(BStruct)
- assert len(d) == 3
- assert d[0][0] == 'a1'
- assert d[0][1].type is BLong
- assert d[0][1].offset == 0
- assert d[0][1].bitshift == -1
- assert d[0][1].bitsize == -1
- assert d[1][0] == 'a2'
- assert d[1][1].type is BChar
- assert d[1][1].offset == sizeof(BLong)
- assert d[1][1].bitshift == -1
- assert d[1][1].bitsize == -1
- assert d[2][0] == 'a3'
- assert d[2][1].type is BShort
- assert d[2][1].offset == sizeof(BLong) + sizeof(BShort)
- assert d[2][1].bitshift == -1
- assert d[2][1].bitsize == -1
- assert sizeof(BStruct) == 2 * sizeof(BLong)
- assert alignof(BStruct) == alignof(BLong)
-
- def test_complete_union(self):
- BLong = new_primitive_type("long")
- BChar = new_primitive_type("char")
- BUnion = new_union_type("foo")
- assert _getfields(BUnion) is None
- complete_struct_or_union(BUnion, [('a1', BLong, -1),
- ('a2', BChar, -1)])
- d = _getfields(BUnion)
- assert len(d) == 2
- assert d[0][0] == 'a1'
- assert d[0][1].type is BLong
- assert d[0][1].offset == 0
- assert d[1][0] == 'a2'
- assert d[1][1].type is BChar
- assert d[1][1].offset == 0
- assert sizeof(BUnion) == sizeof(BLong)
- assert alignof(BUnion) == alignof(BLong)
-
- def test_struct_instance(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- BStructPtr = new_pointer_type(BStruct)
- p = cast(BStructPtr, None)
- py.test.raises(AttributeError, "p.a1") # opaque
- complete_struct_or_union(BStruct, [('a1', BInt, -1),
- ('a2', BInt, -1)])
- p = newp(BStructPtr, None)
- s = p[0]
- assert s.a1 == 0
- s.a2 = 123
- assert s.a1 == 0
- assert s.a2 == 123
- py.test.raises(OverflowError, "s.a1 = sys.maxint+1")
- assert s.a1 == 0
- py.test.raises(AttributeError, "p.foobar")
- py.test.raises(AttributeError, "s.foobar")
-
- def test_struct_pointer(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- BStructPtr = new_pointer_type(BStruct)
- complete_struct_or_union(BStruct, [('a1', BInt, -1),
- ('a2', BInt, -1)])
- p = newp(BStructPtr, None)
- assert p.a1 == 0 # read/write via the pointer (C equivalent: '->')
- p.a2 = 123
- assert p.a1 == 0
- assert p.a2 == 123
-
- def test_struct_init_list(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- BStructPtr = new_pointer_type(BStruct)
- complete_struct_or_union(BStruct, [('a1', BInt, -1),
- ('a2', BInt, -1),
- ('a3', BInt, -1)])
- s = newp(BStructPtr, [123, 456])
- assert s.a1 == 123
- assert s.a2 == 456
- assert s.a3 == 0
-
- def test_array_in_struct(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- BArrayInt5 = new_array_type(new_pointer_type(BInt), 5)
- complete_struct_or_union(BStruct, [('a1', BArrayInt5, -1)])
- s = newp(new_pointer_type(BStruct), [[20, 24, 27, 29, 30]])
- assert s.a1[2] == 27
- assert repr(s.a1) == "<cdata 'int[5]'>"
-
- def test_offsetof(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- py.test.raises(TypeError, offsetof, BInt, "abc")
- py.test.raises(TypeError, offsetof, BStruct, "abc")
- complete_struct_or_union(BStruct, [('abc', BInt, -1), ('def', BInt, -1)])
- assert offsetof(BStruct, 'abc') == 0
- assert offsetof(BStruct, 'def') == size_of_int()
- py.test.raises(KeyError, offsetof, BStruct, "ghi")
-
- def test_function_type(self):
- BInt = new_primitive_type("int")
- BFunc = new_function_type((BInt, BInt), BInt, False)
- assert repr(BFunc) == "<ctype 'int(*)(int, int)'>"
- BFunc2 = new_function_type((), BFunc, False)
- assert repr(BFunc2) == "<ctype 'int(*(*)())(int, int)'>"
-
- def test_function_type_taking_struct(self):
- BChar = new_primitive_type("char")
- BShort = new_primitive_type("short")
- BStruct = new_struct_type("foo")
- complete_struct_or_union(BStruct, [('a1', BChar, -1),
- ('a2', BShort, -1)])
- BFunc = new_function_type((BStruct,), BShort, False)
- assert repr(BFunc) == "<ctype 'short(*)(struct foo)'>"
-
- def test_function_void_result(self):
- BVoid = new_void_type()
- BInt = new_primitive_type("int")
- BFunc = new_function_type((BInt, BInt), BVoid, False)
- assert repr(BFunc) == "<ctype 'void(*)(int, int)'>"
-
- def test_call_function_0(self):
- BSignedChar = new_primitive_type("signed char")
- BFunc0 = new_function_type((BSignedChar, BSignedChar), BSignedChar, False)
- f = cast(BFunc0, _testfunc(0))
- assert f(40, 2) == 42
- assert f(-100, -100) == -200 + 256
- py.test.raises(OverflowError, f, 128, 0)
- py.test.raises(OverflowError, f, 0, 128)
-
- def test_call_function_1(self):
- BInt = new_primitive_type("int")
- BLong = new_primitive_type("long")
- BFunc1 = new_function_type((BInt, BLong), BLong, False)
- f = cast(BFunc1, _testfunc(1))
- assert f(40, 2) == 42
- assert f(-100, -100) == -200
- int_max = (1 << (8*size_of_int()-1)) - 1
- long_max = (1 << (8*size_of_long()-1)) - 1
- if int_max == long_max:
- assert f(int_max, 1) == - int_max - 1
- else:
- assert f(int_max, 1) == int_max + 1
-
- def test_call_function_2(self):
- BLongLong = new_primitive_type("long long")
- BFunc2 = new_function_type((BLongLong, BLongLong), BLongLong, False)
- f = cast(BFunc2, _testfunc(2))
- longlong_max = (1 << (8*sizeof(BLongLong)-1)) - 1
- assert f(longlong_max - 42, 42) == longlong_max
- assert f(43, longlong_max - 42) == - longlong_max - 1
-
- def test_call_function_3(self):
- BFloat = new_primitive_type("float")
- BDouble = new_primitive_type("double")
- BFunc3 = new_function_type((BFloat, BDouble), BDouble, False)
- f = cast(BFunc3, _testfunc(3))
- assert f(1.25, 5.1) == 1.25 + 5.1 # exact
- res = f(1.3, 5.1)
- assert res != 6.4 and abs(res - 6.4) < 1E-5 # inexact
-
- def test_call_function_4(self):
- BFloat = new_primitive_type("float")
- BDouble = new_primitive_type("double")
- BFunc4 = new_function_type((BFloat, BDouble), BFloat, False)
- f = cast(BFunc4, _testfunc(4))
- res = f(1.25, 5.1)
- assert res != 6.35 and abs(res - 6.35) < 1E-5 # inexact
-
- def test_call_function_5(self):
- BVoid = new_void_type()
- BFunc5 = new_function_type((), BVoid, False)
- f = cast(BFunc5, _testfunc(5))
- f() # did not crash
-
- def test_call_function_6(self):
- BInt = new_primitive_type("int")
- BIntPtr = new_pointer_type(BInt)
- BFunc6 = new_function_type((BIntPtr,), BIntPtr, False)
- f = cast(BFunc6, _testfunc(6))
- x = newp(BIntPtr, 42)
- res = f(x)
- assert typeof(res) is BIntPtr
- assert res[0] == 42 - 1000
- #
- BIntArray = new_array_type(BIntPtr, None)
- BFunc6bis = new_function_type((BIntArray,), BIntPtr, False)
- f = cast(BFunc6bis, _testfunc(6))
- #
- py.test.raises(TypeError, f, [142])
- #
- x = newp(BIntArray, [242])
- res = f(x)
- assert typeof(res) is BIntPtr
- assert res[0] == 242 - 1000
-
- def test_call_function_7(self):
- BChar = new_primitive_type("char")
- BShort = new_primitive_type("short")
- BStruct = new_struct_type("foo")
- BStructPtr = new_pointer_type(BStruct)
- complete_struct_or_union(BStruct, [('a1', BChar, -1),
- ('a2', BShort, -1)])
- BFunc7 = new_function_type((BStruct,), BShort, False)
- f = cast(BFunc7, _testfunc(7))
- res = f({'a1': 'A', 'a2': -4042})
- assert res == -4042 + ord('A')
- #
- x = newp(BStructPtr, {'a1': 'A', 'a2': -4042})
- res = f(x[0])
- assert res == -4042 + ord('A')
-
- def test_call_function_9(self):
- BInt = new_primitive_type("int")
- BFunc9 = new_function_type((BInt,), BInt, True) # vararg
- f = cast(BFunc9, _testfunc(9))
- assert f(0) == 0
- assert f(1, cast(BInt, 42)) == 42
- assert f(2, cast(BInt, 40), cast(BInt, 2)) == 42
- py.test.raises(TypeError, f, 1, 42)
-
- def test_new_charp(self):
- BChar = new_primitive_type("char")
- BCharP = new_pointer_type(BChar)
- BCharA = new_array_type(BCharP, None)
- x = newp(BCharA, 42)
- assert len(x) == 42
- x = newp(BCharA, "foobar")
- assert len(x) == 7
-
- def test_load_and_call_function(self):
- BChar = new_primitive_type("char")
- BCharP = new_pointer_type(BChar)
- BLong = new_primitive_type("long")
- BFunc = new_function_type((BCharP,), BLong, False)
- ll = self.b._find_and_load_library()
- strlen = ll.load_function(BFunc, "strlen")
- input = newp(new_array_type(BCharP, None), "foobar")
- assert strlen(input) == 6
- #
- assert strlen("foobarbaz") == 9
-
- def test_read_variable(self):
- if sys.platform == 'win32':
- py.test.skip("untested")
- BVoidP = new_pointer_type(new_void_type())
- ll = self.b._find_and_load_library()
- stderr = ll.read_variable(BVoidP, "stderr")
- assert stderr == cast(BVoidP, _testfunc(8))
-
- def test_write_variable(self):
- if sys.platform == 'win32':
- py.test.skip("untested")
- BVoidP = new_pointer_type(new_void_type())
- ll = self.b._find_and_load_library()
- stderr = ll.read_variable(BVoidP, "stderr")
- ll.write_variable(BVoidP, "stderr", None)
- assert ll.read_variable(BVoidP, "stderr") is None
- ll.write_variable(BVoidP, "stderr", stderr)
- assert ll.read_variable(BVoidP, "stderr") == stderr
-
- def test_callback(self):
- BInt = new_primitive_type("int")
- def make_callback(self):
- def cb(n):
- return n + 1
- BFunc = new_function_type((BInt,), BInt, False)
- return callback(BFunc, cb) # 'cb' and 'BFunc' go out of scope
- f = make_callback()
- assert f(-142) == -141
-
- def test_a_lot_of_callbacks(self):
- BInt = new_primitive_type("int")
- def make_callback(m):
- def cb(n):
- return n + m
- BFunc = new_function_type((BInt,), BInt, False)
- return callback(BFunc, cb) # 'cb' and 'BFunc' go out of scope
- #
- flist = [make_callback(i) for i in range(10000)]
- for i, f in enumerate(flist):
- assert f(-142) == -142 + i
-
- def test_enum_type(self):
- BEnum = new_enum_type("foo", (), ())
- assert repr(BEnum) == "<ctype 'enum foo'>"
- assert _getfields(BEnum) == []
- #
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
- assert _getfields(BEnum) == [(-20, 'ab'), (0, 'def'), (1, 'c')]
-
- def test_cast_to_enum(self):
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
- e = cast(BEnum, 0)
- assert repr(e) == "<cdata 'enum foo'>"
- assert str(e) == 'def'
- assert str(cast(BEnum, -20)) == 'ab'
- assert str(cast(BEnum, 'c')) == 'c'
- assert int(cast(BEnum, 'c')) == 1
- assert int(cast(BEnum, 'def')) == 0
- assert int(cast(BEnum, -242 + 2**128)) == -242
- assert str(cast(BEnum, -242 + 2**128)) == '#-242'
- assert str(cast(BEnum, '#-20')) == 'ab'
-
- def test_enum_in_struct(self):
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
- BStruct = new_struct_type("bar")
- BStructPtr = new_pointer_type(BStruct)
- complete_struct_or_union(BStruct, [('a1', BEnum, -1)])
- p = newp(BStructPtr, [-20])
- assert p.a1 == "ab"
- p = newp(BStructPtr, ["c"])
- assert p.a1 == "c"
- e = py.test.raises(TypeError, newp, BStructPtr, [None])
- assert "must be a str or int, not NoneType" in str(e.value)
-
- def test_struct_with_bitfields(self):
- BLong = new_primitive_type("long")
- BStruct = new_struct_type("foo")
- LONGBITS = 8 * sizeof(BLong)
- complete_struct_or_union(BStruct, [('a1', BLong, 1),
- ('a2', BLong, 2),
- ('a3', BLong, 3),
- ('a4', BLong, LONGBITS - 5)])
- d = _getfields(BStruct)
- assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0
- assert d[3][1].offset == sizeof(BLong)
- assert d[0][1].bitshift == 0
- assert d[0][1].bitsize == 1
- assert d[1][1].bitshift == 1
- assert d[1][1].bitsize == 2
- assert d[2][1].bitshift == 3
- assert d[2][1].bitsize == 3
- assert d[3][1].bitshift == 0
- assert d[3][1].bitsize == LONGBITS - 5
- assert sizeof(BStruct) == 2 * sizeof(BLong)
- assert alignof(BStruct) == alignof(BLong)
-
- def test_bitfield_instance(self):
- BInt = new_primitive_type("int")
- BUnsignedInt = new_primitive_type("unsigned int")
- BStruct = new_struct_type("foo")
- complete_struct_or_union(BStruct, [('a1', BInt, 1),
- ('a2', BUnsignedInt, 2),
- ('a3', BInt, 3)])
- p = newp(new_pointer_type(BStruct), None)
- p.a1 = -1
- assert p.a1 == -1
- p.a1 = 0
- py.test.raises(OverflowError, "p.a1 = 2")
- assert p.a1 == 0
- #
- p.a1 = -1
- p.a2 = 3
- p.a3 = -4
- py.test.raises(OverflowError, "p.a3 = 4")
- e = py.test.raises(OverflowError, "p.a3 = -5")
- assert str(e.value) == ("value -5 outside the range allowed by the "
- "bit field width: -4 <= x <= 3")
- assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4
- #
- # special case for convenience: "int x:1", while normally signed,
- # allows also setting the value "1" (it still gets read back as -1)
- p.a1 = 1
- assert p.a1 == -1
- e = py.test.raises(OverflowError, "p.a1 = -2")
- assert str(e.value) == ("value -2 outside the range allowed by the "
- "bit field width: -1 <= x <= 1")
-
- def test_bitfield_instance_init(self):
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo")
- complete_struct_or_union(BStruct, [('a1', BInt, 1)])
- py.test.raises(NotImplementedError, newp, new_pointer_type(BStruct), [-1])
-
- def test_gc(self):
- from gc import collect
- BInt = new_primitive_type("int")
- n = cast(BInt, 123)
- py.test.raises(TypeError, gc, n, 5)
- destroyed = []
- m = gc(n, destroyed.append)
- assert repr(m) == "<cdata 'int' with destructor>"
- assert destroyed == []
- del m; collect()
- assert len(destroyed) == 1
- assert int(destroyed[0]) == 123
+mod = tmpname.pyimport()
+for key, value in mod.__dict__.items():
+ if key.startswith('test_'):
+ setattr(AppTestC, key, value)
diff --git a/pypy/module/_ffi_backend/test/test_file.py b/pypy/module/_ffi_backend/test/test_file.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_ffi_backend/test/test_file.py
@@ -0,0 +1,13 @@
+import urllib2, py
+
+
+def test_same_file():
+ # '_backend_test_c.py' is a copy of 'c/test_c.py' from the CFFI repo,
+ # with the header lines (up to '# _____') stripped.
+ url = 'https://bitbucket.org/cffi/cffi/raw/default/c/test_c.py'
+ source = urllib2.urlopen(url).read()
+ #
+ dest = py.path.local(__file__).join('..', '_backend_test_c.py').read()
+ #
+ source = source[source.index('# _____________'):]
+ assert source == dest
More information about the pypy-commit
mailing list