[pypy-commit] pypy reflex-support: access to global builtin objects

wlav noreply at buildbot.pypy.org
Thu Mar 1 09:07:35 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r53037:95808653de2b
Date: 2012-02-29 14:47 -0800
http://bitbucket.org/pypy/pypy/changeset/95808653de2b/

Log:	access to global builtin objects

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
@@ -67,7 +67,7 @@
     return method
 
 
-def make_datamember(cppdm):
+def make_data_member(cppdm):
     rettype = cppdm.get_returntype()
     if not rettype:                              # return builtin type
         cppclass = None
@@ -103,7 +103,7 @@
     # static ones also to the meta class (needed for property setters)
     for dm in cppns.get_data_member_names():
         cppdm = cppns.get_data_member(dm)
-        pydm = make_datamember(cppdm)
+        pydm = make_data_member(cppdm)
         nsdct[dm] = pydm
         setattr(metans, dm, pydm)
 
@@ -178,7 +178,7 @@
     # static ones also to the meta class (needed for property setters)
     for dm_name in cpptype.get_data_member_names():
         cppdm = cpptype.get_data_member(dm_name)
-        pydm = make_datamember(cppdm)
+        pydm = make_data_member(cppdm)
 
         setattr(pycpptype, dm_name, pydm)
         if cppdm.is_static():
@@ -199,23 +199,35 @@
         scope = gbl
         fullname = name
 
-    # lookup class ...
+    # lookup if already created (e.g. as a function return type)
     try:
         return _existing_cppitems[fullname]
     except KeyError:
         pass
 
-    # ... if lookup failed, create (classes, templates, functions)
+    # ... if lookup failed, create as appropriate
     pycppitem = None
 
+    # namespaces are "open"; TODO: classes are too (template methods, inner classes ...)
+    if isinstance(scope, CppyyNamespaceMeta):
+        global _loaded_dictionaries_isdirty
+        if _loaded_dictionaries_isdirty:  # TODO: this should be per namespace
+            if not scope._cpp_proxy:
+                scope._cpp_proxy = cppyy._type_byname(scope.__name__)
+            scope._cpp_proxy.update()     # TODO: this is currently quadratic
+            _loaded_dictionaries_isdirty = False
+
+    # classes
     cppitem = cppyy._type_byname(fullname)
     if cppitem:
         if cppitem.is_namespace():
             pycppitem = make_cppnamespace(fullname, cppitem)
         else:
             pycppitem = make_cppclass(fullname, cppitem)
+        _existing_cppitems[fullname] = pycppitem
         scope.__dict__[name] = pycppitem
 
+    # templates
     if not cppitem:
         cppitem = cppyy._template_byname(fullname)
         if cppitem:
@@ -223,18 +235,29 @@
             _existing_cppitems[fullname] = pycppitem
             scope.__dict__[name] = pycppitem
 
-    if not cppitem and isinstance(scope, CppyyNamespaceMeta):
-        global _loaded_dictionaries_isdirty
-        if _loaded_dictionaries_isdirty:  # TODO: this should've been per namespace
-            scope._cpp_proxy.update()  # TODO: this is currently quadratic
-        cppitem = scope._cpp_proxy.get_overload(name)
-        pycppitem = make_static_function(scope._cpp_proxy, name, cppitem)
-        setattr(scope.__class__, name, pycppitem)
-        pycppitem = getattr(scope, name)
-        _loaded_dictionaries_isdirty = False
+    # functions
+    if not cppitem:
+        try:
+            cppitem = scope._cpp_proxy.get_overload(name)
+            pycppitem = make_static_function(scope._cpp_proxy, name, cppitem)
+            setattr(scope.__class__, name, pycppitem)
+            pycppitem = getattr(scope, name)      # binds function as needed
+        except AttributeError:
+            pass
+
+    # data
+    if not cppitem:
+        try:
+            cppitem = scope._cpp_proxy.get_data_member(name)
+            pycppitem = make_data_member(cppitem)
+            setattr(scope, name, pycppitem)
+            if cppitem.is_static():
+                setattr(scope.__class__, name, pycppitem)
+            pycppitem = getattr(scope, name)      # gets actual property value
+        except AttributeError:
+            pass
 
     if pycppitem:
-        _existing_cppitems[fullname] = pycppitem
         return pycppitem
 
     raise AttributeError("'%s' has no attribute '%s'", (str(scope), name))
diff --git a/pypy/module/cppyy/test/datatypes.cxx b/pypy/module/cppyy/test/datatypes.cxx
--- a/pypy/module/cppyy/test/datatypes.cxx
+++ b/pypy/module/cppyy/test/datatypes.cxx
@@ -1,6 +1,7 @@
 #include "datatypes.h"
 
 
+//===========================================================================
 cppyy_test_data::cppyy_test_data() : m_owns_arrays(false)
 {
     m_bool   = false;
@@ -72,7 +73,7 @@
     }
 }
 
-// getters
+//- getters -----------------------------------------------------------------
 bool           cppyy_test_data::get_bool()   { return m_bool; }
 char           cppyy_test_data::get_char()   { return m_char; }
 unsigned char  cppyy_test_data::get_uchar()  { return m_uchar; }
@@ -103,7 +104,7 @@
 double* cppyy_test_data::get_double_array()  { return m_double_array; }
 double* cppyy_test_data::get_double_array2() { return m_double_array2; }
 
-// setters
+//- setters -----------------------------------------------------------------
 void cppyy_test_data::set_bool(bool b)              { m_bool   = b; }
 void cppyy_test_data::set_char(char c)              { m_char   = c; }
 void cppyy_test_data::set_uchar(unsigned char uc)   { m_uchar  = uc; }
@@ -127,6 +128,8 @@
 float          cppyy_test_data::s_float  = -404.f;
 double         cppyy_test_data::s_double = -505.;
 
+
+//= global functions ========================================================
 long get_pod_address(cppyy_test_data& c)
 {
     return (long)&c.m_pod;
@@ -141,3 +144,28 @@
 {
     return (long)&c.m_pod.m_double;
 }
+
+//= global variables/pointers ===============================================
+int g_int = 42;
+
+void set_global_int(int i) {
+   g_int = i;
+}
+
+int get_global_int() {
+   return g_int;
+}
+
+cppyy_test_pod* g_pod = (cppyy_test_pod*)0;
+
+bool is_global_pod(cppyy_test_pod* t) {
+   return t == g_pod;
+}
+
+void set_global_pod(cppyy_test_pod* t) {
+   g_pod = t;
+}
+
+cppyy_test_pod* get_global_pod() {
+   return g_pod;
+}
diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h
--- a/pypy/module/cppyy/test/datatypes.h
+++ b/pypy/module/cppyy/test/datatypes.h
@@ -114,7 +114,18 @@
 };
 
 
-// global functions
+//= global functions ========================================================
 long get_pod_address(cppyy_test_data& c);
 long get_int_address(cppyy_test_data& c);
 long get_double_address(cppyy_test_data& c);
+
+
+//= global variables/pointers ===============================================
+extern int g_int;
+void set_global_int(int i);
+int get_global_int();
+
+extern cppyy_test_pod* g_pod;
+bool is_global_pod(cppyy_test_pod* t);
+void set_global_pod(cppyy_test_pod* t);
+cppyy_test_pod* get_global_pod();
diff --git a/pypy/module/cppyy/test/datatypes.xml b/pypy/module/cppyy/test/datatypes.xml
--- a/pypy/module/cppyy/test/datatypes.xml
+++ b/pypy/module/cppyy/test/datatypes.xml
@@ -3,7 +3,12 @@
   <class pattern="cppyy_test_*" />
 
   <function pattern="get_*" />
+  <function pattern="set_*" />
+  <function pattern="is_*" />
 
   <variable name="N" />
 
+  <variable name="g_int" />
+  <variable name="g_pod" />
+
 </lcgdict>
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
@@ -233,7 +233,7 @@
         assert b.m_a          == 11
         assert b.m_da         == 11.11
         assert b.m_b          == 22
-      # assert b.get_value()  == 22
+        assert b.get_value()  == 22
 
         b.m_db = 22.22
         assert b.m_db         == 22.22
@@ -257,7 +257,7 @@
         assert c1.m_a         == 11
         assert c1.m_b         == 22
         assert c1.m_c         == 33
-      # assert c1.get_value() == 33
+        assert c1.get_value() == 33
 
         c1.destruct()
 
@@ -285,7 +285,7 @@
         assert d.m_b          == 22
         assert d.m_c          == 33
         assert d.m_d          == 44
-      # assert d.get_value()  == 44
+        assert d.get_value()  == 44
 
         d.destruct()
 
diff --git a/pypy/module/cppyy/test/test_cppyy.py b/pypy/module/cppyy/test/test_cppyy.py
--- a/pypy/module/cppyy/test/test_cppyy.py
+++ b/pypy/module/cppyy/test/test_cppyy.py
@@ -114,7 +114,6 @@
         e2.destruct()
         assert t.get_overload("getCount").call(None, None) == 0
 
-
         raises(TypeError, t.get_overload("addDataToInt").call, 41, None, 4)
 
     def test05_memory(self):
diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py
--- a/pypy/module/cppyy/test/test_datatypes.py
+++ b/pypy/module/cppyy/test/test_datatypes.py
@@ -332,3 +332,21 @@
         raises(TypeError, c.m_int,      1.)
 
         c.destruct()
+
+    def test09_global_builtin_type(self):
+        """Test access to a global builtin type"""
+
+        import cppyy
+        gbl = cppyy.gbl
+
+        import pprint
+        pprint.pprint(dir(gbl))
+        assert gbl.g_int == gbl.get_global_int()
+
+        gbl.set_global_int(32)
+        assert gbl.get_global_int() == 32
+        assert gbl.g_int == 32
+
+        gbl.g_int = 22
+        assert gbl.get_global_int() == 22
+        assert gbl.g_int == 22


More information about the pypy-commit mailing list