Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r64520:b2f349753621 Date: 2013-05-23 15:15 -0700 http://bitbucket.org/pypy/pypy/changeset/b2f349753621/
Log: merge default 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/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -68,7 +68,8 @@ del working_modules["_minimal_curses"] del working_modules["_posixsubprocess"] -# del working_modules["cppyy"] # not tested on win32 + if "cppyy" in working_modules: + del working_modules["cppyy"] # not tested on win32 # The _locale module is needed by site.py on Windows default_modules["_locale"] = None @@ -81,7 +82,8 @@ del working_modules["_minimal_curses"] del working_modules["termios"] del working_modules["_multiprocessing"] # depends on rctime -# del working_modules["cppyy"] # depends on ctypes + if "cppyy" in working_modules: + del working_modules["cppyy"] # depends on ctypes module_dependencies = { diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -151,6 +151,7 @@ if w_fields == space.w_None: self.fields = None else: + self.fields = {} ofs_and_items = [] size = 0 for key in space.listview(w_fields): @@ -338,8 +339,9 @@ elif char == 'V': num = 20 basename = 'void' - w_box_type = space.gettypefor(interp_boxes.W_VoidBox) - return dtype_from_list(space, space.newlist([])) + itemtype = types.VoidType(size) + return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(size), + "V", space.gettypefor(interp_boxes.W_VoidBox)) else: assert char == 'U' basename = 'unicode' diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -280,17 +280,6 @@ assert a.dtype.__reduce__() == (dtype, ('i4', 0, 1), (3, '<', None, None, None, -1, -1, 0)) assert loads(dumps(a.dtype)) == a.dtype - def test_pickle_record(self): - from numpypy import array, dtype - from cPickle import loads, dumps - - d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)]) - assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '<', None, ('x', 'y', 'z', 'value'), {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0), 'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12)}, 20, 1, 0)) - - new_d = loads(dumps(d)) - - assert new_d.__reduce__() == d.__reduce__() - class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): import numpypy as numpy @@ -768,6 +757,7 @@ assert isinstance(unicode_(3), str) class AppTestRecordDtypes(BaseNumpyAppTest): + spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"]) def test_create(self): from numpypy import dtype, void @@ -814,6 +804,30 @@ assert dt.subdtype == (dtype(float), (10,)) assert dt.base == dtype(float) + def test_pickle_record(self): + from numpypy import array, dtype + from cPickle import loads, dumps + + d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)]) + assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '<', None, ('x', 'y', 'z', 'value'), {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0), 'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12)}, 20, 1, 0)) + + new_d = loads(dumps(d)) + + assert new_d.__reduce__() == d.__reduce__() + + def test_pickle_record_subarrays(self): + from numpypy import array, dtype + from cPickle import loads, dumps + + d = dtype([("x", "int32", (3,)), ("y", "int32", (2,)), ("z", "int32", (4,)), ("value", float, (5,))]) + new_d = loads(dumps(d)) + + keys = d.fields.keys() + keys.sort() + assert keys == ["value", "x", "y", "z"] + + assert new_d.itemsize == d.itemsize == 76 + class AppTestNotDirect(BaseNumpyAppTest): def setup_class(cls): BaseNumpyAppTest.setup_class.__func__(cls) 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, diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -3,8 +3,6 @@ from rpython.config.config import ChoiceOption, StrOption, Config from rpython.config.config import ConfigError from rpython.config.support import detect_number_of_processors -from rpython.jit.backend.detect_cpu import autodetect -from rpython.jit.backend.detect_cpu import MODEL_X86, MODEL_X86_NO_SSE2, MODEL_X86_64 DEFL_INLINE_THRESHOLD = 32.4 # just enough to inline add__Int_Int() # and just small enough to prevend inlining of some rlist functions. @@ -15,9 +13,7 @@ DEFL_GC = "minimark" -_is_x86 = autodetect() in (MODEL_X86, MODEL_X86_64, MODEL_X86_NO_SSE2) - -if sys.platform.startswith("linux") and _is_x86: +if sys.platform.startswith("linux"): DEFL_ROOTFINDER_WITHJIT = "asmgcc" else: DEFL_ROOTFINDER_WITHJIT = "shadowstack" _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit