1import py 2import pytest 3import platform, imp 4import sys, os, ctypes 5import cffi 6from testing.udir import udir 7from testing.support import * 8from cffi.recompiler import recompile 9from cffi.cffi_opcode import PRIMITIVE_TO_INDEX 10 11SIZE_OF_INT = ctypes.sizeof(ctypes.c_int) 12SIZE_OF_LONG = ctypes.sizeof(ctypes.c_long) 13SIZE_OF_SHORT = ctypes.sizeof(ctypes.c_short) 14SIZE_OF_PTR = ctypes.sizeof(ctypes.c_void_p) 15SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar) 16 17 18def setup_module(): 19 global ffi, construction_params 20 ffi1 = cffi.FFI() 21 DEFS = r""" 22 struct repr { short a, b, c; }; 23 struct simple { int a; short b, c; }; 24 struct array { int a[2]; char b[3]; }; 25 struct recursive { int value; struct recursive *next; }; 26 union simple_u { int a; short b, c; }; 27 union init_u { char a; int b; }; 28 struct four_s { int a; short b, c, d; }; 29 union four_u { int a; short b, c, d; }; 30 struct string { const char *name; }; 31 struct ustring { const wchar_t *name; }; 32 struct voidp { void *p; int *q; short *r; }; 33 struct ab { int a, b; }; 34 struct abc { int a, b, c; }; 35 36 /* don't use A0, B0, CC0, D0 because termios.h might be included 37 and it has its own #defines for these names */ 38 enum foq { cffiA0, cffiB0, cffiCC0, cffiD0 }; 39 enum bar { A1, B1=-2, CC1, D1, E1 }; 40 enum baz { A2=0x1000, B2=0x2000 }; 41 enum foo2 { A3, B3, C3, D3 }; 42 struct bar_with_e { enum foo2 e; }; 43 enum noncont { A4, B4=42, C4 }; 44 enum etypes {A5='!', B5='\'', C5=0x10, D5=010, E5=- 0x10, F5=-010}; 45 typedef enum { Value0 = 0 } e_t, *pe_t; 46 enum e_noninj { AA3=0, BB3=0, CC3=0, DD3=0 }; 47 enum e_prev { AA4, BB4=2, CC4=4, DD4=BB4, EE4, FF4=CC4, GG4=FF4 }; 48 49 struct nesting { struct abc d, e; }; 50 struct array2 { int a, b; int c[99]; }; 51 struct align { char a; short b; char c; }; 52 struct bitfield { int a:10, b:20, c:3; }; 53 typedef enum { AA2, BB2, CC2 } foo_e_t; 54 typedef struct { foo_e_t f:2; } bfenum_t; 55 typedef struct { int a; } anon_foo_t; 56 typedef struct { char b, c; } anon_bar_t; 57 typedef struct named_foo_s { int a; } named_foo_t, *named_foo_p; 58 typedef struct { int a; } unnamed_foo_t, *unnamed_foo_p; 59 struct nonpacked { char a; int b; }; 60 struct array0 { int len; short data[0]; }; 61 struct array_no_length { int x; int a[]; }; 62 63 struct nested_anon { 64 struct { int a, b; }; 65 union { int c, d; }; 66 }; 67 struct nested_field_ofs_s { 68 struct { int a; char b; }; 69 union { char c; }; 70 }; 71 union nested_anon_u { 72 struct { int a, b; }; 73 union { int c, d; }; 74 }; 75 struct abc50 { int a, b; int c[50]; }; 76 struct ints_and_bitfield { int a,b,c,d,e; int x:1; }; 77 """ 78 DEFS_PACKED = """ 79 struct is_packed { char a; int b; } /*here*/; 80 """ 81 if sys.platform == "win32": 82 DEFS = DEFS.replace('data[0]', 'data[1]') # not supported 83 CCODE = (DEFS + "\n#pragma pack(push,1)\n" + DEFS_PACKED + 84 "\n#pragma pack(pop)\n") 85 else: 86 CCODE = (DEFS + 87 DEFS_PACKED.replace('/*here*/', '__attribute__((packed))')) 88 89 ffi1.cdef(DEFS) 90 ffi1.cdef(DEFS_PACKED, packed=True) 91 ffi1.set_source("test_new_ffi_1", CCODE) 92 93 outputfilename = recompile(ffi1, "test_new_ffi_1", CCODE, 94 tmpdir=str(udir)) 95 module = imp.load_dynamic("test_new_ffi_1", outputfilename) 96 ffi = module.ffi 97 construction_params = (ffi1, CCODE) 98 99 100class TestNewFFI1: 101 102 def test_integer_ranges(self): 103 for (c_type, size) in [('char', 1), 104 ('short', 2), 105 ('short int', 2), 106 ('', 4), 107 ('int', 4), 108 ('long', SIZE_OF_LONG), 109 ('long int', SIZE_OF_LONG), 110 ('long long', 8), 111 ('long long int', 8), 112 ]: 113 for unsigned in [None, False, True]: 114 c_decl = {None: '', 115 False: 'signed ', 116 True: 'unsigned '}[unsigned] + c_type 117 if c_decl == 'char' or c_decl == '': 118 continue 119 self._test_int_type(ffi, c_decl, size, unsigned) 120 121 def test_fixedsize_int(self): 122 for size in [1, 2, 4, 8]: 123 self._test_int_type(ffi, 'int%d_t' % (8*size), size, False) 124 self._test_int_type(ffi, 'uint%d_t' % (8*size), size, True) 125 self._test_int_type(ffi, 'intptr_t', SIZE_OF_PTR, False) 126 self._test_int_type(ffi, 'uintptr_t', SIZE_OF_PTR, True) 127 self._test_int_type(ffi, 'ptrdiff_t', SIZE_OF_PTR, False) 128 self._test_int_type(ffi, 'size_t', SIZE_OF_PTR, True) 129 self._test_int_type(ffi, 'ssize_t', SIZE_OF_PTR, False) 130 131 def _test_int_type(self, ffi, c_decl, size, unsigned): 132 if unsigned: 133 min = 0 134 max = (1 << (8*size)) - 1 135 else: 136 min = -(1 << (8*size-1)) 137 max = (1 << (8*size-1)) - 1 138 min = int(min) 139 max = int(max) 140 p = ffi.cast(c_decl, min) 141 assert p == min 142 assert bool(p) is bool(min) 143 assert int(p) == min 144 p = ffi.cast(c_decl, max) 145 assert int(p) == max 146 p = ffi.cast(c_decl, long(max)) 147 assert int(p) == max 148 q = ffi.cast(c_decl, min - 1) 149 assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max 150 q = ffi.cast(c_decl, long(min - 1)) 151 assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max 152 assert q == p 153 assert int(q) == int(p) 154 assert hash(q) == hash(p) 155 c_decl_ptr = '%s *' % c_decl 156 py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1) 157 py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1) 158 py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(min - 1)) 159 py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(max + 1)) 160 assert ffi.new(c_decl_ptr, min)[0] == min 161 assert ffi.new(c_decl_ptr, max)[0] == max 162 assert ffi.new(c_decl_ptr, long(min))[0] == min 163 assert ffi.new(c_decl_ptr, long(max))[0] == max 164 165 def test_new_unsupported_type(self): 166 e = py.test.raises(TypeError, ffi.new, "int") 167 assert str(e.value) == "expected a pointer or array ctype, got 'int'" 168 169 def test_new_single_integer(self): 170 p = ffi.new("int *") # similar to ffi.new("int[1]") 171 assert p[0] == 0 172 p[0] = -123 173 assert p[0] == -123 174 p = ffi.new("int *", -42) 175 assert p[0] == -42 176 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT 177 178 def test_new_array_no_arg(self): 179 p = ffi.new("int[10]") 180 # the object was zero-initialized: 181 for i in range(10): 182 assert p[i] == 0 183 184 def test_array_indexing(self): 185 p = ffi.new("int[10]") 186 p[0] = 42 187 p[9] = 43 188 assert p[0] == 42 189 assert p[9] == 43 190 with pytest.raises(IndexError): 191 p[10] 192 with pytest.raises(IndexError): 193 p[10] = 44 194 with pytest.raises(IndexError): 195 p[-1] 196 with pytest.raises(IndexError): 197 p[-1] = 44 198 199 def test_new_array_args(self): 200 # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" 201 # then here we must enclose the items in a list 202 p = ffi.new("int[5]", [10, 20, 30, 40, 50]) 203 assert p[0] == 10 204 assert p[1] == 20 205 assert p[2] == 30 206 assert p[3] == 40 207 assert p[4] == 50 208 p = ffi.new("int[4]", [25]) 209 assert p[0] == 25 210 assert p[1] == 0 # follow C convention rather than LuaJIT's 211 assert p[2] == 0 212 assert p[3] == 0 213 p = ffi.new("int[4]", [ffi.cast("int", -5)]) 214 assert p[0] == -5 215 assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT) 216 217 def test_new_array_varsize(self): 218 p = ffi.new("int[]", 10) # a single integer is the length 219 assert p[9] == 0 220 with pytest.raises(IndexError): 221 p[10] 222 # 223 py.test.raises(TypeError, ffi.new, "int[]") 224 # 225 p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C 226 assert p[0] == -6 227 assert p[1] == -7 228 with pytest.raises(IndexError): 229 p[2] 230 assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT) 231 # 232 p = ffi.new("int[]", 0) 233 with pytest.raises(IndexError): 234 p[0] 235 py.test.raises(ValueError, ffi.new, "int[]", -1) 236 assert repr(p) == "<cdata 'int[]' owning 0 bytes>" 237 238 def test_pointer_init(self): 239 n = ffi.new("int *", 24) 240 a = ffi.new("int *[10]", [ffi.NULL, ffi.NULL, n, n, ffi.NULL]) 241 for i in range(10): 242 if i not in (2, 3): 243 assert a[i] == ffi.NULL 244 assert a[2] == a[3] == n 245 246 def test_cannot_cast(self): 247 a = ffi.new("short int[10]") 248 e = py.test.raises(TypeError, ffi.new, "long int **", a) 249 msg = str(e.value) 250 assert "'short[10]'" in msg and "'long *'" in msg 251 252 def test_new_pointer_to_array(self): 253 a = ffi.new("int[4]", [100, 102, 104, 106]) 254 p = ffi.new("int **", a) 255 assert p[0] == ffi.cast("int *", a) 256 assert p[0][2] == 104 257 p = ffi.cast("int *", a) 258 assert p[0] == 100 259 assert p[1] == 102 260 assert p[2] == 104 261 assert p[3] == 106 262 # keepalive: a 263 264 def test_pointer_direct(self): 265 p = ffi.cast("int*", 0) 266 assert p is not None 267 assert bool(p) is False 268 assert p == ffi.cast("int*", 0) 269 assert p != None 270 assert repr(p) == "<cdata 'int *' NULL>" 271 a = ffi.new("int[]", [123, 456]) 272 p = ffi.cast("int*", a) 273 assert bool(p) is True 274 assert p == ffi.cast("int*", a) 275 assert p != ffi.cast("int*", 0) 276 assert p[0] == 123 277 assert p[1] == 456 278 279 def test_repr(self): 280 typerepr = "<ctype '%s'>" 281 p = ffi.cast("short unsigned int", 0) 282 assert repr(p) == "<cdata 'unsigned short' 0>" 283 assert repr(ffi.typeof(p)) == typerepr % "unsigned short" 284 p = ffi.cast("unsigned short int", 0) 285 assert repr(p) == "<cdata 'unsigned short' 0>" 286 assert repr(ffi.typeof(p)) == typerepr % "unsigned short" 287 p = ffi.cast("int*", 0) 288 assert repr(p) == "<cdata 'int *' NULL>" 289 assert repr(ffi.typeof(p)) == typerepr % "int *" 290 # 291 p = ffi.new("int*") 292 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT 293 assert repr(ffi.typeof(p)) == typerepr % "int *" 294 p = ffi.new("int**") 295 assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR 296 assert repr(ffi.typeof(p)) == typerepr % "int * *" 297 p = ffi.new("int [2]") 298 assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2*SIZE_OF_INT) 299 assert repr(ffi.typeof(p)) == typerepr % "int[2]" 300 p = ffi.new("int*[2][3]") 301 assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % ( 302 6*SIZE_OF_PTR) 303 assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" 304 p = ffi.new("struct repr *") 305 assert repr(p) == "<cdata 'struct repr *' owning %d bytes>" % ( 306 3*SIZE_OF_SHORT) 307 assert repr(ffi.typeof(p)) == typerepr % "struct repr *" 308 # 309 q = ffi.cast("short", -123) 310 assert repr(q) == "<cdata 'short' -123>" 311 assert repr(ffi.typeof(q)) == typerepr % "short" 312 p = ffi.new("int*") 313 q = ffi.cast("short*", p) 314 assert repr(q).startswith("<cdata 'short *' 0x") 315 assert repr(ffi.typeof(q)) == typerepr % "short *" 316 p = ffi.new("int [2]") 317 q = ffi.cast("int*", p) 318 assert repr(q).startswith("<cdata 'int *' 0x") 319 assert repr(ffi.typeof(q)) == typerepr % "int *" 320 p = ffi.new("struct repr*") 321 q = ffi.cast("struct repr *", p) 322 assert repr(q).startswith("<cdata 'struct repr *' 0x") 323 assert repr(ffi.typeof(q)) == typerepr % "struct repr *" 324 prevrepr = repr(q) 325 q = q[0] 326 assert repr(q) == prevrepr.replace(' *', ' &') 327 assert repr(ffi.typeof(q)) == typerepr % "struct repr" 328 329 def test_new_array_of_array(self): 330 p = ffi.new("int[3][4]") 331 p[0][0] = 10 332 p[2][3] = 33 333 assert p[0][0] == 10 334 assert p[2][3] == 33 335 with pytest.raises(IndexError): 336 p[1][-1] 337 338 def test_constructor_array_of_array(self): 339 p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) 340 assert p[2][1] == 15 341 342 def test_new_array_of_pointer_1(self): 343 n = ffi.new("int*", 99) 344 p = ffi.new("int*[4]") 345 p[3] = n 346 a = p[3] 347 assert repr(a).startswith("<cdata 'int *' 0x") 348 assert a[0] == 99 349 350 def test_new_array_of_pointer_2(self): 351 n = ffi.new("int[1]", [99]) 352 p = ffi.new("int*[4]") 353 p[3] = n 354 a = p[3] 355 assert repr(a).startswith("<cdata 'int *' 0x") 356 assert a[0] == 99 357 358 def test_char(self): 359 assert ffi.new("char*", b"\xff")[0] == b'\xff' 360 assert ffi.new("char*")[0] == b'\x00' 361 assert int(ffi.cast("char", 300)) == 300 - 256 362 assert not bool(ffi.cast("char", 0)) 363 assert bool(ffi.cast("char", 1)) 364 assert bool(ffi.cast("char", 255)) 365 py.test.raises(TypeError, ffi.new, "char*", 32) 366 py.test.raises(TypeError, ffi.new, "char*", u+"x") 367 py.test.raises(TypeError, ffi.new, "char*", b"foo") 368 # 369 p = ffi.new("char[]", [b'a', b'b', b'\x9c']) 370 assert len(p) == 3 371 assert p[0] == b'a' 372 assert p[1] == b'b' 373 assert p[2] == b'\x9c' 374 p[0] = b'\xff' 375 assert p[0] == b'\xff' 376 p = ffi.new("char[]", b"abcd") 377 assert len(p) == 5 378 assert p[4] == b'\x00' # like in C, with: char[] p = "abcd"; 379 # 380 p = ffi.new("char[4]", b"ab") 381 assert len(p) == 4 382 assert [p[i] for i in range(4)] == [b'a', b'b', b'\x00', b'\x00'] 383 p = ffi.new("char[2]", b"ab") 384 assert len(p) == 2 385 assert [p[i] for i in range(2)] == [b'a', b'b'] 386 py.test.raises(IndexError, ffi.new, "char[2]", b"abc") 387 388 def check_wchar_t(self, ffi): 389 try: 390 ffi.cast("wchar_t", 0) 391 except NotImplementedError: 392 py.test.skip("NotImplementedError: wchar_t") 393 394 def test_wchar_t(self): 395 self.check_wchar_t(ffi) 396 assert ffi.new("wchar_t*", u+'x')[0] == u+'x' 397 assert ffi.new("wchar_t*", u+'\u1234')[0] == u+'\u1234' 398 if SIZE_OF_WCHAR > 2: 399 assert ffi.new("wchar_t*", u+'\U00012345')[0] == u+'\U00012345' 400 else: 401 py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345') 402 assert ffi.new("wchar_t*")[0] == u+'\x00' 403 assert int(ffi.cast("wchar_t", 300)) == 300 404 assert not bool(ffi.cast("wchar_t", 0)) 405 assert bool(ffi.cast("wchar_t", 1)) 406 assert bool(ffi.cast("wchar_t", 65535)) 407 if SIZE_OF_WCHAR > 2: 408 assert bool(ffi.cast("wchar_t", 65536)) 409 py.test.raises(TypeError, ffi.new, "wchar_t*", 32) 410 py.test.raises(TypeError, ffi.new, "wchar_t*", "foo") 411 # 412 p = ffi.new("wchar_t[]", [u+'a', u+'b', u+'\u1234']) 413 assert len(p) == 3 414 assert p[0] == u+'a' 415 assert p[1] == u+'b' and type(p[1]) is unicode 416 assert p[2] == u+'\u1234' 417 p[0] = u+'x' 418 assert p[0] == u+'x' and type(p[0]) is unicode 419 p[1] = u+'\u1357' 420 assert p[1] == u+'\u1357' 421 p = ffi.new("wchar_t[]", u+"abcd") 422 assert len(p) == 5 423 assert p[4] == u+'\x00' 424 p = ffi.new("wchar_t[]", u+"a\u1234b") 425 assert len(p) == 4 426 assert p[1] == u+'\u1234' 427 # 428 p = ffi.new("wchar_t[]", u+'\U00023456') 429 if SIZE_OF_WCHAR == 2: 430 assert len(p) == 3 431 assert p[0] == u+'\ud84d' 432 assert p[1] == u+'\udc56' 433 assert p[2] == u+'\x00' 434 else: 435 assert len(p) == 2 436 assert p[0] == u+'\U00023456' 437 assert p[1] == u+'\x00' 438 # 439 p = ffi.new("wchar_t[4]", u+"ab") 440 assert len(p) == 4 441 assert [p[i] for i in range(4)] == [u+'a', u+'b', u+'\x00', u+'\x00'] 442 p = ffi.new("wchar_t[2]", u+"ab") 443 assert len(p) == 2 444 assert [p[i] for i in range(2)] == [u+'a', u+'b'] 445 py.test.raises(IndexError, ffi.new, "wchar_t[2]", u+"abc") 446 447 def test_none_as_null_doesnt_work(self): 448 p = ffi.new("int*[1]") 449 assert p[0] is not None 450 assert p[0] != None 451 assert p[0] == ffi.NULL 452 assert repr(p[0]) == "<cdata 'int *' NULL>" 453 # 454 n = ffi.new("int*", 99) 455 p = ffi.new("int*[]", [n]) 456 assert p[0][0] == 99 457 with pytest.raises(TypeError): 458 p[0] = None 459 p[0] = ffi.NULL 460 assert p[0] == ffi.NULL 461 462 def test_float(self): 463 p = ffi.new("float[]", [-2, -2.5]) 464 assert p[0] == -2.0 465 assert p[1] == -2.5 466 p[1] += 17.75 467 assert p[1] == 15.25 468 # 469 p = ffi.new("float*", 15.75) 470 assert p[0] == 15.75 471 py.test.raises(TypeError, int, p) 472 py.test.raises(TypeError, float, p) 473 p[0] = 0.0 474 assert bool(p) is True 475 # 476 p = ffi.new("float*", 1.1) 477 f = p[0] 478 assert f != 1.1 # because of rounding effect 479 assert abs(f - 1.1) < 1E-7 480 # 481 INF = 1E200 * 1E200 482 assert 1E200 != INF 483 p[0] = 1E200 484 assert p[0] == INF # infinite, not enough precision 485 486 def test_struct_simple(self): 487 s = ffi.new("struct simple*") 488 assert s.a == s.b == s.c == 0 489 s.b = -23 490 assert s.b == -23 491 with pytest.raises(OverflowError): 492 s.b = 32768 493 # 494 s = ffi.new("struct simple*", [-2, -3]) 495 assert s.a == -2 496 assert s.b == -3 497 assert s.c == 0 498 with pytest.raises((AttributeError, TypeError)): 499 del s.a 500 assert repr(s) == "<cdata 'struct simple *' owning %d bytes>" % ( 501 SIZE_OF_INT + 2 * SIZE_OF_SHORT) 502 # 503 py.test.raises(ValueError, ffi.new, "struct simple*", [1, 2, 3, 4]) 504 505 def test_constructor_struct_from_dict(self): 506 s = ffi.new("struct simple*", {'b': 123, 'c': 456}) 507 assert s.a == 0 508 assert s.b == 123 509 assert s.c == 456 510 py.test.raises(KeyError, ffi.new, "struct simple*", {'d': 456}) 511 512 def test_struct_pointer(self): 513 s = ffi.new("struct simple*") 514 assert s[0].a == s[0].b == s[0].c == 0 515 s[0].b = -23 516 assert s[0].b == s.b == -23 517 with pytest.raises(OverflowError): 518 s[0].b = -32769 519 with pytest.raises(IndexError): 520 s[1] 521 522 def test_struct_opaque(self): 523 py.test.raises(ffi.error, ffi.new, "struct baz*") 524 # should 'ffi.new("struct baz **") work? it used to, but it was 525 # not particularly useful... 526 py.test.raises(ffi.error, ffi.new, "struct baz**") 527 528 def test_pointer_to_struct(self): 529 s = ffi.new("struct simple *") 530 s.a = -42 531 assert s[0].a == -42 532 p = ffi.new("struct simple **", s) 533 assert p[0].a == -42 534 assert p[0][0].a == -42 535 p[0].a = -43 536 assert s.a == -43 537 assert s[0].a == -43 538 p[0][0].a = -44 539 assert s.a == -44 540 assert s[0].a == -44 541 s.a = -45 542 assert p[0].a == -45 543 assert p[0][0].a == -45 544 s[0].a = -46 545 assert p[0].a == -46 546 assert p[0][0].a == -46 547 548 def test_constructor_struct_of_array(self): 549 s = ffi.new("struct array *", [[10, 11], [b'a', b'b', b'c']]) 550 assert s.a[1] == 11 551 assert s.b[2] == b'c' 552 s.b[1] = b'X' 553 assert s.b[0] == b'a' 554 assert s.b[1] == b'X' 555 assert s.b[2] == b'c' 556 557 def test_recursive_struct(self): 558 s = ffi.new("struct recursive*") 559 t = ffi.new("struct recursive*") 560 s.value = 123 561 s.next = t 562 t.value = 456 563 assert s.value == 123 564 assert s.next.value == 456 565 566 def test_union_simple(self): 567 u = ffi.new("union simple_u*") 568 assert u.a == u.b == u.c == 0 569 u.b = -23 570 assert u.b == -23 571 assert u.a != 0 572 with pytest.raises(OverflowError): 573 u.b = 32768 574 # 575 u = ffi.new("union simple_u*", [-2]) 576 assert u.a == -2 577 with pytest.raises((AttributeError, TypeError)): 578 del u.a 579 assert repr(u) == "<cdata 'union simple_u *' owning %d bytes>" % ( 580 SIZE_OF_INT,) 581 582 def test_union_opaque(self): 583 py.test.raises(ffi.error, ffi.new, "union baz*") 584 # should 'ffi.new("union baz **") work? it used to, but it was 585 # not particularly useful... 586 py.test.raises(ffi.error, ffi.new, "union baz**") 587 588 def test_union_initializer(self): 589 py.test.raises(TypeError, ffi.new, "union init_u*", b'A') 590 py.test.raises(TypeError, ffi.new, "union init_u*", 5) 591 py.test.raises(ValueError, ffi.new, "union init_u*", [b'A', 5]) 592 u = ffi.new("union init_u*", [b'A']) 593 assert u.a == b'A' 594 py.test.raises(TypeError, ffi.new, "union init_u*", [1005]) 595 u = ffi.new("union init_u*", {'b': 12345}) 596 assert u.b == 12345 597 u = ffi.new("union init_u*", []) 598 assert u.a == b'\x00' 599 assert u.b == 0 600 601 def test_sizeof_type(self): 602 for c_type, expected_size in [ 603 ('char', 1), 604 ('unsigned int', 4), 605 ('char *', SIZE_OF_PTR), 606 ('int[5]', 20), 607 ('struct four_s', 12), 608 ('union four_u', 4), 609 ]: 610 size = ffi.sizeof(c_type) 611 assert size == expected_size, (size, expected_size, ctype) 612 613 def test_sizeof_cdata(self): 614 assert ffi.sizeof(ffi.new("short*")) == SIZE_OF_PTR 615 assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT 616 # 617 a = ffi.new("int[]", [10, 11, 12, 13, 14]) 618 assert len(a) == 5 619 assert ffi.sizeof(a) == 5 * SIZE_OF_INT 620 621 def test_string_from_char_pointer(self): 622 x = ffi.new("char*", b"x") 623 assert str(x) == repr(x) 624 assert ffi.string(x) == b"x" 625 assert ffi.string(ffi.new("char*", b"\x00")) == b"" 626 py.test.raises(TypeError, ffi.new, "char*", unicode("foo")) 627 628 def test_unicode_from_wchar_pointer(self): 629 self.check_wchar_t(ffi) 630 x = ffi.new("wchar_t*", u+"x") 631 assert unicode(x) == unicode(repr(x)) 632 assert ffi.string(x) == u+"x" 633 assert ffi.string(ffi.new("wchar_t*", u+"\x00")) == u+"" 634 635 def test_string_from_char_array(self): 636 p = ffi.new("char[]", b"hello.") 637 p[5] = b'!' 638 assert ffi.string(p) == b"hello!" 639 p[6] = b'?' 640 assert ffi.string(p) == b"hello!?" 641 p[3] = b'\x00' 642 assert ffi.string(p) == b"hel" 643 assert ffi.string(p, 2) == b"he" 644 with pytest.raises(IndexError): 645 p[7] = b'X' 646 # 647 a = ffi.new("char[]", b"hello\x00world") 648 assert len(a) == 12 649 p = ffi.cast("char *", a) 650 assert ffi.string(p) == b'hello' 651 652 def test_string_from_wchar_array(self): 653 self.check_wchar_t(ffi) 654 assert ffi.string(ffi.cast("wchar_t", "x")) == u+"x" 655 assert ffi.string(ffi.cast("wchar_t", u+"x")) == u+"x" 656 x = ffi.cast("wchar_t", "x") 657 assert str(x) == repr(x) 658 assert ffi.string(x) == u+"x" 659 # 660 p = ffi.new("wchar_t[]", u+"hello.") 661 p[5] = u+'!' 662 assert ffi.string(p) == u+"hello!" 663 p[6] = u+'\u04d2' 664 assert ffi.string(p) == u+"hello!\u04d2" 665 p[3] = u+'\x00' 666 assert ffi.string(p) == u+"hel" 667 assert ffi.string(p, 123) == u+"hel" 668 with pytest.raises(IndexError): 669 p[7] = u+'X' 670 # 671 a = ffi.new("wchar_t[]", u+"hello\x00world") 672 assert len(a) == 12 673 p = ffi.cast("wchar_t *", a) 674 assert ffi.string(p) == u+'hello' 675 assert ffi.string(p, 123) == u+'hello' 676 assert ffi.string(p, 5) == u+'hello' 677 assert ffi.string(p, 2) == u+'he' 678 679 def test_fetch_const_char_p_field(self): 680 # 'const' is ignored so far, in the declaration of 'struct string' 681 t = ffi.new("const char[]", b"testing") 682 s = ffi.new("struct string*", [t]) 683 assert type(s.name) not in (bytes, str, unicode) 684 assert ffi.string(s.name) == b"testing" 685 with pytest.raises(TypeError): 686 s.name = None 687 s.name = ffi.NULL 688 assert s.name == ffi.NULL 689 690 def test_fetch_const_wchar_p_field(self): 691 # 'const' is ignored so far 692 self.check_wchar_t(ffi) 693 t = ffi.new("const wchar_t[]", u+"testing") 694 s = ffi.new("struct ustring*", [t]) 695 assert type(s.name) not in (bytes, str, unicode) 696 assert ffi.string(s.name) == u+"testing" 697 s.name = ffi.NULL 698 assert s.name == ffi.NULL 699 700 def test_voidp(self): 701 py.test.raises(TypeError, ffi.new, "void*") 702 p = ffi.new("void **") 703 assert p[0] == ffi.NULL 704 a = ffi.new("int[]", [10, 11, 12]) 705 p = ffi.new("void **", a) 706 vp = p[0] 707 with pytest.raises(TypeError): 708 vp[0] 709 py.test.raises(TypeError, ffi.new, "short **", a) 710 # 711 s = ffi.new("struct voidp *") 712 s.p = a # works 713 s.q = a # works 714 with pytest.raises(TypeError): 715 s.r = a # fails 716 b = ffi.cast("int *", a) 717 s.p = b # works 718 s.q = b # works 719 with pytest.raises(TypeError): 720 s.r = b # fails 721 722 def test_functionptr_simple(self): 723 py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) 724 def cb(n): 725 return n + 1 726 cb.__qualname__ = 'cb' 727 p = ffi.callback("int(*)(int)", cb) 728 res = p(41) # calling an 'int(*)(int)', i.e. a function pointer 729 assert res == 42 and type(res) is int 730 res = p(ffi.cast("int", -41)) 731 assert res == -40 and type(res) is int 732 assert repr(p).startswith( 733 "<cdata 'int(*)(int)' calling <function cb at 0x") 734 assert ffi.typeof(p) is ffi.typeof("int(*)(int)") 735 q = ffi.new("int(**)(int)", p) 736 assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % ( 737 SIZE_OF_PTR) 738 with pytest.raises(TypeError): 739 q(43) 740 res = q[0](43) 741 assert res == 44 742 q = ffi.cast("int(*)(int)", p) 743 assert repr(q).startswith("<cdata 'int(*)(int)' 0x") 744 res = q(45) 745 assert res == 46 746 747 def test_functionptr_advanced(self): 748 t = ffi.typeof("int(*(*)(int))(int)") 749 assert repr(t) == "<ctype '%s'>" % "int(*(*)(int))(int)" 750 751 def test_functionptr_voidptr_return(self): 752 def cb(): 753 return ffi.NULL 754 p = ffi.callback("void*(*)()", cb) 755 res = p() 756 assert res is not None 757 assert res == ffi.NULL 758 int_ptr = ffi.new('int*') 759 void_ptr = ffi.cast('void*', int_ptr) 760 def cb(): 761 return void_ptr 762 p = ffi.callback("void*(*)()", cb) 763 res = p() 764 assert res == void_ptr 765 766 def test_functionptr_intptr_return(self): 767 def cb(): 768 return ffi.NULL 769 p = ffi.callback("int*(*)()", cb) 770 res = p() 771 assert res == ffi.NULL 772 int_ptr = ffi.new('int*') 773 def cb(): 774 return int_ptr 775 p = ffi.callback("int*(*)()", cb) 776 res = p() 777 assert repr(res).startswith("<cdata 'int *' 0x") 778 assert res == int_ptr 779 int_array_ptr = ffi.new('int[1]') 780 def cb(): 781 return int_array_ptr 782 p = ffi.callback("int*(*)()", cb) 783 res = p() 784 assert repr(res).startswith("<cdata 'int *' 0x") 785 assert res == int_array_ptr 786 787 def test_functionptr_void_return(self): 788 def foo(): 789 pass 790 foo_cb = ffi.callback("void foo()", foo) 791 result = foo_cb() 792 assert result is None 793 794 def test_char_cast(self): 795 p = ffi.cast("int", b'\x01') 796 assert ffi.typeof(p) is ffi.typeof("int") 797 assert int(p) == 1 798 p = ffi.cast("int", ffi.cast("char", b"a")) 799 assert int(p) == ord("a") 800 p = ffi.cast("int", ffi.cast("char", b"\x80")) 801 assert int(p) == 0x80 # "char" is considered unsigned in this case 802 p = ffi.cast("int", b"\x81") 803 assert int(p) == 0x81 804 805 def test_wchar_cast(self): 806 self.check_wchar_t(ffi) 807 p = ffi.cast("int", ffi.cast("wchar_t", u+'\u1234')) 808 assert int(p) == 0x1234 809 p = ffi.cast("long long", ffi.cast("wchar_t", -1)) 810 if SIZE_OF_WCHAR == 2: # 2 bytes, unsigned 811 assert int(p) == 0xffff 812 elif (sys.platform.startswith('linux') and 813 platform.machine().startswith('x86')): # known to be signed 814 assert int(p) == -1 815 else: # in general, it can be either signed or not 816 assert int(p) in [-1, 0xffffffff] # e.g. on arm, both cases occur 817 p = ffi.cast("int", u+'\u1234') 818 assert int(p) == 0x1234 819 820 def test_cast_array_to_charp(self): 821 a = ffi.new("short int[]", [0x1234, 0x5678]) 822 p = ffi.cast("char*", a) 823 data = b''.join([p[i] for i in range(4)]) 824 if sys.byteorder == 'little': 825 assert data == b'\x34\x12\x78\x56' 826 else: 827 assert data == b'\x12\x34\x56\x78' 828 829 def test_cast_between_pointers(self): 830 a = ffi.new("short int[]", [0x1234, 0x5678]) 831 p = ffi.cast("short*", a) 832 p2 = ffi.cast("int*", p) 833 q = ffi.cast("char*", p2) 834 data = b''.join([q[i] for i in range(4)]) 835 if sys.byteorder == 'little': 836 assert data == b'\x34\x12\x78\x56' 837 else: 838 assert data == b'\x12\x34\x56\x78' 839 840 def test_cast_pointer_and_int(self): 841 a = ffi.new("short int[]", [0x1234, 0x5678]) 842 l1 = ffi.cast("intptr_t", a) 843 p = ffi.cast("short*", a) 844 l2 = ffi.cast("intptr_t", p) 845 assert int(l1) == int(l2) != 0 846 q = ffi.cast("short*", l1) 847 assert q == ffi.cast("short*", int(l1)) 848 assert q[0] == 0x1234 849 assert int(ffi.cast("intptr_t", ffi.NULL)) == 0 850 851 def test_cast_functionptr_and_int(self): 852 def cb(n): 853 return n + 1 854 a = ffi.callback("int(*)(int)", cb) 855 p = ffi.cast("void *", a) 856 assert p 857 b = ffi.cast("int(*)(int)", p) 858 assert b(41) == 42 859 assert a == b 860 assert hash(a) == hash(b) 861 862 def test_callback_crash(self): 863 def cb(n): 864 raise Exception 865 a = ffi.callback("int(*)(int)", cb, error=42) 866 res = a(1) # and the error reported to stderr 867 assert res == 42 868 869 def test_structptr_argument(self): 870 def cb(p): 871 return p[0].a * 1000 + p[0].b * 100 + p[1].a * 10 + p[1].b 872 a = ffi.callback("int(*)(struct ab[])", cb) 873 res = a([[5, 6], {'a': 7, 'b': 8}]) 874 assert res == 5678 875 res = a([[5], {'b': 8}]) 876 assert res == 5008 877 878 def test_array_argument_as_list(self): 879 seen = [] 880 def cb(argv): 881 seen.append(ffi.string(argv[0])) 882 seen.append(ffi.string(argv[1])) 883 a = ffi.callback("void(*)(char *[])", cb) 884 a([ffi.new("char[]", b"foobar"), ffi.new("char[]", b"baz")]) 885 assert seen == [b"foobar", b"baz"] 886 887 def test_cast_float(self): 888 a = ffi.cast("float", 12) 889 assert float(a) == 12.0 890 a = ffi.cast("float", 12.5) 891 assert float(a) == 12.5 892 a = ffi.cast("float", b"A") 893 assert float(a) == ord("A") 894 a = ffi.cast("int", 12.9) 895 assert int(a) == 12 896 a = ffi.cast("char", 66.9 + 256) 897 assert ffi.string(a) == b"B" 898 # 899 a = ffi.cast("float", ffi.cast("int", 12)) 900 assert float(a) == 12.0 901 a = ffi.cast("float", ffi.cast("double", 12.5)) 902 assert float(a) == 12.5 903 a = ffi.cast("float", ffi.cast("char", b"A")) 904 assert float(a) == ord("A") 905 a = ffi.cast("int", ffi.cast("double", 12.9)) 906 assert int(a) == 12 907 a = ffi.cast("char", ffi.cast("double", 66.9 + 256)) 908 assert ffi.string(a) == b"B" 909 910 def test_enum(self): 911 # enum foq { A0, B0, CC0, D0 }; 912 assert ffi.string(ffi.cast("enum foq", 0)) == "cffiA0" 913 assert ffi.string(ffi.cast("enum foq", 2)) == "cffiCC0" 914 assert ffi.string(ffi.cast("enum foq", 3)) == "cffiD0" 915 assert ffi.string(ffi.cast("enum foq", 4)) == "4" 916 # enum bar { A1, B1=-2, CC1, D1, E1 }; 917 assert ffi.string(ffi.cast("enum bar", 0)) == "A1" 918 assert ffi.string(ffi.cast("enum bar", -2)) == "B1" 919 assert ffi.string(ffi.cast("enum bar", -1)) == "CC1" 920 assert ffi.string(ffi.cast("enum bar", 1)) == "E1" 921 assert ffi.cast("enum bar", -2) == ffi.cast("enum bar", -2) 922 assert ffi.cast("enum foq", 0) == ffi.cast("enum bar", 0) 923 assert ffi.cast("enum bar", 0) == ffi.cast("int", 0) 924 assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>" 925 assert repr(ffi.cast("enum foq", -1)) == ( # enums are unsigned, if 926 "<cdata 'enum foq' 4294967295>") or ( # they contain no neg value 927 sys.platform == "win32") # (but not on msvc) 928 # enum baz { A2=0x1000, B2=0x2000 }; 929 assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A2" 930 assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B2" 931 932 def test_enum_in_struct(self): 933 # enum foo2 { A3, B3, C3, D3 }; 934 # struct bar_with_e { enum foo2 e; }; 935 s = ffi.new("struct bar_with_e *") 936 s.e = 0 937 assert s.e == 0 938 s.e = 3 939 assert s.e == 3 940 assert s[0].e == 3 941 s[0].e = 2 942 assert s.e == 2 943 assert s[0].e == 2 944 s.e = ffi.cast("enum foo2", -1) 945 assert s.e in (4294967295, -1) # two choices 946 assert s[0].e in (4294967295, -1) 947 s.e = s.e 948 with pytest.raises(TypeError): 949 s.e = 'B3' 950 with pytest.raises(TypeError): 951 s.e = '2' 952 with pytest.raises(TypeError): 953 s.e = '#2' 954 with pytest.raises(TypeError): 955 s.e = '#7' 956 957 def test_enum_non_contiguous(self): 958 # enum noncont { A4, B4=42, C4 }; 959 assert ffi.string(ffi.cast("enum noncont", 0)) == "A4" 960 assert ffi.string(ffi.cast("enum noncont", 42)) == "B4" 961 assert ffi.string(ffi.cast("enum noncont", 43)) == "C4" 962 invalid_value = ffi.cast("enum noncont", 2) 963 assert int(invalid_value) == 2 964 assert ffi.string(invalid_value) == "2" 965 966 def test_enum_char_hex_oct(self): 967 # enum etypes {A5='!', B5='\'', C5=0x10, D5=010, E5=- 0x10, F5=-010}; 968 assert ffi.string(ffi.cast("enum etypes", ord('!'))) == "A5" 969 assert ffi.string(ffi.cast("enum etypes", ord("'"))) == "B5" 970 assert ffi.string(ffi.cast("enum etypes", 16)) == "C5" 971 assert ffi.string(ffi.cast("enum etypes", 8)) == "D5" 972 assert ffi.string(ffi.cast("enum etypes", -16)) == "E5" 973 assert ffi.string(ffi.cast("enum etypes", -8)) == "F5" 974 975 def test_array_of_struct(self): 976 s = ffi.new("struct ab[1]") 977 with pytest.raises(AttributeError): 978 s.b 979 with pytest.raises(AttributeError): 980 s.b = 412 981 s[0].b = 412 982 assert s[0].b == 412 983 with pytest.raises(IndexError): 984 s[1] 985 986 def test_pointer_to_array(self): 987 p = ffi.new("int(**)[5]") 988 assert repr(p) == "<cdata 'int(* *)[5]' owning %d bytes>" % SIZE_OF_PTR 989 990 def test_iterate_array(self): 991 a = ffi.new("char[]", b"hello") 992 assert list(a) == [b"h", b"e", b"l", b"l", b"o", b"\0"] 993 assert list(iter(a)) == [b"h", b"e", b"l", b"l", b"o", b"\0"] 994 # 995 py.test.raises(TypeError, iter, ffi.cast("char *", a)) 996 py.test.raises(TypeError, list, ffi.cast("char *", a)) 997 py.test.raises(TypeError, iter, ffi.new("int *")) 998 py.test.raises(TypeError, list, ffi.new("int *")) 999 1000 def test_offsetof(self): 1001 # struct abc { int a, b, c; }; 1002 assert ffi.offsetof("struct abc", "a") == 0 1003 assert ffi.offsetof("struct abc", "b") == 4 1004 assert ffi.offsetof("struct abc", "c") == 8 1005 1006 def test_offsetof_nested(self): 1007 # struct nesting { struct abc d, e; }; 1008 assert ffi.offsetof("struct nesting", "e") == 12 1009 py.test.raises(KeyError, ffi.offsetof, "struct nesting", "e.a") 1010 assert ffi.offsetof("struct nesting", "e", "a") == 12 1011 assert ffi.offsetof("struct nesting", "e", "b") == 16 1012 assert ffi.offsetof("struct nesting", "e", "c") == 20 1013 1014 def test_offsetof_array(self): 1015 assert ffi.offsetof("int[]", 51) == 51 * ffi.sizeof("int") 1016 assert ffi.offsetof("int *", 51) == 51 * ffi.sizeof("int") 1017 # struct array2 { int a, b; int c[99]; }; 1018 assert ffi.offsetof("struct array2", "c") == 2 * ffi.sizeof("int") 1019 assert ffi.offsetof("struct array2", "c", 0) == 2 * ffi.sizeof("int") 1020 assert ffi.offsetof("struct array2", "c", 51) == 53 * ffi.sizeof("int") 1021 1022 def test_alignof(self): 1023 # struct align { char a; short b; char c; }; 1024 assert ffi.alignof("int") == 4 1025 assert ffi.alignof("double") in (4, 8) 1026 assert ffi.alignof("struct align") == 2 1027 1028 def test_bitfield(self): 1029 # struct bitfield { int a:10, b:20, c:3; }; 1030 assert ffi.sizeof("struct bitfield") == 8 1031 s = ffi.new("struct bitfield *") 1032 s.a = 511 1033 with pytest.raises(OverflowError): 1034 s.a = 512 1035 with pytest.raises(OverflowError): 1036 s[0].a = 512 1037 assert s.a == 511 1038 s.a = -512 1039 with pytest.raises(OverflowError): 1040 s.a = -513 1041 with pytest.raises(OverflowError): 1042 s[0].a = -513 1043 assert s.a == -512 1044 s.c = 3 1045 assert s.c == 3 1046 with pytest.raises(OverflowError): 1047 s.c = 4 1048 with pytest.raises(OverflowError): 1049 s[0].c = 4 1050 s.c = -4 1051 assert s.c == -4 1052 1053 def test_bitfield_enum(self): 1054 # typedef enum { AA1, BB1, CC1 } foo_e_t; 1055 # typedef struct { foo_e_t f:2; } bfenum_t; 1056 if sys.platform == "win32": 1057 py.test.skip("enums are not unsigned") 1058 s = ffi.new("bfenum_t *") 1059 s.f = 2 1060 assert s.f == 2 1061 1062 def test_anonymous_struct(self): 1063 # typedef struct { int a; } anon_foo_t; 1064 # typedef struct { char b, c; } anon_bar_t; 1065 f = ffi.new("anon_foo_t *", [12345]) 1066 b = ffi.new("anon_bar_t *", [b"B", b"C"]) 1067 assert f.a == 12345 1068 assert b.b == b"B" 1069 assert b.c == b"C" 1070 assert repr(b).startswith("<cdata 'anon_bar_t *'") 1071 1072 def test_struct_with_two_usages(self): 1073 # typedef struct named_foo_s { int a; } named_foo_t, *named_foo_p; 1074 # typedef struct { int a; } unnamed_foo_t, *unnamed_foo_p; 1075 f = ffi.new("named_foo_t *", [12345]) 1076 ps = ffi.new("named_foo_p[]", [f]) 1077 f = ffi.new("unnamed_foo_t *", [12345]) 1078 ps = ffi.new("unnamed_foo_p[]", [f]) 1079 1080 def test_pointer_arithmetic(self): 1081 s = ffi.new("short[]", list(range(100, 110))) 1082 p = ffi.cast("short *", s) 1083 assert p[2] == 102 1084 assert p+1 == p+1 1085 assert p+1 != p+0 1086 assert p == p+0 == p-0 1087 assert (p+1)[0] == 101 1088 assert (p+19)[-10] == 109 1089 assert (p+5) - (p+1) == 4 1090 assert p == s+0 1091 assert p+1 == s+1 1092 1093 def test_pointer_comparison(self): 1094 s = ffi.new("short[]", list(range(100))) 1095 p = ffi.cast("short *", s) 1096 assert (p < s) is False 1097 assert (p <= s) is True 1098 assert (p == s) is True 1099 assert (p != s) is False 1100 assert (p > s) is False 1101 assert (p >= s) is True 1102 assert (s < p) is False 1103 assert (s <= p) is True 1104 assert (s == p) is True 1105 assert (s != p) is False 1106 assert (s > p) is False 1107 assert (s >= p) is True 1108 q = p + 1 1109 assert (q < s) is False 1110 assert (q <= s) is False 1111 assert (q == s) is False 1112 assert (q != s) is True 1113 assert (q > s) is True 1114 assert (q >= s) is True 1115 assert (s < q) is True 1116 assert (s <= q) is True 1117 assert (s == q) is False 1118 assert (s != q) is True 1119 assert (s > q) is False 1120 assert (s >= q) is False 1121 assert (q < p) is False 1122 assert (q <= p) is False 1123 assert (q == p) is False 1124 assert (q != p) is True 1125 assert (q > p) is True 1126 assert (q >= p) is True 1127 assert (p < q) is True 1128 assert (p <= q) is True 1129 assert (p == q) is False 1130 assert (p != q) is True 1131 assert (p > q) is False 1132 assert (p >= q) is False 1133 # 1134 assert (None == s) is False 1135 assert (None != s) is True 1136 assert (s == None) is False 1137 assert (s != None) is True 1138 assert (None == q) is False 1139 assert (None != q) is True 1140 assert (q == None) is False 1141 assert (q != None) is True 1142 1143 def test_integer_comparison(self): 1144 x = ffi.cast("int", 123) 1145 y = ffi.cast("int", 456) 1146 assert x < y 1147 # 1148 z = ffi.cast("double", 78.9) 1149 assert x > z 1150 assert y > z 1151 1152 def test_ffi_buffer_ptr(self): 1153 a = ffi.new("short *", 100) 1154 try: 1155 b = ffi.buffer(a) 1156 except NotImplementedError as e: 1157 py.test.skip(str(e)) 1158 content = b[:] 1159 assert len(content) == len(b) == 2 1160 if sys.byteorder == 'little': 1161 assert content == b'\x64\x00' 1162 assert b[0] == b'\x64' 1163 b[0] = b'\x65' 1164 else: 1165 assert content == b'\x00\x64' 1166 assert b[1] == b'\x64' 1167 b[1] = b'\x65' 1168 assert a[0] == 101 1169 1170 def test_ffi_buffer_array(self): 1171 a = ffi.new("int[]", list(range(100, 110))) 1172 try: 1173 b = ffi.buffer(a) 1174 except NotImplementedError as e: 1175 py.test.skip(str(e)) 1176 content = b[:] 1177 if sys.byteorder == 'little': 1178 assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') 1179 b[4] = b'\x45' 1180 else: 1181 assert content.startswith(b'\x00\x00\x00\x64\x00\x00\x00\x65') 1182 b[7] = b'\x45' 1183 assert len(content) == 4 * 10 1184 assert a[1] == 0x45 1185 1186 def test_ffi_buffer_ptr_size(self): 1187 a = ffi.new("short *", 0x4243) 1188 try: 1189 b = ffi.buffer(a, 1) 1190 except NotImplementedError as e: 1191 py.test.skip(str(e)) 1192 content = b[:] 1193 assert len(content) == 1 1194 if sys.byteorder == 'little': 1195 assert content == b'\x43' 1196 b[0] = b'\x62' 1197 assert a[0] == 0x4262 1198 else: 1199 assert content == b'\x42' 1200 b[0] = b'\x63' 1201 assert a[0] == 0x6343 1202 1203 def test_ffi_buffer_array_size(self): 1204 a1 = ffi.new("int[]", list(range(100, 110))) 1205 a2 = ffi.new("int[]", list(range(100, 115))) 1206 try: 1207 ffi.buffer(a1) 1208 except NotImplementedError as e: 1209 py.test.skip(str(e)) 1210 assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:] 1211 1212 def test_ffi_buffer_with_file(self): 1213 import tempfile, os, array 1214 fd, filename = tempfile.mkstemp() 1215 f = os.fdopen(fd, 'r+b') 1216 a = ffi.new("int[]", list(range(1005))) 1217 try: 1218 ffi.buffer(a, 512) 1219 except NotImplementedError as e: 1220 py.test.skip(str(e)) 1221 f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) 1222 f.seek(0) 1223 assert f.read() == arraytostring(array.array('i', range(1000))) 1224 f.seek(0) 1225 b = ffi.new("int[]", 1005) 1226 f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) 1227 assert list(a)[:1000] + [0] * (len(a)-1000) == list(b) 1228 f.close() 1229 os.unlink(filename) 1230 1231 def test_ffi_buffer_with_io(self): 1232 import io, array 1233 f = io.BytesIO() 1234 a = ffi.new("int[]", list(range(1005))) 1235 try: 1236 ffi.buffer(a, 512) 1237 except NotImplementedError as e: 1238 py.test.skip(str(e)) 1239 f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) 1240 f.seek(0) 1241 assert f.read() == arraytostring(array.array('i', range(1000))) 1242 f.seek(0) 1243 b = ffi.new("int[]", 1005) 1244 f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) 1245 assert list(a)[:1000] + [0] * (len(a)-1000) == list(b) 1246 f.close() 1247 1248 def test_array_in_struct(self): 1249 # struct array { int a[2]; char b[3]; }; 1250 p = ffi.new("struct array *") 1251 p.a[1] = 5 1252 assert p.a[1] == 5 1253 assert repr(p.a).startswith("<cdata 'int[2]' 0x") 1254 1255 def test_struct_containing_array_varsize_workaround(self): 1256 if sys.platform == "win32": 1257 py.test.skip("array of length 0 not supported") 1258 # struct array0 { int len; short data[0]; }; 1259 p = ffi.new("char[]", ffi.sizeof("struct array0") + 7 * SIZE_OF_SHORT) 1260 q = ffi.cast("struct array0 *", p) 1261 assert q.len == 0 1262 # 'q.data' gets not a 'short[0]', but just a 'short *' instead 1263 assert repr(q.data).startswith("<cdata 'short *' 0x") 1264 assert q.data[6] == 0 1265 q.data[6] = 15 1266 assert q.data[6] == 15 1267 1268 def test_new_struct_containing_array_varsize(self): 1269 py.test.skip("later?") 1270 ffi.cdef("struct foo_s { int len; short data[]; };") 1271 p = ffi.new("struct foo_s *", 10) # a single integer is the length 1272 assert p.len == 0 1273 assert p.data[9] == 0 1274 with pytest.raises(IndexError): 1275 p.data[10] 1276 1277 def test_ffi_typeof_getcname(self): 1278 assert ffi.getctype("int") == "int" 1279 assert ffi.getctype("int", 'x') == "int x" 1280 assert ffi.getctype("int*") == "int *" 1281 assert ffi.getctype("int*", '') == "int *" 1282 assert ffi.getctype("int*", 'x') == "int * x" 1283 assert ffi.getctype("int", '*') == "int *" 1284 assert ffi.getctype("int", ' * x ') == "int * x" 1285 assert ffi.getctype(ffi.typeof("int*"), '*') == "int * *" 1286 assert ffi.getctype("int", '[5]') == "int[5]" 1287 assert ffi.getctype("int[5]", '[6]') == "int[6][5]" 1288 assert ffi.getctype("int[5]", '(*)') == "int(*)[5]" 1289 # special-case for convenience: automatically put '()' around '*' 1290 assert ffi.getctype("int[5]", '*') == "int(*)[5]" 1291 assert ffi.getctype("int[5]", '*foo') == "int(*foo)[5]" 1292 assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]" 1293 1294 def test_array_of_func_ptr(self): 1295 f = ffi.cast("int(*)(int)", 42) 1296 assert f != ffi.NULL 1297 py.test.raises(ffi.error, ffi.cast, "int(int)", 42) 1298 py.test.raises(ffi.error, ffi.new, "int([5])(int)") 1299 a = ffi.new("int(*[5])(int)", [f]) 1300 assert ffi.getctype(ffi.typeof(a)) == "int(*[5])(int)" 1301 assert len(a) == 5 1302 assert a[0] == f 1303 assert a[1] == ffi.NULL 1304 py.test.raises(TypeError, ffi.cast, "int(*)(int)[5]", 0) 1305 # 1306 def cb(n): 1307 return n + 1 1308 f = ffi.callback("int(*)(int)", cb) 1309 a = ffi.new("int(*[5])(int)", [f, f]) 1310 assert a[1](42) == 43 1311 1312 def test_callback_as_function_argument(self): 1313 # In C, function arguments can be declared with a function type, 1314 # which is automatically replaced with the ptr-to-function type. 1315 def cb(a, b): 1316 return chr(ord(a) + ord(b)).encode() 1317 f = ffi.callback("char cb(char, char)", cb) 1318 assert f(b'A', b'\x01') == b'B' 1319 def g(callback): 1320 return callback(b'A', b'\x01') 1321 g = ffi.callback("char g(char cb(char, char))", g) 1322 assert g(f) == b'B' 1323 1324 def test_vararg_callback(self): 1325 py.test.skip("callback with '...'") 1326 def cb(i, va_list): 1327 j = ffi.va_arg(va_list, "int") 1328 k = ffi.va_arg(va_list, "long long") 1329 return i * 2 + j * 3 + k * 5 1330 f = ffi.callback("long long cb(long i, ...)", cb) 1331 res = f(10, ffi.cast("int", 100), ffi.cast("long long", 1000)) 1332 assert res == 20 + 300 + 5000 1333 1334 def test_callback_decorator(self): 1335 # 1336 @ffi.callback("long(long, long)", error=42) 1337 def cb(a, b): 1338 return a - b 1339 # 1340 assert cb(-100, -10) == -90 1341 sz = ffi.sizeof("long") 1342 assert cb((1 << (sz*8-1)) - 1, -10) == 42 1343 1344 def test_anonymous_enum(self): 1345 # typedef enum { Value0 = 0 } e_t, *pe_t; 1346 assert ffi.getctype("e_t*") == 'e_t *' 1347 assert ffi.getctype("pe_t") == 'e_t *' 1348 assert ffi.getctype("foo_e_t*") == 'foo_e_t *' 1349 1350 def test_new_ctype(self): 1351 p = ffi.new("int *") 1352 py.test.raises(TypeError, ffi.new, p) 1353 p = ffi.new(ffi.typeof("int *"), 42) 1354 assert p[0] == 42 1355 1356 def test_enum_with_non_injective_mapping(self): 1357 # enum e_noninj { AA3=0, BB3=0, CC3=0, DD3=0 }; 1358 e = ffi.cast("enum e_noninj", 0) 1359 assert ffi.string(e) == "AA3" # pick the first one arbitrarily 1360 1361 def test_enum_refer_previous_enum_value(self): 1362 # enum e_prev { AA4, BB4=2, CC4=4, DD4=BB4, EE4, FF4=CC4, GG4=FF4 }; 1363 assert ffi.string(ffi.cast("enum e_prev", 2)) == "BB4" 1364 assert ffi.string(ffi.cast("enum e_prev", 3)) == "EE4" 1365 assert ffi.sizeof("char[DD4]") == 2 1366 assert ffi.sizeof("char[EE4]") == 3 1367 assert ffi.sizeof("char[FF4]") == 4 1368 assert ffi.sizeof("char[GG4]") == 4 1369 1370 def test_nested_anonymous_struct(self): 1371 # struct nested_anon { 1372 # struct { int a, b; }; 1373 # union { int c, d; }; 1374 # }; 1375 assert ffi.sizeof("struct nested_anon") == 3 * SIZE_OF_INT 1376 p = ffi.new("struct nested_anon *", [1, 2, 3]) 1377 assert p.a == 1 1378 assert p.b == 2 1379 assert p.c == 3 1380 assert p.d == 3 1381 p.d = 17 1382 assert p.c == 17 1383 p.b = 19 1384 assert p.a == 1 1385 assert p.b == 19 1386 assert p.c == 17 1387 assert p.d == 17 1388 p = ffi.new("struct nested_anon *", {'b': 12, 'd': 14}) 1389 assert p.a == 0 1390 assert p.b == 12 1391 assert p.c == 14 1392 assert p.d == 14 1393 1394 def test_nested_field_offset_align(self): 1395 # struct nested_field_ofs_s { 1396 # struct { int a; char b; }; 1397 # union { char c; }; 1398 # }; 1399 assert ffi.offsetof("struct nested_field_ofs_s", "c") == 2 * SIZE_OF_INT 1400 assert ffi.sizeof("struct nested_field_ofs_s") == 3 * SIZE_OF_INT 1401 1402 def test_nested_anonymous_union(self): 1403 # union nested_anon_u { 1404 # struct { int a, b; }; 1405 # union { int c, d; }; 1406 # }; 1407 assert ffi.sizeof("union nested_anon_u") == 2 * SIZE_OF_INT 1408 p = ffi.new("union nested_anon_u *", [5]) 1409 assert p.a == 5 1410 assert p.b == 0 1411 assert p.c == 5 1412 assert p.d == 5 1413 p.d = 17 1414 assert p.c == 17 1415 assert p.a == 17 1416 p.b = 19 1417 assert p.a == 17 1418 assert p.b == 19 1419 assert p.c == 17 1420 assert p.d == 17 1421 p = ffi.new("union nested_anon_u *", {'d': 14}) 1422 assert p.a == 14 1423 assert p.b == 0 1424 assert p.c == 14 1425 assert p.d == 14 1426 p = ffi.new("union nested_anon_u *", {'b': 12}) 1427 assert p.a == 0 1428 assert p.b == 12 1429 assert p.c == 0 1430 assert p.d == 0 1431 # we cannot specify several items in the dict, even though 1432 # in theory in this particular case it would make sense 1433 # to give both 'a' and 'b' 1434 1435 def test_cast_to_array_type(self): 1436 p = ffi.new("int[4]", [-5]) 1437 q = ffi.cast("int[3]", p) 1438 assert q[0] == -5 1439 assert repr(q).startswith("<cdata 'int[3]' 0x") 1440 1441 def test_gc(self): 1442 p = ffi.new("int *", 123) 1443 seen = [] 1444 def destructor(p1): 1445 assert p1 is p 1446 assert p1[0] == 123 1447 seen.append(1) 1448 q = ffi.gc(p, destructor=destructor) 1449 import gc; gc.collect() 1450 assert seen == [] 1451 del q 1452 import gc; gc.collect(); gc.collect(); gc.collect() 1453 assert seen == [1] 1454 1455 def test_gc_2(self): 1456 p = ffi.new("int *", 123) 1457 seen = [] 1458 q1 = ffi.gc(p, lambda p: seen.append(1)) 1459 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1460 import gc; gc.collect() 1461 assert seen == [] 1462 del q1, q2 1463 import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() 1464 assert seen == [2, 1] 1465 1466 def test_gc_3(self): 1467 p = ffi.new("int *", 123) 1468 r = ffi.new("int *", 123) 1469 seen = [] 1470 seen_r = [] 1471 q1 = ffi.gc(p, lambda p: seen.append(1)) 1472 s1 = ffi.gc(r, lambda r: seen_r.append(4)) 1473 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1474 s2 = ffi.gc(s1, lambda r: seen_r.append(5)) 1475 q3 = ffi.gc(q2, lambda p: seen.append(3)) 1476 import gc; gc.collect() 1477 assert seen == [] 1478 assert seen_r == [] 1479 del q1, q2, q3, s2, s1 1480 import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() 1481 assert seen == [3, 2, 1] 1482 assert seen_r == [5, 4] 1483 1484 def test_gc_4(self): 1485 p = ffi.new("int *", 123) 1486 seen = [] 1487 q1 = ffi.gc(p, lambda p: seen.append(1)) 1488 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1489 q3 = ffi.gc(q2, lambda p: seen.append(3)) 1490 import gc; gc.collect() 1491 assert seen == [] 1492 del q1, q3 # q2 remains, and has a hard ref to q1 1493 import gc; gc.collect(); gc.collect(); gc.collect() 1494 assert seen == [3] 1495 1496 def test_release(self): 1497 p = ffi.new("int[]", 123) 1498 ffi.release(p) 1499 # here, reading p[0] might give garbage or segfault... 1500 ffi.release(p) # no effect 1501 1502 def test_release_new_allocator(self): 1503 seen = [] 1504 def myalloc(size): 1505 seen.append(size) 1506 return ffi.new("char[]", b"X" * size) 1507 def myfree(raw): 1508 seen.append(raw) 1509 alloc2 = ffi.new_allocator(alloc=myalloc, free=myfree) 1510 p = alloc2("int[]", 15) 1511 assert seen == [15 * 4] 1512 ffi.release(p) 1513 assert seen == [15 * 4, p] 1514 ffi.release(p) # no effect 1515 assert seen == [15 * 4, p] 1516 # 1517 del seen[:] 1518 p = alloc2("struct ab *") 1519 assert seen == [2 * 4] 1520 ffi.release(p) 1521 assert seen == [2 * 4, p] 1522 ffi.release(p) # no effect 1523 assert seen == [2 * 4, p] 1524 1525 def test_CData_CType(self): 1526 assert isinstance(ffi.cast("int", 0), ffi.CData) 1527 assert isinstance(ffi.new("int *"), ffi.CData) 1528 assert not isinstance(ffi.typeof("int"), ffi.CData) 1529 assert not isinstance(ffi.cast("int", 0), ffi.CType) 1530 assert not isinstance(ffi.new("int *"), ffi.CType) 1531 1532 def test_CData_CType_2(self): 1533 assert isinstance(ffi.typeof("int"), ffi.CType) 1534 1535 def test_bool(self): 1536 assert int(ffi.cast("_Bool", 0.1)) == 1 1537 assert int(ffi.cast("_Bool", -0.0)) == 0 1538 assert int(ffi.cast("_Bool", b'\x02')) == 1 1539 assert int(ffi.cast("_Bool", b'\x00')) == 0 1540 assert int(ffi.cast("_Bool", b'\x80')) == 1 1541 assert ffi.new("_Bool *", False)[0] == 0 1542 assert ffi.new("_Bool *", 1)[0] == 1 1543 py.test.raises(OverflowError, ffi.new, "_Bool *", 2) 1544 py.test.raises(TypeError, ffi.string, ffi.cast("_Bool", 2)) 1545 1546 def test_addressof(self): 1547 p = ffi.new("struct ab *") 1548 a = ffi.addressof(p[0]) 1549 assert repr(a).startswith("<cdata 'struct ab *' 0x") 1550 assert a == p 1551 py.test.raises(TypeError, ffi.addressof, p) 1552 py.test.raises((AttributeError, TypeError), ffi.addressof, 5) 1553 py.test.raises(TypeError, ffi.addressof, ffi.cast("int", 5)) 1554 1555 def test_addressof_field(self): 1556 p = ffi.new("struct ab *") 1557 b = ffi.addressof(p[0], 'b') 1558 assert repr(b).startswith("<cdata 'int *' 0x") 1559 assert int(ffi.cast("uintptr_t", b)) == ( 1560 int(ffi.cast("uintptr_t", p)) + ffi.sizeof("int")) 1561 assert b == ffi.addressof(p, 'b') 1562 assert b != ffi.addressof(p, 'a') 1563 1564 def test_addressof_field_nested(self): 1565 # struct nesting { struct abc d, e; }; 1566 p = ffi.new("struct nesting *") 1567 py.test.raises(KeyError, ffi.addressof, p[0], 'e.b') 1568 a = ffi.addressof(p[0], 'e', 'b') 1569 assert int(ffi.cast("uintptr_t", a)) == ( 1570 int(ffi.cast("uintptr_t", p)) + 1571 ffi.sizeof("struct abc") + ffi.sizeof("int")) 1572 1573 def test_addressof_anonymous_struct(self): 1574 # typedef struct { int a; } anon_foo_t; 1575 p = ffi.new("anon_foo_t *") 1576 a = ffi.addressof(p[0]) 1577 assert a == p 1578 1579 def test_addressof_array(self): 1580 p = ffi.new("int[52]") 1581 p0 = ffi.addressof(p) 1582 assert p0 == p 1583 assert ffi.typeof(p0) is ffi.typeof("int(*)[52]") 1584 py.test.raises(TypeError, ffi.addressof, p0) 1585 # 1586 p1 = ffi.addressof(p, 25) 1587 assert ffi.typeof(p1) is ffi.typeof("int *") 1588 assert (p1 - p) == 25 1589 assert ffi.addressof(p, 0) == p 1590 1591 def test_addressof_pointer(self): 1592 array = ffi.new("int[50]") 1593 p = ffi.cast("int *", array) 1594 py.test.raises(TypeError, ffi.addressof, p) 1595 assert ffi.addressof(p, 0) == p 1596 assert ffi.addressof(p, 25) == p + 25 1597 assert ffi.typeof(ffi.addressof(p, 25)) == ffi.typeof(p) 1598 # 1599 array = ffi.new("struct ab[50]") 1600 p = ffi.cast("int *", array) 1601 py.test.raises(TypeError, ffi.addressof, p) 1602 assert ffi.addressof(p, 0) == p 1603 assert ffi.addressof(p, 25) == p + 25 1604 assert ffi.typeof(ffi.addressof(p, 25)) == ffi.typeof(p) 1605 1606 def test_addressof_array_in_struct(self): 1607 # struct abc50 { int a, b; int c[50]; }; 1608 p = ffi.new("struct abc50 *") 1609 p1 = ffi.addressof(p, "c", 25) 1610 assert ffi.typeof(p1) is ffi.typeof("int *") 1611 assert p1 == ffi.cast("int *", p) + 27 1612 assert ffi.addressof(p, "c") == ffi.cast("int *", p) + 2 1613 assert ffi.addressof(p, "c", 0) == ffi.cast("int *", p) + 2 1614 p2 = ffi.addressof(p, 1) 1615 assert ffi.typeof(p2) is ffi.typeof("struct abc50 *") 1616 assert p2 == p + 1 1617 1618 def test_multiple_independent_structs(self): 1619 CDEF2 = "struct ab { int x; };" 1620 ffi2 = cffi.FFI(); ffi2.cdef(CDEF2) 1621 outputfilename = recompile(ffi2, "test_multiple_independent_structs", 1622 CDEF2, tmpdir=str(udir)) 1623 module = imp.load_dynamic("test_multiple_independent_structs", 1624 outputfilename) 1625 ffi1 = module.ffi 1626 foo1 = ffi1.new("struct ab *", [10]) 1627 foo2 = ffi .new("struct ab *", [20, 30]) 1628 assert foo1.x == 10 1629 assert foo2.a == 20 1630 assert foo2.b == 30 1631 1632 def test_include_struct_union_enum_typedef(self): 1633 ffi1, CCODE = construction_params 1634 ffi2 = cffi.FFI() 1635 ffi2.include(ffi1) 1636 outputfilename = recompile(ffi2, 1637 "test_include_struct_union_enum_typedef", 1638 CCODE, tmpdir=str(udir)) 1639 module = imp.load_dynamic("test_include_struct_union_enum_typedef", 1640 outputfilename) 1641 ffi2 = module.ffi 1642 # 1643 p = ffi2.new("struct nonpacked *", [b'A', -43141]) 1644 assert p.a == b'A' 1645 assert p.b == -43141 1646 # 1647 p = ffi.new("union simple_u *", [-52525]) 1648 assert p.a == -52525 1649 # 1650 p = ffi.cast("enum foq", 2) 1651 assert ffi.string(p) == "cffiCC0" 1652 assert ffi2.sizeof("char[cffiCC0]") == 2 1653 # 1654 p = ffi.new("anon_foo_t *", [-52526]) 1655 assert p.a == -52526 1656 p = ffi.new("named_foo_p", [-52527]) 1657 assert p.a == -52527 1658 1659 def test_struct_packed(self): 1660 # struct nonpacked { char a; int b; }; 1661 # struct is_packed { char a; int b; } __attribute__((packed)); 1662 assert ffi.sizeof("struct nonpacked") == 8 1663 assert ffi.sizeof("struct is_packed") == 5 1664 assert ffi.alignof("struct nonpacked") == 4 1665 assert ffi.alignof("struct is_packed") == 1 1666 s = ffi.new("struct is_packed[2]") 1667 s[0].b = 42623381 1668 s[0].a = b'X' 1669 s[1].b = -4892220 1670 s[1].a = b'Y' 1671 assert s[0].b == 42623381 1672 assert s[0].a == b'X' 1673 assert s[1].b == -4892220 1674 assert s[1].a == b'Y' 1675 1676 def test_not_supported_bitfield_in_result(self): 1677 # struct ints_and_bitfield { int a,b,c,d,e; int x:1; }; 1678 e = py.test.raises(NotImplementedError, ffi.callback, 1679 "struct ints_and_bitfield foo(void)", lambda: 42) 1680 assert str(e.value) == ("struct ints_and_bitfield(*)(): " 1681 "callback with unsupported argument or return type or with '...'") 1682 1683 def test_inspecttype(self): 1684 assert ffi.typeof("long").kind == "primitive" 1685 assert ffi.typeof("long(*)(long, long**, ...)").cname == ( 1686 "long(*)(long, long * *, ...)") 1687 assert ffi.typeof("long(*)(long, long**, ...)").ellipsis is True 1688 1689 def test_new_handle(self): 1690 o = [2, 3, 4] 1691 p = ffi.new_handle(o) 1692 assert ffi.typeof(p) == ffi.typeof("void *") 1693 assert ffi.from_handle(p) is o 1694 assert ffi.from_handle(ffi.cast("char *", p)) is o 1695 py.test.raises(RuntimeError, ffi.from_handle, ffi.NULL) 1696 1697 def test_struct_array_no_length(self): 1698 # struct array_no_length { int x; int a[]; }; 1699 p = ffi.new("struct array_no_length *", [100, [200, 300, 400]]) 1700 assert p.x == 100 1701 assert ffi.typeof(p.a) is ffi.typeof("int[]") # length available 1702 assert p.a[0] == 200 1703 assert p.a[1] == 300 1704 assert p.a[2] == 400 1705 assert len(p.a) == 3 1706 assert list(p.a) == [200, 300, 400] 1707 q = ffi.cast("struct array_no_length *", p) 1708 assert ffi.typeof(q.a) is ffi.typeof("int *") # no length available 1709 assert q.a[0] == 200 1710 assert q.a[1] == 300 1711 assert q.a[2] == 400 1712 py.test.raises(TypeError, len, q.a) 1713 py.test.raises(TypeError, list, q.a) 1714 1715 def test_all_primitives(self): 1716 assert set(PRIMITIVE_TO_INDEX) == set([ 1717 "char", 1718 "short", 1719 "int", 1720 "long", 1721 "long long", 1722 "signed char", 1723 "unsigned char", 1724 "unsigned short", 1725 "unsigned int", 1726 "unsigned long", 1727 "unsigned long long", 1728 "float", 1729 "double", 1730 "long double", 1731 "wchar_t", 1732 "char16_t", 1733 "char32_t", 1734 "_Bool", 1735 "int8_t", 1736 "uint8_t", 1737 "int16_t", 1738 "uint16_t", 1739 "int32_t", 1740 "uint32_t", 1741 "int64_t", 1742 "uint64_t", 1743 "int_least8_t", 1744 "uint_least8_t", 1745 "int_least16_t", 1746 "uint_least16_t", 1747 "int_least32_t", 1748 "uint_least32_t", 1749 "int_least64_t", 1750 "uint_least64_t", 1751 "int_fast8_t", 1752 "uint_fast8_t", 1753 "int_fast16_t", 1754 "uint_fast16_t", 1755 "int_fast32_t", 1756 "uint_fast32_t", 1757 "int_fast64_t", 1758 "uint_fast64_t", 1759 "intptr_t", 1760 "uintptr_t", 1761 "intmax_t", 1762 "uintmax_t", 1763 "ptrdiff_t", 1764 "size_t", 1765 "ssize_t", 1766 'float _Complex', 1767 'double _Complex', 1768 ]) 1769 for name in PRIMITIVE_TO_INDEX: 1770 x = ffi.sizeof(name) 1771 assert 1 <= x <= 16 1772 1773 def test_emit_c_code(self): 1774 ffi = cffi.FFI() 1775 ffi.set_source("foobar", "??") 1776 c_file = str(udir.join('test_emit_c_code')) 1777 ffi.emit_c_code(c_file) 1778 assert os.path.isfile(c_file) 1779 1780 def test_import_from_lib(self): 1781 ffi2 = cffi.FFI() 1782 ffi2.cdef("int myfunc(int); extern int myvar;\n#define MYFOO ...\n") 1783 outputfilename = recompile(ffi2, "_test_import_from_lib", 1784 "int myfunc(int x) { return x + 1; }\n" 1785 "int myvar = -5;\n" 1786 "#define MYFOO 42", tmpdir=str(udir)) 1787 imp.load_dynamic("_test_import_from_lib", outputfilename) 1788 from _test_import_from_lib.lib import myfunc, myvar, MYFOO 1789 assert MYFOO == 42 1790 assert myfunc(43) == 44 1791 assert myvar == -5 # but can't be changed, so not very useful 1792 with pytest.raises(ImportError): 1793 from _test_import_from_lib.lib import bar 1794 d = {} 1795 exec("from _test_import_from_lib.lib import *", d) 1796 assert (set(key for key in d if not key.startswith('_')) == 1797 set(['myfunc', 'MYFOO'])) 1798 # 1799 # also test "import *" on the module itself, which should be 1800 # equivalent to "import ffi, lib" 1801 d = {} 1802 exec("from _test_import_from_lib import *", d) 1803 assert (sorted([x for x in d.keys() if not x.startswith('__')]) == 1804 ['ffi', 'lib']) 1805 1806 def test_char16_t(self): 1807 x = ffi.new("char16_t[]", 5) 1808 assert len(x) == 5 and ffi.sizeof(x) == 10 1809 x[2] = u+'\u1324' 1810 assert x[2] == u+'\u1324' 1811 y = ffi.new("char16_t[]", u+'\u1234\u5678') 1812 assert len(y) == 3 1813 assert list(y) == [u+'\u1234', u+'\u5678', u+'\x00'] 1814 assert ffi.string(y) == u+'\u1234\u5678' 1815 z = ffi.new("char16_t[]", u+'\U00012345') 1816 assert len(z) == 3 1817 assert list(z) == [u+'\ud808', u+'\udf45', u+'\x00'] 1818 assert ffi.string(z) == u+'\U00012345' 1819 1820 def test_char32_t(self): 1821 x = ffi.new("char32_t[]", 5) 1822 assert len(x) == 5 and ffi.sizeof(x) == 20 1823 x[3] = u+'\U00013245' 1824 assert x[3] == u+'\U00013245' 1825 y = ffi.new("char32_t[]", u+'\u1234\u5678') 1826 assert len(y) == 3 1827 assert list(y) == [u+'\u1234', u+'\u5678', u+'\x00'] 1828 z = ffi.new("char32_t[]", u+'\U00012345') 1829 assert len(z) == 2 1830 assert list(z) == [u+'\U00012345', u+'\x00'] # maybe a 2-unichars strin 1831 assert ffi.string(z) == u+'\U00012345' 1832