[pypy-commit] pypy cffi-new-allocator: error fixes

arigo noreply at buildbot.pypy.org
Mon Jul 6 17:15:44 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-new-allocator
Changeset: r78463:d926a809bca0
Date: 2015-07-06 17:09 +0200
http://bitbucket.org/pypy/pypy/changeset/d926a809bca0/

Log:	error fixes

diff --git a/pypy/module/_cffi_backend/allocator.py b/pypy/module/_cffi_backend/allocator.py
--- a/pypy/module/_cffi_backend/allocator.py
+++ b/pypy/module/_cffi_backend/allocator.py
@@ -16,7 +16,7 @@
         self.should_clear_after_alloc = should_clear_after_alloc
 
     def allocate(self, space, datasize, ctype, length=-1):
-        from pypy.module._cffi_backend import cdataobj, ctypeptr, ffi_obj
+        from pypy.module._cffi_backend import cdataobj, ctypeptr
         if self.w_alloc is None:
             if self.should_clear_after_alloc:
                 ptr = lltype.malloc(rffi.CCHARP.TO, datasize,
@@ -29,15 +29,18 @@
             w_raw_cdata = space.call_function(self.w_alloc,
                                               space.wrap(datasize))
             if not isinstance(w_raw_cdata, cdataobj.W_CData):
-                raise oefmt(ffi_obj.get_ffi_error(space),
-                            "expected cdata object from the call to %R, "
-                            "got '%T'", self.w_alloc, w_raw_cdata)
+                raise oefmt(space.w_TypeError,
+                            "alloc() must return a cdata object (got %T)",
+                            w_raw_cdata)
             if not isinstance(w_raw_cdata.ctype, ctypeptr.W_CTypePtrOrArray):
-                raise oefmt(ffi_obj.get_ffi_error(space),
-                            "expected cdata pointer from the call to %R, "
-                            "got '%s'", self.w_alloc, w_raw_cdata.ctype.name)
+                raise oefmt(space.w_TypeError,
+                            "alloc() must return a cdata pointer, not '%s'",
+                            w_raw_cdata.ctype.name)
             #
             ptr = w_raw_cdata.unsafe_escaping_ptr()
+            if not ptr:
+                raise oefmt(space.w_MemoryError, "alloc() returned NULL")
+            #
             if self.should_clear_after_alloc:
                 rffi.c_memset(rffi.cast(rffi.VOIDP, ptr), 0,
                               rffi.cast(rffi.SIZE_T, datasize))
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -340,3 +340,30 @@
         assert ffi.typeof(p1) == ffi.typeof("int[10]")
         assert ffi.sizeof(p1) == 40
         assert p1[5] == 0
+
+    def test_ffi_new_allocator_4(self):
+        import _cffi_backend as _cffi1_backend
+        ffi = _cffi1_backend.FFI()
+        raises(TypeError, ffi.new_allocator, free=lambda x: None)
+        #
+        def myalloc2(size):
+            raise LookupError
+        alloc2 = ffi.new_allocator(myalloc2)
+        raises(LookupError, alloc2, "int[5]")
+        #
+        def myalloc3(size):
+            return 42
+        alloc3 = ffi.new_allocator(myalloc3)
+        e = 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 = 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)
+        raises(MemoryError, alloc5, "int[5]")


More information about the pypy-commit mailing list