[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