Author: Armin Rigo <[email protected]>
Branch:
Changeset: r64518:a57f07766fff
Date: 2013-05-23 21:31 +0200
http://bitbucket.org/pypy/pypy/changeset/a57f07766fff/
Log: Run pypy/tool/import_cffi
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,5 +4,5 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "0.6"
-__version_info__ = (0, 6)
+__version__ = "0.7"
+__version_info__ = (0, 7)
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
@@ -73,15 +73,15 @@
if name.startswith('RTLD_'):
setattr(self, name, getattr(backend, name))
#
- BVoidP = self._get_cached_btype(model.voidp_type)
+ self.BVoidP = self._get_cached_btype(model.voidp_type)
if isinstance(backend, types.ModuleType):
# _cffi_backend: attach these constants to the class
if not hasattr(FFI, 'NULL'):
- FFI.NULL = self.cast(BVoidP, 0)
+ FFI.NULL = self.cast(self.BVoidP, 0)
FFI.CData, FFI.CType = backend._get_types()
else:
# ctypes backend: attach these constants to the instance
- self.NULL = self.cast(BVoidP, 0)
+ self.NULL = self.cast(self.BVoidP, 0)
self.CData, self.CType = backend._get_types()
def cdef(self, csource, override=False):
@@ -346,6 +346,12 @@
self._cdefsources.extend(ffi_to_include._cdefsources)
self._cdefsources.append(']')
+ def new_handle(self, x):
+ return self._backend.newp_handle(self.BVoidP, x)
+
+ def from_handle(self, x):
+ return self._backend.from_handle(x)
+
def _make_ffi_library(ffi, libname, flags):
import os
@@ -372,8 +378,8 @@
BType = ffi._get_cached_btype(tp)
try:
value = backendlib.load_function(BType, name)
- except KeyError:
- raise AttributeError(name)
+ except KeyError as e:
+ raise AttributeError('%s: %s' % (name, e))
library.__dict__[name] = value
return
#
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -16,6 +16,7 @@
class CTypesData(object):
__metaclass__ = CTypesType
__slots__ = ['__weakref__']
+ __name__ = '<cdata>'
def __init__(self, *args):
raise TypeError("cannot instantiate %r" % (self.__class__,))
@@ -491,6 +492,8 @@
elif BItem in (getbtype(model.PrimitiveType('signed char')),
getbtype(model.PrimitiveType('unsigned char'))):
kind = 'bytep'
+ elif BItem is getbtype(model.void_type):
+ kind = 'voidp'
else:
kind = 'generic'
#
@@ -546,13 +549,13 @@
def __setitem__(self, index, value):
self._as_ctype_ptr[index] = BItem._to_ctypes(value)
- if kind == 'charp':
+ if kind == 'charp' or kind == 'voidp':
@classmethod
- def _arg_to_ctypes(cls, value):
- if isinstance(value, bytes):
- return ctypes.c_char_p(value)
+ def _arg_to_ctypes(cls, *value):
+ if value and isinstance(value[0], bytes):
+ return ctypes.c_char_p(value[0])
else:
- return super(CTypesPtr, cls)._arg_to_ctypes(value)
+ return super(CTypesPtr, cls)._arg_to_ctypes(*value)
if kind == 'charp' or kind == 'bytep':
def _to_string(self, maxlen):
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -15,6 +15,20 @@
def patch_extension_kwds(self, kwds):
pass
+ def find_module(self, module_name, path, so_suffix):
+ try:
+ f, filename, descr = imp.find_module(module_name, path)
+ except ImportError:
+ return None
+ if f is not None:
+ f.close()
+ # Note that after a setuptools installation, there are both .py
+ # and .so files with the same basename. The code here relies on
+ # imp.find_module() locating the .so in priority.
+ if descr[0] != so_suffix:
+ return None
+ return filename
+
def collect_types(self):
self._typesdict = {}
self._generate("collecttype")
@@ -427,9 +441,9 @@
prnt('static void %s(%s *p)' % (checkfuncname, cname))
prnt('{')
prnt(' /* only to generate compile-time warnings or errors */')
- for fname, ftype, _ in tp.enumfields():
+ for fname, ftype, fbitsize in tp.enumfields():
if (isinstance(ftype, model.PrimitiveType)
- and ftype.is_integer_type()):
+ and ftype.is_integer_type()) or fbitsize >= 0:
# accept all integers, but complain on float or double
prnt(' (void)((p->%s) << 1);' % fname)
else:
diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py
--- a/lib_pypy/cffi/vengine_gen.py
+++ b/lib_pypy/cffi/vengine_gen.py
@@ -1,4 +1,4 @@
-import sys
+import sys, os
import types
from . import model, ffiplatform
@@ -20,6 +20,16 @@
# up in kwds['export_symbols'].
kwds.setdefault('export_symbols', self.export_symbols)
+ def find_module(self, module_name, path, so_suffix):
+ basename = module_name + so_suffix
+ if path is None:
+ path = sys.path
+ for dirname in path:
+ filename = os.path.join(dirname, basename)
+ if os.path.isfile(filename):
+ return filename
+ return None
+
def collect_types(self):
pass # not needed in the generic engine
@@ -216,9 +226,9 @@
prnt('static void %s(%s *p)' % (checkfuncname, cname))
prnt('{')
prnt(' /* only to generate compile-time warnings or errors */')
- for fname, ftype, _ in tp.enumfields():
+ for fname, ftype, fbitsize in tp.enumfields():
if (isinstance(ftype, model.PrimitiveType)
- and ftype.is_integer_type()):
+ and ftype.is_integer_type()) or fbitsize >= 0:
# accept all integers, but complain on float or double
prnt(' (void)((p->%s) << 1);' % fname)
else:
diff --git a/lib_pypy/cffi/verifier.py b/lib_pypy/cffi/verifier.py
--- a/lib_pypy/cffi/verifier.py
+++ b/lib_pypy/cffi/verifier.py
@@ -102,21 +102,10 @@
path = pkg.__path__
else:
path = None
- try:
- f, filename, descr = imp.find_module(self.get_module_name(),
- path)
- except ImportError:
+ filename = self._vengine.find_module(self.get_module_name(), path,
+ _get_so_suffix())
+ if filename is None:
return
- if f is not None:
- f.close()
- if filename.lower().endswith('.py'):
- # on PyPy, if there are both .py and .pypy-19.so files in
- # the same directory, the .py file is returned. That's the
- # case after a setuptools installation. We never want to
- # load the .py file here...
- filename = filename[:-3] + _get_so_suffix()
- if not os.path.isfile(filename):
- return
self.modulefilename = filename
self._vengine.collect_types()
self._has_module = True
diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
@@ -971,6 +971,16 @@
s.c = -4
assert s.c == -4
+ def test_bitfield_enum(self):
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("""
+ typedef enum { AA, BB, CC } foo_e;
+ typedef struct { foo_e f:2; } foo_s;
+ """)
+ s = ffi.new("foo_s *")
+ s.f = 2
+ assert s.f == 2
+
def test_anonymous_struct(self):
ffi = FFI(backend=self.Backend())
ffi.cdef("typedef struct { int a; } foo_t;")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
@@ -28,3 +28,12 @@
assert ffi.typeof("long(*)(long, long**, ...)").cname == (
"long(*)(long, long * *, ...)")
assert ffi.typeof("long(*)(long, long**, ...)").ellipsis is True
+
+ def test_new_handle(self):
+ ffi = FFI(backend=self.Backend())
+ o = [2, 3, 4]
+ p = ffi.new_handle(o)
+ assert ffi.typeof(p) == ffi.typeof("void *")
+ assert ffi.from_handle(p) is o
+ assert ffi.from_handle(ffi.cast("char *", p)) is o
+ py.test.raises(RuntimeError, ffi.from_handle, ffi.NULL)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_function.py
b/pypy/module/test_lib_pypy/cffi_tests/test_function.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_function.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_function.py
@@ -334,6 +334,31 @@
assert lib.EE == -5
assert lib.FF == -4
+ def test_void_star_accepts_string(self):
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("""int strlen(const void *);""")
+ lib = ffi.dlopen(None)
+ res = lib.strlen(b"hello")
+ assert res == 5
+
+ def test_signed_char_star_accepts_string(self):
+ if self.Backend is CTypesBackend:
+ py.test.skip("not supported by the ctypes backend")
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("""int strlen(signed char *);""")
+ lib = ffi.dlopen(None)
+ res = lib.strlen(b"hello")
+ assert res == 5
+
+ def test_unsigned_char_star_accepts_string(self):
+ if self.Backend is CTypesBackend:
+ py.test.skip("not supported by the ctypes backend")
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("""int strlen(unsigned char *);""")
+ lib = ffi.dlopen(None)
+ res = lib.strlen(b"hello")
+ assert res == 5
+
def test_missing_function(self):
ffi = FFI(backend=self.Backend())
ffi.cdef("""
@@ -341,3 +366,19 @@
""")
m = ffi.dlopen("m")
assert not hasattr(m, 'nonexistent')
+
+ def test_wraps_from_stdlib(self):
+ import functools
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("""
+ double sin(double x);
+ """)
+ def my_decorator(f):
+ @functools.wraps(f)
+ def wrapper(*args):
+ return f(*args) + 100
+ return wrapper
+ m = ffi.dlopen("m")
+ sin100 = my_decorator(m.sin)
+ x = sin100(1.23)
+ assert x == math.sin(1.23) + 100
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
@@ -522,6 +522,18 @@
py.test.raises(OverflowError, "s.b = 4")
assert s.b == 3
+def test_struct_with_bitfield_enum():
+ ffi = FFI()
+ code = """
+ typedef enum { AA, BB, CC } foo_e;
+ typedef struct { foo_e f:2; } foo_s;
+ """
+ ffi.cdef(code)
+ ffi.verify(code)
+ s = ffi.new("foo_s *")
+ s.f = 2
+ assert s.f == 2
+
def test_unsupported_struct_with_bitfield_ellipsis():
ffi = FFI()
py.test.raises(NotImplementedError, ffi.cdef,
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
b/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
@@ -24,6 +24,12 @@
modules = ('cffi', '_cffi_backend')
except ImportError:
modules = ('cffi', '_cffi_backend', 'pycparser')
+ try:
+ import ply
+ except ImportError:
+ pass
+ else:
+ modules += ('ply',) # needed for older versions of pycparser
for module in modules:
target = imp.find_module(module)[1]
os.symlink(target, os.path.join(site_packages,
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit