Author: Armin Rigo <ar...@tunes.org> Branch: cffi-static-callback Changeset: r80681:5a15e8752bc4 Date: 2015-11-15 13:30 +0100 http://bitbucket.org/pypy/pypy/changeset/5a15e8752bc4/
Log: fixes diff --git a/pypy/module/_cffi_backend/call_python.py b/pypy/module/_cffi_backend/call_python.py --- a/pypy/module/_cffi_backend/call_python.py +++ b/pypy/module/_cffi_backend/call_python.py @@ -98,7 +98,7 @@ return llhelper(lltype.Ptr(CALLPY_FN), _cffi_call_python) -class Cache: +class KeepaliveCache: def __init__(self, space): self.cache_dict = {} @@ -110,9 +110,8 @@ ffi = space.interp_w(W_FFIObject, w_ffi) if space.is_w(w_name, space.w_None): - XXX - else: - name = space.str_w(w_name) + w_name = space.getattr(w_python_callable, space.wrap('__name__')) + name = space.str_w(w_name) ctx = ffi.ctxobj.ctx index = parse_c_type.search_in_globals(ctx, name) @@ -136,7 +135,7 @@ w_python_callable, w_error, w_onerror) key = rffi.cast(lltype.Signed, callpy) - space.fromcache(Cache).cache_dict[key] = callpython + space.fromcache(KeepaliveCache).cache_dict[key] = callpython callpy.c_reserved1 = rffi.cast(rffi.CCHARP, callpython.hide_object()) # return a cdata of type function-pointer, equal to the one diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -47,8 +47,9 @@ class W_CallPython(W_CData): """Base class for W_CDataCallback, also used from call_python.py. """ + decode_args_from_libffi = False + error_string = '' w_onerror = None - decode_args_from_libffi = False def __init__(self, space, cdata, ctype, w_callable, w_error, w_onerror): W_CData.__init__(self, space, cdata, ctype) @@ -66,13 +67,14 @@ # fresult = self.getfunctype().ctitem size = fresult.size - if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG: - size = SIZE_OF_FFI_ARG - with lltype.scoped_alloc(rffi.CCHARP.TO, size, zero=True) as ll_error: - if not space.is_none(w_error): - convert_from_object_fficallback(fresult, ll_error, w_error, - self.decode_args_from_libffi) - self.error_string = rffi.charpsize2str(ll_error, size) + if size > 0: + if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG: + size = SIZE_OF_FFI_ARG + with lltype.scoped_alloc(rffi.CCHARP.TO, size, zero=True) as ll_err: + if not space.is_none(w_error): + convert_from_object_fficallback(fresult, ll_err, w_error, + self.decode_args_from_libffi) + self.error_string = rffi.charpsize2str(ll_err, size) # # We must setup the GIL here, in case the callback is invoked in # some other non-Pythonic thread. This is the same as cffi on diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -34,9 +34,11 @@ def _clean_cache(space): "NOT_RPYTHON" from pypy.module._cffi_backend.realize_c_type import RealizeCache + from pypy.module._cffi_backend.call_python import KeepaliveCache if hasattr(space, 'fromcache'): # not with the TinyObjSpace space.fromcache(UniqueCache).__init__(space) space.fromcache(RealizeCache).__init__(space) + space.fromcache(KeepaliveCache).__init__(space) # ____________________________________________________________ diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py --- a/pypy/module/_cffi_backend/test/test_recompiler.py +++ b/pypy/module/_cffi_backend/test/test_recompiler.py @@ -1473,51 +1473,50 @@ assert lib.boz() is boz() is None assert seen == ["Boz", "Boz"] - def test_call_python_bogus_name(): - ffi = FFI() - ffi.cdef("int abc;") - lib = verify(ffi, 'test_call_python_bogus_name', "int abc;") + def test_call_python_bogus_name(self): + ffi, lib = self.prepare("int abc;", + 'test_call_python_bogus_name', + "int abc;") def fn(): pass - py.test.raises(ffi.error, ffi.call_python("unknown_name"), fn) - py.test.raises(ffi.error, ffi.call_python("abc"), fn) + raises(ffi.error, ffi.call_python("unknown_name"), fn) + raises(ffi.error, ffi.call_python("abc"), fn) assert lib.abc == 0 - e = py.test.raises(ffi.error, ffi.call_python("abc"), fn) + e = raises(ffi.error, ffi.call_python("abc"), fn) assert str(e.value) == ("ffi.call_python('abc'): name not found as a " "CFFI_CALL_PYTHON line from the cdef") - e = py.test.raises(ffi.error, ffi.call_python(), fn) + e = raises(ffi.error, ffi.call_python(), fn) assert str(e.value) == ("ffi.call_python('fn'): name not found as a " "CFFI_CALL_PYTHON line from the cdef") # - py.test.raises(TypeError, ffi.call_python(42), fn) - py.test.raises((TypeError, AttributeError), ffi.call_python(), "foo") + raises(TypeError, ffi.call_python(42), fn) + raises((TypeError, AttributeError), ffi.call_python(), "foo") class X: pass x = X() x.__name__ = x - py.test.raises(TypeError, ffi.call_python(), x) + raises(TypeError, ffi.call_python(), x) - def test_call_python_bogus_result_type(): - ffi = FFI() - ffi.cdef("CFFI_CALL_PYTHON void bar(int);") - lib = verify(ffi, 'test_call_python_bogus_result_type', "") - # + def test_call_python_bogus_result_type(self): + ffi, lib = self.prepare("CFFI_CALL_PYTHON void bar(int);", + 'test_call_python_bogus_result_type', + "") def bar(n): return n * 10 bar1 = ffi.call_python()(bar) - with StdErrCapture() as f: + with self.StdErrCapture() as f: res = bar1(321) assert res is None assert f.getvalue() == ( "From cffi callback %r:\n" % (bar,) + "Trying to convert the result back to C:\n" - "TypeError: callback with the return type 'void' must return None\n") + "TypeError: callback with the return type 'void' must return None\n" + ) - def test_call_python_redefine(): - ffi = FFI() - ffi.cdef("CFFI_CALL_PYTHON int bar(int);") - lib = verify(ffi, 'test_call_python_redefine', "") - # + def test_call_python_redefine(self): + ffi, lib = self.prepare("CFFI_CALL_PYTHON int bar(int);", + 'test_call_python_redefine', + "") @ffi.call_python() def bar(n): return n * 10 @@ -1528,16 +1527,14 @@ return -n assert lib.bar(42) == -42 - def test_call_python_struct(): - ffi = FFI() - ffi.cdef(""" + def test_call_python_struct(self): + ffi, lib = self.prepare(""" struct foo_s { int a, b, c; }; CFFI_CALL_PYTHON int bar(int, struct foo_s, int); CFFI_CALL_PYTHON struct foo_s baz(int, int); CFFI_CALL_PYTHON struct foo_s bok(void); - """) - lib = verify(ffi, 'test_call_python_struct', - "struct foo_s { int a, b, c; };") + """, 'test_call_python_struct', + "struct foo_s { int a, b, c; };") # @ffi.call_python() def bar(x, s, z): @@ -1559,14 +1556,12 @@ res = lib.bok() assert [res.a, res.b, res.c] == [10, 20, 30] - def test_call_python_long_double(): - ffi = FFI() - ffi.cdef(""" + def test_call_python_long_double(self): + ffi, lib = self.prepare(""" CFFI_CALL_PYTHON int bar(int, long double, int); CFFI_CALL_PYTHON long double baz(int, int); CFFI_CALL_PYTHON long double bok(void); - """) - lib = verify(ffi, 'test_call_python_long_double', "") + """, 'test_call_python_long_double', "") # @ffi.call_python() def bar(x, l, z): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit