[pypy-commit] pypy reflex-support: (arigo, cfbolz): refactoring: pass a bit everywhere the subtype that should be

cfbolz noreply at buildbot.pypy.org
Fri Jul 15 13:18:48 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: reflex-support
Changeset: r45613:5ac7b89a8285
Date: 2011-07-15 13:18 +0200
http://bitbucket.org/pypy/pypy/changeset/5ac7b89a8285/

Log:	(arigo, cfbolz): refactoring: pass a bit everywhere the subtype that
	should be used for resulting W_CPPInstance instances. This makes it
	possible to not need a wrapper on the Python side any more.

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
@@ -15,11 +15,12 @@
 def get_rawobject(space, w_obj):
     if not space.eq_w(w_obj, space.w_None):
         from pypy.module.cppyy.interp_cppyy import W_CPPInstance
-        w_cpp_instance = space.findattr(w_obj, space.wrap("_cppinstance"))
-        cpp_instance = space.interp_w(W_CPPInstance, w_cpp_instance, can_be_None=True)
+        cpp_instance = space.interp_w(W_CPPInstance, w_obj)
         if cpp_instance:
             assert lltype.typeOf(cpp_instance.rawobject) == rffi.VOIDP
             return cpp_instance.rawobject
+        else:
+            xxx
     return lltype.nullptr(rffi.VOIDP.TO)
 
 def _direct_ptradd(ptr, offset):
@@ -31,6 +32,8 @@
     _immutable = True
     libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
 
+    name = ""
+
     def __init__(self, space, array_size):
         pass
 
@@ -54,7 +57,7 @@
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
         raise FastCallNotPossible
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         self._is_abstract()
 
     def to_memory(self, space, w_obj, w_value, offset):
@@ -88,7 +91,7 @@
         else:
             self.size = array_size
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         if hasattr(space, "fake"):
             raise NotImplementedError
         # read access, so no copy needed
@@ -114,7 +117,7 @@
     def __init__(self, space, array_size):
         self.size = sys.maxint
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         # read access, so no copy needed
         address_value = self._get_raw_address(space, w_obj, offset)
         address = rffi.cast(rffi.ULONGP, address_value)
@@ -164,7 +167,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         if address[0] == '\x01':
             return space.w_True
@@ -206,7 +209,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain): 
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         return space.wrap(address[0])
 
@@ -228,7 +231,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         intptr = rffi.cast(rffi.INTP, address)
         return space.wrap(intptr[0])
@@ -252,7 +255,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         ulongptr = rffi.cast(rffi.UINTP, address)
         return space.wrap(ulongptr[0])
@@ -276,7 +279,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         longptr = rffi.cast(rffi.LONGP, address)
         return space.wrap(longptr[0])
@@ -300,7 +303,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         ulongptr = rffi.cast(rffi.ULONGP, address)
         return space.wrap(ulongptr[0])
@@ -324,7 +327,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         shortptr = rffi.cast(rffi.SHORTP, address)
         return space.wrap(shortptr[0])
@@ -349,7 +352,7 @@
         # it's required to sent an rffi.DOUBLE not r_singlefloat
         argchain.arg_singlefloat(space.float_w(w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         floatptr = rffi.cast(rffi.FLOATP, address)
         return space.wrap(float(floatptr[0]))
@@ -375,7 +378,7 @@
     def convert_argument_libffi(self, space, w_obj, argchain):
         argchain.arg(self._unwrap_object(space, w_obj))
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         doubleptr = rffi.cast(rffi.DOUBLEP, address)
         return space.wrap(doubleptr[0])
@@ -396,7 +399,7 @@
         typecode = _direct_ptradd(address, capi.c_function_arg_typeoffset())
         typecode[0] = 'a'
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
         charpptr = rffi.cast(rffi.CCHARPP, address)
         return space.wrap(rffi.charp2str(charpptr[0]))
@@ -471,8 +474,9 @@
     _immutable_ = True
     _immutable_fields_ = ["cpptype"]
 
-    def __init__(self, space, cpptype):
+    def __init__(self, space, cpptype, name):
         self.cpptype = cpptype
+        self.name = name
 
     def _unwrap_object(self, space, w_obj):
         from pypy.module.cppyy.interp_cppyy import W_CPPInstance
@@ -503,10 +507,10 @@
 class InstanceConverter(InstancePtrConverter):
     _immutable_ = True
 
-    def from_memory(self, space, w_obj, offset):
+    def from_memory(self, space, w_obj, w_type, offset):
         address = rffi.cast(rffi.VOIDP, self._get_raw_address(space, w_obj, offset))
         from pypy.module.cppyy import interp_cppyy
-        return interp_cppyy.W_CPPInstance(space, self.cpptype, address, False)
+        return interp_cppyy.new_instance(space, w_type, self.cpptype, address, False)
 
 
 _converters = {}
@@ -552,9 +556,9 @@
         from pypy.module.cppyy.interp_cppyy import W_CPPType
         cpptype = space.interp_w(W_CPPType, cpptype, can_be_None=False)
         if compound == "*" or compound == "&":
-            return InstancePtrConverter(space, cpptype)
+            return InstancePtrConverter(space, cpptype, clean_name)
         elif compound == "":
-            return InstanceConverter(space, cpptype)
+            return InstanceConverter(space, cpptype, clean_name)
     
     #   6) void converter, which fails on use
     #
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
@@ -19,10 +19,10 @@
     def __init__(self, space, name, cpptype):
         self.name = name
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         raise NotImplementedError
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
         raise FastCallNotPossible
 
@@ -31,7 +31,7 @@
     _immutable_ = True
     typecode = 'P'
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         if hasattr(space, "fake"):
             raise NotImplementedError
         lresult = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
@@ -44,11 +44,11 @@
     _immutable_ = True
     libffitype = libffi.types.void
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         capi.c_call_v(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.w_None
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         libffifunc.call(argchain, lltype.Void)
         return space.w_None
 
@@ -57,11 +57,11 @@
     _immutable_ = True
     libffitype = libffi.types.schar
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_b(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.wrap(result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.CHAR)
         return space.wrap(bool(ord(result)))
 
@@ -69,11 +69,11 @@
     _immutable_ = True
     libffitype = libffi.types.schar
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_c(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.wrap(result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.CHAR)
         return space.wrap(result)
 
@@ -81,11 +81,11 @@
     _immutable_ = True
     libffitype = libffi.types.sshort
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_h(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.wrap(result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.SHORT)
         return space.wrap(result)
 
@@ -96,11 +96,11 @@
     def _wrap_result(self, space, result):
         return space.wrap(result)
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_i(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return self._wrap_result(space, result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.INT)
         return space.wrap(result)
 
@@ -111,11 +111,11 @@
     def _wrap_result(self, space, result):
         return space.wrap(rffi.cast(rffi.UINT, result))
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return self._wrap_result(space, result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.UINT)
         return space.wrap(result)
 
@@ -126,11 +126,11 @@
     def _wrap_result(self, space, result):
         return space.wrap(result)
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return self._wrap_result(space, result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.LONG)
         return space.wrap(result)
 
@@ -141,7 +141,7 @@
     def _wrap_result(self, space, result):
         return space.wrap(rffi.cast(rffi.ULONG, result))
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.ULONG)
         return space.wrap(result)
 
@@ -153,7 +153,7 @@
         intptr = rffi.cast(rffi.INTP, result)
         return space.wrap(intptr[0])
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.INTP)
         return space.wrap(result[0])
 
@@ -165,7 +165,7 @@
         longptr = rffi.cast(rffi.LONGP, result)
         return space.wrap(longptr[0])
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.LONGP)
         return space.wrap(result[0])
 
@@ -173,11 +173,11 @@
     _immutable_ = True
     libffitype = libffi.types.float
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_f(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.wrap(result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.FLOAT)
         return space.wrap(result)
 
@@ -185,11 +185,11 @@
     _immutable_ = True
     libffitype = libffi.types.double
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         result = capi.c_call_d(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         return space.wrap(result)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.DOUBLE)
         return space.wrap(result)
 
@@ -197,7 +197,7 @@
 class CStringExecutor(FunctionExecutor):
     _immutable_ = True
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         lresult = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
         ccpresult = rffi.cast(rffi.CCHARP, lresult)
         result = rffi.charp2str(ccpresult)  # TODO: make it a choice to free
@@ -241,28 +241,28 @@
         FunctionExecutor.__init__(self, space, name, cpptype)
         self.cpptype = cpptype
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         from pypy.module.cppyy import interp_cppyy
         long_result = capi.c_call_l(
             func.cpptype.handle, func.method_index, cppthis, num_args, args)
         ptr_result = rffi.cast(rffi.VOIDP, long_result)
-        return interp_cppyy.W_CPPInstance(space, self.cpptype, ptr_result, False)
+        return interp_cppyy.new_instance(space, w_returntype, self.cpptype, ptr_result, False)
 
-    def execute_libffi(self, space, libffifunc, argchain):
+    def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         from pypy.module.cppyy import interp_cppyy
         ptr_result = rffi.cast(rffi.VOIDP, libffifunc.call(argchain, rffi.VOIDP))
-        return interp_cppyy.W_CPPInstance(space, self.cpptype, ptr_result, False)
+        return interp_cppyy.new_instance(space, w_returntype, self.cpptype, ptr_result, False)
 
 
 class InstanceExecutor(InstancePtrExecutor):
     _immutable_ = True
 
-    def execute(self, space, func, cppthis, num_args, args):
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
         from pypy.module.cppyy import interp_cppyy
         long_result = capi.c_call_o(
             func.cpptype.handle, func.method_index, cppthis, num_args, args, self.cpptype.handle)
         ptr_result = rffi.cast(rffi.VOIDP, long_result)
-        return interp_cppyy.W_CPPInstance(space, self.cpptype, ptr_result, True)
+        return interp_cppyy.new_instance(space, w_returntype, self.cpptype, ptr_result, True)
 
 
 _executors = {}
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
@@ -109,18 +109,18 @@
 
         if self.methgetter and cppthis: # only for methods
             try:
-                return self.do_fast_call(cppthis, args_w)
+                return self.do_fast_call(cppthis, w_type, args_w)
             except FastCallNotPossible:
                 pass
 
         args = self.prepare_arguments(args_w)
         try:
-            return self.executor.execute(self.space, self, cppthis, len(args_w), args)
+            return self.executor.execute(self.space, w_type, self, cppthis, len(args_w), args)
         finally:
             self.free_arguments(args, len(args_w))
 
     @jit.unroll_safe
-    def do_fast_call(self, cppthis, args_w):
+    def do_fast_call(self, cppthis, w_type, args_w):
         space = self.space
         # XXX factor out
         if len(self.arg_types) < len(args_w) or len(args_w) < self.args_required:
@@ -139,7 +139,7 @@
             conv = self.arg_converters[i]
             w_arg = args_w[i]
             conv.convert_argument_libffi(space, w_arg, argchain)
-        return self.executor.execute_libffi(space, libffi_func, argchain)
+        return self.executor.execute_libffi(space, w_type, libffi_func, argchain)
 
     @jit.elidable_promote()
     def _get_libffi_func(self, funcptr):
@@ -218,7 +218,7 @@
         assert not cppthis
         args = self.prepare_arguments(args_w)
         try:
-            return self.executor.execute(self.space, self, NULL_VOIDP,
+            return self.executor.execute(self.space, w_type, self, NULL_VOIDP,
                                          len(args_w), args)
         finally:
             self.free_arguments(args, len(args_w))
@@ -237,10 +237,7 @@
         except Exception, e:
             capi.c_deallocate(self.cpptype.handle, newthis)
             raise
-        w_instance = self.space.allocate_instance(W_CPPInstance, w_type)
-        instance = self.space.interp_w(W_CPPInstance, w_instance)
-        W_CPPInstance.__init__(instance, self.space, self.cpptype, newthis, True)
-        return w_instance
+        return new_instance(self.space, w_type, self.cpptype, newthis, True)
 
 
 class W_CPPOverload(Wrappable):
@@ -303,47 +300,31 @@
     _immutable_=True
     _immutable_fields_ = ["converter", "offset"]
 
-    def __init__(self, space, type_name, offset):
+    def __init__(self, space, type_name, offset, is_static):
         self.space = space
         self.converter = converter.get_converter(self.space, type_name)
         self.offset = offset
+        self._is_static = is_static
+
+    def get_returntype(self):
+        return self.space.wrap(self.converter.name)
 
     def is_static(self):
-        return self.space.w_False
+        return self.space.newbool(self._is_static)
 
-    def __get__(self, args_w):
-        return self.converter.from_memory(self.space, args_w[0], self.offset)
+    def get(self, w_cppinstance, w_type):
+        return self.converter.from_memory(self.space, w_cppinstance, w_type, self.offset)
 
-    def __set__(self, args_w):
-        self.converter.to_memory(self.space, args_w[0], args_w[1], self.offset)
+    def set(self, w_cppinstance, w_value):
+        self.converter.to_memory(self.space, w_cppinstance, w_value, self.offset)
         return self.space.w_None
 
 W_CPPDataMember.typedef = TypeDef(
     'CPPDataMember',
     is_static = interp2app(W_CPPDataMember.is_static, unwrap_spec=['self']),
-    __get__ = interp2app(W_CPPDataMember.__get__, unwrap_spec=['self', 'args_w']),
-    __set__ = interp2app(W_CPPDataMember.__set__, unwrap_spec=['self', 'args_w']),
-)
-
-
-class W_CPPStaticDataMember(W_CPPDataMember):
-    _immutable_=True
-
-    def is_static(self):
-        return self.space.w_True
-
-    def __get__(self, args_w):
-        return self.converter.from_memory(self.space, self.space.w_None, self.offset)
-
-    def __set__(self, args_w):
-        self.converter.to_memory(self.space, self.space.w_None, args_w[1], self.offset)
-        return self.space.w_None
-
-W_CPPStaticDataMember.typedef = TypeDef(
-    'CPPStaticDataMember',
-    is_static = interp2app(W_CPPStaticDataMember.is_static, unwrap_spec=['self']),
-    __get__ = interp2app(W_CPPStaticDataMember.__get__, unwrap_spec=['self', 'args_w']),
-    __set__ = interp2app(W_CPPStaticDataMember.__set__, unwrap_spec=['self', 'args_w']),
+    get_returntype = interp2app(W_CPPDataMember.get_returntype, unwrap_spec=['self']),
+    get = interp2app(W_CPPDataMember.get, unwrap_spec=['self', W_Root, W_Root]),
+    set = interp2app(W_CPPDataMember.set, unwrap_spec=['self', W_Root, W_Root]),
 )
 
 
@@ -387,9 +368,7 @@
         try:
             return self.methods[name]
         except KeyError:
-            raise OperationError(
-                self.space.w_AttributeError,
-                self.space.wrap(str("class %s has no attribute %s" % (self.name, name))))
+            raise self.missing_attribute_error(name)
 
     def get_data_member_names(self):
         return self.space.newlist([self.space.wrap(name) for name in self.data_members])
@@ -399,9 +378,12 @@
         try:
             return self.data_members[name]
         except KeyError:
-            raise OperationError(
-                self.space.w_AttributeError,
-                self.space.wrap(str("class %s has no attribute %s" % (self.name, name))))
+            raise self.missing_attribute_error(name)
+
+    def missing_attribute_error(self, name):
+        return OperationError(
+            self.space.w_AttributeError,
+            self.space.wrap("%s '%s' has no attribute %s" % (self.kind, self.name, name)))
 
 W_CPPScope.typedef = TypeDef(
     'CPPScope',
@@ -417,6 +399,7 @@
 # classes for inheritance. Both are python classes, though, and refactoring
 # may be in order at some point.
 class W_CPPNamespace(W_CPPScope):
+    kind = "namespace"
 
     def _make_cppfunction(self, method_index):
         result_type = capi.charp2str_free(capi.c_method_result_type(self.handle, method_index))
@@ -435,7 +418,7 @@
             if not data_member_name in self.data_members:
                 type_name = capi.charp2str_free(capi.c_data_member_type(self.handle, i))
                 offset = capi.c_data_member_offset(self.handle, i)
-                data_member = W_CPPStaticDataMember(self.space, type_name, offset)
+                data_member = W_CPPDataMember(self.space, type_name, offset, True)
                 self.data_members[data_member_name] = data_member
 
     def update(self):
@@ -445,6 +428,7 @@
     def is_namespace(self):
         return self.space.w_True
 
+
 W_CPPNamespace.typedef = TypeDef(
     'CPPNamespace',
     update = interp2app(W_CPPNamespace.update, unwrap_spec=['self']),
@@ -457,6 +441,7 @@
 
 
 class W_CPPType(W_CPPScope):
+    kind = "class"
 
     def _make_cppfunction(self, method_index):
         result_type = capi.charp2str_free(capi.c_method_result_type(self.handle, method_index))
@@ -480,10 +465,8 @@
             data_member_name = capi.charp2str_free(capi.c_data_member_name(self.handle, i))
             type_name = capi.charp2str_free(capi.c_data_member_type(self.handle, i))
             offset = capi.c_data_member_offset(self.handle, i)
-            if capi.c_is_staticdata(self.handle, i):
-                data_member = W_CPPStaticDataMember(self.space, type_name, offset)
-            else:
-                data_member = W_CPPDataMember(self.space, type_name, offset)
+            is_static = bool(capi.c_is_staticdata(self.handle, i))
+            data_member = W_CPPDataMember(self.space, type_name, offset, is_static)
             self.data_members[data_member_name] = data_member
 
     def is_namespace(self):
@@ -559,3 +542,9 @@
     cppclass = interp_attrproperty('cppclass', W_CPPInstance),
     destruct = interp2app(W_CPPInstance.destruct, unwrap_spec=['self']),
 )
+
+def new_instance(space, w_type, cpptype, rawptr, owns):
+    w_instance = space.allocate_instance(W_CPPInstance, w_type)
+    instance = space.interp_w(W_CPPInstance, w_instance)
+    W_CPPInstance.__init__(instance, space, cpptype, rawptr, owns)
+    return w_instance
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -20,6 +20,9 @@
 class CppyyClass(CppyyScopeMeta):
     pass
 
+class CPPObject(cppyy.CPPInstance):
+    __metaclass__ = CppyyClass
+
 
 class CppyyTemplateType(object):
     def __init__(self, scope, name):
@@ -40,62 +43,48 @@
             fullname += '>'
         return getattr(self._scope, fullname)
 
-class CppyyObject(object):
-    __metaclass__ = CppyyClass
 
-    def __init__(self, *args):
-        try:
-            cppol = self._cpp_proxy.get_overload(self._cpp_proxy.type_name)
-        except AttributeError:
-            raise TypeError("cannot instantiate abstract class '%s'" %
-                    self._cpp_proxy.type_name)
-        self._cppinstance = cppol.call(None, cppyy.CPPInstance, *args)
 
-    def destruct(self):
-        self._cppinstance.destruct()
-
-
-def bind_object(cppobj, cppclass):
-    if cppobj is None:
-        return None
-    bound_obj = object.__new__(cppclass)
-    bound_obj._cppinstance = cppobj
-    return bound_obj
 
 def make_static_function(cpptype, func_name, cppol):
     rettype = cppol.get_returntype()
     if not rettype:                              # return builtin type
-        def function(*args):
-            return cppol.call(None, cppyy.CPPInstance, *args)
+        cppclass = None
     else:                                        # return instance
         cppclass = get_cppclass(rettype)
-        def function(*args):
-            return bind_object(cppol.call(None, cppyy.CPPInstance, *args), cppclass)
+    def function(*args):
+        return cppol.call(None, cppclass, *args)
     function.__name__ = func_name
     return staticmethod(function)
 
 def make_method(meth_name, cppol):
     rettype = cppol.get_returntype()
     if not rettype:                              # return builtin type
-        def method(self, *args):
-            return cppol.call(self._cppinstance, cppyy.CPPInstance, *args)
+        cppclass = None
     else:                                        # return instance
         cppclass = get_cppclass(rettype)
-        def method(self, *args):
-            return bind_object(cppol.call(self._cppinstance, cppyy.CPPInstance, *args), cppclass)
+    def method(self, *args):
+        return cppol.call(self, cppclass, *args)
     method.__name__ = meth_name
     return method
 
 
 def make_datamember(cppdm):
-    import cppyy
-    def binder(obj, owner=None):
-        value = cppdm.__get__(obj, owner)
-        if isinstance(value, cppyy.CPPInstance):
-             cppclass = get_cppclass(value.cppclass.type_name)
-             return bind_object(value, cppclass)
-        return value
-    return property(binder, cppdm.__set__)
+    rettype = cppdm.get_returntype()
+    if not rettype:                              # return builtin type
+        cppclass = None
+    else:                                        # return instance
+        cppclass = get_cppclass(rettype)
+    if cppdm.is_static():
+        def binder(obj):
+            return cppdm.get(None, cppclass)
+        def setter(obj, value):
+            return cppdm.set(None, value)
+    else:
+        def binder(obj):
+            return cppdm.get(obj, cppclass)
+        setter = cppdm.set
+    return property(binder, setter)
 
 def make_cppnamespace(namespace_name, cppns):
     d = {"_cpp_proxy" : cppns}
@@ -133,19 +122,34 @@
                 break
     return tuple(bases)
 
+def make_new(class_name, cpptype):
+    try:
+        constructor_overload = cpptype.get_overload(cpptype.type_name)
+    except AttributeError:
+        msg = "cannot instantiate abstract class '%s'" % class_name
+        def __new__(cls, *args):
+            raise TypeError(msg)
+    else:
+        def __new__(cls, *args):
+            return constructor_overload.call(None, cls, *args)
+    return __new__
+
 def make_cppclass(class_name, cpptype):
 
     # get a list of base classes for class creation
     bases = [get_cppclass(base) for base in cpptype.get_base_names()]
     if not bases:
-        bases = [CppyyObject,]
+        bases = [CPPObject,]
 
     # create a meta class to allow properties (for static data write access)
     metabases = [type(base) for base in bases]
     metacpp = type(CppyyClass)(class_name+'_meta', _drop_cycles(metabases), {})
 
+
     # create the python-side C++ class representation
-    d = {"_cpp_proxy" : cpptype}
+    d = {"_cpp_proxy" : cpptype,
+         "__new__"    : make_new(class_name, cpptype),
+         }
     pycpptype = metacpp(class_name, _drop_cycles(bases), d)
  
     # cache result early so that the class methods can find the class itself
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -135,7 +135,7 @@
         pl = payload_class(3.14)
         assert round(pl.getData()-3.14, 8) == 0
 
-        example01_class.staticSetPayload(pl._cppinstance, 41.)
+        example01_class.staticSetPayload(pl, 41.)
         assert pl.getData() == 41.
         example01_class.staticSetPayload(pl, 43.)
         assert pl.getData() == 43.


More information about the pypy-commit mailing list