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

Reply via email to