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 test_function_pointer(self): ffi = FFI(backend=self.Backend()) def cb(charp): assert repr(charp) == "<cdata 'char *'>" return 42 fptr = ffi.callback("int(*)(const char *txt)", cb) assert fptr != ffi.callback("int(*)(const char *)", cb) assert repr(fptr) == "<cdata 'int(*)(char *)' calling %r>" % (cb, ) res = fptr("Hello") assert res == 42 # ffi.cdef(""" int puts(const char *); int fflush(void *); """) fptr = ffi.cast("int(*)(const char *txt)", ffi.C.puts) assert fptr == ffi.C.puts assert repr(fptr) == "<cdata 'int(*)(char *)'>" with FdWriteCapture() as fd: fptr("world") ffi.C.fflush(None) res = fd.getvalue() assert res == 'world\n'
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 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_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_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_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_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_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_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_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_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_anonymous_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("typedef struct { int a; } foo_t;") ffi.cdef("typedef struct { char b, c; } bar_t;") f = ffi.new("foo_t", [12345]) b = ffi.new("bar_t", ["B", "C"]) assert f.a == 12345 assert f.b == "B" assert f.c == "C"
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_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(): 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_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_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_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_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_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_anonymous_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("typedef struct { int a; } foo_t;") ffi.cdef("typedef struct { char b, c; } bar_t;") f = ffi.new("foo_t", [12345]) b = ffi.new("bar_t", ["B", "C"]) assert f.a == 12345 assert f.b == "B" assert f.c == "C"
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_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_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_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_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_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_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_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_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_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_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_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_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_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 42 assert int(ffi.cast("enum foo", "C")) == 43 assert str(ffi.cast("enum foo", 0)) == "A" assert str(ffi.cast("enum foo", 42)) == "B" assert str(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 assert str(invalid_value) == "#2"
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_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_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 42 assert int(ffi.cast("enum foo", "C")) == 43 assert str(ffi.cast("enum foo", 0)) == "A" assert str(ffi.cast("enum foo", 42)) == "B" assert str(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 assert str(invalid_value) == "#2"
def test_puts_wihtout_const(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(char *); int fflush(void *); """) ffi.C.puts # fetch before capturing, for easier debugging with FdWriteCapture() as fd: ffi.C.puts("hello") ffi.C.puts(" world") ffi.C.fflush(None) res = fd.getvalue() assert res == 'hello\n world\n'
def test_puts_wihtout_const(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(char *); int fflush(void *); """) ffi.C.puts # fetch before capturing, for easier debugging with FdWriteCapture() as fd: ffi.C.puts("hello") ffi.C.puts(" world") ffi.C.fflush(None) res = fd.getvalue() assert res == 'hello\n world\n'
def test_union_simple(self): ffi = FFI(backend=self.Backend()) ffi.cdef("union foo { int a; short b, c; };") u = ffi.new("union foo") assert u.a == u.b == u.c == 0 u.b = -23 assert u.b == -23 assert u.a != 0 py.test.raises(OverflowError, "u.b = 32768") # u = ffi.new("union foo", -2) assert u.a == -2 py.test.raises((AttributeError, TypeError), "del u.a") assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
def test_union_simple(self): ffi = FFI(backend=self.Backend()) ffi.cdef("union foo { int a; short b, c; };") u = ffi.new("union foo") assert u.a == u.b == u.c == 0 u.b = -23 assert u.b == -23 assert u.a != 0 py.test.raises(OverflowError, "u.b = 32768") # u = ffi.new("union foo", -2) assert u.a == -2 py.test.raises((AttributeError, TypeError), "del u.a") assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
def test_ffi_nonfull_struct(): py.test.skip("XXX") ffi = FFI() ffi.cdef(""" struct sockaddr { int sa_family; ...; }; """) py.test.raises(VerificationMissing, ffi.sizeof, 'struct sockaddr') ffi.verify(''' #include <sys/types.h> #include <sys/socket.h> ''') assert ffi.sizeof('struct sockaddr') == 14 + ffi.sizeof(int)
def test_repr(self): typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") p = ffi.cast("unsigned short int", 0) assert repr(p) == "<cdata 'unsigned short'>" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("int*", 0) assert repr(p) == "<cdata 'int *'>" assert repr(ffi.typeof(p)) == typerepr % "int *" # p = ffi.new("int") assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT assert repr(ffi.typeof(p)) == typerepr % "int *" p = ffi.new("int*") assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR assert repr(ffi.typeof(p)) == typerepr % "int * *" p = ffi.new("int [2]") assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2 * SIZE_OF_INT) assert repr(ffi.typeof(p)) == typerepr % "int[2]" p = ffi.new("int*[2][3]") assert repr( p) == "<cdata 'int *[2][3]' owning %d bytes>" % (6 * SIZE_OF_PTR) assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" p = ffi.new("struct foo") assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % ( 3 * SIZE_OF_SHORT) assert repr(ffi.typeof(p)) == typerepr % "struct foo *" # q = ffi.cast("short", -123) assert repr(q) == "<cdata 'short'>" assert repr(ffi.typeof(q)) == typerepr % "short" p = ffi.new("int") q = ffi.cast("short*", p) assert repr(q) == "<cdata 'short *'>" assert repr(ffi.typeof(q)) == typerepr % "short *" p = ffi.new("int [2]") q = ffi.cast("int*", p) assert repr(q) == "<cdata 'int *'>" assert repr(ffi.typeof(q)) == typerepr % "int *" p = ffi.new("struct foo") q = ffi.cast("struct foo *", p) assert repr(q) == "<cdata 'struct foo *'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo *" q = q[0] assert repr(q) == "<cdata 'struct foo'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo"
def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 1 assert int(ffi.cast("enum foo", "CC")) == 2 assert int(ffi.cast("enum foo", "D")) == 3 ffi.cdef("enum bar { A, B=-2, CC, D };") assert int(ffi.cast("enum bar", "A")) == 0 assert int(ffi.cast("enum bar", "B")) == -2 assert int(ffi.cast("enum bar", "CC")) == -1 assert int(ffi.cast("enum bar", "D")) == 0 assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", "CC")) == "<cdata 'enum bar'>"
def test_sizeof_type(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct foo { int a; short b, c, d; }; union foo { int a; short b, c, d; }; """) for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), ('char *', SIZE_OF_LONG), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) assert size == expected_size
def test_sizeof_type(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct foo { int a; short b, c, d; }; union foo { int a; short b, c, d; }; """) for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), ('char *', SIZE_OF_LONG), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) assert size == expected_size
def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 1 assert int(ffi.cast("enum foo", "CC")) == 2 assert int(ffi.cast("enum foo", "D")) == 3 ffi.cdef("enum bar { A, B=-2, CC, D };") assert int(ffi.cast("enum bar", "A")) == 0 assert int(ffi.cast("enum bar", "B")) == -2 assert int(ffi.cast("enum bar", "CC")) == -1 assert int(ffi.cast("enum bar", "D")) == 0 assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", "CC")) == "<cdata 'enum bar'>"
def test_repr(self): typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") p = ffi.cast("unsigned short int", 0) assert repr(p) == "<cdata 'unsigned short'>" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("int*", 0) assert repr(p) == "<cdata 'int *'>" assert repr(ffi.typeof(p)) == typerepr % "int *" # p = ffi.new("int") assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT assert repr(ffi.typeof(p)) == typerepr % "int *" p = ffi.new("int*") assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR assert repr(ffi.typeof(p)) == typerepr % "int * *" p = ffi.new("int [2]") assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2*SIZE_OF_INT) assert repr(ffi.typeof(p)) == typerepr % "int[2]" p = ffi.new("int*[2][3]") assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % ( 6*SIZE_OF_PTR) assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" p = ffi.new("struct foo") assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % ( 3*SIZE_OF_SHORT) assert repr(ffi.typeof(p)) == typerepr % "struct foo *" # q = ffi.cast("short", -123) assert repr(q) == "<cdata 'short'>" assert repr(ffi.typeof(q)) == typerepr % "short" p = ffi.new("int") q = ffi.cast("short*", p) assert repr(q) == "<cdata 'short *'>" assert repr(ffi.typeof(q)) == typerepr % "short *" p = ffi.new("int [2]") q = ffi.cast("int*", p) assert repr(q) == "<cdata 'int *'>" assert repr(ffi.typeof(q)) == typerepr % "int *" p = ffi.new("struct foo") q = ffi.cast("struct foo *", p) assert repr(q) == "<cdata 'struct foo *'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo *" q = q[0] assert repr(q) == "<cdata 'struct foo'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo"
def test_enum_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") s = ffi.new("struct bar") s.e = 0 assert s.e == "A" s.e = "D" assert s.e == "D" assert s[0].e == "D" s[0].e = "C" assert s.e == "C" assert s[0].e == "C" s.e = ffi.cast("enum foo", -1) assert s.e == '#-1' assert s[0].e == '#-1' s.e = s.e py.test.raises(TypeError, "s.e = None")
def test_enum_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") s = ffi.new("struct bar") s.e = 0 assert s.e == "A" s.e = "D" assert s.e == "D" assert s[0].e == "D" s[0].e = "C" assert s.e == "C" assert s[0].e == "C" s.e = ffi.cast("enum foo", -1) assert s.e == '#-1' assert s[0].e == '#-1' s.e = s.e py.test.raises(TypeError, "s.e = None")
def test_struct_simple(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo") assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 py.test.raises(OverflowError, "s.b = 32768") # s = ffi.new("struct foo", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 py.test.raises((AttributeError, TypeError), "del s.a") assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # py.test.raises(ValueError, ffi.new, "struct foo", [1, 2, 3, 4])
def test_write_variable(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(const char *); void *stdout, *stderr; """) pout = ffi.C.stdout perr = ffi.C.stderr assert repr(pout) == "<cdata 'void *'>" assert repr(perr) == "<cdata 'void *'>" with FdWriteCapture(2) as fd: # capturing stderr ffi.C.stdout = perr try: ffi.C.puts("hello!") # goes to stdout, which is equal to stderr now finally: ffi.C.stdout = pout res = fd.getvalue() assert res == "hello!\n"