Author: Antonio Cuni <anto.c...@gmail.com> Branch: int_w-refactor Changeset: r69518:612616fc0f38 Date: 2014-02-27 16:38 +0100 http://bitbucket.org/pypy/pypy/changeset/612616fc0f38/
Log: add support for allow_conversion to more objspace methods, and disallow them in _rawffi.alt: this fixes some weird ctypes behavior with old style classes, which might raise AttributeError instead of TypeError when we try to convert them diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1296,16 +1296,16 @@ else: return index - def r_longlong_w(self, w_obj): - bigint = self.bigint_w(w_obj) + def r_longlong_w(self, w_obj, allow_conversion=True): + bigint = self.bigint_w(w_obj, allow_conversion) try: return bigint.tolonglong() except OverflowError: raise OperationError(self.w_OverflowError, self.wrap('integer too large')) - def r_ulonglong_w(self, w_obj): - bigint = self.bigint_w(w_obj) + def r_ulonglong_w(self, w_obj, allow_conversion=True): + bigint = self.bigint_w(w_obj, allow_conversion) try: return bigint.toulonglong() except OverflowError: @@ -1443,10 +1443,7 @@ # This is all interface for gateway.py. gateway_int_w = int_w - - def gateway_float_w(self, w_obj): - return self.float_w(self.float(w_obj)) - + gateway_float_w = float_w gateway_r_longlong_w = r_longlong_w gateway_r_ulonglong_w = r_ulonglong_w @@ -1477,7 +1474,7 @@ def c_uint_w(self, w_obj): # Like space.gateway_uint_w(), but raises an app-level OverflowError if # the integer does not fit in 32 bits. Here for gateway.py. - value = self.gateway_r_uint_w(w_obj) + value = self.uint_w(w_obj) if value > UINT_MAX_32_BITS: raise OperationError(self.w_OverflowError, self.wrap("expected an unsigned 32-bit integer")) @@ -1487,7 +1484,7 @@ # Like space.gateway_int_w(), but raises an app-level ValueError if # the integer is negative or does not fit in 32 bits. Here # for gateway.py. - value = self.gateway_int_w(w_obj) + value = self.int_w(w_obj) if value < 0: raise OperationError(self.w_ValueError, self.wrap("expected a non-negative integer")) @@ -1496,22 +1493,22 @@ self.wrap("expected a 32-bit integer")) return value - def truncatedint_w(self, w_obj): + def truncatedint_w(self, w_obj, allow_conversion=True): # Like space.gateway_int_w(), but return the integer truncated # instead of raising OverflowError. For obscure cases only. try: - return self.int_w(w_obj) + return self.int_w(w_obj, allow_conversion) except OperationError, e: if not e.match(self, self.w_OverflowError): raise from rpython.rlib.rarithmetic import intmask return intmask(self.bigint_w(w_obj).uintmask()) - def truncatedlonglong_w(self, w_obj): + def truncatedlonglong_w(self, w_obj, allow_conversion=True): # Like space.gateway_r_longlong_w(), but return the integer truncated # instead of raising OverflowError. try: - return self.r_longlong_w(w_obj) + return self.r_longlong_w(w_obj, allow_conversion) except OperationError, e: if not e.match(self, self.w_OverflowError): raise diff --git a/pypy/module/_rawffi/alt/test/test_funcptr.py b/pypy/module/_rawffi/alt/test/test_funcptr.py --- a/pypy/module/_rawffi/alt/test/test_funcptr.py +++ b/pypy/module/_rawffi/alt/test/test_funcptr.py @@ -185,6 +185,10 @@ set_val_to_ptr(ptr2, 123) assert get_dummy() == 123 set_val_to_ptr(ptr2, 0) + # + class OldStyle: + pass + raises(TypeError, "set_val_to_ptr(OldStyle(), 0)") def test_convert_strings_to_char_p(self): """ diff --git a/pypy/module/_rawffi/alt/type_converter.py b/pypy/module/_rawffi/alt/type_converter.py --- a/pypy/module/_rawffi/alt/type_converter.py +++ b/pypy/module/_rawffi/alt/type_converter.py @@ -25,7 +25,7 @@ assert libffi.IS_32_BIT self._longlong(w_ffitype, w_obj) elif w_ffitype.is_signed(): - intval = space.truncatedint_w(w_obj) + intval = space.truncatedint_w(w_obj, allow_conversion=False) self.handle_signed(w_ffitype, w_obj, intval) elif self.maybe_handle_char_or_unichar_p(w_ffitype, w_obj): # the object was already handled from within @@ -33,16 +33,16 @@ pass elif w_ffitype.is_pointer(): w_obj = self.convert_pointer_arg_maybe(w_obj, w_ffitype) - intval = space.truncatedint_w(w_obj) + intval = space.truncatedint_w(w_obj, allow_conversion=False) self.handle_pointer(w_ffitype, w_obj, intval) elif w_ffitype.is_unsigned(): - uintval = r_uint(space.truncatedint_w(w_obj)) + uintval = r_uint(space.truncatedint_w(w_obj, allow_conversion=False)) self.handle_unsigned(w_ffitype, w_obj, uintval) elif w_ffitype.is_char(): - intval = space.int_w(space.ord(w_obj)) + intval = space.int_w(space.ord(w_obj), allow_conversion=False) self.handle_char(w_ffitype, w_obj, intval) elif w_ffitype.is_unichar(): - intval = space.int_w(space.ord(w_obj)) + intval = space.int_w(space.ord(w_obj), allow_conversion=False) self.handle_unichar(w_ffitype, w_obj, intval) elif w_ffitype.is_double(): self._float(w_ffitype, w_obj) @@ -60,20 +60,20 @@ def _longlong(self, w_ffitype, w_obj): # a separate function, which can be seen by the jit or not, # depending on whether longlongs are supported - longlongval = self.space.truncatedlonglong_w(w_obj) + longlongval = self.space.truncatedlonglong_w(w_obj, allow_conversion=False) self.handle_longlong(w_ffitype, w_obj, longlongval) def _float(self, w_ffitype, w_obj): # a separate function, which can be seen by the jit or not, # depending on whether floats are supported - floatval = self.space.float_w(w_obj) + floatval = self.space.float_w(w_obj, allow_conversion=False) self.handle_float(w_ffitype, w_obj, floatval) def _singlefloat(self, w_ffitype, w_obj): # a separate function, which can be seen by the jit or not, # depending on whether singlefloats are supported from rpython.rlib.rarithmetic import r_singlefloat - floatval = self.space.float_w(w_obj) + floatval = self.space.float_w(w_obj, allow_conversion=False) singlefloatval = r_singlefloat(floatval) self.handle_singlefloat(w_ffitype, w_obj, singlefloatval) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit