[pypy-commit] pypy int_w-refactor: 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
antocuni
noreply at buildbot.pypy.org
Thu Feb 27 16:39:49 CET 2014
Author: Antonio Cuni <anto.cuni at 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)
More information about the pypy-commit
mailing list