Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit