[pypy-commit] pypy reflex-support: o) simplication of exception handling

wlav noreply at buildbot.pypy.org
Thu Mar 29 00:47:08 CEST 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r54048:dbf598dad646
Date: 2012-03-28 15:47 -0700
http://bitbucket.org/pypy/pypy/changeset/dbf598dad646/

Log:	o) simplication of exception handling o) human-readable error
	messages if all overloads fail o) back to 'auto' for thread safety
	for CINT back-end (still not working as desired)

diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py
--- a/pypy/module/cppyy/capi/cint_capi.py
+++ b/pypy/module/cppyy/capi/cint_capi.py
@@ -20,7 +20,7 @@
 def identify():
     return 'CINT'
 
-threadsafe = False
+threadsafe = 'auto'
 
 # force loading in global mode of core libraries, rather than linking with
 # them as PyPy uses various version of dlopen in various places; note that
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -51,7 +51,7 @@
         return fieldptr
 
     def _is_abstract(self, space):
-        raise TypeError("no converter available")
+        raise OperationError(space.w_TypeError, space.wrap("no converter available"))
 
     def convert_argument(self, space, w_obj, address):
         self._is_abstract(space)
@@ -140,7 +140,8 @@
         try:
             byteptr[0] = buf.get_raw_address()
         except ValueError:
-            raise TypeError("raw buffer interface not supported")
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("raw buffer interface not supported"))
 
 
 class NumericTypeConverterMixin(object):
@@ -190,7 +191,8 @@
         self.name = name
 
     def convert_argument(self, space, w_obj, address):
-        raise TypeError('no converter available for type "%s"' % self.name)
+        raise OperationError(space.w_TypeError,
+                             space.wrap('no converter available for type "%s"' % self.name))
 
 
 class BoolConverter(TypeConverter):
@@ -200,7 +202,8 @@
     def _unwrap_object(self, space, w_obj):
         arg = space.c_int_w(w_obj)
         if arg != False and arg != True:
-            raise ValueError("boolean value should be bool, or integer 1 or 0")
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("boolean value should be bool, or integer 1 or 0"))
         return arg
 
     def convert_argument(self, space, w_obj, address):
@@ -233,14 +236,16 @@
         if space.isinstance_w(w_value, space.w_int):
             ival = space.c_int_w(w_value)
             if ival < 0 or 256 <= ival:
-                raise ValueError("char arg not in range(256)")
+                raise OperationError(space.w_ValueError,
+                                     space.wrap("char arg not in range(256)"))
 
             value = rffi.cast(rffi.CHAR, space.c_int_w(w_value))
         else:
             value = space.str_w(w_value)
 
         if len(value) != 1:  
-            raise ValueError("char expected, got string of size %d" % len(value))
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("char expected, got string of size %d" % len(value)))
         return value[0] # turn it into a "char" to the annotator
 
     def convert_argument(self, space, w_obj, address):
@@ -516,8 +521,9 @@
                     obj.cppclass.handle, self.cpptype.handle, rawobject)
                 obj_address = capi.direct_ptradd(rawobject, offset)
                 return rffi.cast(capi.C_OBJECT, obj_address)
-        raise TypeError("cannot pass %s as %s" %
-                        (space.type(w_obj).getname(space, "?"), self.cpptype.name))
+        raise OperationError(space.w_TypeError,
+                             space.wrap("cannot pass %s as %s" %
+                             (space.type(w_obj).getname(space, "?"), self.cpptype.name)))
 
     def convert_argument(self, space, w_obj, address):
         x = rffi.cast(rffi.VOIDPP, address)
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -1,5 +1,7 @@
 import sys
 
+from pypy.interpreter.error import OperationError
+
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib import libffi, clibffi
 
@@ -19,7 +21,8 @@
         pass
 
     def execute(self, space, cppmethod, cppthis, num_args, args):
-        raise TypeError('return type not available or supported')
+        raise OperationError(space.w_TypeError,
+                             space.wrap('return type not available or supported'))
 
     def execute_libffi(self, space, libffifunc, argchain):
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
@@ -360,7 +363,6 @@
     # currently used until proper lazy instantiation available in interp_cppyy
     return FunctionExecutor(space, None)
  
- #  raise TypeError("no clue what %s is" % name)
 
 _executors["void"]                = VoidExecutor
 _executors["void*"]               = PtrTypeExecutor
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -133,7 +133,8 @@
         args_expected = len(self.arg_defs)
         args_given = len(args_w)
         if args_expected < args_given or args_given < self.args_required:
-            raise TypeError("wrong number of arguments")
+            raise OperationError(self.space.w_TypeError,
+                                 self.space.wrap("wrong number of arguments"))
 
         if self.arg_converters is None:
             self._setup(cppthis)
@@ -235,7 +236,7 @@
         assert lltype.typeOf(newthis) == capi.C_OBJECT
         try:
             CPPMethod.call(self, newthis, args_w)
-        except Exception:
+        except:
             capi.c_deallocate(self.cpptype.handle, newthis)
             raise
         return wrap_new_cppobject_nocast(self.space, None, self.cpptype, newthis, False, True)
@@ -285,12 +286,16 @@
 
         # only get here if all overloads failed ...
         errmsg = 'None of the overloads matched:'
+        if hasattr(self.space, "fake"):     # FakeSpace fails errorstr (see below)
+            raise OperationError(self.space.w_TypeError, self.space.wrap(errmsg))
         for i in range(len(self.functions)):
             cppyyfunc = self.functions[i]
             try:
                 return cppyyfunc.call(cppthis, args_w)
+            except OperationError, e:
+                errmsg += '\n\t'+e.errorstr(self.space)
             except Exception, e:
-                errmsg += '\n\t'+str(e)
+                errmsg += '\n\tException:'+str(e)
 
         raise OperationError(self.space.w_TypeError, self.space.wrap(errmsg))
 
@@ -334,23 +339,13 @@
     def get(self, w_cppinstance, w_type):
         cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
         offset = self._get_offset(cppinstance)
-        try:
-            return self.converter.from_memory(self.space, w_cppinstance, w_type, offset)
-        except TypeError, e:
-            raise OperationError(self.space.w_TypeError, self.space.wrap(str(e)))
-        except ValueError, e:
-            raise OperationError(self.space.w_ValueError, self.space.wrap(str(e)))
+        return self.converter.from_memory(self.space, w_cppinstance, w_type, offset)
 
     def set(self, w_cppinstance, w_value):
         cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
         offset = self._get_offset(cppinstance)
-        try:
-            self.converter.to_memory(self.space, w_cppinstance, w_value, offset)
-            return self.space.w_None
-        except TypeError, e:
-            raise OperationError(self.space.w_TypeError, self.space.wrap(str(e)))
-        except ValueError, e:
-            raise OperationError(self.space.w_ValueError, self.space.wrap(str(e)))
+        self.converter.to_memory(self.space, w_cppinstance, w_value, offset)
+        return self.space.w_None
 
 W_CPPDataMember.typedef = TypeDef(
     'CPPDataMember',
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -25,8 +25,13 @@
     typename = "type"
     def __init__(self, name):
         self.name = name
+        self.__name__ = name
     def getname(self, space, name):
         return self.name
+class FakeException(FakeType):
+    def __init__(self, name):
+        FakeType.__init__(self, name)
+        self.message = name
 
 @jit.dont_look_inside
 def _opaque_direct_ptradd(ptr, offset):
@@ -47,12 +52,12 @@
 class FakeSpace(object):
     fake = True
 
-    w_ValueError = FakeType("ValueError")
-    w_TypeError = FakeType("TypeError")
-    w_AttributeError = FakeType("AttributeError")
-    w_ReferenceError = FakeType("ReferenceError")
-    w_NotImplementedError = FakeType("NotImplementedError")
-    w_RuntimeError = FakeType("RuntimeError")
+    w_ValueError = FakeException("ValueError")
+    w_TypeError = FakeException("TypeError")
+    w_AttributeError = FakeException("AttributeError")
+    w_ReferenceError = FakeException("ReferenceError")
+    w_NotImplementedError = FakeException("NotImplementedError")
+    w_RuntimeError = FakeException("RuntimeError")
 
     w_None = None
     w_str = FakeType("str")
@@ -99,6 +104,9 @@
     def exception_match(self, typ, sub):
         return typ is sub
 
+    def is_w(self, w_one, w_two):
+        return w_one is w_two
+
     def int_w(self, w_obj):
         assert isinstance(w_obj, FakeInt)
         return w_obj.val
@@ -107,11 +115,14 @@
         assert isinstance(w_obj, FakeInt)
         return rarithmetic.r_uint(w_obj.val)
 
-
     def str_w(self, w_obj):
         assert isinstance(w_obj, FakeString)
         return w_obj.val
 
+    def str(self, obj):
+        assert isinstance(obj, str)
+        return obj
+
     c_int_w = int_w
 
     def isinstance_w(self, w_obj, w_type):
@@ -121,6 +132,11 @@
     def type(self, w_obj):
         return FakeType("fake")
 
+    def getattr(self, w_obj, w_name):
+        assert isinstance(w_obj, FakeException)
+        assert self.str_w(w_name) == "__name__"
+        return FakeString(w_obj.name)
+
     def findattr(self, w_obj, w_name):
         return None
 


More information about the pypy-commit mailing list