Commits

wlav committed b8823f4

simplify and improve consistency

Comments (0)

Files changed (7)

pypy/module/cppyy/__init__.py

         '_template_byname'       : 'interp_cppyy.template_byname',
         '_set_class_generator'   : 'interp_cppyy.set_class_generator',
         '_register_class'        : 'interp_cppyy.register_class',
+        '_is_static'             : 'interp_cppyy.is_static',
         'CPPInstance'            : 'interp_cppyy.W_CPPInstance',
         'addressof'              : 'interp_cppyy.addressof',
         'bind_object'            : 'interp_cppyy.bind_object',

pypy/module/cppyy/converter.py

         address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
         from pypy.module.cppyy import interp_cppyy
         return interp_cppyy.wrap_cppobject_nocast(
-            space, w_pycppclass, self.cppclass, address, isref=True, python_owns=False)
+            space, space.w_None, self.cppclass, address, isref=True, python_owns=False)
 
     def to_memory(self, space, w_obj, w_value, offset):
         address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
         address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
         from pypy.module.cppyy import interp_cppyy
         return interp_cppyy.wrap_cppobject_nocast(
-            space, w_pycppclass, self.cppclass, address, isref=False, python_owns=False)
+            space, space.w_None, self.cppclass, address, isref=False, python_owns=False)
 
     def to_memory(self, space, w_obj, w_value, offset):
         self._is_abstract(space)

pypy/module/cppyy/interp_cppyy.py

 
 
 class W_CPPDataMember(Wrappable):
-    _attrs_ = ['space', 'scope', 'converter', 'offset', '_is_static']
-    _immutable_fields = ['scope', 'converter', 'offset', '_is_static']
+    _attrs_ = ['space', 'scope', 'converter', 'offset']
+    _immutable_fields = ['scope', 'converter', 'offset']
 
-    def __init__(self, space, containing_scope, type_name, offset, is_static):
+    def __init__(self, space, containing_scope, type_name, offset):
         self.space = space
         self.scope = containing_scope
         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.newbool(self._is_static)
-
     @jit.elidable_promote()
     def _get_offset(self, cppinstance):
         if cppinstance:
 
 W_CPPDataMember.typedef = TypeDef(
     'CPPDataMember',
-    is_static = interp2app(W_CPPDataMember.is_static),
     get_returntype = interp2app(W_CPPDataMember.get_returntype),
-    get = interp2app(W_CPPDataMember.get),
-    set = interp2app(W_CPPDataMember.set),
+    __get__ = interp2app(W_CPPDataMember.get),
+    __set__ = interp2app(W_CPPDataMember.set),
 )
 W_CPPDataMember.typedef.acceptable_as_base_class = False
 
+class W_CPPStaticData(W_CPPDataMember):
+    def _get_offset(self):
+        return self.offset
+
+    def get(self, w_cppinstance, w_pycppclass):
+        return self.converter.from_memory(self.space, self.space.w_None, w_pycppclass, self.offset)
+
+    def set(self, w_cppinstance, w_value):
+        self.converter.to_memory(self.space, self.space.w_None, w_value, self.offset)
+        return self.space.w_None
+
+W_CPPStaticData.typedef = TypeDef(
+    'CPPStaticData',
+    get_returntype = interp2app(W_CPPStaticData.get_returntype),
+    __get__ = interp2app(W_CPPStaticData.get),
+    __set__ = interp2app(W_CPPStaticData.set),
+)
+W_CPPStaticData.typedef.acceptable_as_base_class = False
+
+def is_static(space, w_obj):
+    try:
+        space.interp_w(W_CPPStaticData, w_obj, can_be_None=False)
+        return space.w_True
+    except Exception:
+        return space.w_False
 
 class W_CPPScope(Wrappable):
     _attrs_ = ['space', 'name', 'handle', 'methods', 'datamembers']
     def _make_datamember(self, dm_name, dm_idx):
         type_name = capi.c_datamember_type(self, dm_idx)
         offset = capi.c_datamember_offset(self, dm_idx)
-        datamember = W_CPPDataMember(self.space, self, type_name, offset, True)
+        datamember = W_CPPStaticData(self.space, self, type_name, offset)
         self.datamembers[dm_name] = datamember
         return datamember
 
             type_name = capi.c_datamember_type(self, i)
             offset = capi.c_datamember_offset(self, i)
             is_static = bool(capi.c_is_staticdata(self, i))
-            datamember = W_CPPDataMember(self.space, self, type_name, offset, is_static)
+            if is_static:
+                datamember = W_CPPStaticData(self.space, self, type_name, offset)
+            else:
+                datamember = W_CPPDataMember(self.space, self, type_name, offset)
             self.datamembers[datamember_name] = datamember
 
     def construct(self):

pypy/module/cppyy/pythonify.py

     return method
 
 
-def make_datamember(cppdm):
-    rettype = cppdm.get_returntype()
-    if not rettype:                              # return builtin type
-        cppclass = None
-    else:                                        # return instance
-        try:
-            cppclass = get_pycppclass(rettype)
-        except AttributeError:
-            import warnings
-            warnings.warn("class %s unknown: no data member access" % rettype,
-                          RuntimeWarning)
-            cppclass = None
-    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(scope, namespace_name, cppns, build_in_full=True):
     # build up a representation of a C++ namespace (namespaces are classes)
 
 
         # add all data members to the dictionary of the class to be created, and
         # static ones also to the meta class (needed for property setters)
-        for dm in cppns.get_datamember_names():
-            cppdm = cppns.get_datamember(dm)
-            pydm = make_datamember(cppdm)
-            setattr(pycppns, dm, pydm)
-            setattr(metans, dm, pydm)
+        for dm_name in cppns.get_datamember_names():
+            cppdm = cppns.get_datamember(dm_name)
+            setattr(pycppns, dm_name, cppdm)
+            setattr(metans, dm_name, cppdm)
 
         modname = pycppns.__name__.replace('::', '.')
         sys.modules['cppyy.gbl.'+modname] = pycppns
     # static ones also to the meta class (needed for property setters)
     for dm_name in cppclass.get_datamember_names():
         cppdm = cppclass.get_datamember(dm_name)
-        pydm = make_datamember(cppdm)
 
         # here, setattr() can not be used, because a data member can shadow one in
         # its base class, resulting in the __set__() of its base class being called
         # by setattr(); so, store directly on the dictionary
-        pycppclass.__dict__[dm_name] = pydm
-        if cppdm.is_static():
-            metacpp.__dict__[dm_name] = pydm
+        pycppclass.__dict__[dm_name] = cppdm
+        if cppyy._is_static(cppdm):
+            metacpp.__dict__[dm_name] = cppdm
 
     # the call to register will add back-end specific pythonizations and thus
     # needs to run first, so that the generic pythonizations can use them
     # data
     if not cppitem:
         try:
-            cppitem = scope._cpp_proxy.get_datamember(name)
-            pycppitem = make_datamember(cppitem)
-            setattr(scope, name, pycppitem)
-            if cppitem.is_static():
-                setattr(scope.__class__, name, pycppitem)
+            cppdm = scope._cpp_proxy.get_datamember(name)
+            setattr(scope, name, cppdm)
+            if cppyy._is_static(cppdm):
+                setattr(scope.__class__, name, cppdm)
             pycppitem = getattr(scope, name)      # gets actual property value
         except AttributeError:
             pass

pypy/module/cppyy/test/advancedcpp.h

 class T1 {
 public:
    T1(T t = T(1)) : m_t1(t) {}
-   T value() { return m_t1; }
+   T get_value() { return m_t1; }
 
 public:
    T m_t1;
 class T2 {
 public:
    T2(T t = T(2)) : m_t2(t) {}
-   T value() { return m_t2; }
+   T get_value() { return m_t2; }
 
 public:
    T m_t2;
 class T3 {
 public:
    T3(T t = T(3), U u = U(33)) : m_t3(t), m_u3(u) {}
-   T value_t() { return m_t3; }
-   U value_u() { return m_u3; }
+   T get_value_t() { return m_t3; }
+   U get_value_u() { return m_u3; }
 
 public:
    T m_t3;
    class T4 {
    public:
       T4(T t = T(4)) : m_t4(t) {}
-      T value() { return m_t4; }
+      T get_value() { return m_t4; }
 
    public:
       T m_t4;

pypy/module/cppyy/test/test_advancedcpp.py

 
         #-----
         t1 = gbl.T1(int)()
-        assert t1.m_t1    == 1
-        assert t1.value() == 1
+        assert t1.m_t1        == 1
+        assert t1.get_value() == 1
         t1.destruct()
 
         #-----
         t1 = gbl.T1(int)(11)
-        assert t1.m_t1    == 11
-        assert t1.value() == 11
+        assert t1.m_t1        == 11
+        assert t1.get_value() == 11
         t1.m_t1 = 111
-        assert t1.value() == 111
-        assert t1.m_t1    == 111
+        assert t1.get_value() == 111
+        assert t1.m_t1        == 111
         t1.destruct()
 
         #-----
         t2 = gbl.T2(gbl.T1(int))(gbl.T1(int)(32))
         t2.m_t2.m_t1 = 32
-        assert t2.m_t2.value() == 32
-        assert t2.m_t2.m_t1    == 32
+        assert t2.m_t2.get_value() == 32
+        assert t2.m_t2.m_t1        == 32
         t2.destruct()
 
     def test05_abstract_classes(self):

pypy/module/cppyy/test/test_pythonify.py

         oldval = cppyy.gbl.ns_example01.gMyGlobalInt
         assert oldval == 99
 
-        proxy = cppyy.gbl.ns_example01.__class__.gMyGlobalInt
+        proxy = cppyy.gbl.ns_example01.__class__.__dict__['gMyGlobalInt']
         cppyy.gbl.ns_example01.gMyGlobalInt = 3
-        assert proxy.__get__(proxy) == 3
+        assert proxy.__get__(proxy, None) == 3
 
         cppyy.gbl.ns_example01.gMyGlobalInt = oldval