diff options
author | Armin Rigo <arigo@tunes.org> | 2015-07-06 17:16:16 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2015-07-06 17:16:16 +0200 |
commit | b0ceca16659c83570e6027ddb8308fd056232486 (patch) | |
tree | 15da215d9e27e01cb995442074d7a7d7f2a1dcb6 /testing/cffi0/test_ffi_backend.py | |
parent | 56020b72ed1211f480d8bf370f2f4c265b6b13ec (diff) | |
download | cffi-b0ceca16659c83570e6027ddb8308fd056232486.tar.gz |
Port the new_allocator() work from pypy
Diffstat (limited to 'testing/cffi0/test_ffi_backend.py')
-rw-r--r-- | testing/cffi0/test_ffi_backend.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/testing/cffi0/test_ffi_backend.py b/testing/cffi0/test_ffi_backend.py index c01a465..436b5b3 100644 --- a/testing/cffi0/test_ffi_backend.py +++ b/testing/cffi0/test_ffi_backend.py @@ -57,6 +57,77 @@ class TestFFI(backend_tests.BackendTests, assert tb.tb_frame.f_code.co_name == 'cb' assert tb.tb_frame.f_locals['n'] == 234 + def test_ffi_new_allocator_2(self): + ffi = FFI(backend=self.Backend()) + seen = [] + def myalloc(size): + seen.append(size) + return ffi.new("char[]", "X" * size) + def myfree(raw): + seen.append(raw) + alloc1 = ffi.new_allocator(myalloc, myfree) + alloc2 = ffi.new_allocator(alloc=myalloc, free=myfree, + should_clear_after_alloc=False) + p1 = alloc1("int[10]") + p2 = alloc2("int[]", 10) + assert seen == [40, 40] + assert ffi.typeof(p1) == ffi.typeof("int[10]") + assert ffi.sizeof(p1) == 40 + assert ffi.typeof(p2) == ffi.typeof("int[]") + assert ffi.sizeof(p2) == 40 + assert p1[5] == 0 + assert p2[6] == ord('X') * 0x01010101 + raw1 = ffi.cast("char *", p1) + raw2 = ffi.cast("char *", p2) + del p1, p2 + retries = 0 + while len(seen) != 4: + retries += 1 + assert retries <= 5 + import gc; gc.collect() + assert seen == [40, 40, raw1, raw2] + assert repr(seen[2]) == "<cdata 'char[]' owning 41 bytes>" + assert repr(seen[3]) == "<cdata 'char[]' owning 41 bytes>" + + def test_ffi_new_allocator_3(self): + ffi = FFI(backend=self.Backend()) + seen = [] + def myalloc(size): + seen.append(size) + return ffi.new("char[]", "X" * size) + alloc1 = ffi.new_allocator(myalloc) # no 'free' + p1 = alloc1("int[10]") + assert seen == [40] + assert ffi.typeof(p1) == ffi.typeof("int[10]") + assert ffi.sizeof(p1) == 40 + assert p1[5] == 0 + + def test_ffi_new_allocator_4(self): + ffi = FFI(backend=self.Backend()) + py.test.raises(TypeError, ffi.new_allocator, free=lambda x: None) + # + def myalloc2(size): + raise LookupError + alloc2 = ffi.new_allocator(myalloc2) + py.test.raises(LookupError, alloc2, "int[5]") + # + def myalloc3(size): + return 42 + alloc3 = ffi.new_allocator(myalloc3) + e = py.test.raises(TypeError, alloc3, "int[5]") + assert str(e.value) == "alloc() must return a cdata object (got int)" + # + def myalloc4(size): + return ffi.cast("int", 42) + alloc4 = ffi.new_allocator(myalloc4) + e = py.test.raises(TypeError, alloc4, "int[5]") + assert str(e.value) == "alloc() must return a cdata pointer, not 'int'" + # + def myalloc5(size): + return ffi.NULL + alloc5 = ffi.new_allocator(myalloc5) + py.test.raises(MemoryError, alloc5, "int[5]") + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): |