def test_simple(): ffi = FFI(backend=FakeBackend()) ffi.cdef("double sin(double x);") m = ffi.load("m") func = m.sin # should be a callable on real backends assert func.name == 'sin' assert func.BType == '<func (<double>), <double>, False>'
def add_ffi(self, nominal_vf, E_matrix, nu_matrix, use_ti, global_sf=None): """Adds Fiber Fraction Imperfection (FFI) There can be only one of these, so calling this function overrides the previous imperfection, if any. Parameters ---------- nominal_vf : float Nominal fiber volume fraction of the material E_matrix : float Young's modulus of the matrix material nu_matrix : float Poisson's ratio of the matrix material use_ti : bool If ``True``, create varying material properties according to the thickness imperfection data (if present). global_sf : float or ``None`` Global scaling factor to apply to the material thickness. Set to ``None`` to disable. The global scaling may be overridden by a thickness imperfection, if ``use_ti`` (see above) is ``True``. Returns ------- ffi : :class:`.FFI` object. """ if self.ffi is not None: warn('FFI object already set, overriding...') self.ffi = FFI(nominal_vf, E_matrix, nu_matrix, use_ti, global_sf) self.ffi.impconf = self return self.ffi
def test_char(self): ffi = FFI(backend=self.Backend()) assert ffi.new("char", "\xff")[0] == '\xff' assert ffi.new("char")[0] == '\x00' assert int(ffi.cast("char", 300)) == 300 - 256 assert bool(ffi.new("char")) py.test.raises(TypeError, ffi.new, "char", 32) py.test.raises(TypeError, ffi.new, "char", "foo") # p = ffi.new("char[]", ['a', 'b', '\x9c']) assert len(p) == 3 assert p[0] == 'a' assert p[1] == 'b' assert p[2] == '\x9c' p[0] = '\xff' assert p[0] == '\xff' p = ffi.new("char[]", "abcd") assert len(p) == 5 assert p[4] == '\x00' # like in C, with: char[] p = "abcd"; # p = ffi.new("char[4]", "ab") assert len(p) == 4 assert [p[i] for i in range(4)] == ['a', 'b', '\x00', '\x00'] p = ffi.new("char[2]", "ab") assert len(p) == 2 assert [p[i] for i in range(2)] == ['a', 'b'] py.test.raises(IndexError, ffi.new, "char[2]", "abc")
def test_constructor_struct_from_dict(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo", {'b': 123, 'c': 456}) assert s.a == 0 assert s.b == 123 assert s.c == 456 py.test.raises(KeyError, ffi.new, "struct foo", {'d': 456})
def test_sin(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" double sin(double x); """) m = ffi.load("m") x = m.sin(1.23) assert x == math.sin(1.23)
def test_strchr(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" char *strchr(const char *s, int c); """) p = ffi.new("char[]", "hello world!") q = ffi.C.strchr(p, ord('w')) assert str(q) == "world!"
def test_passing_array(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int strlen(char[]); """) p = ffi.new("char[]", "hello") res = ffi.C.strlen(p) assert res == 5
def test_pointer_init(self): ffi = FFI(backend=self.Backend()) n = ffi.new("int", 24) a = ffi.new("int *[10]", [None, None, n, n, None]) for i in range(10): if i not in (2, 3): assert a[i] is None assert a[2] == a[3] == n
def test_new_array_of_pointer_2(self): ffi = FFI(backend=self.Backend()) n = ffi.new("int[1]", [99]) p = ffi.new("int*[4]") p[3] = n a = p[3] assert repr(a) == "<cdata 'int *'>" assert a[0] == 99
def test_new_array_of_array(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[3][4]") p[0][0] = 10 p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 py.test.raises(IndexError, "p[1][-1]")
def test_must_specify_type_of_vararg(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int printf(const char *format, ...); """) e = py.test.raises(TypeError, ffi.C.printf, "hello %d\n", 42) assert str(e.value) == ("argument 2 passed in the variadic part " "needs to be a cdata object (got int)")
def test_ffi_string(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[]", range(100, 110)) s = ffi.string(ffi.cast("void *", a), 8) assert type(s) is str if sys.byteorder == 'little': assert s == '\x64\x00\x00\x00\x65\x00\x00\x00' else: assert s == '\x00\x00\x00\x64\x00\x00\x00\x65'
def test_new_single_integer(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int") # similar to ffi.new("int[1]") assert p[0] == 0 p[0] = -123 assert p[0] == -123 p = ffi.new("int", -42) assert p[0] == -42 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
def test_function_with_struct_argument(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct in_addr { unsigned int s_addr; }; char *inet_ntoa(struct in_addr in); """) ina = ffi.new("struct in_addr", [0x04040404]) a = ffi.C.inet_ntoa(ina[0]) assert str(a) == '4.4.4.4'
def test_struct_pointer(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo") assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 py.test.raises(OverflowError, "s[0].b = -32769") py.test.raises(IndexError, "s[1]")
def test_function_has_a_c_type(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(const char *); """) fptr = ffi.C.puts assert ffi.typeof(fptr) == ffi.typeof("int(*)(const char*)") if self.Backend is CTypesBackend: assert repr(fptr) == "<cdata 'int puts(char *)'>"
def test_typedef(): ffi = FFI(backend=FakeBackend()) ffi.cdef(""" typedef unsigned int UInt; typedef UInt UIntReally; UInt foo(void); """) assert ffi.typeof("UIntReally") == '<unsigned int>' assert ffi.C.foo.BType == '<func (), <unsigned int>, False>'
def test_cast_array_to_charp(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("char*", a) data = ''.join([p[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_array_of_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") py.test.raises(AttributeError, 's.b') py.test.raises(AttributeError, 's.b = 412') s[0].b = 412 assert s[0].b == 412 py.test.raises(IndexError, 's[1]')
def test_getting_errno(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int test_getting_errno(void); """) ownlib = ffi.load(self.module) res = ownlib.test_getting_errno() assert res == -1 assert ffi.C.errno == 123
def test_typedef_more_complex(): ffi = FFI(backend=FakeBackend()) ffi.cdef(""" typedef struct { int a, b; } foo_t, *foo_p; int foo(foo_p[]); """) assert str(ffi.typeof("foo_t")) == '<int>a, <int>b' assert ffi.typeof("foo_p") == '<pointer to <int>a, <int>b>' assert ffi.C.foo.BType == ('<func (<pointer to <pointer to ' '<int>a, <int>b>>), <int>, False>')
def test_sinf(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" float sinf(float x); """) m = ffi.load("m") x = m.sinf(1.23) assert type(x) is float assert x != math.sin(1.23) # rounding effects assert abs(x - math.sin(1.23)) < 1E-6
def test_fetch_const_char_p_field(self): # 'const' is ignored so far ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { const char *name; };") t = ffi.new("const char[]", "testing") s = ffi.new("struct foo", [t]) assert type(s.name) is not str assert str(s.name) == "testing" s.name = None assert s.name is None
def test_recursive_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int value; struct foo *next; };") s = ffi.new("struct foo") t = ffi.new("struct foo") s.value = 123 s.next = t t.value = 456 assert s.value == 123 assert s.next.value == 456
def test_constructor_struct_of_array(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a[2]; char b[3]; };") s = ffi.new("struct foo", [[10, 11], ['a', 'b', 'c']]) assert s.a[1] == 11 assert s.b[2] == 'c' s.b[1] = 'X' assert s.b[0] == 'a' assert s.b[1] == 'X' assert s.b[2] == 'c'
def test_fputs(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int fputs(const char *, void *); void *stdout, *stderr; """) with FdWriteCapture(2) as fd: ffi.C.fputs("hello from stderr\n", ffi.C.stderr) res = fd.getvalue() assert res == 'hello from stderr\n'
def test_none_as_null(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int*[1]") assert p[0] is None # n = ffi.new("int", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 p[0] = None assert p[0] is None
def test_char_cast(self): ffi = FFI(backend=self.Backend()) p = ffi.cast("int", '\x01') assert ffi.typeof(p) is ffi.typeof("int") assert int(p) == 1 p = ffi.cast("int", ffi.cast("char", "a")) assert int(p) == ord("a") p = ffi.cast("int", ffi.cast("char", "\x80")) assert int(p) == 0x80 # "char" is considered unsigned in this case p = ffi.cast("int", "\x81") assert int(p) == 0x81
def test_array_indexing(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[10]") p[0] = 42 p[9] = 43 assert p[0] == 42 assert p[9] == 43 py.test.raises(IndexError, "p[10]") py.test.raises(IndexError, "p[10] = 44") py.test.raises(IndexError, "p[-1]") py.test.raises(IndexError, "p[-1] = 44")
def test_new_pointer_to_array(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[4]", [100, 102, 104, 106]) p = ffi.new("int *", a) assert p[0] == ffi.cast("int *", a) assert p[0][2] == 104 p = ffi.cast("int *", a) assert p[0] == 100 assert p[1] == 102 assert p[2] == 104 assert p[3] == 106
def test_cast_between_pointers(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("short*", a) p2 = ffi.cast("int*", p) q = ffi.cast("char*", p2) data = ''.join([q[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_cast_functionptr_and_int(self): ffi = FFI(backend=self.Backend()) def cb(n): return n + 1 a = ffi.callback("int(*)(int)", cb) p = ffi.cast("void *", a) assert p b = ffi.cast("int(*)(int)", p) assert b(41) == 42 assert a == b assert hash(a) == hash(b)
def test_setting_errno(self): if self.Backend is CTypesBackend and '__pypy__' in sys.modules: py.test.skip("XXX errno issue with ctypes on pypy?") ffi = FFI(backend=self.Backend()) ffi.cdef(""" int test_setting_errno(void); """) ownlib = ffi.load(self.module) ffi.C.errno = 42 res = ownlib.test_setting_errno() assert res == 42 assert ffi.C.errno == 42
def test_simple_verify(): ffi = FFI() ffi.cdef("void some_completely_unknown_function();") py.test.raises(CompilationError, ffi.verify) ffi = FFI() ffi.cdef("double sin(double x);") # omission of math.h py.test.raises(CompilationError, ffi.verify) assert ffi.verify('#include <math.h>') is None
def test_pointer_arithmetic(self): ffi = FFI(backend=self.Backend()) s = ffi.new("short[]", range(100, 110)) p = ffi.cast("short *", s) assert p[2] == 102 assert p + 1 == p + 1 assert p + 1 != p + 0 assert p == p + 0 == p - 0 assert (p + 1)[0] == 101 assert (p + 19)[-10] == 109 assert (p + 5) - (p + 1) == 4 assert p == s + 0 assert p + 1 == s + 1