Author: Wim Lavrijsen <wlavrij...@lbl.gov>
Branch: cppyy-packaging
Changeset: r94868:c67865f23398
Date: 2018-07-15 20:17 -0700
http://bitbucket.org/pypy/pypy/changeset/c67865f23398/

Log:    more settable overload properties

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
@@ -24,6 +24,7 @@
 INSTANCE_FLAGS_IS_RVALUE   = 0x0004
 
 OVERLOAD_FLAGS_USE_FFI     = 0x0001
+OVERLOAD_FLAGS_CREATES     = 0x0002
 
 FUNCTION_IS_GLOBAL         = 0x0001
 FUNCTION_IS_STATIC         = 0x0001
@@ -458,6 +459,36 @@
 # need forwarding, which the normal instancemethod does not provide, hence this
 # derived class.
 class MethodWithProps(Method):
+    # set life management of result from the call
+    def fget_creates(self, space):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        return f.fget_creates(space)
+
+    @unwrap_spec(value=bool)
+    def fset_creates(self, space, value):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        f.fset_creates(space, value)
+
+    # set ownership policy of arguments (not yet implemented)
+    def fget_mempolicy(self, space):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        return f.fget_mempolicy(space)
+
+    @unwrap_spec(value=int)
+    def fset_mempolicy(self, space, value):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        f.fset_mempolicy(space, value)
+
+    # set to release the gil during call (not yet implemented)
+    def fget_release_gil(self, space):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        return f.fget_release_gil(space)
+
+    @unwrap_spec(value=bool)
+    def fset_release_gil(self, space, value):
+        f = space.interp_w(W_CPPOverload, self.w_function)
+        f.fset_release_gil(space, value)
+
     # allow user to determine ffi use rules per overload
     def fget_useffi(self, space):
         f = space.interp_w(W_CPPOverload, self.w_function)
@@ -473,22 +504,25 @@
     __doc__ = """cpp_instancemethod(function, instance, class)
 
 Create an instance method object.""",
-    __new__ = interp2app(MethodWithProps.descr_method__new__.im_func),
-    __call__ = interp2app(MethodWithProps.descr_method_call),
-    __get__ = interp2app(MethodWithProps.descr_method_get),
-    im_func = interp_attrproperty_w('w_function', cls=MethodWithProps),
-    __func__ = interp_attrproperty_w('w_function', cls=MethodWithProps),
-    im_self = interp_attrproperty_w('w_instance', cls=MethodWithProps),
-    __self__ = interp_attrproperty_w('w_instance', cls=MethodWithProps),
-    im_class = interp_attrproperty_w('w_class', cls=MethodWithProps),
+    __new__          = interp2app(MethodWithProps.descr_method__new__.im_func),
+    __call__         = interp2app(MethodWithProps.descr_method_call),
+    __get__          = interp2app(MethodWithProps.descr_method_get),
+    im_func          = interp_attrproperty_w('w_function', 
cls=MethodWithProps),
+    __func__         = interp_attrproperty_w('w_function', 
cls=MethodWithProps),
+    im_self          = interp_attrproperty_w('w_instance', 
cls=MethodWithProps),
+    __self__         = interp_attrproperty_w('w_instance', 
cls=MethodWithProps),
+    im_class         = interp_attrproperty_w('w_class', cls=MethodWithProps),
     __getattribute__ = interp2app(MethodWithProps.descr_method_getattribute),
-    __eq__ = interp2app(MethodWithProps.descr_method_eq),
-    __ne__ = descr_generic_ne,
-    __hash__ = interp2app(MethodWithProps.descr_method_hash),
-    __repr__ = interp2app(MethodWithProps.descr_method_repr),
-    __reduce__ = interp2app(MethodWithProps.descr_method__reduce__),
-    __weakref__ = make_weakref_descr(MethodWithProps),
-    __useffi__ = GetSetProperty(MethodWithProps.fget_useffi, 
MethodWithProps.fset_useffi),
+    __eq__           = interp2app(MethodWithProps.descr_method_eq),
+    __ne__           = descr_generic_ne,
+    __hash__         = interp2app(MethodWithProps.descr_method_hash),
+    __repr__         = interp2app(MethodWithProps.descr_method_repr),
+    __reduce__       = interp2app(MethodWithProps.descr_method__reduce__),
+    __weakref__      = make_weakref_descr(MethodWithProps),
+    __creates__      = GetSetProperty(MethodWithProps.fget_creates,     
MethodWithProps.fset_creates),
+    __mempolicy__    = GetSetProperty(MethodWithProps.fget_mempolicy,   
MethodWithProps.fset_mempolicy),
+    __release_gil__  = GetSetProperty(MethodWithProps.fget_release_gil, 
MethodWithProps.fset_release_gil),
+    __useffi__       = GetSetProperty(MethodWithProps.fget_useffi,      
MethodWithProps.fset_useffi),
     )
 MethodWithProps.typedef.acceptable_as_base_class = False
 
@@ -551,7 +585,12 @@
         for i in range(len(self.functions)):
             cppyyfunc = self.functions[i]
             try:
-                return cppyyfunc.call(cppthis, args_w, self.flags & 
OVERLOAD_FLAGS_USE_FFI)
+                w_result = cppyyfunc.call(cppthis, args_w, self.flags & 
OVERLOAD_FLAGS_USE_FFI)
+                if self.flags & OVERLOAD_FLAGS_CREATES:
+                    if isinstance(w_result, W_CPPInstance):
+                        cppinstance = self.space.interp_w(W_CPPInstance, 
w_result)
+                        cppinstance.fset_python_owns(self.space, 
self.space.w_True)
+                return w_result
             except Exception:
                 pass
 
@@ -564,6 +603,7 @@
         for i in range(len(self.functions)):
             cppyyfunc = self.functions[i]
             try:
+                # no need to set ownership on the return value, as none of the 
methods execute
                 return cppyyfunc.call(cppthis, args_w, self.flags & 
OVERLOAD_FLAGS_USE_FFI)
             except OperationError as e:
                 # special case if there's just one function, to prevent 
clogging the error message
@@ -602,6 +642,33 @@
                 return W_CPPOverload(self.space, self.scope, [f])
         raise oefmt(self.space.w_LookupError, "signature '%s' not found", 
signature)
 
+    # set life management of result from the call
+    def fget_creates(self, space):
+        return space.newbool(bool(self.flags & OVERLOAD_FLAGS_CREATES))
+
+    @unwrap_spec(value=bool)
+    def fset_creates(self, space, value):
+        if space.is_true(value):
+            self.flags |= OVERLOAD_FLAGS_CREATES
+        else:
+            self.flags &= ~OVERLOAD_FLAGS_CREATES
+
+    # set ownership policy of arguments (not yet implemented)
+    def fget_mempolicy(self, space):
+        return space.newint(0)
+
+    @unwrap_spec(value=int)
+    def fset_mempolicy(self, space, value):
+        pass
+
+    # set to release the gil during call (not yet implemented)
+    def fget_release_gil(self, space):
+        return space.newbool(True)
+
+    @unwrap_spec(value=bool)
+    def fset_release_gil(self, space, value):
+        pass
+
     # allow user to determine ffi use rules per overload
     def fget_useffi(self, space):
         return space.newbool(bool(self.flags & OVERLOAD_FLAGS_USE_FFI))
@@ -625,11 +692,14 @@
 
 W_CPPOverload.typedef = TypeDef(
     'CPPOverload',
-    __get__      = interp2app(W_CPPOverload.descr_get),
-    __call__     = interp2app(W_CPPOverload.call_args),
-    __useffi__   = GetSetProperty(W_CPPOverload.fget_useffi, 
W_CPPOverload.fset_useffi),
-    __overload__ = interp2app(W_CPPOverload.mp_overload),
-    __doc__      = GetSetProperty(W_CPPOverload.fget_doc)
+    __get__         = interp2app(W_CPPOverload.descr_get),
+    __call__        = interp2app(W_CPPOverload.call_args),
+    __creates__     = GetSetProperty(W_CPPOverload.fget_creates,     
W_CPPOverload.fset_creates),
+    __mempolicy__   = GetSetProperty(W_CPPOverload.fget_mempolicy,   
W_CPPOverload.fset_mempolicy),
+    __release_gil__ = GetSetProperty(W_CPPOverload.fget_release_gil, 
W_CPPOverload.fset_release_gil),
+    __useffi__      = GetSetProperty(W_CPPOverload.fget_useffi,      
W_CPPOverload.fset_useffi),
+    __overload__    = interp2app(W_CPPOverload.mp_overload),
+    __doc__         = GetSetProperty(W_CPPOverload.fget_doc)
 )
 
 
@@ -658,11 +728,14 @@
 
 W_CPPStaticOverload.typedef = TypeDef(
     'CPPStaticOverload',
-    __get__      = interp2app(W_CPPStaticOverload.descr_get),
-    __call__     = interp2app(W_CPPStaticOverload.call_args),
-    __useffi__   = GetSetProperty(W_CPPStaticOverload.fget_useffi, 
W_CPPStaticOverload.fset_useffi),
-    __overload__ = interp2app(W_CPPStaticOverload.mp_overload),
-    __doc__      = GetSetProperty(W_CPPStaticOverload.fget_doc)
+    __get__         = interp2app(W_CPPStaticOverload.descr_get),
+    __call__        = interp2app(W_CPPStaticOverload.call_args),
+    __creates__     = GetSetProperty(W_CPPStaticOverload.fget_creates,     
W_CPPStaticOverload.fset_creates),
+    __mempolicy__   = GetSetProperty(W_CPPStaticOverload.fget_mempolicy,   
W_CPPStaticOverload.fset_mempolicy),
+    __release_gil__ = GetSetProperty(W_CPPStaticOverload.fget_release_gil, 
W_CPPStaticOverload.fset_release_gil),
+    __useffi__      = GetSetProperty(W_CPPStaticOverload.fget_useffi,      
W_CPPStaticOverload.fset_useffi),
+    __overload__    = interp2app(W_CPPStaticOverload.mp_overload),
+    __doc__         = GetSetProperty(W_CPPStaticOverload.fget_doc)
 )
 
 
@@ -871,11 +944,14 @@
 
 W_CPPTemplateOverload.typedef = TypeDef(
     'CPPTemplateOverload',
-    __get__      = interp2app(W_CPPTemplateOverload.descr_get),
-    __getitem__  = interp2app(W_CPPTemplateOverload.getitem),
-    __call__     = interp2app(W_CPPTemplateOverload.call_args),
-    __useffi__   = GetSetProperty(W_CPPTemplateOverload.fget_useffi, 
W_CPPTemplateOverload.fset_useffi),
-    __doc__      = GetSetProperty(W_CPPTemplateOverload.fget_doc)
+    __get__         = interp2app(W_CPPTemplateOverload.descr_get),
+    __getitem__     = interp2app(W_CPPTemplateOverload.getitem),
+    __call__        = interp2app(W_CPPTemplateOverload.call_args),
+    __creates__     = GetSetProperty(W_CPPTemplateOverload.fget_creates,     
W_CPPTemplateOverload.fset_creates),
+    __mempolicy__   = GetSetProperty(W_CPPTemplateOverload.fget_mempolicy,   
W_CPPTemplateOverload.fset_mempolicy),
+    __release_gil__ = GetSetProperty(W_CPPTemplateOverload.fget_release_gil, 
W_CPPTemplateOverload.fset_release_gil),
+    __useffi__      = GetSetProperty(W_CPPTemplateOverload.fget_useffi,      
W_CPPTemplateOverload.fset_useffi),
+    __doc__         = GetSetProperty(W_CPPTemplateOverload.fget_doc)
 )
 
 class W_CPPTemplateStaticOverload(W_CPPStaticOverload, TemplateOverloadMixin):
@@ -929,11 +1005,18 @@
 
 W_CPPTemplateStaticOverload.typedef = TypeDef(
     'CPPTemplateStaticOverload',
-    __get__      = interp2app(W_CPPTemplateStaticOverload.descr_get),
-    __getitem__  = interp2app(W_CPPTemplateStaticOverload.getitem),
-    __call__     = interp2app(W_CPPTemplateStaticOverload.call_args),
-    __useffi__   = GetSetProperty(W_CPPTemplateStaticOverload.fget_useffi, 
W_CPPTemplateStaticOverload.fset_useffi),
-    __doc__      = GetSetProperty(W_CPPTemplateStaticOverload.fget_doc)
+    __get__         = interp2app(W_CPPTemplateStaticOverload.descr_get),
+    __getitem__     = interp2app(W_CPPTemplateStaticOverload.getitem),
+    __call__        = interp2app(W_CPPTemplateStaticOverload.call_args),
+    __creates__     = GetSetProperty(W_CPPTemplateStaticOverload.fget_creates,
+                                     W_CPPTemplateStaticOverload.fset_creates),
+    __mempolicy__   = 
GetSetProperty(W_CPPTemplateStaticOverload.fget_mempolicy,
+                                     
W_CPPTemplateStaticOverload.fset_mempolicy),
+    __release_gil__ = 
GetSetProperty(W_CPPTemplateStaticOverload.fget_release_gil,
+                                     
W_CPPTemplateStaticOverload.fset_release_gil),
+    __useffi__      = GetSetProperty(W_CPPTemplateStaticOverload.fget_useffi,
+                                     W_CPPTemplateStaticOverload.fset_useffi),
+    __doc__         = GetSetProperty(W_CPPTemplateStaticOverload.fget_doc)
 )
 
 
diff --git a/pypy/module/_cppyy/test/pythonizables.cxx 
b/pypy/module/_cppyy/test/pythonizables.cxx
--- a/pypy/module/_cppyy/test/pythonizables.cxx
+++ b/pypy/module/_cppyy/test/pythonizables.cxx
@@ -27,3 +27,5 @@
 unsigned int pyzables::pass_mine_rp(Countable c) { return c.m_check; }
 unsigned int pyzables::pass_mine_rp_ref(const Countable& c) { return 
c.m_check; }
 unsigned int pyzables::pass_mine_rp_ptr(const Countable* c) { return 
c->m_check; }
+
+pyzables::Countable* pyzables::gime_naked_countable() { return new 
Countable{}; }
diff --git a/pypy/module/_cppyy/test/pythonizables.h 
b/pypy/module/_cppyy/test/pythonizables.h
--- a/pypy/module/_cppyy/test/pythonizables.h
+++ b/pypy/module/_cppyy/test/pythonizables.h
@@ -57,4 +57,6 @@
 unsigned int pass_mine_rp_ref(const Countable&);
 unsigned int pass_mine_rp_ptr(const Countable*);
 
+Countable* gime_naked_countable();
+
 } // namespace pyzables
diff --git a/pypy/module/_cppyy/test/test_advancedcpp.py 
b/pypy/module/_cppyy/test/test_advancedcpp.py
--- a/pypy/module/_cppyy/test/test_advancedcpp.py
+++ b/pypy/module/_cppyy/test/test_advancedcpp.py
@@ -686,11 +686,11 @@
         assert cppyy.gbl.my_global_double == 12.
         assert len(cppyy.gbl.my_global_array) == 500
         assert cppyy.gbl.my_global_string1 == "aap  noot  mies"
-        return     # next line currently crashes
         assert cppyy.gbl.my_global_string2 == "zus jet teun"
         # TODO: currently fails b/c double** not understood as &double*
         #assert cppyy.gbl.my_global_ptr[0] == 1234.
 
+        return
         v = cppyy.gbl.my_global_int_holders
         assert len(v) == 5
         expected_vals = [13, 42, 88, -1, 17]
diff --git a/pypy/module/_cppyy/test/test_pythonization.py 
b/pypy/module/_cppyy/test/test_pythonization.py
--- a/pypy/module/_cppyy/test/test_pythonization.py
+++ b/pypy/module/_cppyy/test/test_pythonization.py
@@ -17,14 +17,20 @@
         cls.w_datatypes = cls.space.appexec([], """():
             import ctypes, _cppyy
             _cppyy._post_import_startup()
+            class py(object):
+                pass
+            py.add_pythonization = _cppyy.add_pythonization
+            py.remove_pythonization = _cppyy.remove_pythonization
+            py.pin_type = _cppyy._pin_type
+            _cppyy.py = py
             return ctypes.CDLL(%r, ctypes.RTLD_GLOBAL)""" % (test_dct, ))
 
     def test00_api(self):
         """Test basic semantics of the pythonization API"""
 
-        import _cppyy
+        import _cppyy as cppyy
 
-        raises(TypeError, _cppyy.add_pythonization, 1)
+        raises(TypeError, cppyy.py.add_pythonization, 1)
 
         def pythonizor1(klass, name):
             pass
@@ -34,31 +40,26 @@
 
         pythonizor3 = pythonizor1
 
-        _cppyy.add_pythonization(pythonizor1)
-        assert _cppyy.remove_pythonization(pythonizor2) == False
-        assert _cppyy.remove_pythonization(pythonizor3) == True
-
-    def test01_more_api(self):
-        """Further API semantics"""
-
-        import _cppyy as cppyy
+        cppyy.py.add_pythonization(pythonizor1)
+        assert cppyy.py.remove_pythonization(pythonizor2) == False
+        assert cppyy.py.remove_pythonization(pythonizor3) == True
 
         def pythonizor(klass, name):
             if name == 'pyzables::SomeDummy1':
                 klass.test = 1
 
-        cppyy.add_pythonization(pythonizor)
+        cppyy.py.add_pythonization(pythonizor)
         assert cppyy.gbl.pyzables.SomeDummy1.test == 1
 
         def pythonizor(klass, name):
             if name == 'SomeDummy2':
                 klass.test = 2
-        cppyy.add_pythonization(pythonizor, 'pyzables')
+        cppyy.py.add_pythonization(pythonizor, 'pyzables')
 
         def pythonizor(klass, name):
             if name == 'pyzables::SomeDummy2':
                 klass.test = 3
-        cppyy.add_pythonization(pythonizor)
+        cppyy.py.add_pythonization(pythonizor)
 
         assert cppyy.gbl.pyzables.SomeDummy2.test == 2
 
@@ -66,28 +67,24 @@
             if name == 'TString':
                 klass.__len__ = klass.Length
 
-        cppyy.add_pythonization(root_pythonizor)
+        cppyy.py.add_pythonization(root_pythonizor)
 
         assert len(cppyy.gbl.TString("aap")) == 3
 
-    def test02_type_pinning(self):
+    def test01_type_pinning(self):
         """Verify pinnability of returns"""
 
         import _cppyy as cppyy
 
-        # TODO: disabled for now until decided on proper naming/iface
-        return
-
-        cppyy.gbl.pyzables.GimeDerived._creates = True
+        cppyy.gbl.pyzables.GimeDerived.__creates__ = True
 
         result = cppyy.gbl.pyzables.GimeDerived()
         assert type(result) == cppyy.gbl.pyzables.MyDerived
 
-        cppyy._pin_type(cppyy.gbl.pyzables.MyBase)
+        cppyy.py.pin_type(cppyy.gbl.pyzables.MyBase)
         assert type(result) == cppyy.gbl.pyzables.MyDerived
 
-
-    def test03_transparency(self):
+    def test02_transparency(self):
         """Transparent use of smart pointers"""
 
         import _cppyy as cppyy
@@ -101,7 +98,7 @@
         assert mine.__smartptr__().get().m_check == 0xcdcdcdcd
         assert mine.say_hi() == "Hi!"
 
-    def test04_converters(self):
+    def test03_converters(self):
         """Smart pointer argument passing"""
 
         import _cppyy as cppyy
@@ -126,7 +123,7 @@
         # cppyy.gbl.mine = mine
         pz.renew_mine()
 
-    def test05_executors(self):
+    def test04_executors(self):
         """Smart pointer return types"""
 
         import _cppyy as cppyy
@@ -154,3 +151,25 @@
         assert type(mine.__smartptr__()) == cppyy.gbl.std.shared_ptr(Countable)
         assert mine.__smartptr__().get().m_check == 0xcdcdcdcd
         assert mine.say_hi() == "Hi!"
+
+    def test05_creates_flag(self):
+        """Effect of creates flag on return type"""
+
+        import _cppyy as cppyy
+        import gc
+
+        pz = cppyy.gbl.pyzables
+        Countable = pz.Countable
+
+        gc.collect()
+        oldcount = Countable.sInstances     # there's eg. one global variable
+
+        pz.gime_naked_countable.__creates__ = True
+        for i in range(10):
+            cnt = pz.gime_naked_countable()
+            gc.collect()
+            assert Countable.sInstances == oldcount + 1
+        del cnt
+        gc.collect()
+
+        assert Countable.sInstances == oldcount
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
@@ -141,6 +141,9 @@
         self.w_TypeError           = FakeException(self, "TypeError")
         self.w_ValueError          = FakeException(self, "ValueError")
 
+        self.w_True                = FakeBool(True)
+        self.w_False               = FakeBool(False)
+
     def issequence_w(self, w_obj):
         return True
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to