[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