Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: reflex-support Changeset: r70989:866f101100fc Date: 2014-04-25 16:23 -0700 http://bitbucket.org/pypy/pypy/changeset/866f101100fc/
Log: fix for issue 1676 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 @@ -450,8 +450,8 @@ class CPPConstructor(CPPMethod): """Method dispatcher that constructs new objects. This method can not have - a fast path, a the allocation of the object is currently left to the - reflection layer only, b/c the C++ class may have an overloaded operator + a fast path, as the allocation of the object is currently left to the + reflection layer only, since the C++ class may have an overloaded operator new, disallowing malloc here.""" _immutable_ = True @@ -460,8 +460,18 @@ # TODO: these casts are very, very un-pretty; need to find a way of # re-using CPPMethod's features w/o these roundabouts vscope = rffi.cast(capi.C_OBJECT, self.scope.handle) - w_result = CPPMethod.call(self, vscope, args_w) + cppinstance = None + try: + cppinstance = self.space.interp_w(W_CPPInstance, args_w[0], can_be_None=False) + use_args_w = args_w[1:] + except (OperationError, TypeError), e: + use_args_w = args_w + w_result = CPPMethod.call(self, vscope, use_args_w) newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result)) + if cppinstance: + cppinstance._rawobject = newthis + memory_regulator.register(cppinstance) + return args_w[0] return wrap_cppobject(self.space, newthis, self.scope, do_cast=False, python_owns=True, fresh=True) @@ -1141,10 +1151,14 @@ self.objects = rweakref.RWeakValueDictionary(int, W_CPPInstance) def register(self, obj): + if not obj._rawobject: + return int_address = int(rffi.cast(rffi.LONG, obj._rawobject)) self.objects.set(int_address, obj) def unregister(self, obj): + if not obj._rawobject: + return int_address = int(rffi.cast(rffi.LONG, obj._rawobject)) self.objects.set(int_address, None) @@ -1194,7 +1208,7 @@ w_pycppclass = get_pythonized_cppclass(space, cppclass.handle) # try to recycle existing object if this one is not newly created - if not fresh: + if not fresh and rawobject: obj = memory_regulator.retrieve(rawobject) if obj is not None and obj.cppclass is cppclass: return obj 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 @@ -146,7 +146,12 @@ raise TypeError(msg) else: def __new__(cls, *args): - return constructor_overload.call(None, *args) + # create a place-holder only as there may be a derived class defined + import cppyy + instance = cppyy.bind_object(0, class_name, True) + if not instance.__class__ is cls: + instance.__class__ = cls # happens for derived class + return instance return __new__ def make_pycppclass(scope, class_name, final_class_name, cppclass): @@ -427,7 +432,9 @@ __metaclass__ = CppyyClassMeta def __init__(self, *args, **kwds): - pass # ignored, for the C++ backend, ctor == __new__ + __init__ + # self is only a placeholder; now create the actual C++ object + args = (self,) + args + self._cpp_proxy.get_overload(self._cpp_proxy.type_name).call(None, *args) # class generator callback cppyy._set_class_generator(clgen_callback) 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 @@ -332,6 +332,33 @@ assert 2 == e.fresh(1) assert 3 == e.fresh(2) + def test16_subclassing(self): + """A sub-class on the python side should have that class as type""" + + import cppyy + example01 = cppyy.gbl.example01 + + o = example01() + assert type(o) == example01 + + class MyClass1(example01): + def myfunc(self): + return 1 + + o = MyClass1() + assert type(o) == MyClass1 + assert isinstance(o, example01) + assert o.myfunc() == 1 + + class MyClass2(example01): + def __init__(self, what): + example01.__init__(self) + self.what = what + + o = MyClass2('hi') + assert type(o) == MyClass2 + assert o.what == 'hi' + class AppTestPYTHONIFY_UI: spaceconfig = dict(usemodules=['cppyy', '_rawffi', 'itertools']) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit