Author: Armin Rigo <ar...@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() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit