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