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