[pypy-commit] pypy cling-support: fix handling of abstract classes

wlav pypy.commits at gmail.com
Tue Jul 12 13:58:18 EDT 2016


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: cling-support
Changeset: r85669:cfe5c3380cce
Date: 2016-07-12 10:55 -0700
http://bitbucket.org/pypy/pypy/changeset/cfe5c3380cce/

Log:	fix handling of abstract classes

diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py
--- a/pypy/module/cppyy/capi/builtin_capi.py
+++ b/pypy/module/cppyy/capi/builtin_capi.py
@@ -238,6 +238,13 @@
     compilation_info=backend.eci)
 def c_is_namespace(space, scope):
     return _c_is_namespace(scope)
+_c_is_abstract = rffi.llexternal(
+    "cppyy_is_abstract",
+    [C_SCOPE], rffi.INT,
+    releasegil=ts_reflect,
+    compilation_info=backend.eci)
+def c_is_abstract(space, cpptype):
+    return _c_is_abstract(cpptype)
 _c_is_enum = rffi.llexternal(
     "cppyy_is_enum",
     [rffi.CCHARP], rffi.INT,
diff --git a/pypy/module/cppyy/capi/loadable_capi.py b/pypy/module/cppyy/capi/loadable_capi.py
--- a/pypy/module/cppyy/capi/loadable_capi.py
+++ b/pypy/module/cppyy/capi/loadable_capi.py
@@ -162,6 +162,7 @@
 
             # scope reflection information
             'is_namespace'             : ([c_scope],                  c_int),
+            'is_abstract'              : ([c_type],                   c_int),
             'is_enum'                  : ([c_ccharp],                 c_int),
 
             # type/class reflection information
@@ -367,6 +368,8 @@
 # scope reflection information -----------------------------------------------
 def c_is_namespace(space, scope):
     return space.bool_w(call_capi(space, 'is_namespace', [_Arg(h=scope)]))
+def c_is_abstract(space, scope):
+    return space.bool_w(call_capi(space, 'is_abstract', [_Arg(h=cpptype)]))
 def c_is_enum(space, name):
     return space.bool_w(call_capi(space, 'is_enum', [_Arg(s=name)]))
 
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -85,6 +85,8 @@
     RPY_EXTERN
     int cppyy_is_namespace(cppyy_scope_t scope);
     RPY_EXTERN
+    int cppyy_is_abstract(cppyy_type_t type);
+    RPY_EXTERN
     int cppyy_is_enum(const char* type_name);
 
     /* class reflection information ------------------------------------------- */
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
@@ -1078,16 +1078,13 @@
         return None
 
     def instance__init__(self, args_w):
-        try:
-            constructor_overload = self.cppclass.get_overload(self.cppclass.name)
-            constructor_overload.call(self, args_w)
-        except OperationError as e:
-            if not e.match(self.space, self.space.w_AttributeError):
-                raise
+        if capi.c_is_abstract(self.space, self.cppclass.handle):
             raise oefmt(self.space.w_TypeError,
                         "cannot instantiate abstract class '%s'",
                         self.cppclass.name)
-
+        constructor_overload = self.cppclass.get_overload(self.cppclass.name)
+        constructor_overload.call(self, args_w)
+ 
     def instance__eq__(self, w_other):
         # special case: if other is None, compare pointer-style
         if self.space.is_w(w_other, self.space.w_None):
diff --git a/pypy/module/cppyy/src/clingcwrapper.cxx b/pypy/module/cppyy/src/clingcwrapper.cxx
--- a/pypy/module/cppyy/src/clingcwrapper.cxx
+++ b/pypy/module/cppyy/src/clingcwrapper.cxx
@@ -567,16 +567,18 @@
 // class reflection information ----------------------------------------------
 std::string Cppyy::GetFinalName( TCppType_t klass )
 {
-   if ( klass == GLOBAL_HANDLE )    // due to CLING WORKAROUND in InitConverters_
+   if ( klass == GLOBAL_HANDLE )
       return "";
-   // TODO: either this or GetScopedFinalName is wrong
    TClassRef& cr = type_from_handle( klass );
-   return cr->GetName();
+   std::string clName = cr->GetName();
+   std::string::size_type pos = clName.substr( 0, clName.find( '<' ) ).rfind( "::" );
+   if ( pos != std::string::npos )
+      return clName.substr( pos + 2, std::string::npos );
+   return clName;
 }
 
 std::string Cppyy::GetScopedFinalName( TCppType_t klass )
 {
-   // TODO: either this or GetFinalName is wrong
    TClassRef& cr = type_from_handle( klass );
    return cr->GetName();
 }
@@ -1198,6 +1200,10 @@
     return (int)Cppyy::IsNamespace(scope);
 }
 
+int cppyy_is_abstract(cppyy_type_t type){
+    return (int)Cppyy::IsAbstract(type);
+}
+
 int cppyy_is_enum(const char* type_name){
     return (int)Cppyy::IsEnum(type_name);
 }


More information about the pypy-commit mailing list