[pypy-commit] pypy default: Import and copy cffi/e12558a3ce6b

arigo noreply at buildbot.pypy.org
Sat Jul 4 20:38:52 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r78431:9a4cb1384683
Date: 2015-07-04 20:39 +0200
http://bitbucket.org/pypy/pypy/changeset/9a4cb1384683/

Log:	Import and copy cffi/e12558a3ce6b

diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -327,6 +327,13 @@
         data.  Later, when this new cdata object is garbage-collected,
         'destructor(old_cdata_object)' will be called.
         """
+        try:
+            gcp = self._backend.gcp
+        except AttributeError:
+            pass
+        else:
+            return gcp(cdata, destructor)
+        #
         with self._lock:
             try:
                 gc_weakrefs = self.gc_weakrefs
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -37,6 +37,7 @@
         'from_handle': 'handle.from_handle',
         '_get_types': 'func._get_types',
         'from_buffer': 'func.from_buffer',
+        'gcp': 'func.gcp',
 
         'string': 'func.string',
         'buffer': 'cbuffer.buffer',
diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -539,13 +539,18 @@
 
 
 @jit.dont_look_inside
-def W_FFIObject___new__(space, w_subtype, __args__):
-    r = space.allocate_instance(W_FFIObject, w_subtype)
+def make_plain_ffi_object(space, w_ffitype=None):
+    if w_ffitype is None:
+        w_ffitype = space.gettypefor(W_FFIObject)
+    r = space.allocate_instance(W_FFIObject, w_ffitype)
     # get in 'src_ctx' a NULL which translation doesn't consider to be constant
     src_ctx = rffi.cast(parse_c_type.PCTX, 0)
     r.__init__(space, src_ctx)
     return space.wrap(r)
 
+def W_FFIObject___new__(space, w_subtype, __args__):
+    return make_plain_ffi_object(space, w_subtype)
+
 def make_CData(space):
     return space.gettypefor(W_CData)
 
diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py
--- a/pypy/module/_cffi_backend/func.py
+++ b/pypy/module/_cffi_backend/func.py
@@ -105,3 +105,18 @@
                     "raw address on PyPy", w_x)
     #
     return cdataobj.W_CDataFromBuffer(space, _cdata, w_ctype, buf, w_x)
+
+# ____________________________________________________________
+
+class ConstantFFI:
+    ffi1 = None
+    def _cleanup_(self):
+        self.ffi1 = None
+constant_ffi = ConstantFFI()
+
+ at unwrap_spec(w_cdata=cdataobj.W_CData)
+def gcp(space, w_cdata, w_destructor):
+    if constant_ffi.ffi1 is None:
+        from pypy.module._cffi_backend import ffi_obj
+        constant_ffi.ffi1 = ffi_obj.make_plain_ffi_object(space)
+    return constant_ffi.ffi1.descr_gc(w_cdata, w_destructor)
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
@@ -4,6 +4,8 @@
     spaceconfig = dict(usemodules=('_cffi_backend', 'array'))
 
     def teardown_method(self, meth):
+        from pypy.module._cffi_backend.func import constant_ffi
+        constant_ffi._cleanup_()
         _clean_cache(self.space)
 
     def test_ffi_new(self):
@@ -222,9 +224,10 @@
             assert p1[0] == 123
             seen.append(1)
         ffi.gc(p, destructor=destructor)    # instantly forgotten
+        _cffi1_backend.gcp(p, destructor=destructor)
         for i in range(5):
             if seen:
                 break
             import gc
             gc.collect()
-        assert seen == [1]
+        assert seen == [1, 1]
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1504,16 +1504,19 @@
 
     def test_gc_finite_list(self):
         ffi = FFI(backend=self.Backend())
+        public = not hasattr(ffi._backend, 'gcp')
         p = ffi.new("int *", 123)
         keepalive = []
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-            assert len(ffi.gc_weakrefs.data) == i + 1  #should be a private attr
+            if public:
+                assert len(ffi.gc_weakrefs.data) == i + 1
         del keepalive[:]
         import gc; gc.collect(); gc.collect()
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-        assert len(ffi.gc_weakrefs.data) == 10
+        if public:
+            assert len(ffi.gc_weakrefs.data) == 10
 
     def test_CData_CType(self):
         ffi = FFI(backend=self.Backend())


More information about the pypy-commit mailing list