[pypy-commit] pypy default: update to cffi/6f5001375739 (forgot this)
arigo
pypy.commits at gmail.com
Tue Feb 7 10:37:48 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r90002:c645557d7175
Date: 2017-02-07 16:37 +0100
http://bitbucket.org/pypy/pypy/changeset/c645557d7175/
Log: update to cffi/6f5001375739 (forgot this)
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
@@ -462,7 +462,12 @@
field or array item in the structure or array, recursively in
case of nested structures.
"""
- ctype = self._backend.typeof(cdata)
+ try:
+ ctype = self._backend.typeof(cdata)
+ except TypeError:
+ if '__addressof__' in type(cdata).__dict__:
+ return type(cdata).__addressof__(cdata, *fields_or_indexes)
+ raise
if fields_or_indexes:
ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes)
else:
@@ -775,10 +780,7 @@
key = 'function ' + name
tp, _ = ffi._parser._declarations[key]
BType = ffi._get_cached_btype(tp)
- try:
- value = backendlib.load_function(BType, name)
- except KeyError as e:
- raise AttributeError('%s: %s' % (name, e))
+ value = backendlib.load_function(BType, name)
library.__dict__[name] = value
#
def accessor_variable(name):
@@ -791,6 +793,21 @@
lambda self: read_variable(BType, name),
lambda self, value: write_variable(BType, name, value)))
#
+ def addressof_var(name):
+ try:
+ return addr_variables[name]
+ except KeyError:
+ with ffi._lock:
+ if name not in addr_variables:
+ key = 'variable ' + name
+ tp, _ = ffi._parser._declarations[key]
+ BType = ffi._get_cached_btype(tp)
+ if BType.kind != 'array':
+ BType = model.pointer_cache(ffi, BType)
+ p = backendlib.load_function(BType, name)
+ addr_variables[name] = p
+ return addr_variables[name]
+ #
def accessor_constant(name):
raise NotImplementedError("non-integer constant '%s' cannot be "
"accessed from a dlopen() library" % (name,))
@@ -800,6 +817,7 @@
#
accessors = {}
accessors_version = [False]
+ addr_variables = {}
#
def update_accessors():
if accessors_version[0] is ffi._cdef_version:
@@ -850,6 +868,18 @@
with ffi._lock:
update_accessors()
return accessors.keys()
+ def __addressof__(self, name):
+ if name in library.__dict__:
+ return library.__dict__[name]
+ if name in FFILibrary.__dict__:
+ return addressof_var(name)
+ make_accessor(name)
+ if name in library.__dict__:
+ return library.__dict__[name]
+ if name in FFILibrary.__dict__:
+ return addressof_var(name)
+ raise AttributeError("cffi library has no function or "
+ "global variable named '%s'" % (name,))
#
if libname is not None:
try:
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
@@ -1227,6 +1227,26 @@
assert list(a)[:1000] + [0] * (len(a)-1000) == list(b)
f.close()
+ def test_ffi_buffer_comparisons(self):
+ ffi = FFI(backend=self.Backend())
+ ba = bytearray(range(100, 110))
+ assert ba == memoryview(ba) # justification for the following
+ a = ffi.new("uint8_t[]", list(ba))
+ c = ffi.new("uint8_t[]", [99] + list(ba))
+ try:
+ b_full = ffi.buffer(a)
+ b_short = ffi.buffer(a, 3)
+ b_mid = ffi.buffer(a, 6)
+ b_other = ffi.buffer(c, 6)
+ except NotImplementedError as e:
+ py.test.skip(str(e))
+ else:
+ content = b_full[:]
+ assert content == b_full == ba
+ assert b_other < b_short < b_mid < b_full
+ assert ba > b_mid > ba[0:2]
+ assert b_short != ba[1:4]
+
def test_array_in_struct(self):
ffi = FFI(backend=self.Backend())
ffi.cdef("struct foo_s { int len; short data[5]; };")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
@@ -193,9 +193,12 @@
setattr(s, name, value)
assert getattr(s, name) == value
raw1 = ffi.buffer(s)[:]
+ buff1 = ffi.buffer(s)
t = lib.try_with_value(fnames.index(name), value)
raw2 = ffi.buffer(t, len(raw1))[:]
assert raw1 == raw2
+ buff2 = ffi.buffer(t, len(buff1))
+ assert buff1 == buff2
def test_bitfield_basic(self):
self.check("int a; int b:9; int c:20; int y;", 8, 4, 12)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
@@ -283,3 +283,21 @@
assert ret.right == ownlib.right
assert ret.top == ownlib.top
assert ret.bottom == ownlib.bottom
+
+ def test_addressof_lib(self):
+ if self.module is None:
+ py.test.skip("fix the auto-generation of the tiny test lib")
+ if self.Backend is CTypesBackend:
+ py.test.skip("not implemented with the ctypes backend")
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("long left; int test_getting_errno(void);")
+ lib = ffi.dlopen(self.module)
+ lib.left = 123456
+ p = ffi.addressof(lib, "left")
+ assert ffi.typeof(p) == ffi.typeof("long *")
+ assert p[0] == 123456
+ p[0] += 1
+ assert lib.left == 123457
+ pfn = ffi.addressof(lib, "test_getting_errno")
+ assert ffi.typeof(pfn) == ffi.typeof("int(*)(void)")
+ assert pfn == lib.test_getting_errno
More information about the pypy-commit
mailing list