Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r84274:e46b5cbc8d94
Date: 2016-05-07 14:48 +0200
http://bitbucket.org/pypy/pypy/changeset/e46b5cbc8d94/

Log:    update to cffi/4d19ce180883

diff --git a/pypy/module/_cffi_backend/cdataobj.py 
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -365,8 +365,16 @@
         return self.ctype.size
 
     def with_gc(self, w_destructor):
+        space = self.space
+        if space.is_none(w_destructor):
+            if isinstance(self, W_CDataGCP):
+                self.w_destructor = None
+                return space.w_None
+            raise oefmt(space.w_TypeError,
+                        "Can remove destructor only on a object "
+                        "previously returned by ffi.gc()")
         with self as ptr:
-            return W_CDataGCP(self.space, ptr, self.ctype, self, w_destructor)
+            return W_CDataGCP(space, ptr, self.ctype, self, w_destructor)
 
     def unpack(self, length):
         from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray
@@ -538,7 +546,7 @@
 class W_CDataGCP(W_CData):
     """For ffi.gc()."""
     _attrs_ = ['w_original_cdata', 'w_destructor']
-    _immutable_fields_ = ['w_original_cdata', 'w_destructor']
+    _immutable_fields_ = ['w_original_cdata']
 
     def __init__(self, space, cdata, ctype, w_original_cdata, w_destructor):
         W_CData.__init__(self, space, cdata, ctype)
@@ -552,7 +560,10 @@
 
     def call_destructor(self):
         assert isinstance(self, W_CDataGCP)
-        self.space.call_function(self.w_destructor, self.w_original_cdata)
+        w_destructor = self.w_destructor
+        if w_destructor is not None:
+            self.w_destructor = None
+            self.space.call_function(w_destructor, self.w_original_cdata)
 
 
 W_CData.typedef = TypeDef(
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
@@ -331,6 +331,25 @@
             gc.collect()
         assert seen == [1]
 
+    def test_ffi_gc_disable(self):
+        import _cffi_backend as _cffi1_backend
+        ffi = _cffi1_backend.FFI()
+        p = ffi.new("int *", 123)
+        raises(TypeError, ffi.gc, p, None)
+        seen = []
+        q1 = ffi.gc(p, lambda p: seen.append(1))
+        q2 = ffi.gc(q1, lambda p: seen.append(2))
+        import gc; gc.collect()
+        assert seen == []
+        assert ffi.gc(q1, None) is None
+        del q1, q2
+        for i in range(5):
+            if seen:
+                break
+            import gc
+            gc.collect()
+        assert seen == [2]
+
     def test_ffi_new_allocator_1(self):
         import _cffi_backend as _cffi1_backend
         ffi = _cffi1_backend.FFI()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to