[pypy-commit] pypy reflex-support: support for dir() on CINT namespaces (can't be complete, but is good enough for now)

wlav noreply at buildbot.pypy.org
Sun Jul 1 23:31:05 CEST 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r55889:6dce3c53bb42
Date: 2012-06-29 16:32 -0700
http://bitbucket.org/pypy/pypy/changeset/6dce3c53bb42/

Log:	support for dir() on CINT namespaces (can't be complete, but is good
	enough for now)

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
@@ -534,14 +534,22 @@
         return self.space.w_True
 
     def ns__dir__(self):
+        # Collect a list of everything (currently) available in the namespace.
+        # The backend can filter by returning empty strings. Special care is
+        # taken for functions, which need not be unique (overloading).
         alldir = []
         for i in range(capi.c_num_scopes(self)):
-            alldir.append(capi.c_scope_name(self, i))
+            sname = capi.c_scope_name(self, i)
+            if sname: alldir.append(sname)
+        allmeth = []
         for i in range(capi.c_num_methods(self)):
             idx = capi.c_method_index_at(self, i)
-            alldir.append(capi.c_method_name(self, idx))
+            mname = capi.c_method_name(self, idx)
+            if mname: allmeth.append(mname)
+        alldir += set(allmeth)
         for i in range(capi.c_num_datamembers(self)):
-            alldir.append(capi.c_datamember_name(self, i))
+            dname = capi.c_datamember_name(self, i)
+            if dname: alldir.append(dname)
         return self.space.wrap(alldir)
         
 
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -16,6 +16,7 @@
 #include "TClass.h"
 #include "TClassEdit.h"
 #include "TClassRef.h"
+#include "TClassTable.h"
 #include "TDataMember.h"
 #include "TFunction.h"
 #include "TGlobal.h"
@@ -208,6 +209,28 @@
 
 
 /* name to opaque C++ scope representation -------------------------------- */
+int cppyy_num_scopes(cppyy_scope_t handle) {
+    TClassRef cr = type_from_handle(handle);
+    if (cr.GetClass()) {
+        /* not supported as CINT does not store classes hierarchically */
+        return 0;
+    }
+    return gClassTable->Classes();
+}
+
+char* cppyy_scope_name(cppyy_scope_t handle, int iscope) {
+    TClassRef cr = type_from_handle(handle);
+    if (cr.GetClass()) {
+        /* not supported as CINT does not store classes hierarchically */
+        assert(!"scope name lookup not supported on inner scopes");
+        return 0;
+    }
+    std::string name = gClassTable->At(iscope);
+    if (name.find("::") == std::string::npos)
+        return cppstring_to_cstring(name);
+    return cppstring_to_cstring("");
+}
+
 char* cppyy_resolve_name(const char* cppitem_name) {
     std::string tname = cppitem_name;
 
diff --git a/pypy/module/cppyy/test/fragile_LinkDef.h b/pypy/module/cppyy/test/fragile_LinkDef.h
--- a/pypy/module/cppyy/test/fragile_LinkDef.h
+++ b/pypy/module/cppyy/test/fragile_LinkDef.h
@@ -5,6 +5,9 @@
 #pragma link off all functions;
 
 #pragma link C++ namespace fragile;
+#pragma link C++ namespace fragile::nested1;
+#pragma link C++ namespace fragile::nested1::nested2;
+#pragma link C++ namespace fragile::nested1::nested2::nested3;
 
 #pragma link C++ class fragile::A;
 #pragma link C++ class fragile::B;
@@ -16,6 +19,9 @@
 #pragma link C++ class fragile::H;
 #pragma link C++ class fragile::I;
 #pragma link C++ class fragile::J;
+#pragma link C++ class fragile::nested1::A;
+#pragma link C++ class fragile::nested1::nested2::A;
+#pragma link C++ class fragile::nested1::nested2::nested3::A;
 
 #pragma link C++ variable fragile::gI;
 
diff --git a/pypy/module/cppyy/test/test_fragile.py b/pypy/module/cppyy/test/test_fragile.py
--- a/pypy/module/cppyy/test/test_fragile.py
+++ b/pypy/module/cppyy/test/test_fragile.py
@@ -1,6 +1,7 @@
 import py, os, sys
 from pypy.conftest import gettestobjspace
 
+from pypy.module.cppyy import capi
 
 currpath = py.path.local(__file__).dirpath()
 test_dct = str(currpath.join("fragileDict.so"))
@@ -19,6 +20,7 @@
         cls.space = space
         env = os.environ
         cls.w_test_dct  = space.wrap(test_dct)
+        cls.w_capi = space.wrap(capi)
         cls.w_fragile = cls.space.appexec([], """():
             import cppyy
             return cppyy.load_reflection_info(%r)""" % (test_dct, ))
@@ -200,14 +202,22 @@
 
         import cppyy
 
-        members = dir(cppyy.gbl.fragile)
-        assert 'A' in members
-        assert 'B' in members
-        assert 'C' in members
-        assert 'D' in members                # classes
+        if self.capi.identify() == 'CINT':   # CINT only support classes on global space
+            members = dir(cppyy.gbl)
+            assert 'TROOT' in members
+            assert 'TSystem' in members
+            assert 'TClass' in members
+            members = dir(cppyy.gbl.fragile)
+        else:
+            members = dir(cppyy.gbl.fragile)
+            assert 'A' in members
+            assert 'B' in members
+            assert 'C' in members
+            assert 'D' in members            # classes
+
+            assert 'nested1' in members          # namespace
 
         assert 'fglobal' in members          # function
-        assert 'nested1' in members          # namespace
         assert 'gI'in members                # variable
 
     def test12_imports(self):


More information about the pypy-commit mailing list