[pypy-commit] pypy reflex-support: fix for issue 1676
wlav
noreply at buildbot.pypy.org
Sat Apr 26 02:10:59 CEST 2014
Author: Wim Lavrijsen <WLavrijsen at 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'])
More information about the pypy-commit
mailing list