1import py 2def _setup_path(): 3 import os, sys 4 if '__pypy__' in sys.builtin_module_names: 5 py.test.skip("_cffi_backend.c: not tested on top of pypy, " 6 "use pypy/module/_cffi_backend/test/ instead.") 7 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) 8_setup_path() 9from _cffi_backend import * 10from _cffi_backend import _testfunc, _get_types, _get_common_types, __version__ 11 12# ____________________________________________________________ 13 14import sys 15assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" 16 " of cffi that differs from the one that we" 17 " get from 'import _cffi_backend'") 18if sys.version_info < (3,): 19 type_or_class = "type" 20 mandatory_b_prefix = '' 21 mandatory_u_prefix = 'u' 22 bytechr = chr 23 bitem2bchr = lambda x: x 24 class U(object): 25 def __add__(self, other): 26 return eval('u'+repr(other).replace(r'\\u', r'\u') 27 .replace(r'\\U', r'\U')) 28 u = U() 29 str2bytes = str 30 strict_compare = False 31else: 32 type_or_class = "class" 33 long = int 34 unicode = str 35 unichr = chr 36 mandatory_b_prefix = 'b' 37 mandatory_u_prefix = '' 38 bytechr = lambda n: bytes([n]) 39 bitem2bchr = bytechr 40 u = "" 41 str2bytes = lambda s: bytes(s, "ascii") 42 strict_compare = True 43 44def size_of_int(): 45 BInt = new_primitive_type("int") 46 return sizeof(BInt) 47 48def size_of_long(): 49 BLong = new_primitive_type("long") 50 return sizeof(BLong) 51 52def size_of_ptr(): 53 BInt = new_primitive_type("int") 54 BPtr = new_pointer_type(BInt) 55 return sizeof(BPtr) 56 57 58def find_and_load_library(name, flags=RTLD_NOW): 59 import ctypes.util 60 if name is None: 61 path = None 62 else: 63 path = ctypes.util.find_library(name) 64 if path is None and name == 'c': 65 assert sys.platform == 'win32' 66 assert sys.version_info >= (3,) 67 py.test.skip("dlopen(None) cannot work on Windows with Python 3") 68 return load_library(path, flags) 69 70def test_load_library(): 71 x = find_and_load_library('c') 72 assert repr(x).startswith("<clibrary '") 73 x = find_and_load_library('c', RTLD_NOW | RTLD_GLOBAL) 74 assert repr(x).startswith("<clibrary '") 75 x = find_and_load_library('c', RTLD_LAZY) 76 assert repr(x).startswith("<clibrary '") 77 78def test_all_rtld_symbols(): 79 import sys 80 FFI_DEFAULT_ABI # these symbols must be defined 81 FFI_CDECL 82 RTLD_LAZY 83 RTLD_NOW 84 RTLD_GLOBAL 85 RTLD_LOCAL 86 if sys.platform.startswith("linux"): 87 RTLD_NODELETE 88 RTLD_NOLOAD 89 RTLD_DEEPBIND 90 91def test_new_primitive_type(): 92 py.test.raises(KeyError, new_primitive_type, "foo") 93 p = new_primitive_type("signed char") 94 assert repr(p) == "<ctype 'signed char'>" 95 96def check_dir(p, expected): 97 got = [name for name in dir(p) if not name.startswith('_')] 98 assert got == sorted(expected) 99 100def test_inspect_primitive_type(): 101 p = new_primitive_type("signed char") 102 assert p.kind == "primitive" 103 assert p.cname == "signed char" 104 check_dir(p, ['cname', 'kind']) 105 106def test_cast_to_signed_char(): 107 p = new_primitive_type("signed char") 108 x = cast(p, -65 + 17*256) 109 assert repr(x) == "<cdata 'signed char' -65>" 110 assert repr(type(x)) == "<%s '_cffi_backend.CData'>" % type_or_class 111 assert int(x) == -65 112 x = cast(p, -66 + (1<<199)*256) 113 assert repr(x) == "<cdata 'signed char' -66>" 114 assert int(x) == -66 115 assert (x == cast(p, -66)) is True 116 assert (x != cast(p, -66)) is False 117 q = new_primitive_type("short") 118 assert (x == cast(q, -66)) is True 119 assert (x != cast(q, -66)) is False 120 121def test_sizeof_type(): 122 py.test.raises(TypeError, sizeof, 42.5) 123 p = new_primitive_type("short") 124 assert sizeof(p) == 2 125 126def test_integer_types(): 127 for name in ['signed char', 'short', 'int', 'long', 'long long']: 128 p = new_primitive_type(name) 129 size = sizeof(p) 130 min = -(1 << (8*size-1)) 131 max = (1 << (8*size-1)) - 1 132 assert int(cast(p, min)) == min 133 assert int(cast(p, max)) == max 134 assert int(cast(p, min - 1)) == max 135 assert int(cast(p, max + 1)) == min 136 py.test.raises(TypeError, cast, p, None) 137 assert long(cast(p, min - 1)) == max 138 assert int(cast(p, b'\x08')) == 8 139 assert int(cast(p, u+'\x08')) == 8 140 for name in ['char', 'short', 'int', 'long', 'long long']: 141 p = new_primitive_type('unsigned ' + name) 142 size = sizeof(p) 143 max = (1 << (8*size)) - 1 144 assert int(cast(p, 0)) == 0 145 assert int(cast(p, max)) == max 146 assert int(cast(p, -1)) == max 147 assert int(cast(p, max + 1)) == 0 148 assert long(cast(p, -1)) == max 149 assert int(cast(p, b'\xFE')) == 254 150 assert int(cast(p, u+'\xFE')) == 254 151 152def test_no_float_on_int_types(): 153 p = new_primitive_type('long') 154 py.test.raises(TypeError, float, cast(p, 42)) 155 py.test.raises(TypeError, complex, cast(p, 42)) 156 157def test_float_types(): 158 INF = 1E200 * 1E200 159 for name in ["float", "double"]: 160 p = new_primitive_type(name) 161 assert bool(cast(p, 0)) is False # since 1.7 162 assert bool(cast(p, -0.0)) is False # since 1.7 163 assert bool(cast(p, 1e-42)) is True 164 assert bool(cast(p, -1e-42)) is True 165 assert bool(cast(p, INF)) 166 assert bool(cast(p, -INF)) 167 assert bool(cast(p, float("nan"))) 168 assert int(cast(p, -150)) == -150 169 assert int(cast(p, 61.91)) == 61 170 assert long(cast(p, 61.91)) == 61 171 assert type(int(cast(p, 61.91))) is int 172 assert type(int(cast(p, 1E22))) is long 173 assert type(long(cast(p, 61.91))) is long 174 assert type(long(cast(p, 1E22))) is long 175 py.test.raises(OverflowError, int, cast(p, INF)) 176 py.test.raises(OverflowError, int, cast(p, -INF)) 177 assert float(cast(p, 1.25)) == 1.25 178 assert float(cast(p, INF)) == INF 179 assert float(cast(p, -INF)) == -INF 180 if name == "float": 181 assert float(cast(p, 1.1)) != 1.1 # rounding error 182 assert float(cast(p, 1E200)) == INF # limited range 183 184 assert cast(p, -1.1) == cast(p, -1.1) 185 assert repr(float(cast(p, -0.0))) == '-0.0' 186 assert float(cast(p, b'\x09')) == 9.0 187 assert float(cast(p, u+'\x09')) == 9.0 188 assert float(cast(p, True)) == 1.0 189 py.test.raises(TypeError, cast, p, None) 190 191def test_complex_types(): 192 INF = 1E200 * 1E200 193 for name in ["float", "double"]: 194 p = new_primitive_type(name + " _Complex") 195 assert bool(cast(p, 0)) is False 196 assert bool(cast(p, INF)) 197 assert bool(cast(p, -INF)) 198 assert bool(cast(p, 0j)) is False 199 assert bool(cast(p, INF*1j)) 200 assert bool(cast(p, -INF*1j)) 201 # "can't convert complex to float", like CPython's "float(0j)" 202 py.test.raises(TypeError, int, cast(p, -150)) 203 py.test.raises(TypeError, long, cast(p, -150)) 204 py.test.raises(TypeError, float, cast(p, -150)) 205 assert complex(cast(p, 1.25)) == 1.25 206 assert complex(cast(p, 1.25j)) == 1.25j 207 assert complex(cast(p, complex(0,INF))) == complex(0,INF) 208 assert complex(cast(p, -INF)) == -INF 209 if name == "float": 210 assert complex(cast(p, 1.1j)) != 1.1j # rounding error 211 assert complex(cast(p, 1E200+3j)) == INF+3j # limited range 212 assert complex(cast(p, complex(3,1E200))) == complex(3,INF) # limited range 213 214 assert cast(p, -1.1j) == cast(p, -1.1j) 215 assert repr(complex(cast(p, -0.0)).real) == '-0.0' 216 #assert repr(complex(cast(p, -0j))) == '-0j' # http://bugs.python.org/issue29602 217 assert complex(cast(p, b'\x09')) == 9.0 + 0j 218 assert complex(cast(p, u+'\x09')) == 9.0 + 0j 219 assert complex(cast(p, True)) == 1.0 + 0j 220 py.test.raises(TypeError, cast, p, None) 221 # 222 py.test.raises(TypeError, cast, new_primitive_type(name), 1+0j) 223 # 224 for basetype in ["char", "int", "uint64_t", "float", 225 "double", "long double"]: 226 baseobj = cast(new_primitive_type(basetype), 65) 227 py.test.raises(TypeError, complex, baseobj) 228 # 229 BArray = new_array_type(new_pointer_type(p), 10) 230 x = newp(BArray, None) 231 x[5] = 12.34 + 56.78j 232 assert type(x[5]) is complex 233 assert abs(x[5] - (12.34 + 56.78j)) < 1e-5 234 assert (x[5] == 12.34 + 56.78j) == (name == "double") # rounding error 235 # 236 class Foo: 237 def __complex__(self): 238 return 2 + 3j 239 assert complex(Foo()) == 2 + 3j 240 assert complex(cast(p, Foo())) == 2 + 3j 241 py.test.raises(TypeError, cast, new_primitive_type("int"), 1+0j) 242 243def test_character_type(): 244 p = new_primitive_type("char") 245 assert bool(cast(p, 'A')) is True 246 assert bool(cast(p, '\x00')) is False # since 1.7 247 assert cast(p, '\x00') == cast(p, -17*256) 248 assert int(cast(p, 'A')) == 65 249 assert long(cast(p, 'A')) == 65 250 assert type(int(cast(p, 'A'))) is int 251 assert type(long(cast(p, 'A'))) is long 252 assert str(cast(p, 'A')) == repr(cast(p, 'A')) 253 assert repr(cast(p, 'A')) == "<cdata 'char' %s'A'>" % mandatory_b_prefix 254 assert repr(cast(p, 255)) == r"<cdata 'char' %s'\xff'>" % mandatory_b_prefix 255 assert repr(cast(p, 0)) == r"<cdata 'char' %s'\x00'>" % mandatory_b_prefix 256 257def test_pointer_type(): 258 p = new_primitive_type("int") 259 assert repr(p) == "<ctype 'int'>" 260 p = new_pointer_type(p) 261 assert repr(p) == "<ctype 'int *'>" 262 p = new_pointer_type(p) 263 assert repr(p) == "<ctype 'int * *'>" 264 p = new_pointer_type(p) 265 assert repr(p) == "<ctype 'int * * *'>" 266 267def test_inspect_pointer_type(): 268 p1 = new_primitive_type("int") 269 p2 = new_pointer_type(p1) 270 assert p2.kind == "pointer" 271 assert p2.cname == "int *" 272 assert p2.item is p1 273 check_dir(p2, ['cname', 'kind', 'item']) 274 p3 = new_pointer_type(p2) 275 assert p3.item is p2 276 277def test_pointer_to_int(): 278 BInt = new_primitive_type("int") 279 py.test.raises(TypeError, newp, BInt) 280 py.test.raises(TypeError, newp, BInt, None) 281 BPtr = new_pointer_type(BInt) 282 p = newp(BPtr) 283 assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int() 284 p = newp(BPtr, None) 285 assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int() 286 p = newp(BPtr, 5000) 287 assert repr(p) == "<cdata 'int *' owning %d bytes>" % size_of_int() 288 q = cast(BPtr, p) 289 assert repr(q).startswith("<cdata 'int *' 0x") 290 assert p == q 291 assert hash(p) == hash(q) 292 e = py.test.raises(TypeError, newp, new_array_type(BPtr, None), None) 293 assert str(e.value) == ( 294 "expected new array length or list/tuple/str, not NoneType") 295 296def test_pointer_bool(): 297 BInt = new_primitive_type("int") 298 BPtr = new_pointer_type(BInt) 299 p = cast(BPtr, 0) 300 assert bool(p) is False 301 p = cast(BPtr, 42) 302 assert bool(p) is True 303 304def test_pointer_to_pointer(): 305 BInt = new_primitive_type("int") 306 BPtr = new_pointer_type(BInt) 307 BPtrPtr = new_pointer_type(BPtr) 308 p = newp(BPtrPtr, None) 309 assert repr(p) == "<cdata 'int * *' owning %d bytes>" % size_of_ptr() 310 311def test_reading_pointer_to_int(): 312 BInt = new_primitive_type("int") 313 BPtr = new_pointer_type(BInt) 314 p = newp(BPtr, None) 315 assert p[0] == 0 316 p = newp(BPtr, 5000) 317 assert p[0] == 5000 318 py.test.raises(IndexError, "p[1]") 319 py.test.raises(IndexError, "p[-1]") 320 321def test_reading_pointer_to_float(): 322 BFloat = new_primitive_type("float") 323 py.test.raises(TypeError, newp, BFloat, None) 324 BPtr = new_pointer_type(BFloat) 325 p = newp(BPtr, None) 326 assert p[0] == 0.0 and type(p[0]) is float 327 p = newp(BPtr, 1.25) 328 assert p[0] == 1.25 and type(p[0]) is float 329 p = newp(BPtr, 1.1) 330 assert p[0] != 1.1 and abs(p[0] - 1.1) < 1E-5 # rounding errors 331 332def test_cast_float_to_int(): 333 for type in ["int", "unsigned int", "long", "unsigned long", 334 "long long", "unsigned long long"]: 335 p = new_primitive_type(type) 336 assert int(cast(p, 4.2)) == 4 337 py.test.raises(TypeError, newp, new_pointer_type(p), 4.2) 338 339def test_newp_integer_types(): 340 for name in ['signed char', 'short', 'int', 'long', 'long long']: 341 p = new_primitive_type(name) 342 pp = new_pointer_type(p) 343 size = sizeof(p) 344 min = -(1 << (8*size-1)) 345 max = (1 << (8*size-1)) - 1 346 assert newp(pp, min)[0] == min 347 assert newp(pp, max)[0] == max 348 py.test.raises(OverflowError, newp, pp, min - 2 ** 32) 349 py.test.raises(OverflowError, newp, pp, min - 2 ** 64) 350 py.test.raises(OverflowError, newp, pp, max + 2 ** 32) 351 py.test.raises(OverflowError, newp, pp, max + 2 ** 64) 352 py.test.raises(OverflowError, newp, pp, min - 1) 353 py.test.raises(OverflowError, newp, pp, max + 1) 354 py.test.raises(OverflowError, newp, pp, min - 1 - 2 ** 32) 355 py.test.raises(OverflowError, newp, pp, min - 1 - 2 ** 64) 356 py.test.raises(OverflowError, newp, pp, max + 1) 357 py.test.raises(OverflowError, newp, pp, max + 1 + 2 ** 32) 358 py.test.raises(OverflowError, newp, pp, max + 1 + 2 ** 64) 359 py.test.raises(TypeError, newp, pp, 1.0) 360 for name in ['char', 'short', 'int', 'long', 'long long']: 361 p = new_primitive_type('unsigned ' + name) 362 pp = new_pointer_type(p) 363 size = sizeof(p) 364 max = (1 << (8*size)) - 1 365 assert newp(pp, 0)[0] == 0 366 assert newp(pp, max)[0] == max 367 py.test.raises(OverflowError, newp, pp, -1) 368 py.test.raises(OverflowError, newp, pp, max + 1) 369 370def test_reading_pointer_to_char(): 371 BChar = new_primitive_type("char") 372 py.test.raises(TypeError, newp, BChar, None) 373 BPtr = new_pointer_type(BChar) 374 p = newp(BPtr, None) 375 assert p[0] == b'\x00' 376 p = newp(BPtr, b'A') 377 assert p[0] == b'A' 378 py.test.raises(TypeError, newp, BPtr, 65) 379 py.test.raises(TypeError, newp, BPtr, b"foo") 380 py.test.raises(TypeError, newp, BPtr, u+"foo") 381 c = cast(BChar, b'A') 382 assert str(c) == repr(c) 383 assert int(c) == ord(b'A') 384 py.test.raises(TypeError, cast, BChar, b'foo') 385 py.test.raises(TypeError, cast, BChar, u+'foo') 386 e = py.test.raises(TypeError, newp, new_array_type(BPtr, None), 12.3) 387 assert str(e.value) == ( 388 "expected new array length or list/tuple/str, not float") 389 390def test_reading_pointer_to_pointer(): 391 BVoidP = new_pointer_type(new_void_type()) 392 BCharP = new_pointer_type(new_primitive_type("char")) 393 BInt = new_primitive_type("int") 394 BIntPtr = new_pointer_type(BInt) 395 BIntPtrPtr = new_pointer_type(BIntPtr) 396 q = newp(BIntPtr, 42) 397 assert q[0] == 42 398 p = newp(BIntPtrPtr, None) 399 assert p[0] is not None 400 assert p[0] == cast(BVoidP, 0) 401 assert p[0] == cast(BCharP, 0) 402 assert p[0] != None 403 assert repr(p[0]) == "<cdata 'int *' NULL>" 404 p[0] = q 405 assert p[0] != cast(BVoidP, 0) 406 assert p[0] != cast(BCharP, 0) 407 assert p[0][0] == 42 408 q[0] += 1 409 assert p[0][0] == 43 410 p = newp(BIntPtrPtr, q) 411 assert p[0][0] == 43 412 413def test_load_standard_library(): 414 if sys.platform == "win32": 415 py.test.raises(OSError, find_and_load_library, None) 416 return 417 x = find_and_load_library(None) 418 BVoidP = new_pointer_type(new_void_type()) 419 assert x.load_function(BVoidP, 'strcpy') 420 py.test.raises(AttributeError, x.load_function, 421 BVoidP, 'xxx_this_function_does_not_exist') 422 # the next one is from 'libm', not 'libc', but we assume 423 # that it is already loaded too, so it should work 424 assert x.load_function(BVoidP, 'sqrt') 425 # 426 x.close_lib() 427 py.test.raises(ValueError, x.load_function, BVoidP, 'sqrt') 428 x.close_lib() 429 430def test_no_len_on_nonarray(): 431 p = new_primitive_type("int") 432 py.test.raises(TypeError, len, cast(p, 42)) 433 434def test_cmp_none(): 435 p = new_primitive_type("int") 436 x = cast(p, 42) 437 assert (x == None) is False 438 assert (x != None) is True 439 assert (x == ["hello"]) is False 440 assert (x != ["hello"]) is True 441 y = cast(p, 0) 442 assert (y == None) is False 443 444def test_invalid_indexing(): 445 p = new_primitive_type("int") 446 x = cast(p, 42) 447 py.test.raises(TypeError, "x[0]") 448 449def test_default_str(): 450 BChar = new_primitive_type("char") 451 x = cast(BChar, 42) 452 assert str(x) == repr(x) 453 BInt = new_primitive_type("int") 454 x = cast(BInt, 42) 455 assert str(x) == repr(x) 456 BArray = new_array_type(new_pointer_type(BInt), 10) 457 x = newp(BArray, None) 458 assert str(x) == repr(x) 459 460def test_default_unicode(): 461 BInt = new_primitive_type("int") 462 x = cast(BInt, 42) 463 assert unicode(x) == unicode(repr(x)) 464 BArray = new_array_type(new_pointer_type(BInt), 10) 465 x = newp(BArray, None) 466 assert unicode(x) == unicode(repr(x)) 467 468def test_cast_from_cdataint(): 469 BInt = new_primitive_type("int") 470 x = cast(BInt, 0) 471 y = cast(new_pointer_type(BInt), x) 472 assert bool(y) is False 473 # 474 x = cast(BInt, 42) 475 y = cast(BInt, x) 476 assert int(y) == 42 477 y = cast(new_primitive_type("char"), x) 478 assert int(y) == 42 479 y = cast(new_primitive_type("float"), x) 480 assert float(y) == 42.0 481 # 482 z = cast(BInt, 42.5) 483 assert int(z) == 42 484 z = cast(BInt, y) 485 assert int(z) == 42 486 487def test_void_type(): 488 p = new_void_type() 489 assert p.kind == "void" 490 assert p.cname == "void" 491 check_dir(p, ['kind', 'cname']) 492 493def test_array_type(): 494 p = new_primitive_type("int") 495 assert repr(p) == "<ctype 'int'>" 496 # 497 py.test.raises(TypeError, new_array_type, new_pointer_type(p), "foo") 498 py.test.raises(ValueError, new_array_type, new_pointer_type(p), -42) 499 # 500 p1 = new_array_type(new_pointer_type(p), None) 501 assert repr(p1) == "<ctype 'int[]'>" 502 py.test.raises(ValueError, new_array_type, new_pointer_type(p1), 42) 503 # 504 p1 = new_array_type(new_pointer_type(p), 42) 505 p2 = new_array_type(new_pointer_type(p1), 25) 506 assert repr(p2) == "<ctype 'int[25][42]'>" 507 p2 = new_array_type(new_pointer_type(p1), None) 508 assert repr(p2) == "<ctype 'int[][42]'>" 509 # 510 py.test.raises(OverflowError, 511 new_array_type, new_pointer_type(p), sys.maxsize+1) 512 py.test.raises(OverflowError, 513 new_array_type, new_pointer_type(p), sys.maxsize // 3) 514 515def test_inspect_array_type(): 516 p = new_primitive_type("int") 517 p1 = new_array_type(new_pointer_type(p), None) 518 assert p1.kind == "array" 519 assert p1.cname == "int[]" 520 assert p1.item is p 521 assert p1.length is None 522 check_dir(p1, ['cname', 'kind', 'item', 'length']) 523 p1 = new_array_type(new_pointer_type(p), 42) 524 assert p1.kind == "array" 525 assert p1.cname == "int[42]" 526 assert p1.item is p 527 assert p1.length == 42 528 check_dir(p1, ['cname', 'kind', 'item', 'length']) 529 530def test_array_instance(): 531 LENGTH = 1423 532 p = new_primitive_type("int") 533 p1 = new_array_type(new_pointer_type(p), LENGTH) 534 a = newp(p1, None) 535 assert repr(a) == "<cdata 'int[%d]' owning %d bytes>" % ( 536 LENGTH, LENGTH * size_of_int()) 537 assert len(a) == LENGTH 538 for i in range(LENGTH): 539 assert a[i] == 0 540 py.test.raises(IndexError, "a[LENGTH]") 541 py.test.raises(IndexError, "a[-1]") 542 for i in range(LENGTH): 543 a[i] = i * i + 1 544 for i in range(LENGTH): 545 assert a[i] == i * i + 1 546 e = py.test.raises(IndexError, "a[LENGTH+100] = 500") 547 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) 548 py.test.raises(TypeError, int, a) 549 550def test_array_of_unknown_length_instance(): 551 p = new_primitive_type("int") 552 p1 = new_array_type(new_pointer_type(p), None) 553 py.test.raises(TypeError, newp, p1, None) 554 py.test.raises(ValueError, newp, p1, -42) 555 a = newp(p1, 42) 556 assert len(a) == 42 557 for i in range(42): 558 a[i] -= i 559 for i in range(42): 560 assert a[i] == -i 561 py.test.raises(IndexError, "a[42]") 562 py.test.raises(IndexError, "a[-1]") 563 py.test.raises(IndexError, "a[42] = 123") 564 py.test.raises(IndexError, "a[-1] = 456") 565 566def test_array_of_unknown_length_instance_with_initializer(): 567 p = new_primitive_type("int") 568 p1 = new_array_type(new_pointer_type(p), None) 569 a = newp(p1, list(range(42))) 570 assert len(a) == 42 571 a = newp(p1, tuple(range(142))) 572 assert len(a) == 142 573 574def test_array_initializer(): 575 p = new_primitive_type("int") 576 p1 = new_array_type(new_pointer_type(p), None) 577 a = newp(p1, list(range(100, 142))) 578 for i in range(42): 579 assert a[i] == 100 + i 580 # 581 p2 = new_array_type(new_pointer_type(p), 43) 582 a = newp(p2, tuple(range(100, 142))) 583 for i in range(42): 584 assert a[i] == 100 + i 585 assert a[42] == 0 # extra uninitialized item 586 587def test_array_add(): 588 p = new_primitive_type("int") 589 p1 = new_array_type(new_pointer_type(p), 5) # int[5] 590 p2 = new_array_type(new_pointer_type(p1), 3) # int[3][5] 591 a = newp(p2, [list(range(n, n+5)) for n in [100, 200, 300]]) 592 assert repr(a) == "<cdata 'int[3][5]' owning %d bytes>" % ( 593 3*5*size_of_int(),) 594 assert repr(a + 0).startswith("<cdata 'int(*)[5]' 0x") 595 assert 0 + a == a + 0 != 1 + a == a + 1 596 assert repr(a[0]).startswith("<cdata 'int[5]' 0x") 597 assert repr((a + 0)[0]).startswith("<cdata 'int[5]' 0x") 598 assert repr(a[0] + 0).startswith("<cdata 'int *' 0x") 599 assert type(a[0][0]) is int 600 assert type((a[0] + 0)[0]) is int 601 602def test_array_sub(): 603 BInt = new_primitive_type("int") 604 BArray = new_array_type(new_pointer_type(BInt), 5) # int[5] 605 a = newp(BArray, None) 606 p = a + 1 607 assert p - a == 1 608 assert p - (a+0) == 1 609 assert a == (p - 1) 610 BPtr = new_pointer_type(new_primitive_type("short")) 611 q = newp(BPtr, None) 612 py.test.raises(TypeError, "p - q") 613 py.test.raises(TypeError, "q - p") 614 py.test.raises(TypeError, "a - q") 615 e = py.test.raises(TypeError, "q - a") 616 assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" 617 618def test_ptr_sub_unaligned(): 619 BInt = new_primitive_type("int") 620 BIntPtr = new_pointer_type(BInt) 621 a = cast(BIntPtr, 1240) 622 for bi in range(1430, 1438): 623 b = cast(BIntPtr, bi) 624 if ((bi - 1240) % size_of_int()) == 0: 625 assert b - a == (bi - 1240) // size_of_int() 626 assert a - b == (1240 - bi) // size_of_int() 627 else: 628 py.test.raises(ValueError, "b - a") 629 py.test.raises(ValueError, "a - b") 630 631def test_cast_primitive_from_cdata(): 632 p = new_primitive_type("int") 633 n = cast(p, cast(p, -42)) 634 assert int(n) == -42 635 # 636 p = new_primitive_type("unsigned int") 637 n = cast(p, cast(p, 42)) 638 assert int(n) == 42 639 # 640 p = new_primitive_type("long long") 641 n = cast(p, cast(p, -(1<<60))) 642 assert int(n) == -(1<<60) 643 # 644 p = new_primitive_type("unsigned long long") 645 n = cast(p, cast(p, 1<<63)) 646 assert int(n) == 1<<63 647 # 648 p = new_primitive_type("float") 649 n = cast(p, cast(p, 42.5)) 650 assert float(n) == 42.5 651 # 652 p = new_primitive_type("char") 653 n = cast(p, cast(p, "A")) 654 assert int(n) == ord("A") 655 656def test_new_primitive_from_cdata(): 657 p = new_primitive_type("int") 658 p1 = new_pointer_type(p) 659 n = newp(p1, cast(p, -42)) 660 assert n[0] == -42 661 # 662 p = new_primitive_type("unsigned int") 663 p1 = new_pointer_type(p) 664 n = newp(p1, cast(p, 42)) 665 assert n[0] == 42 666 # 667 p = new_primitive_type("float") 668 p1 = new_pointer_type(p) 669 n = newp(p1, cast(p, 42.5)) 670 assert n[0] == 42.5 671 # 672 p = new_primitive_type("char") 673 p1 = new_pointer_type(p) 674 n = newp(p1, cast(p, "A")) 675 assert n[0] == b"A" 676 677def test_cast_between_pointers(): 678 BIntP = new_pointer_type(new_primitive_type("int")) 679 BIntA = new_array_type(BIntP, None) 680 a = newp(BIntA, [40, 41, 42, 43, 44]) 681 BShortP = new_pointer_type(new_primitive_type("short")) 682 b = cast(BShortP, a) 683 c = cast(BIntP, b) 684 assert c[3] == 43 685 BLongLong = new_primitive_type("long long") 686 d = cast(BLongLong, c) 687 e = cast(BIntP, d) 688 assert e[3] == 43 689 f = cast(BIntP, int(d)) 690 assert f[3] == 43 691 # 692 b = cast(BShortP, 0) 693 assert not b 694 c = cast(BIntP, b) 695 assert not c 696 assert int(cast(BLongLong, c)) == 0 697 698def test_alignof(): 699 BInt = new_primitive_type("int") 700 assert alignof(BInt) == sizeof(BInt) 701 BPtr = new_pointer_type(BInt) 702 assert alignof(BPtr) == sizeof(BPtr) 703 BArray = new_array_type(BPtr, None) 704 assert alignof(BArray) == alignof(BInt) 705 706def test_new_struct_type(): 707 BStruct = new_struct_type("foo") 708 assert repr(BStruct) == "<ctype 'foo'>" 709 BStruct = new_struct_type("struct foo") 710 assert repr(BStruct) == "<ctype 'struct foo'>" 711 BPtr = new_pointer_type(BStruct) 712 assert repr(BPtr) == "<ctype 'struct foo *'>" 713 py.test.raises(ValueError, sizeof, BStruct) 714 py.test.raises(ValueError, alignof, BStruct) 715 716def test_new_union_type(): 717 BUnion = new_union_type("union foo") 718 assert repr(BUnion) == "<ctype 'union foo'>" 719 BPtr = new_pointer_type(BUnion) 720 assert repr(BPtr) == "<ctype 'union foo *'>" 721 722def test_complete_struct(): 723 BLong = new_primitive_type("long") 724 BChar = new_primitive_type("char") 725 BShort = new_primitive_type("short") 726 BStruct = new_struct_type("struct foo") 727 assert BStruct.kind == "struct" 728 assert BStruct.cname == "struct foo" 729 assert BStruct.fields is None 730 check_dir(BStruct, ['cname', 'kind', 'fields']) 731 # 732 complete_struct_or_union(BStruct, [('a1', BLong, -1), 733 ('a2', BChar, -1), 734 ('a3', BShort, -1)]) 735 d = BStruct.fields 736 assert len(d) == 3 737 assert d[0][0] == 'a1' 738 assert d[0][1].type is BLong 739 assert d[0][1].offset == 0 740 assert d[0][1].bitshift == -1 741 assert d[0][1].bitsize == -1 742 assert d[1][0] == 'a2' 743 assert d[1][1].type is BChar 744 assert d[1][1].offset == sizeof(BLong) 745 assert d[1][1].bitshift == -1 746 assert d[1][1].bitsize == -1 747 assert d[2][0] == 'a3' 748 assert d[2][1].type is BShort 749 assert d[2][1].offset == sizeof(BLong) + sizeof(BShort) 750 assert d[2][1].bitshift == -1 751 assert d[2][1].bitsize == -1 752 assert sizeof(BStruct) == 2 * sizeof(BLong) 753 assert alignof(BStruct) == alignof(BLong) 754 755def test_complete_union(): 756 BLong = new_primitive_type("long") 757 BChar = new_primitive_type("char") 758 BUnion = new_union_type("union foo") 759 assert BUnion.kind == "union" 760 assert BUnion.cname == "union foo" 761 assert BUnion.fields is None 762 complete_struct_or_union(BUnion, [('a1', BLong, -1), 763 ('a2', BChar, -1)]) 764 d = BUnion.fields 765 assert len(d) == 2 766 assert d[0][0] == 'a1' 767 assert d[0][1].type is BLong 768 assert d[0][1].offset == 0 769 assert d[1][0] == 'a2' 770 assert d[1][1].type is BChar 771 assert d[1][1].offset == 0 772 assert sizeof(BUnion) == sizeof(BLong) 773 assert alignof(BUnion) == alignof(BLong) 774 775def test_struct_instance(): 776 BInt = new_primitive_type("int") 777 BStruct = new_struct_type("struct foo") 778 BStructPtr = new_pointer_type(BStruct) 779 p = cast(BStructPtr, 42) 780 e = py.test.raises(AttributeError, "p.a1") # opaque 781 assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " 782 "cannot read fields") 783 e = py.test.raises(AttributeError, "p.a1 = 10") # opaque 784 assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " 785 "cannot write fields") 786 787 complete_struct_or_union(BStruct, [('a1', BInt, -1), 788 ('a2', BInt, -1)]) 789 p = newp(BStructPtr, None) 790 s = p[0] 791 assert s.a1 == 0 792 s.a2 = 123 793 assert s.a1 == 0 794 assert s.a2 == 123 795 py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") 796 assert s.a1 == 0 797 e = py.test.raises(AttributeError, "p.foobar") 798 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" 799 e = py.test.raises(AttributeError, "p.foobar = 42") 800 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" 801 e = py.test.raises(AttributeError, "s.foobar") 802 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" 803 e = py.test.raises(AttributeError, "s.foobar = 42") 804 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" 805 j = cast(BInt, 42) 806 e = py.test.raises(AttributeError, "j.foobar") 807 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" 808 e = py.test.raises(AttributeError, "j.foobar = 42") 809 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" 810 j = cast(new_pointer_type(BInt), 42) 811 e = py.test.raises(AttributeError, "j.foobar") 812 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" 813 e = py.test.raises(AttributeError, "j.foobar = 42") 814 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" 815 pp = newp(new_pointer_type(BStructPtr), p) 816 e = py.test.raises(AttributeError, "pp.a1") 817 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" 818 e = py.test.raises(AttributeError, "pp.a1 = 42") 819 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" 820 821def test_union_instance(): 822 BInt = new_primitive_type("int") 823 BUInt = new_primitive_type("unsigned int") 824 BUnion = new_union_type("union bar") 825 complete_struct_or_union(BUnion, [('a1', BInt, -1), ('a2', BUInt, -1)]) 826 p = newp(new_pointer_type(BUnion), [-42]) 827 bigval = -42 + (1 << (8*size_of_int())) 828 assert p.a1 == -42 829 assert p.a2 == bigval 830 p = newp(new_pointer_type(BUnion), {'a2': bigval}) 831 assert p.a1 == -42 832 assert p.a2 == bigval 833 py.test.raises(OverflowError, newp, new_pointer_type(BUnion), 834 {'a1': bigval}) 835 p = newp(new_pointer_type(BUnion), []) 836 assert p.a1 == p.a2 == 0 837 838def test_struct_pointer(): 839 BInt = new_primitive_type("int") 840 BStruct = new_struct_type("struct foo") 841 BStructPtr = new_pointer_type(BStruct) 842 complete_struct_or_union(BStruct, [('a1', BInt, -1), 843 ('a2', BInt, -1)]) 844 p = newp(BStructPtr, None) 845 assert p.a1 == 0 # read/write via the pointer (C equivalent: '->') 846 p.a2 = 123 847 assert p.a1 == 0 848 assert p.a2 == 123 849 850def test_struct_init_list(): 851 BVoidP = new_pointer_type(new_void_type()) 852 BInt = new_primitive_type("int") 853 BIntPtr = new_pointer_type(BInt) 854 BStruct = new_struct_type("struct foo") 855 BStructPtr = new_pointer_type(BStruct) 856 complete_struct_or_union(BStruct, [('a1', BInt, -1), 857 ('a2', BInt, -1), 858 ('a3', BInt, -1), 859 ('p4', BIntPtr, -1)]) 860 s = newp(BStructPtr, [123, 456]) 861 assert s.a1 == 123 862 assert s.a2 == 456 863 assert s.a3 == 0 864 assert s.p4 == cast(BVoidP, 0) 865 assert s.p4 != 0 866 # 867 s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) 868 assert s.a1 == 0 869 assert s.a2 == 41122 870 assert s.a3 == -123 871 assert s.p4 == cast(BVoidP, 0) 872 # 873 py.test.raises(KeyError, newp, BStructPtr, {'foobar': 0}) 874 # 875 p = newp(BIntPtr, 14141) 876 s = newp(BStructPtr, [12, 34, 56, p]) 877 assert s.p4 == p 878 assert s.p4 879 # 880 s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) 881 assert s.p4 == cast(BVoidP, 0) 882 assert not s.p4 883 # 884 py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) 885 886def test_array_in_struct(): 887 BInt = new_primitive_type("int") 888 BStruct = new_struct_type("struct foo") 889 BArrayInt5 = new_array_type(new_pointer_type(BInt), 5) 890 complete_struct_or_union(BStruct, [('a1', BArrayInt5, -1)]) 891 s = newp(new_pointer_type(BStruct), [[20, 24, 27, 29, 30]]) 892 assert s.a1[2] == 27 893 assert repr(s.a1).startswith("<cdata 'int[5]' 0x") 894 895def test_offsetof(): 896 def offsetof(BType, fieldname): 897 return typeoffsetof(BType, fieldname)[1] 898 BInt = new_primitive_type("int") 899 BStruct = new_struct_type("struct foo") 900 py.test.raises(TypeError, offsetof, BInt, "abc") 901 py.test.raises(TypeError, offsetof, BStruct, "abc") 902 complete_struct_or_union(BStruct, [('abc', BInt, -1), ('def', BInt, -1)]) 903 assert offsetof(BStruct, 'abc') == 0 904 assert offsetof(BStruct, 'def') == size_of_int() 905 py.test.raises(KeyError, offsetof, BStruct, "ghi") 906 assert offsetof(new_pointer_type(BStruct), "def") == size_of_int() 907 908def test_function_type(): 909 BInt = new_primitive_type("int") 910 BFunc = new_function_type((BInt, BInt), BInt, False) 911 assert repr(BFunc) == "<ctype 'int(*)(int, int)'>" 912 BFunc2 = new_function_type((), BFunc, False) 913 assert repr(BFunc2) == "<ctype 'int(*(*)())(int, int)'>" 914 915def test_inspect_function_type(): 916 BInt = new_primitive_type("int") 917 BFunc = new_function_type((BInt, BInt), BInt, False) 918 assert BFunc.kind == "function" 919 assert BFunc.cname == "int(*)(int, int)" 920 assert BFunc.args == (BInt, BInt) 921 assert BFunc.result is BInt 922 assert BFunc.ellipsis is False 923 assert BFunc.abi == FFI_DEFAULT_ABI 924 925def test_function_type_taking_struct(): 926 BChar = new_primitive_type("char") 927 BShort = new_primitive_type("short") 928 BStruct = new_struct_type("struct foo") 929 complete_struct_or_union(BStruct, [('a1', BChar, -1), 930 ('a2', BShort, -1)]) 931 BFunc = new_function_type((BStruct,), BShort, False) 932 assert repr(BFunc) == "<ctype 'short(*)(struct foo)'>" 933 934def test_function_void_result(): 935 BVoid = new_void_type() 936 BInt = new_primitive_type("int") 937 BFunc = new_function_type((BInt, BInt), BVoid, False) 938 assert repr(BFunc) == "<ctype 'void(*)(int, int)'>" 939 940def test_function_void_arg(): 941 BVoid = new_void_type() 942 BInt = new_primitive_type("int") 943 py.test.raises(TypeError, new_function_type, (BVoid,), BInt, False) 944 945def test_call_function_0(): 946 BSignedChar = new_primitive_type("signed char") 947 BFunc0 = new_function_type((BSignedChar, BSignedChar), BSignedChar, False) 948 f = cast(BFunc0, _testfunc(0)) 949 assert f(40, 2) == 42 950 assert f(-100, -100) == -200 + 256 951 py.test.raises(OverflowError, f, 128, 0) 952 py.test.raises(OverflowError, f, 0, 128) 953 954def test_call_function_0_pretend_bool_result(): 955 BSignedChar = new_primitive_type("signed char") 956 BBool = new_primitive_type("_Bool") 957 BFunc0 = new_function_type((BSignedChar, BSignedChar), BBool, False) 958 f = cast(BFunc0, _testfunc(0)) 959 assert f(40, -39) is True 960 assert f(40, -40) is False 961 py.test.raises(ValueError, f, 40, 2) 962 963def test_call_function_1(): 964 BInt = new_primitive_type("int") 965 BLong = new_primitive_type("long") 966 BFunc1 = new_function_type((BInt, BLong), BLong, False) 967 f = cast(BFunc1, _testfunc(1)) 968 assert f(40, 2) == 42 969 assert f(-100, -100) == -200 970 int_max = (1 << (8*size_of_int()-1)) - 1 971 long_max = (1 << (8*size_of_long()-1)) - 1 972 if int_max == long_max: 973 assert f(int_max, 1) == - int_max - 1 974 else: 975 assert f(int_max, 1) == int_max + 1 976 977def test_call_function_2(): 978 BLongLong = new_primitive_type("long long") 979 BFunc2 = new_function_type((BLongLong, BLongLong), BLongLong, False) 980 f = cast(BFunc2, _testfunc(2)) 981 longlong_max = (1 << (8*sizeof(BLongLong)-1)) - 1 982 assert f(longlong_max - 42, 42) == longlong_max 983 assert f(43, longlong_max - 42) == - longlong_max - 1 984 985def test_call_function_3(): 986 BFloat = new_primitive_type("float") 987 BDouble = new_primitive_type("double") 988 BFunc3 = new_function_type((BFloat, BDouble), BDouble, False) 989 f = cast(BFunc3, _testfunc(3)) 990 assert f(1.25, 5.1) == 1.25 + 5.1 # exact 991 res = f(1.3, 5.1) 992 assert res != 6.4 and abs(res - 6.4) < 1E-5 # inexact 993 994def test_call_function_4(): 995 BFloat = new_primitive_type("float") 996 BDouble = new_primitive_type("double") 997 BFunc4 = new_function_type((BFloat, BDouble), BFloat, False) 998 f = cast(BFunc4, _testfunc(4)) 999 res = f(1.25, 5.1) 1000 assert res != 6.35 and abs(res - 6.35) < 1E-5 # inexact 1001 1002def test_call_function_5(): 1003 BVoid = new_void_type() 1004 BFunc5 = new_function_type((), BVoid, False) 1005 f = cast(BFunc5, _testfunc(5)) 1006 f() # did not crash 1007 1008def test_call_function_6(): 1009 BInt = new_primitive_type("int") 1010 BIntPtr = new_pointer_type(BInt) 1011 BFunc6 = new_function_type((BIntPtr,), BIntPtr, False) 1012 f = cast(BFunc6, _testfunc(6)) 1013 x = newp(BIntPtr, 42) 1014 res = f(x) 1015 assert typeof(res) is BIntPtr 1016 assert res[0] == 42 - 1000 1017 # 1018 BIntArray = new_array_type(BIntPtr, None) 1019 BFunc6bis = new_function_type((BIntArray,), BIntPtr, False) 1020 f = cast(BFunc6bis, _testfunc(6)) 1021 # 1022 res = f([142]) 1023 assert typeof(res) is BIntPtr 1024 assert res[0] == 142 - 1000 1025 # 1026 res = f((143,)) 1027 assert typeof(res) is BIntPtr 1028 assert res[0] == 143 - 1000 1029 # 1030 x = newp(BIntArray, [242]) 1031 res = f(x) 1032 assert typeof(res) is BIntPtr 1033 assert res[0] == 242 - 1000 1034 # 1035 py.test.raises(TypeError, f, 123456) 1036 py.test.raises(TypeError, f, "foo") 1037 py.test.raises(TypeError, f, u+"bar") 1038 1039def test_call_function_7(): 1040 BChar = new_primitive_type("char") 1041 BShort = new_primitive_type("short") 1042 BStruct = new_struct_type("struct foo") 1043 BStructPtr = new_pointer_type(BStruct) 1044 complete_struct_or_union(BStruct, [('a1', BChar, -1), 1045 ('a2', BShort, -1)]) 1046 BFunc7 = new_function_type((BStruct,), BShort, False) 1047 f = cast(BFunc7, _testfunc(7)) 1048 res = f({'a1': b'A', 'a2': -4042}) 1049 assert res == -4042 + ord(b'A') 1050 # 1051 x = newp(BStructPtr, {'a1': b'A', 'a2': -4042}) 1052 res = f(x[0]) 1053 assert res == -4042 + ord(b'A') 1054 1055def test_call_function_20(): 1056 BChar = new_primitive_type("char") 1057 BShort = new_primitive_type("short") 1058 BStruct = new_struct_type("struct foo") 1059 BStructPtr = new_pointer_type(BStruct) 1060 complete_struct_or_union(BStruct, [('a1', BChar, -1), 1061 ('a2', BShort, -1)]) 1062 BFunc20 = new_function_type((BStructPtr,), BShort, False) 1063 f = cast(BFunc20, _testfunc(20)) 1064 x = newp(BStructPtr, {'a1': b'A', 'a2': -4042}) 1065 # can't pass a 'struct foo' 1066 py.test.raises(TypeError, f, x[0]) 1067 1068def test_call_function_21(): 1069 BInt = new_primitive_type("int") 1070 BStruct = new_struct_type("struct foo") 1071 complete_struct_or_union(BStruct, [('a', BInt, -1), 1072 ('b', BInt, -1), 1073 ('c', BInt, -1), 1074 ('d', BInt, -1), 1075 ('e', BInt, -1), 1076 ('f', BInt, -1), 1077 ('g', BInt, -1), 1078 ('h', BInt, -1), 1079 ('i', BInt, -1), 1080 ('j', BInt, -1)]) 1081 BFunc21 = new_function_type((BStruct,), BInt, False) 1082 f = cast(BFunc21, _testfunc(21)) 1083 res = f(list(range(13, 3, -1))) 1084 lst = [(n << i) for (i, n) in enumerate(range(13, 3, -1))] 1085 assert res == sum(lst) 1086 1087def test_call_function_22(): 1088 BInt = new_primitive_type("int") 1089 BArray10 = new_array_type(new_pointer_type(BInt), 10) 1090 BStruct = new_struct_type("struct foo") 1091 BStructP = new_pointer_type(BStruct) 1092 complete_struct_or_union(BStruct, [('a', BArray10, -1)]) 1093 BFunc22 = new_function_type((BStruct, BStruct), BStruct, False) 1094 f = cast(BFunc22, _testfunc(22)) 1095 p1 = newp(BStructP, {'a': list(range(100, 110))}) 1096 p2 = newp(BStructP, {'a': list(range(1000, 1100, 10))}) 1097 res = f(p1[0], p2[0]) 1098 for i in range(10): 1099 assert res.a[i] == p1.a[i] - p2.a[i] 1100 1101def test_call_function_23(): 1102 BVoid = new_void_type() # declaring the function as int(void*) 1103 BVoidP = new_pointer_type(BVoid) 1104 BInt = new_primitive_type("int") 1105 BFunc23 = new_function_type((BVoidP,), BInt, False) 1106 f = cast(BFunc23, _testfunc(23)) 1107 res = f(b"foo") 1108 assert res == 1000 * ord(b'f') 1109 res = f(cast(BVoidP, 0)) # NULL 1110 assert res == -42 1111 py.test.raises(TypeError, f, None) 1112 py.test.raises(TypeError, f, 0) 1113 py.test.raises(TypeError, f, 0.0) 1114 1115def test_call_function_23_bis(): 1116 # declaring the function as int(unsigned char*) 1117 BUChar = new_primitive_type("unsigned char") 1118 BUCharP = new_pointer_type(BUChar) 1119 BInt = new_primitive_type("int") 1120 BFunc23 = new_function_type((BUCharP,), BInt, False) 1121 f = cast(BFunc23, _testfunc(23)) 1122 res = f(b"foo") 1123 assert res == 1000 * ord(b'f') 1124 1125def test_call_function_23_bool_array(): 1126 # declaring the function as int(_Bool*) 1127 BBool = new_primitive_type("_Bool") 1128 BBoolP = new_pointer_type(BBool) 1129 BInt = new_primitive_type("int") 1130 BFunc23 = new_function_type((BBoolP,), BInt, False) 1131 f = cast(BFunc23, _testfunc(23)) 1132 res = f(b"\x01\x01") 1133 assert res == 1000 1134 py.test.raises(ValueError, f, b"\x02\x02") 1135 1136def test_cannot_pass_struct_with_array_of_length_0(): 1137 BInt = new_primitive_type("int") 1138 BArray0 = new_array_type(new_pointer_type(BInt), 0) 1139 BStruct = new_struct_type("struct foo") 1140 BStructP = new_pointer_type(BStruct) 1141 complete_struct_or_union(BStruct, [('a', BArray0)]) 1142 BFunc = new_function_type((BStruct,), BInt, False) 1143 py.test.raises(NotImplementedError, cast(BFunc, 123), cast(BStructP, 123)) 1144 BFunc2 = new_function_type((BInt,), BStruct, False) 1145 py.test.raises(NotImplementedError, cast(BFunc2, 123), 123) 1146 1147def test_call_function_9(): 1148 BInt = new_primitive_type("int") 1149 BFunc9 = new_function_type((BInt,), BInt, True) # vararg 1150 f = cast(BFunc9, _testfunc(9)) 1151 assert f(0) == 0 1152 assert f(1, cast(BInt, 42)) == 42 1153 assert f(2, cast(BInt, 40), cast(BInt, 2)) == 42 1154 py.test.raises(TypeError, f, 1, 42) 1155 py.test.raises(TypeError, f, 2, None) 1156 # promotion of chars and shorts to ints 1157 BSChar = new_primitive_type("signed char") 1158 BUChar = new_primitive_type("unsigned char") 1159 BSShort = new_primitive_type("short") 1160 assert f(3, cast(BSChar, -3), cast(BUChar, 200), cast(BSShort, -5)) == 192 1161 1162def test_call_function_24(): 1163 BFloat = new_primitive_type("float") 1164 BFloatComplex = new_primitive_type("float _Complex") 1165 BFunc3 = new_function_type((BFloat, BFloat), BFloatComplex, False) 1166 if 0: # libffi returning nonsense silently, so logic disabled for now 1167 f = cast(BFunc3, _testfunc(24)) 1168 result = f(1.25, 5.1) 1169 assert type(result) == complex 1170 assert result.real == 1.25 # exact 1171 assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact 1172 else: 1173 f = cast(BFunc3, _testfunc(9)) 1174 py.test.raises(NotImplementedError, f, 12.3, 34.5) 1175 1176def test_call_function_25(): 1177 BDouble = new_primitive_type("double") 1178 BDoubleComplex = new_primitive_type("double _Complex") 1179 BFunc3 = new_function_type((BDouble, BDouble), BDoubleComplex, False) 1180 if 0: # libffi returning nonsense silently, so logic disabled for now 1181 f = cast(BFunc3, _testfunc(25)) 1182 result = f(1.25, 5.1) 1183 assert type(result) == complex 1184 assert result.real == 1.25 # exact 1185 assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-10) # inexact 1186 else: 1187 f = cast(BFunc3, _testfunc(9)) 1188 py.test.raises(NotImplementedError, f, 12.3, 34.5) 1189 1190def test_cannot_call_with_a_autocompleted_struct(): 1191 BSChar = new_primitive_type("signed char") 1192 BDouble = new_primitive_type("double") 1193 BStruct = new_struct_type("struct foo") 1194 BStructPtr = new_pointer_type(BStruct) 1195 complete_struct_or_union(BStruct, [('c', BDouble, -1, 8), 1196 ('a', BSChar, -1, 2), 1197 ('b', BSChar, -1, 0)]) 1198 BFunc = new_function_type((BStruct,), BDouble) # internally not callable 1199 dummy_func = cast(BFunc, 42) 1200 e = py.test.raises(NotImplementedError, dummy_func, "?") 1201 msg = ("ctype 'struct foo' not supported as argument. It is a struct " 1202 'declared with "...;", but the C calling convention may depend ' 1203 "on the missing fields; or, it contains anonymous struct/unions. " 1204 "Such structs are only supported as argument if the function is " 1205 "'API mode' and non-variadic (i.e. declared inside ffibuilder." 1206 "cdef()+ffibuilder.set_source() and not taking a final '...' " 1207 "argument)") 1208 assert str(e.value) == msg 1209 1210def test_new_charp(): 1211 BChar = new_primitive_type("char") 1212 BCharP = new_pointer_type(BChar) 1213 BCharA = new_array_type(BCharP, None) 1214 x = newp(BCharA, 42) 1215 assert len(x) == 42 1216 x = newp(BCharA, b"foobar") 1217 assert len(x) == 7 1218 1219def test_load_and_call_function(): 1220 BChar = new_primitive_type("char") 1221 BCharP = new_pointer_type(BChar) 1222 BLong = new_primitive_type("long") 1223 BFunc = new_function_type((BCharP,), BLong, False) 1224 ll = find_and_load_library('c') 1225 strlen = ll.load_function(BFunc, "strlen") 1226 input = newp(new_array_type(BCharP, None), b"foobar") 1227 assert strlen(input) == 6 1228 # 1229 assert strlen(b"foobarbaz") == 9 1230 # 1231 BVoidP = new_pointer_type(new_void_type()) 1232 strlenaddr = ll.load_function(BVoidP, "strlen") 1233 assert strlenaddr == cast(BVoidP, strlen) 1234 1235def test_read_variable(): 1236 ## FIXME: this test assumes glibc specific behavior, it's not compliant with C standard 1237 ## https://bugs.pypy.org/issue1643 1238 if not sys.platform.startswith("linux"): 1239 py.test.skip("untested") 1240 BVoidP = new_pointer_type(new_void_type()) 1241 ll = find_and_load_library('c') 1242 stderr = ll.read_variable(BVoidP, "stderr") 1243 assert stderr == cast(BVoidP, _testfunc(8)) 1244 # 1245 ll.close_lib() 1246 py.test.raises(ValueError, ll.read_variable, BVoidP, "stderr") 1247 1248def test_read_variable_as_unknown_length_array(): 1249 ## FIXME: this test assumes glibc specific behavior, it's not compliant with C standard 1250 ## https://bugs.pypy.org/issue1643 1251 if not sys.platform.startswith("linux"): 1252 py.test.skip("untested") 1253 BCharP = new_pointer_type(new_primitive_type("char")) 1254 BArray = new_array_type(BCharP, None) 1255 ll = find_and_load_library('c') 1256 stderr = ll.read_variable(BArray, "stderr") 1257 assert repr(stderr).startswith("<cdata 'char *' 0x") 1258 # ^^ and not 'char[]', which is basically not allowed and would crash 1259 1260def test_write_variable(): 1261 ## FIXME: this test assumes glibc specific behavior, it's not compliant with C standard 1262 ## https://bugs.pypy.org/issue1643 1263 if not sys.platform.startswith("linux"): 1264 py.test.skip("untested") 1265 BVoidP = new_pointer_type(new_void_type()) 1266 ll = find_and_load_library('c') 1267 stderr = ll.read_variable(BVoidP, "stderr") 1268 ll.write_variable(BVoidP, "stderr", cast(BVoidP, 0)) 1269 assert ll.read_variable(BVoidP, "stderr") is not None 1270 assert not ll.read_variable(BVoidP, "stderr") 1271 ll.write_variable(BVoidP, "stderr", stderr) 1272 assert ll.read_variable(BVoidP, "stderr") == stderr 1273 # 1274 ll.close_lib() 1275 py.test.raises(ValueError, ll.write_variable, BVoidP, "stderr", stderr) 1276 1277def test_callback(): 1278 BInt = new_primitive_type("int") 1279 def make_callback(): 1280 def cb(n): 1281 return n + 1 1282 BFunc = new_function_type((BInt,), BInt, False) 1283 return callback(BFunc, cb, 42) # 'cb' and 'BFunc' go out of scope 1284 f = make_callback() 1285 assert f(-142) == -141 1286 assert repr(f).startswith( 1287 "<cdata 'int(*)(int)' calling <function ") 1288 assert "cb at 0x" in repr(f) 1289 e = py.test.raises(TypeError, f) 1290 assert str(e.value) == "'int(*)(int)' expects 1 arguments, got 0" 1291 1292def test_callback_exception(): 1293 try: 1294 import cStringIO 1295 except ImportError: 1296 import io as cStringIO # Python 3 1297 import linecache 1298 def matches(istr, ipattern): 1299 str, pattern = istr, ipattern 1300 while '$' in pattern: 1301 i = pattern.index('$') 1302 assert str[:i] == pattern[:i] 1303 j = str.find(pattern[i+1], i) 1304 assert i + 1 <= j <= str.find('\n', i) 1305 str = str[j:] 1306 pattern = pattern[i+1:] 1307 assert str == pattern 1308 return True 1309 def check_value(x): 1310 if x == 10000: 1311 raise ValueError(42) 1312 def Zcb1(x): 1313 check_value(x) 1314 return x * 3 1315 BShort = new_primitive_type("short") 1316 BFunc = new_function_type((BShort,), BShort, False) 1317 f = callback(BFunc, Zcb1, -42) 1318 # 1319 seen = [] 1320 oops_result = None 1321 def oops(*args): 1322 seen.append(args) 1323 return oops_result 1324 ff = callback(BFunc, Zcb1, -42, oops) 1325 # 1326 orig_stderr = sys.stderr 1327 orig_getline = linecache.getline 1328 try: 1329 linecache.getline = lambda *args: 'LINE' # hack: speed up PyPy tests 1330 sys.stderr = cStringIO.StringIO() 1331 assert f(100) == 300 1332 assert sys.stderr.getvalue() == '' 1333 assert f(10000) == -42 1334 assert matches(sys.stderr.getvalue(), """\ 1335From cffi callback <function$Zcb1 at 0x$>: 1336Traceback (most recent call last): 1337 File "$", line $, in Zcb1 1338 $ 1339 File "$", line $, in check_value 1340 $ 1341ValueError: 42 1342""") 1343 sys.stderr = cStringIO.StringIO() 1344 bigvalue = 20000 1345 assert f(bigvalue) == -42 1346 assert matches(sys.stderr.getvalue(), """\ 1347From cffi callback <function$Zcb1 at 0x$>: 1348Trying to convert the result back to C: 1349OverflowError: integer 60000 does not fit 'short' 1350""") 1351 sys.stderr = cStringIO.StringIO() 1352 bigvalue = 20000 1353 assert len(seen) == 0 1354 assert ff(bigvalue) == -42 1355 assert sys.stderr.getvalue() == "" 1356 assert len(seen) == 1 1357 exc, val, tb = seen[0] 1358 assert exc is OverflowError 1359 assert str(val) == "integer 60000 does not fit 'short'" 1360 # 1361 sys.stderr = cStringIO.StringIO() 1362 bigvalue = 20000 1363 del seen[:] 1364 oops_result = 81 1365 assert ff(bigvalue) == 81 1366 oops_result = None 1367 assert sys.stderr.getvalue() == "" 1368 assert len(seen) == 1 1369 exc, val, tb = seen[0] 1370 assert exc is OverflowError 1371 assert str(val) == "integer 60000 does not fit 'short'" 1372 # 1373 sys.stderr = cStringIO.StringIO() 1374 bigvalue = 20000 1375 del seen[:] 1376 oops_result = "xy" # not None and not an int! 1377 assert ff(bigvalue) == -42 1378 oops_result = None 1379 assert matches(sys.stderr.getvalue(), """\ 1380From cffi callback <function$Zcb1 at 0x$>: 1381Trying to convert the result back to C: 1382OverflowError: integer 60000 does not fit 'short' 1383 1384During the call to 'onerror', another exception occurred: 1385 1386TypeError: $integer$ 1387""") 1388 # 1389 sys.stderr = cStringIO.StringIO() 1390 seen = "not a list" # this makes the oops() function crash 1391 assert ff(bigvalue) == -42 1392 assert matches(sys.stderr.getvalue(), """\ 1393From cffi callback <function$Zcb1 at 0x$>: 1394Trying to convert the result back to C: 1395OverflowError: integer 60000 does not fit 'short' 1396 1397During the call to 'onerror', another exception occurred: 1398 1399Traceback (most recent call last): 1400 File "$", line $, in oops 1401 $ 1402AttributeError: 'str' object has no attribute 'append' 1403""") 1404 finally: 1405 sys.stderr = orig_stderr 1406 linecache.getline = orig_getline 1407 1408def test_callback_return_type(): 1409 for rettype in ["signed char", "short", "int", "long", "long long", 1410 "unsigned char", "unsigned short", "unsigned int", 1411 "unsigned long", "unsigned long long"]: 1412 BRet = new_primitive_type(rettype) 1413 def cb(n): 1414 return n + 1 1415 BFunc = new_function_type((BRet,), BRet) 1416 f = callback(BFunc, cb, 42) 1417 assert f(41) == 42 1418 if rettype.startswith("unsigned "): 1419 min = 0 1420 max = (1 << (8*sizeof(BRet))) - 1 1421 else: 1422 min = -(1 << (8*sizeof(BRet)-1)) 1423 max = (1 << (8*sizeof(BRet)-1)) - 1 1424 assert f(min) == min + 1 1425 assert f(max - 1) == max 1426 assert f(max) == 42 1427 1428def test_a_lot_of_callbacks(): 1429 BIGNUM = 10000 1430 if 'PY_DOT_PY' in globals(): BIGNUM = 100 # tests on py.py 1431 # 1432 BInt = new_primitive_type("int") 1433 BFunc = new_function_type((BInt,), BInt, False) 1434 def make_callback(m): 1435 def cb(n): 1436 return n + m 1437 return callback(BFunc, cb, 42) # 'cb' and 'BFunc' go out of scope 1438 # 1439 flist = [make_callback(i) for i in range(BIGNUM)] 1440 for i, f in enumerate(flist): 1441 assert f(-142) == -142 + i 1442 1443def test_callback_receiving_tiny_struct(): 1444 BSChar = new_primitive_type("signed char") 1445 BInt = new_primitive_type("int") 1446 BStruct = new_struct_type("struct foo") 1447 BStructPtr = new_pointer_type(BStruct) 1448 complete_struct_or_union(BStruct, [('a', BSChar, -1), 1449 ('b', BSChar, -1)]) 1450 def cb(s): 1451 return s.a + 10 * s.b 1452 BFunc = new_function_type((BStruct,), BInt) 1453 f = callback(BFunc, cb) 1454 p = newp(BStructPtr, [-2, -4]) 1455 n = f(p[0]) 1456 assert n == -42 1457 1458def test_callback_returning_tiny_struct(): 1459 BSChar = new_primitive_type("signed char") 1460 BInt = new_primitive_type("int") 1461 BStruct = new_struct_type("struct foo") 1462 BStructPtr = new_pointer_type(BStruct) 1463 complete_struct_or_union(BStruct, [('a', BSChar, -1), 1464 ('b', BSChar, -1)]) 1465 def cb(n): 1466 return newp(BStructPtr, [-n, -3*n])[0] 1467 BFunc = new_function_type((BInt,), BStruct) 1468 f = callback(BFunc, cb) 1469 s = f(10) 1470 assert typeof(s) is BStruct 1471 assert repr(s) == "<cdata 'struct foo' owning 2 bytes>" 1472 assert s.a == -10 1473 assert s.b == -30 1474 1475def test_callback_receiving_struct(): 1476 BSChar = new_primitive_type("signed char") 1477 BInt = new_primitive_type("int") 1478 BDouble = new_primitive_type("double") 1479 BStruct = new_struct_type("struct foo") 1480 BStructPtr = new_pointer_type(BStruct) 1481 complete_struct_or_union(BStruct, [('a', BSChar, -1), 1482 ('b', BDouble, -1)]) 1483 def cb(s): 1484 return s.a + int(s.b) 1485 BFunc = new_function_type((BStruct,), BInt) 1486 f = callback(BFunc, cb) 1487 p = newp(BStructPtr, [-2, 44.444]) 1488 n = f(p[0]) 1489 assert n == 42 1490 1491def test_callback_returning_struct(): 1492 BSChar = new_primitive_type("signed char") 1493 BInt = new_primitive_type("int") 1494 BDouble = new_primitive_type("double") 1495 BStruct = new_struct_type("struct foo") 1496 BStructPtr = new_pointer_type(BStruct) 1497 complete_struct_or_union(BStruct, [('a', BSChar, -1), 1498 ('b', BDouble, -1)]) 1499 def cb(n): 1500 return newp(BStructPtr, [-n, 1E-42])[0] 1501 BFunc = new_function_type((BInt,), BStruct) 1502 f = callback(BFunc, cb) 1503 s = f(10) 1504 assert typeof(s) is BStruct 1505 assert repr(s) in ["<cdata 'struct foo' owning 12 bytes>", 1506 "<cdata 'struct foo' owning 16 bytes>"] 1507 assert s.a == -10 1508 assert s.b == 1E-42 1509 1510def test_callback_receiving_big_struct(): 1511 BInt = new_primitive_type("int") 1512 BStruct = new_struct_type("struct foo") 1513 BStructPtr = new_pointer_type(BStruct) 1514 complete_struct_or_union(BStruct, [('a', BInt, -1), 1515 ('b', BInt, -1), 1516 ('c', BInt, -1), 1517 ('d', BInt, -1), 1518 ('e', BInt, -1), 1519 ('f', BInt, -1), 1520 ('g', BInt, -1), 1521 ('h', BInt, -1), 1522 ('i', BInt, -1), 1523 ('j', BInt, -1)]) 1524 def cb(s): 1525 for i, name in enumerate("abcdefghij"): 1526 assert getattr(s, name) == 13 - i 1527 return 42 1528 BFunc = new_function_type((BStruct,), BInt) 1529 f = callback(BFunc, cb) 1530 p = newp(BStructPtr, list(range(13, 3, -1))) 1531 n = f(p[0]) 1532 assert n == 42 1533 1534def test_callback_returning_big_struct(): 1535 BInt = new_primitive_type("int") 1536 BStruct = new_struct_type("struct foo") 1537 BStructPtr = new_pointer_type(BStruct) 1538 complete_struct_or_union(BStruct, [('a', BInt, -1), 1539 ('b', BInt, -1), 1540 ('c', BInt, -1), 1541 ('d', BInt, -1), 1542 ('e', BInt, -1), 1543 ('f', BInt, -1), 1544 ('g', BInt, -1), 1545 ('h', BInt, -1), 1546 ('i', BInt, -1), 1547 ('j', BInt, -1)]) 1548 def cb(): 1549 return newp(BStructPtr, list(range(13, 3, -1)))[0] 1550 BFunc = new_function_type((), BStruct) 1551 f = callback(BFunc, cb) 1552 s = f() 1553 assert typeof(s) is BStruct 1554 assert repr(s) in ["<cdata 'struct foo' owning 40 bytes>", 1555 "<cdata 'struct foo' owning 80 bytes>"] 1556 for i, name in enumerate("abcdefghij"): 1557 assert getattr(s, name) == 13 - i 1558 1559def test_callback_returning_void(): 1560 BVoid = new_void_type() 1561 BFunc = new_function_type((), BVoid, False) 1562 def cb(): 1563 seen.append(42) 1564 f = callback(BFunc, cb) 1565 seen = [] 1566 f() 1567 assert seen == [42] 1568 py.test.raises(TypeError, callback, BFunc, cb, -42) 1569 1570def test_enum_type(): 1571 BUInt = new_primitive_type("unsigned int") 1572 BEnum = new_enum_type("foo", (), (), BUInt) 1573 assert repr(BEnum) == "<ctype 'foo'>" 1574 assert BEnum.kind == "enum" 1575 assert BEnum.cname == "foo" 1576 assert BEnum.elements == {} 1577 # 1578 BInt = new_primitive_type("int") 1579 BEnum = new_enum_type("enum foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) 1580 assert BEnum.kind == "enum" 1581 assert BEnum.cname == "enum foo" 1582 assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} 1583 # 'elements' is not the real dict, but merely a copy 1584 BEnum.elements[2] = '??' 1585 assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} 1586 # 1587 BEnum = new_enum_type("enum bar", ('ab', 'cd'), (5, 5), BUInt) 1588 assert BEnum.elements == {5: 'ab'} 1589 assert BEnum.relements == {'ab': 5, 'cd': 5} 1590 1591def test_cast_to_enum(): 1592 BInt = new_primitive_type("int") 1593 BEnum = new_enum_type("enum foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) 1594 assert sizeof(BEnum) == sizeof(BInt) 1595 e = cast(BEnum, 0) 1596 assert repr(e) == "<cdata 'enum foo' 0: def>" 1597 assert repr(cast(BEnum, -42)) == "<cdata 'enum foo' -42>" 1598 assert repr(cast(BEnum, -20)) == "<cdata 'enum foo' -20: ab>" 1599 assert string(e) == 'def' 1600 assert string(cast(BEnum, -20)) == 'ab' 1601 assert int(cast(BEnum, 1)) == 1 1602 assert int(cast(BEnum, 0)) == 0 1603 assert int(cast(BEnum, -242 + 2**128)) == -242 1604 assert string(cast(BEnum, -242 + 2**128)) == '-242' 1605 # 1606 BUInt = new_primitive_type("unsigned int") 1607 BEnum = new_enum_type("enum bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) 1608 e = cast(BEnum, -1) 1609 assert repr(e) == "<cdata 'enum bar' 4294967295>" # unsigned int 1610 # 1611 BLong = new_primitive_type("long") 1612 BEnum = new_enum_type("enum baz", (), (), BLong) 1613 assert sizeof(BEnum) == sizeof(BLong) 1614 e = cast(BEnum, -1) 1615 assert repr(e) == "<cdata 'enum baz' -1>" 1616 1617def test_enum_with_non_injective_mapping(): 1618 BInt = new_primitive_type("int") 1619 BEnum = new_enum_type("enum foo", ('ab', 'cd'), (7, 7), BInt) 1620 e = cast(BEnum, 7) 1621 assert repr(e) == "<cdata 'enum foo' 7: ab>" 1622 assert string(e) == 'ab' 1623 1624def test_enum_in_struct(): 1625 BInt = new_primitive_type("int") 1626 BEnum = new_enum_type("enum foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) 1627 BStruct = new_struct_type("struct bar") 1628 BStructPtr = new_pointer_type(BStruct) 1629 complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) 1630 p = newp(BStructPtr, [-20]) 1631 assert p.a1 == -20 1632 p = newp(BStructPtr, [12]) 1633 assert p.a1 == 12 1634 e = py.test.raises(TypeError, newp, BStructPtr, [None]) 1635 msg = str(e.value) 1636 assert ("an integer is required" in msg or # CPython 1637 "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys 1638 "expected integer, got NoneType object" in msg) # newer PyPys 1639 py.test.raises(TypeError, 'p.a1 = "def"') 1640 if sys.version_info < (3,): 1641 BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) 1642 assert string(cast(BEnum2, 5)) == 'abc' 1643 assert type(string(cast(BEnum2, 5))) is str 1644 1645def test_enum_overflow(): 1646 max_uint = 2 ** (size_of_int()*8) - 1 1647 max_int = max_uint // 2 1648 max_ulong = 2 ** (size_of_long()*8) - 1 1649 max_long = max_ulong // 2 1650 for BPrimitive in [new_primitive_type("int"), 1651 new_primitive_type("unsigned int"), 1652 new_primitive_type("long"), 1653 new_primitive_type("unsigned long")]: 1654 for x in [max_uint, max_int, max_ulong, max_long]: 1655 for testcase in [x, x+1, -x-1, -x-2]: 1656 if int(cast(BPrimitive, testcase)) == testcase: 1657 # fits 1658 BEnum = new_enum_type("foo", ("AA",), (testcase,), 1659 BPrimitive) 1660 assert int(cast(BEnum, testcase)) == testcase 1661 else: 1662 # overflows 1663 py.test.raises(OverflowError, new_enum_type, 1664 "foo", ("AA",), (testcase,), BPrimitive) 1665 1666def test_callback_returning_enum(): 1667 BInt = new_primitive_type("int") 1668 BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) 1669 def cb(n): 1670 if n & 1: 1671 return cast(BEnum, n) 1672 else: 1673 return n 1674 BFunc = new_function_type((BInt,), BEnum) 1675 f = callback(BFunc, cb) 1676 assert f(0) == 0 1677 assert f(1) == 1 1678 assert f(-20) == -20 1679 assert f(20) == 20 1680 assert f(21) == 21 1681 1682def test_callback_returning_enum_unsigned(): 1683 BInt = new_primitive_type("int") 1684 BUInt = new_primitive_type("unsigned int") 1685 BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) 1686 def cb(n): 1687 if n & 1: 1688 return cast(BEnum, n) 1689 else: 1690 return n 1691 BFunc = new_function_type((BInt,), BEnum) 1692 f = callback(BFunc, cb) 1693 assert f(0) == 0 1694 assert f(1) == 1 1695 assert f(-21) == 2**32 - 21 1696 assert f(20) == 20 1697 assert f(21) == 21 1698 1699def test_callback_returning_char(): 1700 BInt = new_primitive_type("int") 1701 BChar = new_primitive_type("char") 1702 def cb(n): 1703 return bytechr(n) 1704 BFunc = new_function_type((BInt,), BChar) 1705 f = callback(BFunc, cb) 1706 assert f(0) == b'\x00' 1707 assert f(255) == b'\xFF' 1708 1709def _hacked_pypy_uni4(): 1710 pyuni4 = {1: True, 2: False}[len(u+'\U00012345')] 1711 return 'PY_DOT_PY' in globals() and not pyuni4 1712 1713def test_callback_returning_wchar_t(): 1714 BInt = new_primitive_type("int") 1715 BWChar = new_primitive_type("wchar_t") 1716 def cb(n): 1717 if n == -1: 1718 return u+'\U00012345' 1719 if n == -2: 1720 raise ValueError 1721 return unichr(n) 1722 BFunc = new_function_type((BInt,), BWChar) 1723 f = callback(BFunc, cb) 1724 assert f(0) == unichr(0) 1725 assert f(255) == unichr(255) 1726 assert f(0x1234) == u+'\u1234' 1727 if sizeof(BWChar) == 4 and not _hacked_pypy_uni4(): 1728 assert f(-1) == u+'\U00012345' 1729 assert f(-2) == u+'\x00' # and an exception printed to stderr 1730 1731def test_struct_with_bitfields(): 1732 BLong = new_primitive_type("long") 1733 BStruct = new_struct_type("struct foo") 1734 LONGBITS = 8 * sizeof(BLong) 1735 complete_struct_or_union(BStruct, [('a1', BLong, 1), 1736 ('a2', BLong, 2), 1737 ('a3', BLong, 3), 1738 ('a4', BLong, LONGBITS - 5)]) 1739 d = BStruct.fields 1740 assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0 1741 assert d[3][1].offset == sizeof(BLong) 1742 def f(m, r): 1743 if sys.byteorder == 'little': 1744 return r 1745 else: 1746 return LONGBITS - m - r 1747 assert d[0][1].bitshift == f(1, 0) 1748 assert d[0][1].bitsize == 1 1749 assert d[1][1].bitshift == f(2, 1) 1750 assert d[1][1].bitsize == 2 1751 assert d[2][1].bitshift == f(3, 3) 1752 assert d[2][1].bitsize == 3 1753 assert d[3][1].bitshift == f(LONGBITS - 5, 0) 1754 assert d[3][1].bitsize == LONGBITS - 5 1755 assert sizeof(BStruct) == 2 * sizeof(BLong) 1756 assert alignof(BStruct) == alignof(BLong) 1757 1758def test_bitfield_instance(): 1759 BInt = new_primitive_type("int") 1760 BUnsignedInt = new_primitive_type("unsigned int") 1761 BStruct = new_struct_type("struct foo") 1762 complete_struct_or_union(BStruct, [('a1', BInt, 1), 1763 ('a2', BUnsignedInt, 2), 1764 ('a3', BInt, 3)]) 1765 p = newp(new_pointer_type(BStruct), None) 1766 p.a1 = -1 1767 assert p.a1 == -1 1768 p.a1 = 0 1769 py.test.raises(OverflowError, "p.a1 = 2") 1770 assert p.a1 == 0 1771 # 1772 p.a1 = -1 1773 p.a2 = 3 1774 p.a3 = -4 1775 py.test.raises(OverflowError, "p.a3 = 4") 1776 e = py.test.raises(OverflowError, "p.a3 = -5") 1777 assert str(e.value) == ("value -5 outside the range allowed by the " 1778 "bit field width: -4 <= x <= 3") 1779 assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 1780 # 1781 # special case for convenience: "int x:1", while normally signed, 1782 # allows also setting the value "1" (it still gets read back as -1) 1783 p.a1 = 1 1784 assert p.a1 == -1 1785 e = py.test.raises(OverflowError, "p.a1 = -2") 1786 assert str(e.value) == ("value -2 outside the range allowed by the " 1787 "bit field width: -1 <= x <= 1") 1788 1789def test_bitfield_instance_init(): 1790 BInt = new_primitive_type("int") 1791 BStruct = new_struct_type("struct foo") 1792 complete_struct_or_union(BStruct, [('a1', BInt, 1)]) 1793 p = newp(new_pointer_type(BStruct), [-1]) 1794 assert p.a1 == -1 1795 p = newp(new_pointer_type(BStruct), {'a1': -1}) 1796 assert p.a1 == -1 1797 # 1798 BUnion = new_union_type("union bar") 1799 complete_struct_or_union(BUnion, [('a1', BInt, 1)]) 1800 p = newp(new_pointer_type(BUnion), [-1]) 1801 assert p.a1 == -1 1802 1803def test_weakref(): 1804 import _weakref 1805 BInt = new_primitive_type("int") 1806 BPtr = new_pointer_type(BInt) 1807 rlist = [_weakref.ref(BInt), 1808 _weakref.ref(newp(BPtr, 42)), 1809 _weakref.ref(cast(BPtr, 42)), 1810 _weakref.ref(cast(BInt, 42)), 1811 _weakref.ref(buffer(newp(BPtr, 42))), 1812 ] 1813 for i in range(5): 1814 import gc; gc.collect() 1815 if [r() for r in rlist] == [None for r in rlist]: 1816 break 1817 1818def test_no_inheritance(): 1819 BInt = new_primitive_type("int") 1820 try: 1821 class foo(type(BInt)): pass 1822 except TypeError: 1823 pass 1824 else: 1825 raise AssertionError 1826 x = cast(BInt, 42) 1827 try: 1828 class foo(type(x)): pass 1829 except TypeError: 1830 pass 1831 else: 1832 raise AssertionError 1833 1834def test_assign_string(): 1835 BChar = new_primitive_type("char") 1836 BArray1 = new_array_type(new_pointer_type(BChar), 5) 1837 BArray2 = new_array_type(new_pointer_type(BArray1), 5) 1838 a = newp(BArray2, [b"abc", b"de", b"ghij"]) 1839 assert string(a[1]) == b"de" 1840 assert string(a[2]) == b"ghij" 1841 a[2] = b"." 1842 assert string(a[2]) == b"." 1843 a[2] = b"12345" 1844 assert string(a[2]) == b"12345" 1845 e = py.test.raises(IndexError, 'a[2] = b"123456"') 1846 assert 'char[5]' in str(e.value) 1847 assert 'got 6 characters' in str(e.value) 1848 1849def test_add_error(): 1850 x = cast(new_primitive_type("int"), 42) 1851 py.test.raises(TypeError, "x + 1") 1852 py.test.raises(TypeError, "x - 1") 1853 1854def test_void_errors(): 1855 py.test.raises(ValueError, alignof, new_void_type()) 1856 py.test.raises(TypeError, newp, new_pointer_type(new_void_type()), None) 1857 1858def test_too_many_items(): 1859 BChar = new_primitive_type("char") 1860 BArray = new_array_type(new_pointer_type(BChar), 5) 1861 py.test.raises(IndexError, newp, BArray, tuple(b'123456')) 1862 py.test.raises(IndexError, newp, BArray, list(b'123456')) 1863 py.test.raises(IndexError, newp, BArray, b'123456') 1864 BStruct = new_struct_type("struct foo") 1865 complete_struct_or_union(BStruct, []) 1866 py.test.raises(TypeError, newp, new_pointer_type(BStruct), b'') 1867 py.test.raises(ValueError, newp, new_pointer_type(BStruct), [b'1']) 1868 1869def test_more_type_errors(): 1870 BInt = new_primitive_type("int") 1871 BChar = new_primitive_type("char") 1872 BArray = new_array_type(new_pointer_type(BChar), 5) 1873 py.test.raises(TypeError, newp, BArray, 12.34) 1874 BArray = new_array_type(new_pointer_type(BInt), 5) 1875 py.test.raises(TypeError, newp, BArray, 12.34) 1876 BFloat = new_primitive_type("float") 1877 py.test.raises(TypeError, cast, BFloat, newp(BArray, None)) 1878 1879def test_more_overflow_errors(): 1880 BUInt = new_primitive_type("unsigned int") 1881 py.test.raises(OverflowError, newp, new_pointer_type(BUInt), -1) 1882 py.test.raises(OverflowError, newp, new_pointer_type(BUInt), 2**32) 1883 1884def test_newp_copying(): 1885 """Test that we can do newp(<type>, <cdata of the given type>) for most 1886 types, including same-type arrays. 1887 """ 1888 BInt = new_primitive_type("int") 1889 p = newp(new_pointer_type(BInt), cast(BInt, 42)) 1890 assert p[0] == 42 1891 # 1892 BUInt = new_primitive_type("unsigned int") 1893 p = newp(new_pointer_type(BUInt), cast(BUInt, 42)) 1894 assert p[0] == 42 1895 # 1896 BChar = new_primitive_type("char") 1897 p = newp(new_pointer_type(BChar), cast(BChar, '!')) 1898 assert p[0] == b'!' 1899 # 1900 BFloat = new_primitive_type("float") 1901 p = newp(new_pointer_type(BFloat), cast(BFloat, 12.25)) 1902 assert p[0] == 12.25 1903 # 1904 BStruct = new_struct_type("struct foo_s") 1905 BStructPtr = new_pointer_type(BStruct) 1906 complete_struct_or_union(BStruct, [('a1', BInt, -1)]) 1907 s1 = newp(BStructPtr, [42]) 1908 p1 = newp(new_pointer_type(BStructPtr), s1) 1909 assert p1[0] == s1 1910 # 1911 BArray = new_array_type(new_pointer_type(BInt), None) 1912 a1 = newp(BArray, [1, 2, 3, 4]) 1913 py.test.raises(TypeError, newp, BArray, a1) 1914 BArray6 = new_array_type(new_pointer_type(BInt), 6) 1915 a1 = newp(BArray6, [10, 20, 30]) 1916 a2 = newp(BArray6, a1) 1917 assert list(a2) == [10, 20, 30, 0, 0, 0] 1918 # 1919 s1 = newp(BStructPtr, [42]) 1920 s2 = newp(BStructPtr, s1[0]) 1921 assert s2.a1 == 42 1922 # 1923 BUnion = new_union_type("union foo_u") 1924 BUnionPtr = new_pointer_type(BUnion) 1925 complete_struct_or_union(BUnion, [('a1', BInt, -1)]) 1926 u1 = newp(BUnionPtr, [42]) 1927 u2 = newp(BUnionPtr, u1[0]) 1928 assert u2.a1 == 42 1929 # 1930 BFunc = new_function_type((BInt,), BUInt) 1931 p1 = cast(BFunc, 42) 1932 p2 = newp(new_pointer_type(BFunc), p1) 1933 assert p2[0] == p1 1934 1935def test_string(): 1936 BChar = new_primitive_type("char") 1937 assert string(cast(BChar, 42)) == b'*' 1938 assert string(cast(BChar, 0)) == b'\x00' 1939 BCharP = new_pointer_type(BChar) 1940 BArray = new_array_type(BCharP, 10) 1941 a = newp(BArray, b"hello") 1942 assert len(a) == 10 1943 assert string(a) == b"hello" 1944 p = a + 2 1945 assert string(p) == b"llo" 1946 assert string(newp(new_array_type(BCharP, 4), b"abcd")) == b"abcd" 1947 py.test.raises(RuntimeError, string, cast(BCharP, 0)) 1948 assert string(a, 4) == b"hell" 1949 assert string(a, 5) == b"hello" 1950 assert string(a, 6) == b"hello" 1951 1952def test_string_byte(): 1953 BByte = new_primitive_type("signed char") 1954 assert string(cast(BByte, 42)) == b'*' 1955 assert string(cast(BByte, 0)) == b'\x00' 1956 BArray = new_array_type(new_pointer_type(BByte), None) 1957 a = newp(BArray, [65, 66, 67]) 1958 assert type(string(a)) is bytes and string(a) == b'ABC' 1959 # 1960 BByte = new_primitive_type("unsigned char") 1961 assert string(cast(BByte, 42)) == b'*' 1962 assert string(cast(BByte, 0)) == b'\x00' 1963 BArray = new_array_type(new_pointer_type(BByte), None) 1964 a = newp(BArray, [65, 66, 67]) 1965 assert type(string(a)) is bytes and string(a) == b'ABC' 1966 if 'PY_DOT_PY' not in globals() and sys.version_info < (3,): 1967 assert string(a, 8).startswith(b'ABC') # may contain additional garbage 1968 1969def test_string_wchar(): 1970 for typename in ["wchar_t", "char16_t", "char32_t"]: 1971 _test_string_wchar_variant(typename) 1972 1973def _test_string_wchar_variant(typename): 1974 BWChar = new_primitive_type(typename) 1975 assert string(cast(BWChar, 42)) == u+'*' 1976 assert string(cast(BWChar, 0x4253)) == u+'\u4253' 1977 assert string(cast(BWChar, 0)) == u+'\x00' 1978 BArray = new_array_type(new_pointer_type(BWChar), None) 1979 a = newp(BArray, [u+'A', u+'B', u+'C']) 1980 assert type(string(a)) is unicode and string(a) == u+'ABC' 1981 if 'PY_DOT_PY' not in globals() and sys.version_info < (3,): 1982 try: 1983 # may contain additional garbage 1984 assert string(a, 8).startswith(u+'ABC') 1985 except ValueError: # garbage contains values > 0x10FFFF 1986 assert sizeof(BWChar) == 4 1987 1988def test_string_typeerror(): 1989 BShort = new_primitive_type("short") 1990 BArray = new_array_type(new_pointer_type(BShort), None) 1991 a = newp(BArray, [65, 66, 67]) 1992 py.test.raises(TypeError, string, a) 1993 1994def test_bug_convert_to_ptr(): 1995 BChar = new_primitive_type("char") 1996 BCharP = new_pointer_type(BChar) 1997 BDouble = new_primitive_type("double") 1998 x = cast(BDouble, 42) 1999 py.test.raises(TypeError, newp, new_pointer_type(BCharP), x) 2000 2001def test_set_struct_fields(): 2002 BChar = new_primitive_type("char") 2003 BCharP = new_pointer_type(BChar) 2004 BCharArray10 = new_array_type(BCharP, 10) 2005 BStruct = new_struct_type("struct foo") 2006 BStructPtr = new_pointer_type(BStruct) 2007 complete_struct_or_union(BStruct, [('a1', BCharArray10, -1)]) 2008 p = newp(BStructPtr, None) 2009 assert string(p.a1) == b'' 2010 p.a1 = b'foo' 2011 assert string(p.a1) == b'foo' 2012 assert list(p.a1) == [b'f', b'o', b'o'] + [b'\x00'] * 7 2013 p.a1 = [b'x', b'y'] 2014 assert string(p.a1) == b'xyo' 2015 2016def test_invalid_function_result_types(): 2017 BFunc = new_function_type((), new_void_type()) 2018 BArray = new_array_type(new_pointer_type(BFunc), 5) # works 2019 new_function_type((), BFunc) # works 2020 new_function_type((), new_primitive_type("int")) 2021 new_function_type((), new_pointer_type(BFunc)) 2022 BUnion = new_union_type("union foo_u") 2023 complete_struct_or_union(BUnion, []) 2024 BFunc = new_function_type((), BUnion) 2025 py.test.raises(NotImplementedError, cast(BFunc, 123)) 2026 py.test.raises(TypeError, new_function_type, (), BArray) 2027 2028def test_struct_return_in_func(): 2029 BChar = new_primitive_type("char") 2030 BShort = new_primitive_type("short") 2031 BFloat = new_primitive_type("float") 2032 BDouble = new_primitive_type("double") 2033 BInt = new_primitive_type("int") 2034 BStruct = new_struct_type("struct foo_s") 2035 complete_struct_or_union(BStruct, [('a1', BChar, -1), 2036 ('a2', BShort, -1)]) 2037 BFunc10 = new_function_type((BInt,), BStruct) 2038 f = cast(BFunc10, _testfunc(10)) 2039 s = f(40) 2040 assert repr(s) == "<cdata 'struct foo_s' owning 4 bytes>" 2041 assert s.a1 == bytechr(40) 2042 assert s.a2 == 40 * 40 2043 # 2044 BStruct11 = new_struct_type("struct test11") 2045 complete_struct_or_union(BStruct11, [('a1', BInt, -1), 2046 ('a2', BInt, -1)]) 2047 BFunc11 = new_function_type((BInt,), BStruct11) 2048 f = cast(BFunc11, _testfunc(11)) 2049 s = f(40) 2050 assert repr(s) == "<cdata 'struct test11' owning 8 bytes>" 2051 assert s.a1 == 40 2052 assert s.a2 == 40 * 40 2053 # 2054 BStruct12 = new_struct_type("struct test12") 2055 complete_struct_or_union(BStruct12, [('a1', BDouble, -1), 2056 ]) 2057 BFunc12 = new_function_type((BInt,), BStruct12) 2058 f = cast(BFunc12, _testfunc(12)) 2059 s = f(40) 2060 assert repr(s) == "<cdata 'struct test12' owning 8 bytes>" 2061 assert s.a1 == 40.0 2062 # 2063 BStruct13 = new_struct_type("struct test13") 2064 complete_struct_or_union(BStruct13, [('a1', BInt, -1), 2065 ('a2', BInt, -1), 2066 ('a3', BInt, -1)]) 2067 BFunc13 = new_function_type((BInt,), BStruct13) 2068 f = cast(BFunc13, _testfunc(13)) 2069 s = f(40) 2070 assert repr(s) == "<cdata 'struct test13' owning 12 bytes>" 2071 assert s.a1 == 40 2072 assert s.a2 == 40 * 40 2073 assert s.a3 == 40 * 40 * 40 2074 # 2075 BStruct14 = new_struct_type("struct test14") 2076 complete_struct_or_union(BStruct14, [('a1', BFloat, -1), 2077 ]) 2078 BFunc14 = new_function_type((BInt,), BStruct14) 2079 f = cast(BFunc14, _testfunc(14)) 2080 s = f(40) 2081 assert repr(s) == "<cdata 'struct test14' owning 4 bytes>" 2082 assert s.a1 == 40.0 2083 # 2084 BStruct15 = new_struct_type("struct test15") 2085 complete_struct_or_union(BStruct15, [('a1', BFloat, -1), 2086 ('a2', BInt, -1)]) 2087 BFunc15 = new_function_type((BInt,), BStruct15) 2088 f = cast(BFunc15, _testfunc(15)) 2089 s = f(40) 2090 assert repr(s) == "<cdata 'struct test15' owning 8 bytes>" 2091 assert s.a1 == 40.0 2092 assert s.a2 == 40 * 40 2093 # 2094 BStruct16 = new_struct_type("struct test16") 2095 complete_struct_or_union(BStruct16, [('a1', BFloat, -1), 2096 ('a2', BFloat, -1)]) 2097 BFunc16 = new_function_type((BInt,), BStruct16) 2098 f = cast(BFunc16, _testfunc(16)) 2099 s = f(40) 2100 assert repr(s) == "<cdata 'struct test16' owning 8 bytes>" 2101 assert s.a1 == 40.0 2102 assert s.a2 == -40.0 2103 # 2104 BStruct17 = new_struct_type("struct test17") 2105 complete_struct_or_union(BStruct17, [('a1', BInt, -1), 2106 ('a2', BFloat, -1)]) 2107 BFunc17 = new_function_type((BInt,), BStruct17) 2108 f = cast(BFunc17, _testfunc(17)) 2109 s = f(40) 2110 assert repr(s) == "<cdata 'struct test17' owning 8 bytes>" 2111 assert s.a1 == 40 2112 assert s.a2 == 40.0 * 40.0 2113 # 2114 BStruct17Ptr = new_pointer_type(BStruct17) 2115 BFunc18 = new_function_type((BStruct17Ptr,), BInt) 2116 f = cast(BFunc18, _testfunc(18)) 2117 x = f([[40, 2.5]]) 2118 assert x == 42 2119 x = f([{'a2': 43.1}]) 2120 assert x == 43 2121 2122def test_cast_with_functionptr(): 2123 BFunc = new_function_type((), new_void_type()) 2124 BFunc2 = new_function_type((), new_primitive_type("short")) 2125 BCharP = new_pointer_type(new_primitive_type("char")) 2126 BIntP = new_pointer_type(new_primitive_type("int")) 2127 BStruct = new_struct_type("struct foo") 2128 BStructPtr = new_pointer_type(BStruct) 2129 complete_struct_or_union(BStruct, [('a1', BFunc, -1)]) 2130 newp(BStructPtr, [cast(BFunc, 0)]) 2131 newp(BStructPtr, [cast(BCharP, 0)]) 2132 py.test.raises(TypeError, newp, BStructPtr, [cast(BIntP, 0)]) 2133 py.test.raises(TypeError, newp, BStructPtr, [cast(BFunc2, 0)]) 2134 2135def test_wchar(): 2136 _test_wchar_variant("wchar_t") 2137 if sys.platform.startswith("linux"): 2138 BWChar = new_primitive_type("wchar_t") 2139 assert sizeof(BWChar) == 4 2140 # wchar_t is often signed on Linux, but not always (e.g. on ARM) 2141 assert int(cast(BWChar, -1)) in (-1, 4294967295) 2142 2143def test_char16(): 2144 BChar16 = new_primitive_type("char16_t") 2145 assert sizeof(BChar16) == 2 2146 _test_wchar_variant("char16_t") 2147 assert int(cast(BChar16, -1)) == 0xffff # always unsigned 2148 2149def test_char32(): 2150 BChar32 = new_primitive_type("char32_t") 2151 assert sizeof(BChar32) == 4 2152 _test_wchar_variant("char32_t") 2153 assert int(cast(BChar32, -1)) == 0xffffffff # always unsigned 2154 2155def _test_wchar_variant(typename): 2156 BWChar = new_primitive_type(typename) 2157 BInt = new_primitive_type("int") 2158 pyuni4 = {1: True, 2: False}[len(u+'\U00012345')] 2159 wchar4 = {2: False, 4: True}[sizeof(BWChar)] 2160 assert str(cast(BWChar, 0x45)) == "<cdata '%s' %s'E'>" % ( 2161 typename, mandatory_u_prefix) 2162 assert str(cast(BWChar, 0x1234)) == "<cdata '%s' %s'\u1234'>" % ( 2163 typename, mandatory_u_prefix) 2164 if not _hacked_pypy_uni4(): 2165 if wchar4: 2166 x = cast(BWChar, 0x12345) 2167 assert str(x) == "<cdata '%s' %s'\U00012345'>" % ( 2168 typename, mandatory_u_prefix) 2169 assert int(x) == 0x12345 2170 else: 2171 x = cast(BWChar, 0x18345) 2172 assert str(x) == "<cdata '%s' %s'\u8345'>" % ( 2173 typename, mandatory_u_prefix) 2174 assert int(x) == 0x8345 2175 # 2176 BWCharP = new_pointer_type(BWChar) 2177 BStruct = new_struct_type("struct foo_s") 2178 BStructPtr = new_pointer_type(BStruct) 2179 complete_struct_or_union(BStruct, [('a1', BWChar, -1), 2180 ('a2', BWCharP, -1)]) 2181 s = newp(BStructPtr) 2182 s.a1 = u+'\x00' 2183 assert s.a1 == u+'\x00' 2184 py.test.raises(TypeError, "s.a1 = b'a'") 2185 py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") 2186 s.a1 = u+'\u1234' 2187 assert s.a1 == u+'\u1234' 2188 if pyuni4: 2189 if wchar4: 2190 s.a1 = u+'\U00012345' 2191 assert s.a1 == u+'\U00012345' 2192 elif wchar4: 2193 if not _hacked_pypy_uni4(): 2194 s.a1 = cast(BWChar, 0x12345) 2195 assert s.a1 == u+'\ud808\udf45' 2196 s.a1 = u+'\ud807\udf44' 2197 assert s.a1 == u+'\U00011f44' 2198 else: 2199 py.test.raises(TypeError, "s.a1 = u+'\U00012345'") 2200 # 2201 BWCharArray = new_array_type(BWCharP, None) 2202 a = newp(BWCharArray, u+'hello \u1234 world') 2203 assert len(a) == 14 # including the final null 2204 assert string(a) == u+'hello \u1234 world' 2205 a[13] = u+'!' 2206 assert string(a) == u+'hello \u1234 world!' 2207 assert str(a) == repr(a) 2208 assert a[6] == u+'\u1234' 2209 a[6] = u+'-' 2210 assert string(a) == u+'hello - world!' 2211 assert str(a) == repr(a) 2212 # 2213 if wchar4 and not _hacked_pypy_uni4(): 2214 u1 = u+'\U00012345\U00012346\U00012347' 2215 a = newp(BWCharArray, u1) 2216 assert len(a) == 4 2217 assert string(a) == u1 2218 assert len(list(a)) == 4 2219 expected = [u+'\U00012345', u+'\U00012346', u+'\U00012347', unichr(0)] 2220 assert list(a) == expected 2221 got = [a[i] for i in range(4)] 2222 assert got == expected 2223 py.test.raises(IndexError, 'a[4]') 2224 # 2225 w = cast(BWChar, 'a') 2226 assert repr(w) == "<cdata '%s' %s'a'>" % (typename, mandatory_u_prefix) 2227 assert str(w) == repr(w) 2228 assert string(w) == u+'a' 2229 assert int(w) == ord('a') 2230 w = cast(BWChar, 0x1234) 2231 assert repr(w) == "<cdata '%s' %s'\u1234'>" % (typename, mandatory_u_prefix) 2232 assert str(w) == repr(w) 2233 assert string(w) == u+'\u1234' 2234 assert int(w) == 0x1234 2235 w = cast(BWChar, u+'\u8234') 2236 assert repr(w) == "<cdata '%s' %s'\u8234'>" % (typename, mandatory_u_prefix) 2237 assert str(w) == repr(w) 2238 assert string(w) == u+'\u8234' 2239 assert int(w) == 0x8234 2240 w = cast(BInt, u+'\u1234') 2241 assert repr(w) == "<cdata 'int' 4660>" 2242 if wchar4 and not _hacked_pypy_uni4(): 2243 w = cast(BWChar, u+'\U00012345') 2244 assert repr(w) == "<cdata '%s' %s'\U00012345'>" % ( 2245 typename, mandatory_u_prefix) 2246 assert str(w) == repr(w) 2247 assert string(w) == u+'\U00012345' 2248 assert int(w) == 0x12345 2249 w = cast(BInt, u+'\U00012345') 2250 assert repr(w) == "<cdata 'int' 74565>" 2251 py.test.raises(TypeError, cast, BInt, u+'') 2252 py.test.raises(TypeError, cast, BInt, u+'XX') 2253 assert int(cast(BInt, u+'a')) == ord('a') 2254 # 2255 a = newp(BWCharArray, u+'hello - world') 2256 p = cast(BWCharP, a) 2257 assert string(p) == u+'hello - world' 2258 p[6] = u+'\u2345' 2259 assert string(p) == u+'hello \u2345 world' 2260 # 2261 s = newp(BStructPtr, [u+'\u1234', p]) 2262 assert s.a1 == u+'\u1234' 2263 assert s.a2 == p 2264 assert str(s.a2) == repr(s.a2) 2265 assert string(s.a2) == u+'hello \u2345 world' 2266 # 2267 q = cast(BWCharP, 0) 2268 assert str(q) == repr(q) 2269 py.test.raises(RuntimeError, string, q) 2270 # 2271 def cb(p): 2272 assert repr(p).startswith("<cdata '%s *' 0x" % typename) 2273 return len(string(p)) 2274 BFunc = new_function_type((BWCharP,), BInt, False) 2275 f = callback(BFunc, cb, -42) 2276 assert f(u+'a\u1234b') == 3 2277 # 2278 if wchar4 and not pyuni4 and not _hacked_pypy_uni4(): 2279 # try out-of-range wchar_t values 2280 x = cast(BWChar, 1114112) 2281 py.test.raises(ValueError, string, x) 2282 x = cast(BWChar, -1) 2283 py.test.raises(ValueError, string, x) 2284 2285def test_wchar_variants_mix(): 2286 BWChar = new_primitive_type("wchar_t") 2287 BChar16 = new_primitive_type("char16_t") 2288 BChar32 = new_primitive_type("char32_t") 2289 assert int(cast(BChar32, cast(BChar16, -2))) == 0xfffe 2290 assert int(cast(BWChar, cast(BChar16, -2))) == 0xfffe 2291 assert int(cast(BChar16, cast(BChar32, 0x0001f345))) == 0xf345 2292 assert int(cast(BChar16, cast(BWChar, 0x0001f345))) == 0xf345 2293 # 2294 BChar16A = new_array_type(new_pointer_type(BChar16), None) 2295 BChar32A = new_array_type(new_pointer_type(BChar32), None) 2296 x = cast(BChar32, 'A') 2297 py.test.raises(TypeError, newp, BChar16A, [x]) 2298 x = cast(BChar16, 'A') 2299 py.test.raises(TypeError, newp, BChar32A, [x]) 2300 # 2301 a = newp(BChar16A, u+'\U00012345') 2302 assert len(a) == 3 2303 a = newp(BChar32A, u+'\U00012345') 2304 assert len(a) == 2 # even if the Python unicode string above is 2 chars 2305 2306def test_keepalive_struct(): 2307 # exception to the no-keepalive rule: p=newp(BStructPtr) returns a 2308 # pointer owning the memory, and p[0] returns a pointer to the 2309 # struct that *also* owns the memory 2310 BStruct = new_struct_type("struct foo") 2311 BStructPtr = new_pointer_type(BStruct) 2312 complete_struct_or_union(BStruct, [('a1', new_primitive_type("int"), -1), 2313 ('a2', new_primitive_type("int"), -1), 2314 ('a3', new_primitive_type("int"), -1)]) 2315 p = newp(BStructPtr) 2316 assert repr(p) == "<cdata 'struct foo *' owning 12 bytes>" 2317 q = p[0] 2318 assert repr(q) == "<cdata 'struct foo' owning 12 bytes>" 2319 q.a1 = 123456 2320 assert p.a1 == 123456 2321 r = cast(BStructPtr, p) 2322 assert repr(r[0]).startswith("<cdata 'struct foo &' 0x") 2323 del p 2324 import gc; gc.collect() 2325 assert q.a1 == 123456 2326 assert repr(q) == "<cdata 'struct foo' owning 12 bytes>" 2327 assert q.a1 == 123456 2328 2329def test_nokeepalive_struct(): 2330 BStruct = new_struct_type("struct foo") 2331 BStructPtr = new_pointer_type(BStruct) 2332 BStructPtrPtr = new_pointer_type(BStructPtr) 2333 complete_struct_or_union(BStruct, [('a1', new_primitive_type("int"), -1)]) 2334 p = newp(BStructPtr) 2335 pp = newp(BStructPtrPtr) 2336 pp[0] = p 2337 s = pp[0][0] 2338 assert repr(s).startswith("<cdata 'struct foo &' 0x") 2339 2340def test_owning_repr(): 2341 BInt = new_primitive_type("int") 2342 BArray = new_array_type(new_pointer_type(BInt), None) # int[] 2343 p = newp(BArray, 7) 2344 assert repr(p) == "<cdata 'int[]' owning 28 bytes>" 2345 assert sizeof(p) == 28 2346 # 2347 BArray = new_array_type(new_pointer_type(BInt), 7) # int[7] 2348 p = newp(BArray, None) 2349 assert repr(p) == "<cdata 'int[7]' owning 28 bytes>" 2350 assert sizeof(p) == 28 2351 2352def test_cannot_dereference_void(): 2353 BVoidP = new_pointer_type(new_void_type()) 2354 p = cast(BVoidP, 123456) 2355 py.test.raises(TypeError, "p[0]") 2356 p = cast(BVoidP, 0) 2357 py.test.raises((TypeError, RuntimeError), "p[0]") 2358 2359def test_iter(): 2360 BInt = new_primitive_type("int") 2361 BIntP = new_pointer_type(BInt) 2362 BArray = new_array_type(BIntP, None) # int[] 2363 p = newp(BArray, 7) 2364 assert list(p) == list(iter(p)) == [0] * 7 2365 # 2366 py.test.raises(TypeError, iter, cast(BInt, 5)) 2367 py.test.raises(TypeError, iter, cast(BIntP, 123456)) 2368 2369def test_cmp(): 2370 BInt = new_primitive_type("int") 2371 BIntP = new_pointer_type(BInt) 2372 BVoidP = new_pointer_type(new_void_type()) 2373 p = newp(BIntP, 123) 2374 q = cast(BInt, 124) 2375 assert (p == q) is False 2376 assert (p != q) is True 2377 assert (q == p) is False 2378 assert (q != p) is True 2379 if strict_compare: 2380 py.test.raises(TypeError, "p < q") 2381 py.test.raises(TypeError, "p <= q") 2382 py.test.raises(TypeError, "q < p") 2383 py.test.raises(TypeError, "q <= p") 2384 py.test.raises(TypeError, "p > q") 2385 py.test.raises(TypeError, "p >= q") 2386 r = cast(BVoidP, p) 2387 assert (p < r) is False 2388 assert (p <= r) is True 2389 assert (p == r) is True 2390 assert (p != r) is False 2391 assert (p > r) is False 2392 assert (p >= r) is True 2393 s = newp(BIntP, 125) 2394 assert (p == s) is False 2395 assert (p != s) is True 2396 assert (p < s) is (p <= s) is (s > p) is (s >= p) 2397 assert (p > s) is (p >= s) is (s < p) is (s <= p) 2398 assert (p < s) ^ (p > s) 2399 2400def test_buffer(): 2401 try: 2402 import __builtin__ 2403 except ImportError: 2404 import builtins as __builtin__ 2405 BShort = new_primitive_type("short") 2406 s = newp(new_pointer_type(BShort), 100) 2407 assert sizeof(s) == size_of_ptr() 2408 assert sizeof(BShort) == 2 2409 assert len(buffer(s)) == 2 2410 # 2411 BChar = new_primitive_type("char") 2412 BCharArray = new_array_type(new_pointer_type(BChar), None) 2413 c = newp(BCharArray, b"hi there") 2414 # 2415 buf = buffer(c) 2416 assert repr(buf).startswith('<_cffi_backend.buffer object at 0x') 2417 assert bytes(buf) == b"hi there\x00" 2418 assert type(buf) is buffer 2419 if sys.version_info < (3,): 2420 assert str(buf) == "hi there\x00" 2421 assert unicode(buf) == u+"hi there\x00" 2422 else: 2423 assert str(buf) == repr(buf) 2424 # --mb_length-- 2425 assert len(buf) == len(b"hi there\x00") 2426 # --mb_item-- 2427 for i in range(-12, 12): 2428 try: 2429 expected = b"hi there\x00"[i] 2430 except IndexError: 2431 py.test.raises(IndexError, "buf[i]") 2432 else: 2433 assert buf[i] == bitem2bchr(expected) 2434 # --mb_slice-- 2435 assert buf[:] == b"hi there\x00" 2436 for i in range(-12, 12): 2437 assert buf[i:] == b"hi there\x00"[i:] 2438 assert buf[:i] == b"hi there\x00"[:i] 2439 for j in range(-12, 12): 2440 assert buf[i:j] == b"hi there\x00"[i:j] 2441 # --misc-- 2442 assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) 2443 # --mb_as_buffer-- 2444 if hasattr(__builtin__, 'buffer'): # Python <= 2.7 2445 py.test.raises(TypeError, __builtin__.buffer, c) 2446 bf1 = __builtin__.buffer(buf) 2447 assert len(bf1) == len(buf) and bf1[3] == "t" 2448 if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 2449 py.test.raises(TypeError, memoryview, c) 2450 mv1 = memoryview(buf) 2451 assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) 2452 # --mb_ass_item-- 2453 expected = list(map(bitem2bchr, b"hi there\x00")) 2454 for i in range(-12, 12): 2455 try: 2456 expected[i] = bytechr(i & 0xff) 2457 except IndexError: 2458 py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") 2459 else: 2460 buf[i] = bytechr(i & 0xff) 2461 assert list(buf) == expected 2462 # --mb_ass_slice-- 2463 buf[:] = b"hi there\x00" 2464 assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) 2465 py.test.raises(ValueError, 'buf[:] = b"shorter"') 2466 py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') 2467 buf[4:2] = b"" # no effect, but should work 2468 assert buf[:] == b"hi there\x00" 2469 buf[:2] = b"HI" 2470 assert buf[:] == b"HI there\x00" 2471 buf[:2] = b"hi" 2472 expected = list(map(bitem2bchr, b"hi there\x00")) 2473 x = 0 2474 for i in range(-12, 12): 2475 for j in range(-12, 12): 2476 start = i if i >= 0 else i + len(buf) 2477 stop = j if j >= 0 else j + len(buf) 2478 start = max(0, min(len(buf), start)) 2479 stop = max(0, min(len(buf), stop)) 2480 sample = bytechr(x & 0xff) * (stop - start) 2481 x += 1 2482 buf[i:j] = sample 2483 expected[i:j] = map(bitem2bchr, sample) 2484 assert list(buf) == expected 2485 2486def test_getcname(): 2487 BUChar = new_primitive_type("unsigned char") 2488 BArray = new_array_type(new_pointer_type(BUChar), 123) 2489 assert getcname(BArray, "<-->") == "unsigned char<-->[123]" 2490 2491def test_errno(): 2492 BVoid = new_void_type() 2493 BFunc5 = new_function_type((), BVoid) 2494 f = cast(BFunc5, _testfunc(5)) 2495 set_errno(50) 2496 f() 2497 assert get_errno() == 65 2498 f(); f() 2499 assert get_errno() == 95 2500 2501def test_errno_callback(): 2502 if globals().get('PY_DOT_PY') == '2.5': 2503 py.test.skip("cannot run this test on py.py with Python 2.5") 2504 set_errno(95) 2505 def cb(): 2506 e = get_errno() 2507 set_errno(e - 6) 2508 BVoid = new_void_type() 2509 BFunc5 = new_function_type((), BVoid) 2510 f = callback(BFunc5, cb) 2511 f() 2512 assert get_errno() == 89 2513 f(); f() 2514 assert get_errno() == 77 2515 2516def test_cast_to_array(): 2517 # not valid in C! extension to get a non-owning <cdata 'int[3]'> 2518 BInt = new_primitive_type("int") 2519 BIntP = new_pointer_type(BInt) 2520 BArray = new_array_type(BIntP, 3) 2521 x = cast(BArray, 0) 2522 assert repr(x) == "<cdata 'int[3]' NULL>" 2523 2524def test_cast_invalid(): 2525 BStruct = new_struct_type("struct foo") 2526 complete_struct_or_union(BStruct, []) 2527 p = cast(new_pointer_type(BStruct), 123456) 2528 s = p[0] 2529 py.test.raises(TypeError, cast, BStruct, s) 2530 2531def test_bug_float_convertion(): 2532 BDouble = new_primitive_type("double") 2533 BDoubleP = new_pointer_type(BDouble) 2534 py.test.raises(TypeError, newp, BDoubleP, "foobar") 2535 2536def test_bug_delitem(): 2537 BChar = new_primitive_type("char") 2538 BCharP = new_pointer_type(BChar) 2539 x = newp(BCharP) 2540 py.test.raises(TypeError, "del x[0]") 2541 2542def test_bug_delattr(): 2543 BLong = new_primitive_type("long") 2544 BStruct = new_struct_type("struct foo") 2545 complete_struct_or_union(BStruct, [('a1', BLong, -1)]) 2546 x = newp(new_pointer_type(BStruct)) 2547 py.test.raises(AttributeError, "del x.a1") 2548 2549def test_variable_length_struct(): 2550 py.test.skip("later") 2551 BLong = new_primitive_type("long") 2552 BArray = new_array_type(new_pointer_type(BLong), None) 2553 BStruct = new_struct_type("struct foo") 2554 BStructP = new_pointer_type(BStruct) 2555 complete_struct_or_union(BStruct, [('a1', BLong, -1), 2556 ('a2', BArray, -1)]) 2557 assert sizeof(BStruct) == size_of_long() 2558 assert alignof(BStruct) == alignof(BLong) 2559 # 2560 py.test.raises(TypeError, newp, BStructP, None) 2561 x = newp(BStructP, 5) 2562 assert sizeof(x) == 6 * size_of_long() 2563 x[4] = 123 2564 assert x[4] == 123 2565 py.test.raises(IndexError, "x[5]") 2566 assert len(x.a2) == 5 2567 # 2568 py.test.raises(TypeError, newp, BStructP, [123]) 2569 x = newp(BStructP, [123, 5]) 2570 assert x.a1 == 123 2571 assert len(x.a2) == 5 2572 assert list(x.a2) == [0] * 5 2573 # 2574 x = newp(BStructP, {'a2': 5}) 2575 assert x.a1 == 0 2576 assert len(x.a2) == 5 2577 assert list(x.a2) == [0] * 5 2578 # 2579 x = newp(BStructP, [123, (4, 5)]) 2580 assert x.a1 == 123 2581 assert len(x.a2) == 2 2582 assert list(x.a2) == [4, 5] 2583 # 2584 x = newp(BStructP, {'a2': (4, 5)}) 2585 assert x.a1 == 0 2586 assert len(x.a2) == 2 2587 assert list(x.a2) == [4, 5] 2588 2589def test_autocast_int(): 2590 BInt = new_primitive_type("int") 2591 BIntPtr = new_pointer_type(BInt) 2592 BLongLong = new_primitive_type("long long") 2593 BULongLong = new_primitive_type("unsigned long long") 2594 BULongLongPtr = new_pointer_type(BULongLong) 2595 x = newp(BIntPtr, cast(BInt, 42)) 2596 assert x[0] == 42 2597 x = newp(BIntPtr, cast(BLongLong, 42)) 2598 assert x[0] == 42 2599 x = newp(BIntPtr, cast(BULongLong, 42)) 2600 assert x[0] == 42 2601 x = newp(BULongLongPtr, cast(BInt, 42)) 2602 assert x[0] == 42 2603 py.test.raises(OverflowError, newp, BULongLongPtr, cast(BInt, -42)) 2604 x = cast(BInt, cast(BInt, 42)) 2605 assert int(x) == 42 2606 x = cast(BInt, cast(BLongLong, 42)) 2607 assert int(x) == 42 2608 x = cast(BInt, cast(BULongLong, 42)) 2609 assert int(x) == 42 2610 x = cast(BULongLong, cast(BInt, 42)) 2611 assert int(x) == 42 2612 x = cast(BULongLong, cast(BInt, -42)) 2613 assert int(x) == 2 ** 64 - 42 2614 x = cast(BIntPtr, cast(BInt, 42)) 2615 assert int(cast(BInt, x)) == 42 2616 2617def test_autocast_float(): 2618 BFloat = new_primitive_type("float") 2619 BDouble = new_primitive_type("float") 2620 BFloatPtr = new_pointer_type(BFloat) 2621 x = newp(BFloatPtr, cast(BDouble, 12.5)) 2622 assert x[0] == 12.5 2623 x = cast(BFloat, cast(BDouble, 12.5)) 2624 assert float(x) == 12.5 2625 2626def test_longdouble(): 2627 py_py = 'PY_DOT_PY' in globals() 2628 BInt = new_primitive_type("int") 2629 BLongDouble = new_primitive_type("long double") 2630 BLongDoublePtr = new_pointer_type(BLongDouble) 2631 BLongDoubleArray = new_array_type(BLongDoublePtr, None) 2632 a = newp(BLongDoubleArray, 1) 2633 x = a[0] 2634 if not py_py: 2635 assert repr(x).startswith("<cdata 'long double' 0.0") 2636 assert float(x) == 0.0 2637 assert int(x) == 0 2638 # 2639 b = newp(BLongDoubleArray, [1.23]) 2640 x = b[0] 2641 if not py_py: 2642 assert repr(x).startswith("<cdata 'long double' 1.23") 2643 assert float(x) == 1.23 2644 assert int(x) == 1 2645 # 2646 BFunc19 = new_function_type((BLongDouble, BInt), BLongDouble) 2647 f = cast(BFunc19, _testfunc(19)) 2648 start = lstart = 1.5 2649 for i in range(107): 2650 start = 4 * start - start * start 2651 lstart = f(lstart, 1) 2652 lother = f(1.5, 107) 2653 if not py_py: 2654 assert float(lstart) == float(lother) 2655 assert repr(lstart) == repr(lother) 2656 if sizeof(BLongDouble) > sizeof(new_primitive_type("double")): 2657 assert float(lstart) != start 2658 assert repr(lstart).startswith("<cdata 'long double' ") 2659 # 2660 c = newp(BLongDoubleArray, [lstart]) 2661 x = c[0] 2662 assert float(f(lstart, 107)) == float(f(x, 107)) 2663 2664def test_get_array_of_length_zero(): 2665 for length in [0, 5, 10]: 2666 BLong = new_primitive_type("long") 2667 BLongP = new_pointer_type(BLong) 2668 BArray0 = new_array_type(BLongP, length) 2669 BStruct = new_struct_type("struct foo") 2670 BStructPtr = new_pointer_type(BStruct) 2671 complete_struct_or_union(BStruct, [('a1', BArray0, -1)]) 2672 p = newp(BStructPtr, None) 2673 if length == 0: 2674 assert repr(p.a1).startswith("<cdata 'long *' 0x") 2675 else: 2676 assert repr(p.a1).startswith("<cdata 'long[%d]' 0x" % length) 2677 2678def test_nested_anonymous_struct(): 2679 BInt = new_primitive_type("int") 2680 BChar = new_primitive_type("char") 2681 BStruct = new_struct_type("struct foo") 2682 BInnerStruct = new_struct_type("struct foo") 2683 complete_struct_or_union(BInnerStruct, [('a1', BInt, -1), 2684 ('a2', BChar, -1)]) 2685 complete_struct_or_union(BStruct, [('', BInnerStruct, -1), 2686 ('a3', BChar, -1)]) 2687 assert sizeof(BInnerStruct) == sizeof(BInt) * 2 # with alignment 2688 assert sizeof(BStruct) == sizeof(BInt) * 3 # 'a3' is placed after 2689 d = BStruct.fields 2690 assert len(d) == 3 2691 assert d[0][0] == 'a1' 2692 assert d[0][1].type is BInt 2693 assert d[0][1].offset == 0 2694 assert d[0][1].bitshift == -1 2695 assert d[0][1].bitsize == -1 2696 assert d[1][0] == 'a2' 2697 assert d[1][1].type is BChar 2698 assert d[1][1].offset == sizeof(BInt) 2699 assert d[1][1].bitshift == -1 2700 assert d[1][1].bitsize == -1 2701 assert d[2][0] == 'a3' 2702 assert d[2][1].type is BChar 2703 assert d[2][1].offset == sizeof(BInt) * 2 2704 assert d[2][1].bitshift == -1 2705 assert d[2][1].bitsize == -1 2706 2707def test_nested_anonymous_struct_2(): 2708 BInt = new_primitive_type("int") 2709 BStruct = new_struct_type("struct foo") 2710 BInnerUnion = new_union_type("union bar") 2711 complete_struct_or_union(BInnerUnion, [('a1', BInt, -1), 2712 ('a2', BInt, -1)]) 2713 complete_struct_or_union(BStruct, [('b1', BInt, -1), 2714 ('', BInnerUnion, -1), 2715 ('b2', BInt, -1)]) 2716 assert sizeof(BInnerUnion) == sizeof(BInt) 2717 assert sizeof(BStruct) == sizeof(BInt) * 3 2718 fields = [(name, fld.offset, fld.flags) for (name, fld) in BStruct.fields] 2719 assert fields == [ 2720 ('b1', 0 * sizeof(BInt), 0), 2721 ('a1', 1 * sizeof(BInt), 0), 2722 ('a2', 1 * sizeof(BInt), 1), 2723 ('b2', 2 * sizeof(BInt), 0), 2724 ] 2725 2726def test_sizeof_union(): 2727 # a union has the largest alignment of its members, and a total size 2728 # that is the largest of its items *possibly further aligned* if 2729 # another smaller item has a larger alignment... 2730 BChar = new_primitive_type("char") 2731 BShort = new_primitive_type("short") 2732 assert sizeof(BShort) == alignof(BShort) == 2 2733 BStruct = new_struct_type("struct foo") 2734 complete_struct_or_union(BStruct, [('a1', BChar), 2735 ('a2', BChar), 2736 ('a3', BChar)]) 2737 assert sizeof(BStruct) == 3 and alignof(BStruct) == 1 2738 BUnion = new_union_type("union u") 2739 complete_struct_or_union(BUnion, [('s', BStruct), 2740 ('i', BShort)]) 2741 assert sizeof(BUnion) == 4 2742 assert alignof(BUnion) == 2 2743 2744def test_unaligned_struct(): 2745 BInt = new_primitive_type("int") 2746 BStruct = new_struct_type("struct foo") 2747 complete_struct_or_union(BStruct, [('b', BInt, -1, 1)], 2748 None, 5, 1) 2749 2750def test_CData_CType(): 2751 CData, CType = _get_types() 2752 BChar = new_primitive_type("char") 2753 BCharP = new_pointer_type(BChar) 2754 nullchr = cast(BChar, 0) 2755 chrref = newp(BCharP, None) 2756 assert isinstance(nullchr, CData) 2757 assert isinstance(chrref, CData) 2758 assert not isinstance(BChar, CData) 2759 assert not isinstance(nullchr, CType) 2760 assert not isinstance(chrref, CType) 2761 assert isinstance(BChar, CType) 2762 2763def test_no_cdata_float(): 2764 BInt = new_primitive_type("int") 2765 BIntP = new_pointer_type(BInt) 2766 BUInt = new_primitive_type("unsigned int") 2767 BUIntP = new_pointer_type(BUInt) 2768 BFloat = new_primitive_type("float") 2769 py.test.raises(TypeError, newp, BIntP, cast(BFloat, 0.0)) 2770 py.test.raises(TypeError, newp, BUIntP, cast(BFloat, 0.0)) 2771 2772def test_bool(): 2773 BBool = new_primitive_type("_Bool") 2774 BBoolP = new_pointer_type(BBool) 2775 assert int(cast(BBool, False)) == 0 2776 assert int(cast(BBool, True)) == 1 2777 assert bool(cast(BBool, False)) is False # since 1.7 2778 assert bool(cast(BBool, True)) is True 2779 assert int(cast(BBool, 3)) == 1 2780 assert int(cast(BBool, long(3))) == 1 2781 assert int(cast(BBool, long(10)**4000)) == 1 2782 assert int(cast(BBool, -0.1)) == 1 2783 assert int(cast(BBool, -0.0)) == 0 2784 assert int(cast(BBool, '\x00')) == 0 2785 assert int(cast(BBool, '\xff')) == 1 2786 assert newp(BBoolP, False)[0] == 0 2787 assert newp(BBoolP, True)[0] == 1 2788 assert newp(BBoolP, 0)[0] == 0 2789 assert newp(BBoolP, 1)[0] == 1 2790 py.test.raises(TypeError, newp, BBoolP, 1.0) 2791 py.test.raises(TypeError, newp, BBoolP, '\x00') 2792 py.test.raises(OverflowError, newp, BBoolP, 2) 2793 py.test.raises(OverflowError, newp, BBoolP, -1) 2794 BCharP = new_pointer_type(new_primitive_type("char")) 2795 p = newp(BCharP, b'\x01') 2796 q = cast(BBoolP, p) 2797 assert q[0] is True 2798 p = newp(BCharP, b'\x00') 2799 q = cast(BBoolP, p) 2800 assert q[0] is False 2801 py.test.raises(TypeError, string, cast(BBool, False)) 2802 BDouble = new_primitive_type("double") 2803 assert int(cast(BBool, cast(BDouble, 0.1))) == 1 2804 assert int(cast(BBool, cast(BDouble, 0.0))) == 0 2805 BBoolA = new_array_type(BBoolP, None) 2806 p = newp(BBoolA, b'\x01\x00') 2807 assert p[0] is True 2808 assert p[1] is False 2809 2810def test_bool_forbidden_cases(): 2811 BBool = new_primitive_type("_Bool") 2812 BBoolP = new_pointer_type(BBool) 2813 BBoolA = new_array_type(BBoolP, None) 2814 BCharP = new_pointer_type(new_primitive_type("char")) 2815 p = newp(BCharP, b'X') 2816 q = cast(BBoolP, p) 2817 py.test.raises(ValueError, "q[0]") 2818 py.test.raises(TypeError, newp, BBoolP, b'\x00') 2819 assert newp(BBoolP, 0)[0] is False 2820 assert newp(BBoolP, 1)[0] is True 2821 py.test.raises(OverflowError, newp, BBoolP, 2) 2822 py.test.raises(OverflowError, newp, BBoolP, -1) 2823 py.test.raises(ValueError, newp, BBoolA, b'\x00\x01\x02') 2824 py.test.raises(OverflowError, newp, BBoolA, [0, 1, 2]) 2825 py.test.raises(TypeError, string, newp(BBoolP, 1)) 2826 py.test.raises(TypeError, string, newp(BBoolA, [1])) 2827 2828def test_typeoffsetof(): 2829 BChar = new_primitive_type("char") 2830 BStruct = new_struct_type("struct foo") 2831 BStructPtr = new_pointer_type(BStruct) 2832 complete_struct_or_union(BStruct, [('a1', BChar, -1), 2833 ('a2', BChar, -1), 2834 ('a3', BChar, -1)]) 2835 py.test.raises(TypeError, typeoffsetof, BStructPtr, None) 2836 py.test.raises(TypeError, typeoffsetof, BStruct, None) 2837 assert typeoffsetof(BStructPtr, 'a1') == (BChar, 0) 2838 assert typeoffsetof(BStruct, 'a1') == (BChar, 0) 2839 assert typeoffsetof(BStructPtr, 'a2') == (BChar, 1) 2840 assert typeoffsetof(BStruct, 'a3') == (BChar, 2) 2841 assert typeoffsetof(BStructPtr, 'a2', 0) == (BChar, 1) 2842 assert typeoffsetof(BStruct, u+'a3') == (BChar, 2) 2843 py.test.raises(TypeError, typeoffsetof, BStructPtr, 'a2', 1) 2844 py.test.raises(KeyError, typeoffsetof, BStructPtr, 'a4') 2845 py.test.raises(KeyError, typeoffsetof, BStruct, 'a5') 2846 py.test.raises(TypeError, typeoffsetof, BStruct, 42) 2847 py.test.raises(TypeError, typeoffsetof, BChar, 'a1') 2848 2849def test_typeoffsetof_array(): 2850 BInt = new_primitive_type("int") 2851 BIntP = new_pointer_type(BInt) 2852 BArray = new_array_type(BIntP, None) 2853 py.test.raises(TypeError, typeoffsetof, BArray, None) 2854 py.test.raises(TypeError, typeoffsetof, BArray, 'a1') 2855 assert typeoffsetof(BArray, 51) == (BInt, 51 * size_of_int()) 2856 assert typeoffsetof(BIntP, 51) == (BInt, 51 * size_of_int()) 2857 assert typeoffsetof(BArray, -51) == (BInt, -51 * size_of_int()) 2858 MAX = sys.maxsize // size_of_int() 2859 assert typeoffsetof(BArray, MAX) == (BInt, MAX * size_of_int()) 2860 assert typeoffsetof(BIntP, MAX) == (BInt, MAX * size_of_int()) 2861 py.test.raises(OverflowError, typeoffsetof, BArray, MAX + 1) 2862 2863def test_typeoffsetof_no_bitfield(): 2864 BInt = new_primitive_type("int") 2865 BStruct = new_struct_type("struct foo") 2866 complete_struct_or_union(BStruct, [('a1', BInt, 4)]) 2867 py.test.raises(TypeError, typeoffsetof, BStruct, 'a1') 2868 2869def test_rawaddressof(): 2870 BChar = new_primitive_type("char") 2871 BCharP = new_pointer_type(BChar) 2872 BStruct = new_struct_type("struct foo") 2873 BStructPtr = new_pointer_type(BStruct) 2874 complete_struct_or_union(BStruct, [('a1', BChar, -1), 2875 ('a2', BChar, -1), 2876 ('a3', BChar, -1)]) 2877 p = newp(BStructPtr) 2878 assert repr(p) == "<cdata 'struct foo *' owning 3 bytes>" 2879 s = p[0] 2880 assert repr(s) == "<cdata 'struct foo' owning 3 bytes>" 2881 a = rawaddressof(BStructPtr, s, 0) 2882 assert repr(a).startswith("<cdata 'struct foo *' 0x") 2883 py.test.raises(TypeError, rawaddressof, BStruct, s, 0) 2884 b = rawaddressof(BCharP, s, 0) 2885 assert b == cast(BCharP, p) 2886 c = rawaddressof(BStructPtr, a, 0) 2887 assert c == a 2888 py.test.raises(TypeError, rawaddressof, BStructPtr, cast(BChar, '?'), 0) 2889 # 2890 d = rawaddressof(BCharP, s, 1) 2891 assert d == cast(BCharP, p) + 1 2892 # 2893 e = cast(BCharP, 109238) 2894 f = rawaddressof(BCharP, e, 42) 2895 assert f == e + 42 2896 # 2897 BCharA = new_array_type(BCharP, None) 2898 e = newp(BCharA, 50) 2899 f = rawaddressof(BCharP, e, 42) 2900 assert f == e + 42 2901 2902def test_newp_signed_unsigned_char(): 2903 BCharArray = new_array_type( 2904 new_pointer_type(new_primitive_type("char")), None) 2905 p = newp(BCharArray, b"foo") 2906 assert len(p) == 4 2907 assert list(p) == [b"f", b"o", b"o", b"\x00"] 2908 # 2909 BUCharArray = new_array_type( 2910 new_pointer_type(new_primitive_type("unsigned char")), None) 2911 p = newp(BUCharArray, b"fo\xff") 2912 assert len(p) == 4 2913 assert list(p) == [ord("f"), ord("o"), 0xff, 0] 2914 # 2915 BSCharArray = new_array_type( 2916 new_pointer_type(new_primitive_type("signed char")), None) 2917 p = newp(BSCharArray, b"fo\xff") 2918 assert len(p) == 4 2919 assert list(p) == [ord("f"), ord("o"), -1, 0] 2920 2921def test_newp_from_bytearray_doesnt_work(): 2922 BCharArray = new_array_type( 2923 new_pointer_type(new_primitive_type("char")), None) 2924 py.test.raises(TypeError, newp, BCharArray, bytearray(b"foo")) 2925 p = newp(BCharArray, 5) 2926 buffer(p)[:] = bytearray(b"foo.\x00") 2927 assert len(p) == 5 2928 assert list(p) == [b"f", b"o", b"o", b".", b"\x00"] 2929 p[1:3] = bytearray(b"XY") 2930 assert list(p) == [b"f", b"X", b"Y", b".", b"\x00"] 2931 2932def test_string_assignment_to_byte_array(): 2933 BByteArray = new_array_type( 2934 new_pointer_type(new_primitive_type("unsigned char")), None) 2935 p = newp(BByteArray, 5) 2936 p[0:3] = bytearray(b"XYZ") 2937 assert list(p) == [ord("X"), ord("Y"), ord("Z"), 0, 0] 2938 2939# XXX hack 2940if sys.version_info >= (3,): 2941 try: 2942 import posix, io 2943 posix.fdopen = io.open 2944 except ImportError: 2945 pass # win32 2946 2947def test_FILE(): 2948 if sys.platform == "win32": 2949 py.test.skip("testing FILE not implemented") 2950 # 2951 BFILE = new_struct_type("struct _IO_FILE") 2952 BFILEP = new_pointer_type(BFILE) 2953 BChar = new_primitive_type("char") 2954 BCharP = new_pointer_type(BChar) 2955 BInt = new_primitive_type("int") 2956 BFunc = new_function_type((BCharP, BFILEP), BInt, False) 2957 BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) 2958 ll = find_and_load_library('c') 2959 fputs = ll.load_function(BFunc, "fputs") 2960 fscanf = ll.load_function(BFunc2, "fscanf") 2961 # 2962 import posix 2963 fdr, fdw = posix.pipe() 2964 fr1 = posix.fdopen(fdr, 'rb', 256) 2965 fw1 = posix.fdopen(fdw, 'wb', 256) 2966 # 2967 fw1.write(b"X") 2968 res = fputs(b"hello world\n", fw1) 2969 assert res >= 0 2970 fw1.flush() # should not be needed 2971 # 2972 p = newp(new_array_type(BCharP, 100), None) 2973 res = fscanf(fr1, b"%s\n", p) 2974 assert res == 1 2975 assert string(p) == b"Xhello" 2976 fr1.close() 2977 fw1.close() 2978 2979def test_FILE_only_for_FILE_arg(): 2980 if sys.platform == "win32": 2981 py.test.skip("testing FILE not implemented") 2982 # 2983 B_NOT_FILE = new_struct_type("struct NOT_FILE") 2984 B_NOT_FILEP = new_pointer_type(B_NOT_FILE) 2985 BChar = new_primitive_type("char") 2986 BCharP = new_pointer_type(BChar) 2987 BInt = new_primitive_type("int") 2988 BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) 2989 ll = find_and_load_library('c') 2990 fputs = ll.load_function(BFunc, "fputs") 2991 # 2992 import posix 2993 fdr, fdw = posix.pipe() 2994 fr1 = posix.fdopen(fdr, 'r') 2995 fw1 = posix.fdopen(fdw, 'w') 2996 # 2997 e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) 2998 assert str(e.value).startswith( 2999 "initializer for ctype 'struct NOT_FILE *' must " 3000 "be a cdata pointer, not ") 3001 3002def test_FILE_object(): 3003 if sys.platform == "win32": 3004 py.test.skip("testing FILE not implemented") 3005 # 3006 BFILE = new_struct_type("FILE") 3007 BFILEP = new_pointer_type(BFILE) 3008 BChar = new_primitive_type("char") 3009 BCharP = new_pointer_type(BChar) 3010 BInt = new_primitive_type("int") 3011 BFunc = new_function_type((BCharP, BFILEP), BInt, False) 3012 BFunc2 = new_function_type((BFILEP,), BInt, False) 3013 ll = find_and_load_library('c') 3014 fputs = ll.load_function(BFunc, "fputs") 3015 fileno = ll.load_function(BFunc2, "fileno") 3016 # 3017 import posix 3018 fdr, fdw = posix.pipe() 3019 fw1 = posix.fdopen(fdw, 'wb', 256) 3020 # 3021 fw1p = cast(BFILEP, fw1) 3022 fw1.write(b"X") 3023 fw1.flush() 3024 res = fputs(b"hello\n", fw1p) 3025 assert res >= 0 3026 res = fileno(fw1p) 3027 assert (res == fdw) == (sys.version_info < (3,)) 3028 fw1.close() 3029 # 3030 data = posix.read(fdr, 256) 3031 assert data == b"Xhello\n" 3032 posix.close(fdr) 3033 3034def test_errno_saved(): 3035 set_errno(42) 3036 # a random function that will reset errno to 0 (at least on non-windows) 3037 import os; os.stat('.') 3038 # 3039 res = get_errno() 3040 assert res == 42 3041 3042def test_GetLastError(): 3043 if sys.platform != "win32": 3044 py.test.skip("GetLastError(): only for Windows") 3045 # 3046 lib = find_and_load_library('KERNEL32.DLL') 3047 BInt = new_primitive_type("int") 3048 BVoid = new_void_type() 3049 BFunc1 = new_function_type((BInt,), BVoid, False) 3050 BFunc2 = new_function_type((), BInt, False) 3051 SetLastError = lib.load_function(BFunc1, "SetLastError") 3052 GetLastError = lib.load_function(BFunc2, "GetLastError") 3053 # 3054 SetLastError(42) 3055 # a random function that will reset the real GetLastError() to 0 3056 import nt; nt.stat('.') 3057 # 3058 res = GetLastError() 3059 assert res == 42 3060 # 3061 SetLastError(2) 3062 code, message = getwinerror() 3063 assert code == 2 3064 assert message == "The system cannot find the file specified" 3065 # 3066 code, message = getwinerror(1155) 3067 assert code == 1155 3068 assert message == ("No application is associated with the " 3069 "specified file for this operation") 3070 3071def test_nonstandard_integer_types(): 3072 for typename in ['int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 3073 'uint32_t', 'int64_t', 'uint64_t', 'intptr_t', 3074 'uintptr_t', 'ptrdiff_t', 'size_t', 'ssize_t', 3075 'int_least8_t', 'uint_least8_t', 3076 'int_least16_t', 'uint_least16_t', 3077 'int_least32_t', 'uint_least32_t', 3078 'int_least64_t', 'uint_least64_t', 3079 'int_fast8_t', 'uint_fast8_t', 3080 'int_fast16_t', 'uint_fast16_t', 3081 'int_fast32_t', 'uint_fast32_t', 3082 'int_fast64_t', 'uint_fast64_t', 3083 'intmax_t', 'uintmax_t']: 3084 new_primitive_type(typename) # works 3085 3086def test_cannot_convert_unicode_to_charp(): 3087 BCharP = new_pointer_type(new_primitive_type("char")) 3088 BCharArray = new_array_type(BCharP, None) 3089 py.test.raises(TypeError, newp, BCharArray, u+'foobar') 3090 3091def test_buffer_keepalive(): 3092 BCharP = new_pointer_type(new_primitive_type("char")) 3093 BCharArray = new_array_type(BCharP, None) 3094 buflist = [] 3095 for i in range(20): 3096 c = newp(BCharArray, str2bytes("hi there %d" % i)) 3097 buflist.append(buffer(c)) 3098 import gc; gc.collect() 3099 for i in range(20): 3100 buf = buflist[i] 3101 assert buf[:] == str2bytes("hi there %d\x00" % i) 3102 3103def test_slice(): 3104 BIntP = new_pointer_type(new_primitive_type("int")) 3105 BIntArray = new_array_type(BIntP, None) 3106 c = newp(BIntArray, 5) 3107 assert len(c) == 5 3108 assert repr(c) == "<cdata 'int[]' owning 20 bytes>" 3109 d = c[1:4] 3110 assert len(d) == 3 3111 assert repr(d) == "<cdata 'int[]' sliced length 3>" 3112 d[0] = 123 3113 d[2] = 456 3114 assert c[1] == 123 3115 assert c[3] == 456 3116 assert d[2] == 456 3117 py.test.raises(IndexError, "d[3]") 3118 py.test.raises(IndexError, "d[-1]") 3119 3120def test_slice_ptr(): 3121 BIntP = new_pointer_type(new_primitive_type("int")) 3122 BIntArray = new_array_type(BIntP, None) 3123 c = newp(BIntArray, 5) 3124 d = (c+1)[0:2] 3125 assert len(d) == 2 3126 assert repr(d) == "<cdata 'int[]' sliced length 2>" 3127 d[1] += 50 3128 assert c[2] == 50 3129 3130def test_slice_array_checkbounds(): 3131 BIntP = new_pointer_type(new_primitive_type("int")) 3132 BIntArray = new_array_type(BIntP, None) 3133 c = newp(BIntArray, 5) 3134 c[0:5] 3135 assert len(c[5:5]) == 0 3136 py.test.raises(IndexError, "c[-1:1]") 3137 cp = c + 0 3138 cp[-1:1] 3139 3140def test_nonstandard_slice(): 3141 BIntP = new_pointer_type(new_primitive_type("int")) 3142 BIntArray = new_array_type(BIntP, None) 3143 c = newp(BIntArray, 5) 3144 e = py.test.raises(IndexError, "c[:5]") 3145 assert str(e.value) == "slice start must be specified" 3146 e = py.test.raises(IndexError, "c[4:]") 3147 assert str(e.value) == "slice stop must be specified" 3148 e = py.test.raises(IndexError, "c[1:2:3]") 3149 assert str(e.value) == "slice with step not supported" 3150 e = py.test.raises(IndexError, "c[1:2:1]") 3151 assert str(e.value) == "slice with step not supported" 3152 e = py.test.raises(IndexError, "c[4:2]") 3153 assert str(e.value) == "slice start > stop" 3154 e = py.test.raises(IndexError, "c[6:6]") 3155 assert str(e.value) == "index too large (expected 6 <= 5)" 3156 3157def test_setslice(): 3158 BIntP = new_pointer_type(new_primitive_type("int")) 3159 BIntArray = new_array_type(BIntP, None) 3160 c = newp(BIntArray, 5) 3161 c[1:3] = [100, 200] 3162 assert list(c) == [0, 100, 200, 0, 0] 3163 cp = c + 3 3164 cp[-1:1] = [300, 400] 3165 assert list(c) == [0, 100, 300, 400, 0] 3166 cp[-1:1] = iter([500, 600]) 3167 assert list(c) == [0, 100, 500, 600, 0] 3168 py.test.raises(ValueError, "cp[-1:1] = [1000]") 3169 assert list(c) == [0, 100, 1000, 600, 0] 3170 py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") 3171 assert list(c) == [0, 100, 700, 800, 0] 3172 3173def test_setslice_array(): 3174 BIntP = new_pointer_type(new_primitive_type("int")) 3175 BIntArray = new_array_type(BIntP, None) 3176 c = newp(BIntArray, 5) 3177 d = newp(BIntArray, [10, 20, 30]) 3178 c[1:4] = d 3179 assert list(c) == [0, 10, 20, 30, 0] 3180 # 3181 BShortP = new_pointer_type(new_primitive_type("short")) 3182 BShortArray = new_array_type(BShortP, None) 3183 d = newp(BShortArray, [40, 50]) 3184 c[1:3] = d 3185 assert list(c) == [0, 40, 50, 30, 0] 3186 3187def test_cdata_name_module_doc(): 3188 p = new_primitive_type("signed char") 3189 x = cast(p, 17) 3190 assert x.__module__ == '_cffi_backend' 3191 assert x.__name__ == '<cdata>' 3192 assert hasattr(x, '__doc__') 3193 3194def test_different_types_of_ptr_equality(): 3195 BVoidP = new_pointer_type(new_void_type()) 3196 BIntP = new_pointer_type(new_primitive_type("int")) 3197 x = cast(BVoidP, 12345) 3198 assert x == cast(BIntP, 12345) 3199 assert x != cast(BIntP, 12344) 3200 assert hash(x) == hash(cast(BIntP, 12345)) 3201 3202def test_new_handle(): 3203 import _weakref 3204 BVoidP = new_pointer_type(new_void_type()) 3205 BCharP = new_pointer_type(new_primitive_type("char")) 3206 class mylist(list): 3207 pass 3208 o = mylist([2, 3, 4]) 3209 x = newp_handle(BVoidP, o) 3210 assert repr(x) == "<cdata 'void *' handle to [2, 3, 4]>" 3211 assert x 3212 assert from_handle(x) is o 3213 assert from_handle(cast(BCharP, x)) is o 3214 wr = _weakref.ref(o) 3215 del o 3216 import gc; gc.collect() 3217 assert wr() is not None 3218 assert from_handle(x) == list((2, 3, 4)) 3219 assert from_handle(cast(BCharP, x)) == list((2, 3, 4)) 3220 del x 3221 for i in range(3): 3222 if wr() is not None: 3223 import gc; gc.collect() 3224 assert wr() is None 3225 py.test.raises(RuntimeError, from_handle, cast(BCharP, 0)) 3226 3227def test_new_handle_cycle(): 3228 import _weakref 3229 BVoidP = new_pointer_type(new_void_type()) 3230 class A(object): 3231 pass 3232 o = A() 3233 o.cycle = newp_handle(BVoidP, o) 3234 wr = _weakref.ref(o) 3235 del o 3236 for i in range(3): 3237 if wr() is not None: 3238 import gc; gc.collect() 3239 assert wr() is None 3240 3241def _test_bitfield_details(flag): 3242 BChar = new_primitive_type("char") 3243 BShort = new_primitive_type("short") 3244 BInt = new_primitive_type("int") 3245 BUInt = new_primitive_type("unsigned int") 3246 BStruct = new_struct_type("struct foo1") 3247 complete_struct_or_union(BStruct, [('a', BChar, -1), 3248 ('b1', BInt, 9), 3249 ('b2', BUInt, 7), 3250 ('c', BChar, -1)], -1, -1, -1, flag) 3251 if not (flag & SF_MSVC_BITFIELDS): # gcc, any variant 3252 assert typeoffsetof(BStruct, 'c') == (BChar, 3) 3253 assert sizeof(BStruct) == 4 3254 else: # msvc 3255 assert typeoffsetof(BStruct, 'c') == (BChar, 8) 3256 assert sizeof(BStruct) == 12 3257 assert alignof(BStruct) == 4 3258 # 3259 p = newp(new_pointer_type(BStruct), None) 3260 p.a = b'A' 3261 p.b1 = -201 3262 p.b2 = 99 3263 p.c = b'\x9D' 3264 raw = buffer(p)[:] 3265 if sys.byteorder == 'little': 3266 if flag & SF_MSVC_BITFIELDS: 3267 assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' 3268 elif flag & SF_GCC_LITTLE_ENDIAN: 3269 assert raw == b'A7\xC7\x9D' 3270 elif flag & SF_GCC_BIG_ENDIAN: 3271 assert raw == b'A\xE3\x9B\x9D' 3272 else: 3273 raise AssertionError("bad flag") 3274 else: 3275 if flag & SF_MSVC_BITFIELDS: 3276 assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' 3277 elif flag & SF_GCC_LITTLE_ENDIAN: 3278 assert raw == b'A\xC77\x9D' 3279 elif flag & SF_GCC_BIG_ENDIAN: 3280 assert raw == b'A\x9B\xE3\x9D' 3281 else: 3282 raise AssertionError("bad flag") 3283 # 3284 BStruct = new_struct_type("struct foo2") 3285 complete_struct_or_union(BStruct, [('a', BChar, -1), 3286 ('', BShort, 9), 3287 ('c', BChar, -1)], -1, -1, -1, flag) 3288 assert typeoffsetof(BStruct, 'c') == (BChar, 4) 3289 if flag & SF_MSVC_BITFIELDS: 3290 assert sizeof(BStruct) == 6 3291 assert alignof(BStruct) == 2 3292 elif flag & SF_GCC_X86_BITFIELDS: 3293 assert sizeof(BStruct) == 5 3294 assert alignof(BStruct) == 1 3295 elif flag & SF_GCC_ARM_BITFIELDS: 3296 assert sizeof(BStruct) == 6 3297 assert alignof(BStruct) == 2 3298 else: 3299 raise AssertionError("bad flag") 3300 # 3301 BStruct = new_struct_type("struct foo2") 3302 complete_struct_or_union(BStruct, [('a', BChar, -1), 3303 ('', BInt, 0), 3304 ('', BInt, 0), 3305 ('c', BChar, -1)], -1, -1, -1, flag) 3306 if flag & SF_MSVC_BITFIELDS: 3307 assert typeoffsetof(BStruct, 'c') == (BChar, 1) 3308 assert sizeof(BStruct) == 2 3309 assert alignof(BStruct) == 1 3310 elif flag & SF_GCC_X86_BITFIELDS: 3311 assert typeoffsetof(BStruct, 'c') == (BChar, 4) 3312 assert sizeof(BStruct) == 5 3313 assert alignof(BStruct) == 1 3314 elif flag & SF_GCC_ARM_BITFIELDS: 3315 assert typeoffsetof(BStruct, 'c') == (BChar, 4) 3316 assert sizeof(BStruct) == 8 3317 assert alignof(BStruct) == 4 3318 else: 3319 raise AssertionError("bad flag") 3320 3321 3322SF_MSVC_BITFIELDS = 0x01 3323SF_GCC_ARM_BITFIELDS = 0x02 3324SF_GCC_X86_BITFIELDS = 0x10 3325 3326SF_GCC_BIG_ENDIAN = 0x04 3327SF_GCC_LITTLE_ENDIAN = 0x40 3328 3329SF_PACKED = 0x08 3330 3331def test_bitfield_as_x86_gcc(): 3332 _test_bitfield_details(flag=SF_GCC_X86_BITFIELDS|SF_GCC_LITTLE_ENDIAN) 3333 3334def test_bitfield_as_msvc(): 3335 _test_bitfield_details(flag=SF_MSVC_BITFIELDS|SF_GCC_LITTLE_ENDIAN) 3336 3337def test_bitfield_as_arm_gcc(): 3338 _test_bitfield_details(flag=SF_GCC_ARM_BITFIELDS|SF_GCC_LITTLE_ENDIAN) 3339 3340def test_bitfield_as_ppc_gcc(): 3341 # PowerPC uses the same format as X86, but is big-endian 3342 _test_bitfield_details(flag=SF_GCC_X86_BITFIELDS|SF_GCC_BIG_ENDIAN) 3343 3344 3345def test_struct_array_no_length(): 3346 BInt = new_primitive_type("int") 3347 BIntP = new_pointer_type(BInt) 3348 BArray = new_array_type(BIntP, None) 3349 BStruct = new_struct_type("foo") 3350 py.test.raises(TypeError, complete_struct_or_union, 3351 BStruct, [('x', BArray), 3352 ('y', BInt)]) 3353 # 3354 BStruct = new_struct_type("foo") 3355 complete_struct_or_union(BStruct, [('x', BInt), 3356 ('y', BArray)]) 3357 assert sizeof(BStruct) == size_of_int() 3358 d = BStruct.fields 3359 assert len(d) == 2 3360 assert d[0][0] == 'x' 3361 assert d[0][1].type is BInt 3362 assert d[0][1].offset == 0 3363 assert d[0][1].bitshift == -1 3364 assert d[0][1].bitsize == -1 3365 assert d[1][0] == 'y' 3366 assert d[1][1].type is BArray 3367 assert d[1][1].offset == size_of_int() 3368 assert d[1][1].bitshift == -2 3369 assert d[1][1].bitsize == -1 3370 # 3371 p = newp(new_pointer_type(BStruct)) 3372 p.x = 42 3373 assert p.x == 42 3374 assert typeof(p.y) is BArray 3375 assert len(p.y) == 0 3376 assert p.y == cast(BIntP, p) + 1 3377 # 3378 p = newp(new_pointer_type(BStruct), [100]) 3379 assert p.x == 100 3380 assert len(p.y) == 0 3381 # 3382 # Tests for 3383 # ffi.new("struct_with_var_array *", [field.., [the_array_items..]]) 3384 # ffi.new("struct_with_var_array *", [field.., array_size]) 3385 plist = [] 3386 for i in range(20): 3387 if i % 2 == 0: 3388 p = newp(new_pointer_type(BStruct), [100, [200, i, 400]]) 3389 else: 3390 p = newp(new_pointer_type(BStruct), [100, 3]) 3391 p.y[1] = i 3392 p.y[0] = 200 3393 assert p.y[2] == 0 3394 p.y[2] = 400 3395 assert len(p.y) == 3 3396 assert len(p[0].y) == 3 3397 assert len(buffer(p)) == sizeof(BInt) * 4 3398 assert sizeof(p[0]) == sizeof(BInt) * 4 3399 plist.append(p) 3400 for i in range(20): 3401 p = plist[i] 3402 assert p.x == 100 3403 assert p.y[0] == 200 3404 assert p.y[1] == i 3405 assert p.y[2] == 400 3406 assert list(p.y) == [200, i, 400] 3407 # 3408 # the following assignment works, as it normally would, for any array field 3409 p.y = [501, 601] 3410 assert list(p.y) == [501, 601, 400] 3411 p[0].y = [500, 600] 3412 assert list(p[0].y) == [500, 600, 400] 3413 assert repr(p) == "<cdata 'foo *' owning %d bytes>" % ( 3414 sizeof(BStruct) + 3 * sizeof(BInt),) 3415 assert repr(p[0]) == "<cdata 'foo' owning %d bytes>" % ( 3416 sizeof(BStruct) + 3 * sizeof(BInt),) 3417 assert sizeof(p[0]) == sizeof(BStruct) + 3 * sizeof(BInt) 3418 # 3419 # from a non-owning pointer, we can't get the length 3420 q = cast(new_pointer_type(BStruct), p) 3421 assert q.y[0] == 500 3422 assert q[0].y[0] == 500 3423 py.test.raises(TypeError, len, q.y) 3424 py.test.raises(TypeError, len, q[0].y) 3425 assert typeof(q.y) is BIntP 3426 assert typeof(q[0].y) is BIntP 3427 assert sizeof(q[0]) == sizeof(BStruct) 3428 # 3429 # error cases 3430 py.test.raises(IndexError, "p.y[4]") 3431 py.test.raises(TypeError, "p.y = cast(BIntP, 0)") 3432 py.test.raises(TypeError, "p.y = 15") 3433 py.test.raises(TypeError, "p.y = None") 3434 # 3435 # accepting this may be specified by the C99 standard, 3436 # or a GCC strangeness... 3437 BStruct2 = new_struct_type("bar") 3438 complete_struct_or_union(BStruct2, [('f', BStruct), 3439 ('n', BInt)]) 3440 p = newp(new_pointer_type(BStruct2), {'n': 42}) 3441 assert p.n == 42 3442 # 3443 # more error cases 3444 py.test.raises(TypeError, newp, new_pointer_type(BStruct), [100, None]) 3445 BArray4 = new_array_type(BIntP, 4) 3446 BStruct4 = new_struct_type("test4") 3447 complete_struct_or_union(BStruct4, [('a', BArray4)]) # not varsized 3448 py.test.raises(TypeError, newp, new_pointer_type(BStruct4), [None]) 3449 py.test.raises(TypeError, newp, new_pointer_type(BStruct4), [4]) 3450 p = newp(new_pointer_type(BStruct4), [[10, 20, 30]]) 3451 assert p.a[0] == 10 3452 assert p.a[1] == 20 3453 assert p.a[2] == 30 3454 assert p.a[3] == 0 3455 3456def test_struct_array_no_length_explicit_position(): 3457 BInt = new_primitive_type("int") 3458 BIntP = new_pointer_type(BInt) 3459 BArray = new_array_type(BIntP, None) 3460 BStruct = new_struct_type("foo") 3461 complete_struct_or_union(BStruct, [('x', BArray, -1, 0), # actually 3 items 3462 ('y', BInt, -1, 12)]) 3463 p = newp(new_pointer_type(BStruct), [[10, 20], 30]) 3464 assert p.x[0] == 10 3465 assert p.x[1] == 20 3466 assert p.x[2] == 0 3467 assert p.y == 30 3468 p = newp(new_pointer_type(BStruct), {'x': [40], 'y': 50}) 3469 assert p.x[0] == 40 3470 assert p.x[1] == 0 3471 assert p.x[2] == 0 3472 assert p.y == 50 3473 p = newp(new_pointer_type(BStruct), {'y': 60}) 3474 assert p.x[0] == 0 3475 assert p.x[1] == 0 3476 assert p.x[2] == 0 3477 assert p.y == 60 3478 # 3479 # This "should" work too, allocating a larger structure 3480 # (a bit strange in this case, but useful in general) 3481 plist = [] 3482 for i in range(20): 3483 p = newp(new_pointer_type(BStruct), [[10, 20, 30, 40, 50, 60, 70]]) 3484 plist.append(p) 3485 for i in range(20): 3486 p = plist[i] 3487 assert p.x[0] == 10 3488 assert p.x[1] == 20 3489 assert p.x[2] == 30 3490 assert p.x[3] == 40 == p.y 3491 assert p.x[4] == 50 3492 assert p.x[5] == 60 3493 assert p.x[6] == 70 3494 3495def test_struct_array_not_aligned(): 3496 # struct a { int x; char y; char z[]; }; 3497 # ends up of size 8, but 'z' is at offset 5 3498 BChar = new_primitive_type("char") 3499 BInt = new_primitive_type("int") 3500 BCharP = new_pointer_type(BChar) 3501 BArray = new_array_type(BCharP, None) 3502 BStruct = new_struct_type("foo") 3503 complete_struct_or_union(BStruct, [('x', BInt), 3504 ('y', BChar), 3505 ('z', BArray)]) 3506 assert sizeof(BStruct) == 2 * size_of_int() 3507 def offsetof(BType, fieldname): 3508 return typeoffsetof(BType, fieldname)[1] 3509 base = offsetof(BStruct, 'z') 3510 assert base == size_of_int() + 1 3511 # 3512 p = newp(new_pointer_type(BStruct), {'z': 3}) 3513 assert sizeof(p[0]) == base + 3 3514 q = newp(new_pointer_type(BStruct), {'z': size_of_int()}) 3515 assert sizeof(q) == size_of_ptr() 3516 assert sizeof(q[0]) == base + size_of_int() 3517 assert len(p.z) == 3 3518 assert len(p[0].z) == 3 3519 assert len(q.z) == size_of_int() 3520 assert len(q[0].z) == size_of_int() 3521 3522def test_ass_slice(): 3523 BChar = new_primitive_type("char") 3524 BArray = new_array_type(new_pointer_type(BChar), None) 3525 p = newp(BArray, b"foobar") 3526 p[2:5] = [b"*", b"Z", b"T"] 3527 p[1:3] = b"XY" 3528 assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] 3529 py.test.raises(TypeError, "p[1:5] = u+'XYZT'") 3530 py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") 3531 # 3532 for typename in ["wchar_t", "char16_t", "char32_t"]: 3533 BUniChar = new_primitive_type(typename) 3534 BArray = new_array_type(new_pointer_type(BUniChar), None) 3535 p = newp(BArray, u+"foobar") 3536 p[2:5] = [u+"*", u+"Z", u+"T"] 3537 p[1:3] = u+"XY" 3538 assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] 3539 py.test.raises(TypeError, "p[1:5] = b'XYZT'") 3540 py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") 3541 3542def test_void_p_arithmetic(): 3543 BVoid = new_void_type() 3544 BInt = new_primitive_type("intptr_t") 3545 p = cast(new_pointer_type(BVoid), 100000) 3546 assert int(cast(BInt, p)) == 100000 3547 assert int(cast(BInt, p + 42)) == 100042 3548 assert int(cast(BInt, p - (-42))) == 100042 3549 assert (p + 42) - p == 42 3550 q = cast(new_pointer_type(new_primitive_type("char")), 100000) 3551 py.test.raises(TypeError, "p - q") 3552 py.test.raises(TypeError, "q - p") 3553 py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") 3554 py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") 3555 3556def test_sizeof_sliced_array(): 3557 BInt = new_primitive_type("int") 3558 BArray = new_array_type(new_pointer_type(BInt), 10) 3559 p = newp(BArray, None) 3560 assert sizeof(p[2:9]) == 7 * sizeof(BInt) 3561 3562def test_packed(): 3563 BLong = new_primitive_type("long") 3564 BChar = new_primitive_type("char") 3565 BShort = new_primitive_type("short") 3566 for extra_args in [(SF_PACKED,), (0, 1)]: 3567 BStruct = new_struct_type("struct foo") 3568 complete_struct_or_union(BStruct, [('a1', BLong, -1), 3569 ('a2', BChar, -1), 3570 ('a3', BShort, -1)], 3571 None, -1, -1, *extra_args) 3572 d = BStruct.fields 3573 assert len(d) == 3 3574 assert d[0][0] == 'a1' 3575 assert d[0][1].type is BLong 3576 assert d[0][1].offset == 0 3577 assert d[0][1].bitshift == -1 3578 assert d[0][1].bitsize == -1 3579 assert d[1][0] == 'a2' 3580 assert d[1][1].type is BChar 3581 assert d[1][1].offset == sizeof(BLong) 3582 assert d[1][1].bitshift == -1 3583 assert d[1][1].bitsize == -1 3584 assert d[2][0] == 'a3' 3585 assert d[2][1].type is BShort 3586 assert d[2][1].offset == sizeof(BLong) + sizeof(BChar) 3587 assert d[2][1].bitshift == -1 3588 assert d[2][1].bitsize == -1 3589 assert sizeof(BStruct) == sizeof(BLong) + sizeof(BChar) + sizeof(BShort) 3590 assert alignof(BStruct) == 1 3591 # 3592 BStruct2 = new_struct_type("struct foo") 3593 complete_struct_or_union(BStruct2, [('b1', BChar, -1), 3594 ('b2', BLong, -1)], 3595 None, -1, -1, 0, 2) 3596 d = BStruct2.fields 3597 assert len(d) == 2 3598 assert d[0][0] == 'b1' 3599 assert d[0][1].type is BChar 3600 assert d[0][1].offset == 0 3601 assert d[0][1].bitshift == -1 3602 assert d[0][1].bitsize == -1 3603 assert d[1][0] == 'b2' 3604 assert d[1][1].type is BLong 3605 assert d[1][1].offset == 2 3606 assert d[1][1].bitshift == -1 3607 assert d[1][1].bitsize == -1 3608 assert sizeof(BStruct2) == 2 + sizeof(BLong) 3609 assert alignof(BStruct2) == 2 3610 3611def test_packed_with_bitfields(): 3612 if sys.platform == "win32": 3613 py.test.skip("testing gcc behavior") 3614 BLong = new_primitive_type("long") 3615 BChar = new_primitive_type("char") 3616 BStruct = new_struct_type("struct foo") 3617 py.test.raises(NotImplementedError, 3618 complete_struct_or_union, 3619 BStruct, [('a1', BLong, 30), 3620 ('a2', BChar, 5)], 3621 None, -1, -1, SF_PACKED) 3622 3623def test_from_buffer(): 3624 import array 3625 a = array.array('H', [10000, 20000, 30000]) 3626 BChar = new_primitive_type("char") 3627 BCharP = new_pointer_type(BChar) 3628 BCharA = new_array_type(BCharP, None) 3629 c = from_buffer(BCharA, a) 3630 assert typeof(c) is BCharA 3631 assert len(c) == 6 3632 assert repr(c) == "<cdata 'char[]' buffer len 6 from 'array.array' object>" 3633 p = new_pointer_type(new_primitive_type("unsigned short")) 3634 cast(p, c)[1] += 500 3635 assert list(a) == [10000, 20500, 30000] 3636 3637def test_from_buffer_not_str_unicode(): 3638 BChar = new_primitive_type("char") 3639 BCharP = new_pointer_type(BChar) 3640 BCharA = new_array_type(BCharP, None) 3641 p1 = from_buffer(BCharA, b"foo") 3642 assert p1 == from_buffer(BCharA, b"foo") 3643 import gc; gc.collect() 3644 assert p1 == from_buffer(BCharA, b"foo") 3645 py.test.raises(TypeError, from_buffer, BCharA, u+"foo") 3646 try: 3647 from __builtin__ import buffer 3648 except ImportError: 3649 pass 3650 else: 3651 # Python 2 only 3652 contents = from_buffer(BCharA, buffer(b"foo")) 3653 assert len(contents) == len(p1) 3654 for i in range(len(contents)): 3655 assert contents[i] == p1[i] 3656 p4 = buffer(u+"foo") 3657 contents = from_buffer(BCharA, buffer(u+"foo")) 3658 assert len(contents) == len(p4) 3659 for i in range(len(contents)): 3660 assert contents[i] == p4[i] 3661 try: 3662 from __builtin__ import memoryview 3663 except ImportError: 3664 pass 3665 else: 3666 contents = from_buffer(BCharA, memoryview(b"foo")) 3667 assert len(contents) == len(p1) 3668 for i in range(len(contents)): 3669 assert contents[i] == p1[i] 3670 3671 3672def test_from_buffer_bytearray(): 3673 a = bytearray(b"xyz") 3674 BChar = new_primitive_type("char") 3675 BCharP = new_pointer_type(BChar) 3676 BCharA = new_array_type(BCharP, None) 3677 p = from_buffer(BCharA, a) 3678 assert typeof(p) is BCharA 3679 assert len(p) == 3 3680 assert repr(p) == "<cdata 'char[]' buffer len 3 from 'bytearray' object>" 3681 assert p[2] == b"z" 3682 p[2] = b"." 3683 assert a[2] == ord(".") 3684 a[2] = ord("?") 3685 assert p[2] == b"?" 3686 3687def test_from_buffer_more_cases(): 3688 try: 3689 from _cffi_backend import _testbuff 3690 except ImportError: 3691 py.test.skip("not for pypy") 3692 BChar = new_primitive_type("char") 3693 BCharP = new_pointer_type(BChar) 3694 BCharA = new_array_type(BCharP, None) 3695 # 3696 def check1(bufobj, expected): 3697 c = from_buffer(BCharA, bufobj) 3698 assert typeof(c) is BCharA 3699 if sys.version_info >= (3,): 3700 expected = [bytes(c, "ascii") for c in expected] 3701 assert list(c) == list(expected) 3702 # 3703 def check(methods, expected, expected_for_memoryview=None): 3704 if sys.version_info >= (3,): 3705 if methods <= 7: 3706 return 3707 if expected_for_memoryview is not None: 3708 expected = expected_for_memoryview 3709 class X(object): 3710 pass 3711 _testbuff(X, methods) 3712 bufobj = X() 3713 check1(bufobj, expected) 3714 try: 3715 from __builtin__ import buffer 3716 bufobjb = buffer(bufobj) 3717 except (TypeError, ImportError): 3718 pass 3719 else: 3720 check1(bufobjb, expected) 3721 try: 3722 bufobjm = memoryview(bufobj) 3723 except (TypeError, NameError): 3724 pass 3725 else: 3726 check1(bufobjm, expected_for_memoryview or expected) 3727 # 3728 check(1, "RDB") 3729 check(2, "WRB") 3730 check(4, "CHB") 3731 check(8, "GTB") 3732 check(16, "ROB") 3733 # 3734 check(1 | 2, "RDB") 3735 check(1 | 4, "RDB") 3736 check(2 | 4, "CHB") 3737 check(1 | 8, "RDB", "GTB") 3738 check(1 | 16, "RDB", "ROB") 3739 check(2 | 8, "WRB", "GTB") 3740 check(2 | 16, "WRB", "ROB") 3741 check(4 | 8, "CHB", "GTB") 3742 check(4 | 16, "CHB", "ROB") 3743 3744def test_from_buffer_require_writable(): 3745 BChar = new_primitive_type("char") 3746 BCharP = new_pointer_type(BChar) 3747 BCharA = new_array_type(BCharP, None) 3748 p1 = from_buffer(BCharA, b"foo", False) 3749 assert p1 == from_buffer(BCharA, b"foo", False) 3750 py.test.raises((TypeError, BufferError), from_buffer, BCharA, b"foo", True) 3751 ba = bytearray(b"foo") 3752 p1 = from_buffer(BCharA, ba, True) 3753 p1[0] = b"g" 3754 assert ba == b"goo" 3755 3756def test_from_buffer_types(): 3757 BInt = new_primitive_type("int") 3758 BIntP = new_pointer_type(BInt) 3759 BIntA = new_array_type(BIntP, None) 3760 lst = [-12345678, 87654321, 489148] 3761 bytestring = buffer(newp(BIntA, lst))[:] + b'XYZ' 3762 # 3763 p1 = from_buffer(BIntA, bytestring) # int[] 3764 assert typeof(p1) is BIntA 3765 assert len(p1) == 3 3766 assert p1[0] == lst[0] 3767 assert p1[1] == lst[1] 3768 assert p1[2] == lst[2] 3769 py.test.raises(IndexError, "p1[3]") 3770 py.test.raises(IndexError, "p1[-1]") 3771 # 3772 py.test.raises(TypeError, from_buffer, BInt, bytestring) 3773 py.test.raises(TypeError, from_buffer, BIntP, bytestring) 3774 # 3775 BIntA2 = new_array_type(BIntP, 2) 3776 p2 = from_buffer(BIntA2, bytestring) # int[2] 3777 assert typeof(p2) is BIntA2 3778 assert len(p2) == 2 3779 assert p2[0] == lst[0] 3780 assert p2[1] == lst[1] 3781 py.test.raises(IndexError, "p2[2]") 3782 py.test.raises(IndexError, "p2[-1]") 3783 assert p2 == p1 3784 # 3785 BIntA4 = new_array_type(BIntP, 4) # int[4]: too big 3786 py.test.raises(ValueError, from_buffer, BIntA4, bytestring) 3787 # 3788 BStruct = new_struct_type("foo") 3789 complete_struct_or_union(BStruct, [('a1', BInt, -1), 3790 ('a2', BInt, -1)]) 3791 BStructP = new_pointer_type(BStruct) 3792 BStructA = new_array_type(BStructP, None) 3793 p1 = from_buffer(BStructA, bytestring) # struct[] 3794 assert len(p1) == 1 3795 assert typeof(p1) is BStructA 3796 assert p1[0].a1 == lst[0] 3797 assert p1[0].a2 == lst[1] 3798 py.test.raises(IndexError, "p1[1]") 3799 # 3800 BEmptyStruct = new_struct_type("empty") 3801 complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) 3802 assert sizeof(BEmptyStruct) == 0 3803 BEmptyStructP = new_pointer_type(BEmptyStruct) 3804 BEmptyStructA = new_array_type(BEmptyStructP, None) 3805 py.test.raises(ZeroDivisionError, from_buffer, # empty[] 3806 BEmptyStructA, bytestring) 3807 # 3808 BEmptyStructA5 = new_array_type(BEmptyStructP, 5) 3809 p1 = from_buffer(BEmptyStructA5, bytestring) # struct empty[5] 3810 assert typeof(p1) is BEmptyStructA5 3811 assert len(p1) == 5 3812 assert cast(BIntP, p1) == from_buffer(BIntA, bytestring) 3813 3814def test_memmove(): 3815 Short = new_primitive_type("short") 3816 ShortA = new_array_type(new_pointer_type(Short), None) 3817 Char = new_primitive_type("char") 3818 CharA = new_array_type(new_pointer_type(Char), None) 3819 p = newp(ShortA, [-1234, -2345, -3456, -4567, -5678]) 3820 memmove(p, p + 1, 4) 3821 assert list(p) == [-2345, -3456, -3456, -4567, -5678] 3822 p[2] = 999 3823 memmove(p + 2, p, 6) 3824 assert list(p) == [-2345, -3456, -2345, -3456, 999] 3825 memmove(p + 4, newp(CharA, b"\x71\x72"), 2) 3826 if sys.byteorder == 'little': 3827 assert list(p) == [-2345, -3456, -2345, -3456, 0x7271] 3828 else: 3829 assert list(p) == [-2345, -3456, -2345, -3456, 0x7172] 3830 3831def test_memmove_buffer(): 3832 import array 3833 Short = new_primitive_type("short") 3834 ShortA = new_array_type(new_pointer_type(Short), None) 3835 a = array.array('H', [10000, 20000, 30000]) 3836 p = newp(ShortA, 5) 3837 memmove(p, a, 6) 3838 assert list(p) == [10000, 20000, 30000, 0, 0] 3839 memmove(p + 1, a, 6) 3840 assert list(p) == [10000, 10000, 20000, 30000, 0] 3841 b = array.array('h', [-1000, -2000, -3000]) 3842 memmove(b, a, 4) 3843 assert b.tolist() == [10000, 20000, -3000] 3844 assert a.tolist() == [10000, 20000, 30000] 3845 p[0] = 999 3846 p[1] = 998 3847 p[2] = 997 3848 p[3] = 996 3849 p[4] = 995 3850 memmove(b, p, 2) 3851 assert b.tolist() == [999, 20000, -3000] 3852 memmove(b, p + 2, 4) 3853 assert b.tolist() == [997, 996, -3000] 3854 p[2] = -p[2] 3855 p[3] = -p[3] 3856 memmove(b, p + 2, 6) 3857 assert b.tolist() == [-997, -996, 995] 3858 3859def test_memmove_readonly_readwrite(): 3860 SignedChar = new_primitive_type("signed char") 3861 SignedCharA = new_array_type(new_pointer_type(SignedChar), None) 3862 p = newp(SignedCharA, 5) 3863 memmove(p, b"abcde", 3) 3864 assert list(p) == [ord("a"), ord("b"), ord("c"), 0, 0] 3865 memmove(p, bytearray(b"ABCDE"), 2) 3866 assert list(p) == [ord("A"), ord("B"), ord("c"), 0, 0] 3867 py.test.raises((TypeError, BufferError), memmove, b"abcde", p, 3) 3868 ba = bytearray(b"xxxxx") 3869 memmove(dest=ba, src=p, n=3) 3870 assert ba == bytearray(b"ABcxx") 3871 memmove(ba, b"EFGH", 4) 3872 assert ba == bytearray(b"EFGHx") 3873 3874def test_memmove_sign_check(): 3875 SignedChar = new_primitive_type("signed char") 3876 SignedCharA = new_array_type(new_pointer_type(SignedChar), None) 3877 p = newp(SignedCharA, 5) 3878 py.test.raises(ValueError, memmove, p, p + 1, -1) # not segfault 3879 3880def test_memmove_bad_cdata(): 3881 BInt = new_primitive_type("int") 3882 p = cast(BInt, 42) 3883 py.test.raises(TypeError, memmove, p, bytearray(b'a'), 1) 3884 py.test.raises(TypeError, memmove, bytearray(b'a'), p, 1) 3885 3886def test_dereference_null_ptr(): 3887 BInt = new_primitive_type("int") 3888 BIntPtr = new_pointer_type(BInt) 3889 p = cast(BIntPtr, 0) 3890 py.test.raises(RuntimeError, "p[0]") 3891 py.test.raises(RuntimeError, "p[0] = 42") 3892 py.test.raises(RuntimeError, "p[42]") 3893 py.test.raises(RuntimeError, "p[42] = -1") 3894 3895def test_mixup(): 3896 BStruct1 = new_struct_type("foo") 3897 BStruct2 = new_struct_type("foo") # <= same name as BStruct1 3898 BStruct3 = new_struct_type("bar") 3899 BStruct1Ptr = new_pointer_type(BStruct1) 3900 BStruct2Ptr = new_pointer_type(BStruct2) 3901 BStruct3Ptr = new_pointer_type(BStruct3) 3902 BStruct1PtrPtr = new_pointer_type(BStruct1Ptr) 3903 BStruct2PtrPtr = new_pointer_type(BStruct2Ptr) 3904 BStruct3PtrPtr = new_pointer_type(BStruct3Ptr) 3905 pp1 = newp(BStruct1PtrPtr) 3906 pp2 = newp(BStruct2PtrPtr) 3907 pp3 = newp(BStruct3PtrPtr) 3908 pp1[0] = pp1[0] 3909 e = py.test.raises(TypeError, "pp3[0] = pp1[0]") 3910 assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") 3911 assert str(e.value).endswith(", not cdata 'foo *'") 3912 e = py.test.raises(TypeError, "pp2[0] = pp1[0]") 3913 assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " 3914 "be 'foo *', but the types are different (check " 3915 "that you are not e.g. mixing up different ffi " 3916 "instances)") 3917 3918def test_stdcall_function_type(): 3919 assert FFI_CDECL == FFI_DEFAULT_ABI 3920 try: 3921 stdcall = FFI_STDCALL 3922 except NameError: 3923 stdcall = FFI_DEFAULT_ABI 3924 BInt = new_primitive_type("int") 3925 BFunc = new_function_type((BInt, BInt), BInt, False, stdcall) 3926 if stdcall != FFI_DEFAULT_ABI: 3927 assert repr(BFunc) == "<ctype 'int(__stdcall *)(int, int)'>" 3928 else: 3929 assert repr(BFunc) == "<ctype 'int(*)(int, int)'>" 3930 3931def test_get_common_types(): 3932 d = {} 3933 _get_common_types(d) 3934 assert d['bool'] == '_Bool' 3935 3936def test_unpack(): 3937 BChar = new_primitive_type("char") 3938 BArray = new_array_type(new_pointer_type(BChar), 10) # char[10] 3939 p = newp(BArray, b"abc\x00def") 3940 p0 = p 3941 assert unpack(p, 10) == b"abc\x00def\x00\x00\x00" 3942 assert unpack(p+1, 5) == b"bc\x00de" 3943 3944 for typename in ["wchar_t", "char16_t", "char32_t"]: 3945 BWChar = new_primitive_type(typename) 3946 BArray = new_array_type(new_pointer_type(BWChar), 10) # wchar_t[10] 3947 p = newp(BArray, u"abc\x00def") 3948 assert unpack(p, 10) == u"abc\x00def\x00\x00\x00" 3949 3950 for typename, samples in [ 3951 ("uint8_t", [0, 2**8-1]), 3952 ("uint16_t", [0, 2**16-1]), 3953 ("uint32_t", [0, 2**32-1]), 3954 ("uint64_t", [0, 2**64-1]), 3955 ("int8_t", [-2**7, 2**7-1]), 3956 ("int16_t", [-2**15, 2**15-1]), 3957 ("int32_t", [-2**31, 2**31-1]), 3958 ("int64_t", [-2**63, 2**63-1]), 3959 ("_Bool", [False, True]), 3960 ("float", [0.0, 10.5]), 3961 ("double", [12.34, 56.78]), 3962 ]: 3963 BItem = new_primitive_type(typename) 3964 BArray = new_array_type(new_pointer_type(BItem), 10) 3965 p = newp(BArray, samples) 3966 result = unpack(p, len(samples)) 3967 assert result == samples 3968 for i in range(len(samples)): 3969 assert result[i] == p[i] and type(result[i]) is type(p[i]) 3970 assert (type(result[i]) is bool) == (type(samples[i]) is bool) 3971 # 3972 BInt = new_primitive_type("int") 3973 py.test.raises(TypeError, unpack, p) 3974 py.test.raises(TypeError, unpack, b"foobar", 6) 3975 py.test.raises(TypeError, unpack, cast(BInt, 42), 1) 3976 # 3977 BPtr = new_pointer_type(BInt) 3978 random_ptr = cast(BPtr, -424344) 3979 other_ptr = cast(BPtr, 54321) 3980 BArray = new_array_type(new_pointer_type(BPtr), None) 3981 lst = unpack(newp(BArray, [random_ptr, other_ptr]), 2) 3982 assert lst == [random_ptr, other_ptr] 3983 # 3984 BFunc = new_function_type((BInt, BInt), BInt, False) 3985 BFuncPtr = new_pointer_type(BFunc) 3986 lst = unpack(newp(new_array_type(BFuncPtr, None), 2), 2) 3987 assert len(lst) == 2 3988 assert not lst[0] and not lst[1] 3989 assert typeof(lst[0]) is BFunc 3990 # 3991 BStruct = new_struct_type("foo") 3992 BStructPtr = new_pointer_type(BStruct) 3993 e = py.test.raises(ValueError, unpack, cast(BStructPtr, 42), 5) 3994 assert str(e.value) == "'foo *' points to items of unknown size" 3995 complete_struct_or_union(BStruct, [('a1', BInt, -1), 3996 ('a2', BInt, -1)]) 3997 array_of_structs = newp(new_array_type(BStructPtr, None), [[4,5], [6,7]]) 3998 lst = unpack(array_of_structs, 2) 3999 assert typeof(lst[0]) is BStruct 4000 assert lst[0].a1 == 4 and lst[1].a2 == 7 4001 # 4002 py.test.raises(RuntimeError, unpack, cast(new_pointer_type(BChar), 0), 0) 4003 py.test.raises(RuntimeError, unpack, cast(new_pointer_type(BChar), 0), 10) 4004 # 4005 py.test.raises(ValueError, unpack, p0, -1) 4006 py.test.raises(ValueError, unpack, p, -1) 4007 4008def test_cdata_dir(): 4009 BInt = new_primitive_type("int") 4010 p = cast(BInt, 42) 4011 check_dir(p, []) 4012 p = newp(new_array_type(new_pointer_type(BInt), None), 5) 4013 check_dir(p, []) 4014 BStruct = new_struct_type("foo") 4015 p = cast(new_pointer_type(BStruct), 0) 4016 check_dir(p, []) # opaque 4017 complete_struct_or_union(BStruct, [('a2', BInt, -1), 4018 ('a1', BInt, -1)]) 4019 check_dir(p, ['a1', 'a2']) # always sorted 4020 p = newp(new_pointer_type(BStruct), None) 4021 check_dir(p, ['a1', 'a2']) 4022 check_dir(p[0], ['a1', 'a2']) 4023 pp = newp(new_pointer_type(new_pointer_type(BStruct)), p) 4024 check_dir(pp, []) 4025 check_dir(pp[0], ['a1', 'a2']) 4026 check_dir(pp[0][0], ['a1', 'a2']) 4027 4028def test_char_pointer_conversion(): 4029 import warnings 4030 assert __version__.startswith("1."), ( 4031 "the warning will be an error if we ever release cffi 2.x") 4032 BCharP = new_pointer_type(new_primitive_type("char")) 4033 BIntP = new_pointer_type(new_primitive_type("int")) 4034 BVoidP = new_pointer_type(new_void_type()) 4035 BUCharP = new_pointer_type(new_primitive_type("unsigned char")) 4036 z1 = cast(BCharP, 0) 4037 z2 = cast(BIntP, 0) 4038 z3 = cast(BVoidP, 0) 4039 z4 = cast(BUCharP, 0) 4040 with warnings.catch_warnings(record=True) as w: 4041 warnings.simplefilter("always") 4042 newp(new_pointer_type(BIntP), z1) # warn 4043 assert len(w) == 1 4044 newp(new_pointer_type(BVoidP), z1) # fine 4045 assert len(w) == 1 4046 newp(new_pointer_type(BCharP), z2) # warn 4047 assert len(w) == 2 4048 newp(new_pointer_type(BVoidP), z2) # fine 4049 assert len(w) == 2 4050 newp(new_pointer_type(BCharP), z3) # fine 4051 assert len(w) == 2 4052 newp(new_pointer_type(BIntP), z3) # fine 4053 assert len(w) == 2 4054 newp(new_pointer_type(BCharP), z4) # fine (ignore signedness here) 4055 assert len(w) == 2 4056 newp(new_pointer_type(BUCharP), z1) # fine (ignore signedness here) 4057 assert len(w) == 2 4058 newp(new_pointer_type(BUCharP), z3) # fine 4059 assert len(w) == 2 4060 # check that the warnings are associated with lines in this file 4061 assert w[1].lineno == w[0].lineno + 4 4062 4063def test_primitive_comparison(): 4064 def assert_eq(a, b): 4065 assert (a == b) is True 4066 assert (b == a) is True 4067 assert (a != b) is False 4068 assert (b != a) is False 4069 assert (a < b) is False 4070 assert (a <= b) is True 4071 assert (a > b) is False 4072 assert (a >= b) is True 4073 assert (b < a) is False 4074 assert (b <= a) is True 4075 assert (b > a) is False 4076 assert (b >= a) is True 4077 assert hash(a) == hash(b) 4078 def assert_lt(a, b, check_hash=True): 4079 assert (a == b) is False 4080 assert (b == a) is False 4081 assert (a != b) is True 4082 assert (b != a) is True 4083 assert (a < b) is True 4084 assert (a <= b) is True 4085 assert (a > b) is False 4086 assert (a >= b) is False 4087 assert (b < a) is False 4088 assert (b <= a) is False 4089 assert (b > a) is True 4090 assert (b >= a) is True 4091 if check_hash: 4092 assert hash(a) != hash(b) # (or at least, it is unlikely) 4093 def assert_gt(a, b, check_hash=True): 4094 assert_lt(b, a, check_hash) 4095 def assert_ne(a, b): 4096 assert (a == b) is False 4097 assert (b == a) is False 4098 assert (a != b) is True 4099 assert (b != a) is True 4100 if strict_compare: 4101 py.test.raises(TypeError, "a < b") 4102 py.test.raises(TypeError, "a <= b") 4103 py.test.raises(TypeError, "a > b") 4104 py.test.raises(TypeError, "a >= b") 4105 py.test.raises(TypeError, "b < a") 4106 py.test.raises(TypeError, "b <= a") 4107 py.test.raises(TypeError, "b > a") 4108 py.test.raises(TypeError, "b >= a") 4109 elif a < b: 4110 assert_lt(a, b) 4111 else: 4112 assert_lt(b, a) 4113 assert_eq(5, 5) 4114 assert_lt(3, 5) 4115 assert_ne('5', 5) 4116 # 4117 t1 = new_primitive_type("char") 4118 t2 = new_primitive_type("int") 4119 t3 = new_primitive_type("unsigned char") 4120 t4 = new_primitive_type("unsigned int") 4121 t5 = new_primitive_type("float") 4122 t6 = new_primitive_type("double") 4123 assert_eq(cast(t1, 65), b'A') 4124 assert_lt(cast(t1, 64), b'\x99') 4125 assert_gt(cast(t1, 200), b'A') 4126 assert_ne(cast(t1, 65), 65) 4127 assert_eq(cast(t2, -25), -25) 4128 assert_lt(cast(t2, -25), -24) 4129 assert_gt(cast(t2, -25), -26) 4130 assert_eq(cast(t3, 65), 65) 4131 assert_ne(cast(t3, 65), b'A') 4132 assert_ne(cast(t3, 65), cast(t1, 65)) 4133 assert_gt(cast(t4, -1), -1, check_hash=False) 4134 assert_gt(cast(t4, -1), cast(t2, -1), check_hash=False) 4135 assert_gt(cast(t4, -1), 99999) 4136 assert_eq(cast(t4, -1), 256 ** size_of_int() - 1) 4137 assert_eq(cast(t5, 3.0), 3) 4138 assert_eq(cast(t5, 3.5), 3.5) 4139 assert_lt(cast(t5, 3.3), 3.3) # imperfect rounding 4140 assert_eq(cast(t6, 3.3), 3.3) 4141 assert_eq(cast(t5, 3.5), cast(t6, 3.5)) 4142 assert_lt(cast(t5, 3.1), cast(t6, 3.1)) # imperfect rounding 4143 assert_eq(cast(t5, 7.0), cast(t3, 7)) 4144 assert_lt(cast(t5, 3.1), 3.101) 4145 assert_gt(cast(t5, 3.1), 3) 4146 4147def test_explicit_release_new(): 4148 # release() on a ffi.new() object has no effect on CPython, but 4149 # really releases memory on PyPy. We can't test that effect 4150 # though, because a released cdata is not marked. 4151 BIntP = new_pointer_type(new_primitive_type("int")) 4152 p = newp(BIntP) 4153 p[0] = 42 4154 py.test.raises(IndexError, "p[1]") 4155 release(p) 4156 # here, reading p[0] might give garbage or segfault... 4157 release(p) # no effect 4158 # 4159 BStruct = new_struct_type("struct foo") 4160 BStructP = new_pointer_type(BStruct) 4161 complete_struct_or_union(BStruct, [('p', BIntP, -1)]) 4162 pstruct = newp(BStructP) 4163 assert pstruct.p == cast(BIntP, 0) 4164 release(pstruct) 4165 # here, reading pstruct.p might give garbage or segfault... 4166 release(pstruct) # no effect 4167 4168def test_explicit_release_new_contextmgr(): 4169 BIntP = new_pointer_type(new_primitive_type("int")) 4170 with newp(BIntP) as p: 4171 p[0] = 42 4172 assert p[0] == 42 4173 # here, reading p[0] might give garbage or segfault... 4174 release(p) # no effect 4175 4176def test_explicit_release_badtype(): 4177 BIntP = new_pointer_type(new_primitive_type("int")) 4178 p = cast(BIntP, 12345) 4179 py.test.raises(ValueError, release, p) 4180 py.test.raises(ValueError, release, p) 4181 BStruct = new_struct_type("struct foo") 4182 BStructP = new_pointer_type(BStruct) 4183 complete_struct_or_union(BStruct, [('p', BIntP, -1)]) 4184 pstruct = newp(BStructP) 4185 py.test.raises(ValueError, release, pstruct[0]) 4186 4187def test_explicit_release_badtype_contextmgr(): 4188 BIntP = new_pointer_type(new_primitive_type("int")) 4189 p = cast(BIntP, 12345) 4190 py.test.raises(ValueError, "with p: pass") 4191 py.test.raises(ValueError, "with p: pass") 4192 4193def test_explicit_release_gc(): 4194 BIntP = new_pointer_type(new_primitive_type("int")) 4195 seen = [] 4196 intp1 = newp(BIntP, 12345) 4197 p1 = cast(BIntP, intp1) 4198 p = gcp(p1, seen.append) 4199 assert seen == [] 4200 release(p) 4201 assert seen == [p1] 4202 assert p1[0] == 12345 4203 assert p[0] == 12345 # true so far, but might change to raise RuntimeError 4204 release(p) # no effect 4205 4206def test_explicit_release_gc_contextmgr(): 4207 BIntP = new_pointer_type(new_primitive_type("int")) 4208 seen = [] 4209 intp1 = newp(BIntP, 12345) 4210 p1 = cast(BIntP, intp1) 4211 p = gcp(p1, seen.append) 4212 with p: 4213 assert p[0] == 12345 4214 assert seen == [] 4215 assert seen == [p1] 4216 assert p1[0] == 12345 4217 assert p[0] == 12345 # true so far, but might change to raise RuntimeError 4218 release(p) # no effect 4219 4220def test_explicit_release_from_buffer(): 4221 a = bytearray(b"xyz") 4222 BChar = new_primitive_type("char") 4223 BCharP = new_pointer_type(BChar) 4224 BCharA = new_array_type(BCharP, None) 4225 p = from_buffer(BCharA, a) 4226 assert p[2] == b"z" 4227 release(p) 4228 assert p[2] == b"z" # true so far, but might change to raise RuntimeError 4229 release(p) # no effect 4230 4231def test_explicit_release_from_buffer_contextmgr(): 4232 a = bytearray(b"xyz") 4233 BChar = new_primitive_type("char") 4234 BCharP = new_pointer_type(BChar) 4235 BCharA = new_array_type(BCharP, None) 4236 p = from_buffer(BCharA, a) 4237 with p: 4238 assert p[2] == b"z" 4239 assert p[2] == b"z" # true so far, but might change to raise RuntimeError 4240 release(p) # no effect 4241 4242def test_explicit_release_bytearray_on_cpython(): 4243 if '__pypy__' in sys.builtin_module_names: 4244 py.test.skip("pypy's bytearray are never locked") 4245 a = bytearray(b"xyz") 4246 BChar = new_primitive_type("char") 4247 BCharP = new_pointer_type(BChar) 4248 BCharA = new_array_type(BCharP, None) 4249 a += b't' * 10 4250 p = from_buffer(BCharA, a) 4251 py.test.raises(BufferError, "a += b'u' * 100") 4252 release(p) 4253 a += b'v' * 100 4254 release(p) # no effect 4255 a += b'w' * 1000 4256 assert a == bytearray(b"xyz" + b't' * 10 + b'v' * 100 + b'w' * 1000) 4257