[pypy-commit] cffi default: Fix(?) the ctypes backend, as far as the tests are concerned.
arigo
noreply at buildbot.pypy.org
Tue Jun 26 10:02:43 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r517:087f701abe69
Date: 2012-06-26 10:02 +0200
http://bitbucket.org/cffi/cffi/changeset/087f701abe69/
Log: Fix(?) the ctypes backend, as far as the tests are concerned.
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -12,19 +12,25 @@
raise TypeError
@classmethod
- def _arg_to_ctypes(cls, value):
+ def _arg_to_ctypes(cls, *value):
try:
ctype = cls._ctype
except AttributeError:
raise TypeError("cannot create an instance of %r" % (cls,))
- res = cls._to_ctypes(value)
- if not isinstance(res, ctype):
- res = cls._ctype(res)
+ if value:
+ res = cls._to_ctypes(*value)
+ if not isinstance(res, ctype):
+ res = cls._ctype(res)
+ else:
+ res = cls._ctype()
return res
@classmethod
def _create_ctype_obj(cls, init):
- return cls._arg_to_ctypes(init)
+ if init is None:
+ return cls._arg_to_ctypes()
+ else:
+ return cls._arg_to_ctypes(init)
@staticmethod
def _from_ctypes(ctypes_value):
@@ -40,11 +46,19 @@
cls.__module__ = 'ffi'
def _get_own_repr(self):
- return ''
+ raise NotImplementedError
+
+ def _addr_repr(self, address):
+ if address == 0:
+ return 'NULL'
+ else:
+ if address < 0:
+ address += 1 << (8*ctypes.sizeof(ctypes.c_void_p))
+ return '0x%x' % address
def __repr__(self, c_name=None):
own = self._get_own_repr()
- return '<cdata %r%s>' % (c_name or self._get_c_name(), own)
+ return '<cdata %r %s>' % (c_name or self._get_c_name(), own)
def _convert_to_address(self, BClass):
if BClass is None:
@@ -82,8 +96,6 @@
if isinstance(other, CTypesData):
return cmpfunc(self._convert_to_address(None),
other._convert_to_address(None))
- elif other is None:
- return cmpfunc(self._convert_to_address(None), 0)
else:
return NotImplemented
cmp.func_name = name
@@ -112,6 +124,9 @@
def __hash__(self):
return object.__hash__(self)
+ def _get_own_repr(self):
+ return repr(self._from_ctypes(self._value))
+
class CTypesGenericArray(CTypesData):
__slots__ = []
@@ -120,6 +135,9 @@
for i in xrange(len(self)):
yield self[i]
+ def _get_own_repr(self):
+ return self._addr_repr(ctypes.addressof(self._blob))
+
class CTypesGenericPtr(CTypesData):
__slots__ = ['_address', '_as_ctype_ptr']
@@ -145,6 +163,9 @@
self._as_ctype_ptr = ctypes.cast(address, cls._ctype)
return self
+ def _get_own_repr(self):
+ return self._addr_repr(self._address)
+
def _cast_to_integer(self):
return self._address
@@ -153,26 +174,24 @@
@classmethod
def _to_ctypes(cls, value):
- if value is None:
- address = 0
- else:
- address = value._convert_to_address(cls)
+ if not isinstance(value, CTypesData):
+ raise TypeError("unexpected %s object" % type(value).__name__)
+ address = value._convert_to_address(cls)
return ctypes.cast(address, cls._ctype)
@classmethod
def _from_ctypes(cls, ctypes_ptr):
- if not ctypes_ptr:
- return None
address = ctypes.cast(ctypes_ptr, ctypes.c_void_p).value or 0
return cls._new_pointer_at(address)
@classmethod
def _initialize(cls, ctypes_ptr, value):
- if value is not None:
+ if value:
ctypes_ptr.contents = cls._to_ctypes(value).contents
def _convert_to_address(self, BClass):
- if BClass in (self.__class__, None) or BClass._automatic_casts:
+ if (BClass in (self.__class__, None) or BClass._automatic_casts
+ or self._automatic_casts):
return self._address
else:
return CTypesData._convert_to_address(self, BClass)
@@ -186,6 +205,9 @@
# may be overridden
raise TypeError("cannot instantiate opaque type %s" % (cls,))
+ def _get_own_repr(self):
+ return self._addr_repr(ctypes.addressof(self._blob))
+
@classmethod
def _offsetof(cls, fieldname):
return getattr(cls._ctype, fieldname).offset
@@ -453,9 +475,9 @@
def _get_own_repr(self):
if getattr(self, '_own', False):
- return ' owning %d bytes' % (
+ return 'owning %d bytes' % (
ctypes.sizeof(self._as_ctype_ptr.contents),)
- return ''
+ return super(CTypesPtr, self)._get_own_repr()
#
if (BItem is self.ffi._get_cached_btype(model.void_type) or
BItem is self.ffi._get_cached_btype(model.PrimitiveType('char'))):
@@ -534,8 +556,8 @@
def _get_own_repr(self):
if getattr(self, '_own', False):
- return ' owning %d bytes' % (ctypes.sizeof(self._blob),)
- return ''
+ return 'owning %d bytes' % (ctypes.sizeof(self._blob),)
+ return super(CTypesPtr, self)._get_own_repr()
def _convert_to_address(self, BClass):
if BClass in (CTypesPtr, None) or BClass._automatic_casts:
@@ -725,8 +747,8 @@
def _get_own_repr(self):
if getattr(self, '_own_callback', None) is not None:
- return ' calling %r' % (self._own_callback,)
- return ''
+ return 'calling %r' % (self._own_callback,)
+ return super(CTypesFunction, self)._get_own_repr()
def __call__(self, *args):
if has_varargs:
diff --git a/testing/test_function.py b/testing/test_function.py
--- a/testing/test_function.py
+++ b/testing/test_function.py
@@ -168,7 +168,7 @@
fptr = ffi.C.puts
assert ffi.typeof(fptr) == ffi.typeof("int(*)(const char*)")
if self.Backend is CTypesBackend:
- assert repr(fptr) == "<cdata 'int puts(char *)'>"
+ assert repr(fptr).startswith("<cdata 'int puts(char *)' 0x")
def test_function_pointer(self):
ffi = FFI(backend=self.Backend())
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -36,6 +36,11 @@
def new_array_type(self, ptrtype, length):
return '<array %s x %s>' % (ptrtype, length)
+ def new_void_type(self):
+ return "<void>"
+ def cast(self, x, y):
+ return 'casted!'
+
class FakeStruct(object):
def __init__(self, name):
self.name = name
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -78,7 +78,7 @@
assert lib.foo(42) == 43
assert lib.foo(44L) == 45
assert lib.foo(ffi.cast(typename, 46)) == 47
- py.test.raises(TypeError, lib.foo, None)
+ py.test.raises(TypeError, lib.foo, ffi.NULL)
#
# check for overflow cases
if typename in all_float_types:
@@ -120,7 +120,7 @@
ffi = FFI()
ffi.cdef("int *foo(int *);")
lib = ffi.verify("int *foo(int *a) { return a; }")
- assert lib.foo(None) is None
+ assert lib.foo(ffi.NULL) == ffi.NULL
p = ffi.new("int", 42)
q = ffi.new("int", 42)
assert lib.foo(p) == p
@@ -151,7 +151,7 @@
ffi.cdef("typedef struct foo_s foo_t; int bar(foo_t *);")
lib = ffi.verify("typedef struct foo_s foo_t;\n"
"int bar(foo_t *f) { return 42; }\n")
- assert lib.bar(None) == 42
+ assert lib.bar(ffi.NULL) == 42
def test_ffi_full_struct():
ffi = FFI()
@@ -477,7 +477,7 @@
tk = ffi.cast("token_t *", tkmem)
results = [lib.foo(tk) for i in range(6)]
assert results == [1, 3, 4, 6, 8, 9]
- assert lib.foo(None) == -42
+ assert lib.foo(ffi.NULL) == -42
def test_unknown_type_2():
ffi = FFI()
More information about the pypy-commit
mailing list