Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r44560:dc3b3a380dcd
Date: 2011-05-27 17:37 -0700
http://bitbucket.org/pypy/pypy/changeset/dc3b3a380dcd/
Log: initial support for classes in namespaces
diff --git a/pypy/module/cppyy/capi.py b/pypy/module/cppyy/capi.py
--- a/pypy/module/cppyy/capi.py
+++ b/pypy/module/cppyy/capi.py
@@ -48,6 +48,17 @@
compilation_info=eci)
+c_is_namespace = rffi.llexternal(
+ "cppyy_is_namespace",
+ [C_TYPEHANDLE], rffi.INT,
+ compilation_info=eci)
+
+
+c_final_name = rffi.llexternal(
+ "cppyy_final_name",
+ [C_TYPEHANDLE], rffi.CCHARP,
+ compilation_info=eci)
+
c_num_bases = rffi.llexternal(
"cppyy_num_bases",
[C_TYPEHANDLE], rffi.INT,
diff --git a/pypy/module/cppyy/include/reflexcwrapper.h
b/pypy/module/cppyy/include/reflexcwrapper.h
--- a/pypy/module/cppyy/include/reflexcwrapper.h
+++ b/pypy/module/cppyy/include/reflexcwrapper.h
@@ -28,7 +28,11 @@
cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle,
int method_index);
+ /* scope reflection information
------------------------------------------- */
+ int cppyy_is_namespace(cppyy_typehandle_t handle);
+
/* type/class reflection information
-------------------------------------- */
+ char* cppyy_final_name(cppyy_typehandle_t handle);
int cppyy_num_bases(cppyy_typehandle_t handle);
char* cppyy_base_name(cppyy_typehandle_t handle, int base_index);
int cppyy_is_subtype(cppyy_typehandle_t h1, cppyy_typehandle_t h2);
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,7 +24,7 @@
class State(object):
def __init__(self, space):
- self.cpptype_cache = {}
+ self.cpptype_cache = { "void" : W_CPPType(space, "void", NULL_VOIDP) }
def type_byname(space, name):
state = space.fromcache(State)
@@ -35,7 +35,11 @@
handle = capi.c_get_typehandle(name)
if handle:
- cpptype = W_CPPType(space, name, handle)
+ final_name = capi.charp2str_free(capi.c_final_name(handle))
+ if capi.c_is_namespace(handle):
+ cpptype = W_CPPNamespace(space, final_name, handle)
+ else:
+ cpptype = W_CPPType(space, final_name, handle)
state.cpptype_cache[name] = cpptype
cpptype._find_methods()
cpptype._find_data_members()
@@ -160,6 +164,7 @@
args[i] = arg
return args
+ @jit.unroll_safe
def free_arguments(self, args):
for i in range(len(self.arg_types)):
conv = self.arg_converters[i]
@@ -294,7 +299,7 @@
)
-class W_CPPType(Wrappable):
+class W_CPPScope(Wrappable):
_immutable_fields_ = ["name", "handle"]
def __init__(self, space, name, handle):
@@ -309,7 +314,7 @@
self.data_members = {}
# Idem self.methods: a type could hold itself by pointer.
-
+
def _find_methods(self):
num_methods = capi.c_num_methods(self.handle)
args_temp = {}
@@ -322,6 +327,72 @@
overload = W_CPPOverload(self.space, name, functions[:])
self.methods[name] = overload
+ def get_method_names(self):
+ return self.space.newlist([self.space.wrap(name) for name in
self.methods])
+
+ @jit.purefunction
+ def get_overload(self, name):
+ return self.methods[name]
+
+ def get_data_member_names(self):
+ return self.space.newlist([self.space.wrap(name) for name in
self.data_members])
+
+ @jit.purefunction
+ def get_data_member(self, name):
+ return self.data_members[name]
+
+ def invoke(self, name, args_w):
+ overload = self.get_overload(name)
+ return overload.call(NULL_VOIDP, args_w)
+
+W_CPPScope.typedef = TypeDef(
+ 'CPPScope',
+ get_method_names = interp2app(W_CPPScope.get_method_names,
unwrap_spec=['self']),
+ get_overload = interp2app(W_CPPScope.get_overload, unwrap_spec=['self',
str]),
+ get_data_member_names = interp2app(W_CPPScope.get_data_member_names,
unwrap_spec=['self']),
+ get_data_member = interp2app(W_CPPScope.get_data_member,
unwrap_spec=['self', str]),
+ invoke = interp2app(W_CPPScope.invoke, unwrap_spec=['self', str,
'args_w']),
+)
+
+
+# For now, keep namespaces and classes separate as namespaces are extensible
+# with info from multiple dictionaries and do not need to bother with meta
+# classes for inheritance. Both are python classes, though, and refactoring
+# may be in order at some point.
+class W_CPPNamespace(W_CPPScope):
+
+ def _make_cppfunction(self, method_index):
+ result_type =
capi.charp2str_free(capi.c_method_result_type(self.handle, method_index))
+ num_args = capi.c_method_num_args(self.handle, method_index)
+ argtypes = []
+ for i in range(num_args):
+ argtype = capi.charp2str_free(capi.c_method_arg_type(self.handle,
method_index, i))
+ return CPPFunction(self, method_index, result_type, argtypes)
+
+ def _find_data_members(self):
+ num_data_members = capi.c_num_data_members(self.handle)
+ for i in range(num_data_members):
+ data_member_name =
capi.charp2str_free(capi.c_data_member_name(self.handle, i))
+ cpptype = capi.charp2str_free(capi.c_data_member_type(self.handle,
i))
+ offset = capi.c_data_member_offset(self.handle, i)
+ data_member = W_CPPStaticDataMember(self.space, cpptype, offset)
+ self.data_members[data_member_name] = data_member
+
+ def is_namespace(self):
+ return self.space.w_True
+
+W_CPPNamespace.typedef = TypeDef(
+ 'CPPNamespace',
+ get_method_names = interp2app(W_CPPNamespace.get_method_names,
unwrap_spec=['self']),
+ get_overload = interp2app(W_CPPNamespace.get_overload,
unwrap_spec=['self', str]),
+ get_data_member_names = interp2app(W_CPPNamespace.get_data_member_names,
unwrap_spec=['self']),
+ get_data_member = interp2app(W_CPPNamespace.get_data_member,
unwrap_spec=['self', str]),
+ is_namespace = interp2app(W_CPPNamespace.is_namespace,
unwrap_spec=['self']),
+)
+
+
+class W_CPPType(W_CPPScope):
+
def _make_cppfunction(self, method_index):
result_type =
capi.charp2str_free(capi.c_method_result_type(self.handle, method_index))
num_args = capi.c_method_num_args(self.handle, method_index)
@@ -349,6 +420,9 @@
data_member = W_CPPDataMember(self.space, cpptype, offset)
self.data_members[data_member_name] = data_member
+ def is_namespace(self):
+ return self.space.w_False
+
def get_base_names(self):
bases = []
num_bases = capi.c_num_bases(self.handle)
@@ -357,24 +431,6 @@
bases.append(self.space.wrap(base_name))
return self.space.newlist(bases)
- def get_method_names(self):
- return self.space.newlist([self.space.wrap(name) for name in
self.methods])
-
- @jit.purefunction
- def get_overload(self, name):
- return self.methods[name]
-
- def get_data_member_names(self):
- return self.space.newlist([self.space.wrap(name) for name in
self.data_members])
-
- @jit.purefunction
- def get_data_member(self, name):
- return self.data_members[name]
-
- def invoke(self, name, args_w):
- overload = self.get_overload(name)
- return overload.call(NULL_VOIDP, args_w)
-
def construct(self, args_w):
overload = self.get_overload(self.name)
return overload.call(NULL_VOIDP, args_w)
@@ -386,6 +442,7 @@
get_overload = interp2app(W_CPPType.get_overload, unwrap_spec=['self',
str]),
get_data_member_names = interp2app(W_CPPType.get_data_member_names,
unwrap_spec=['self']),
get_data_member = interp2app(W_CPPType.get_data_member,
unwrap_spec=['self', str]),
+ is_namespace = interp2app(W_CPPType.is_namespace, unwrap_spec=['self']),
invoke = interp2app(W_CPPType.invoke, unwrap_spec=['self', str, 'args_w']),
construct = interp2app(W_CPPType.construct, unwrap_spec=['self',
'args_w']),
)
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
@@ -2,8 +2,15 @@
import cppyy
+# For now, keep namespaces and classes separate as namespaces are extensible
+# with info from multiple dictionaries and do not need to bother with meta
+# classes for inheritance. Both are python classes, though, and refactoring
+# may be in order at some point.
+class CppyyNamespace(type):
+ pass
+
class CppyyClass(type):
- pass
+ pass
class CppyyObject(object):
__metaclass__ = CppyyClass
@@ -23,6 +30,7 @@
return bound_obj
def make_static_function(cpptype, name, rettype):
+ print rettype
if not rettype: # return builtin type
def method(*args):
return cpptype.invoke(name, *args)
@@ -45,20 +53,46 @@
return method
-_existing_classes = {}
-def get_cppclass(name):
- # lookup class
+def __ns_getattr__(self, attr):
try:
- return _existing_classes[name]
- except KeyError:
- pass
+ cppclass = get_cppitem(attr, self.__name__)
+ self.__dict__[attr] = cppclass
+ return cppclass
+ except TypeError, e:
+ import traceback
+ traceback.print_exc()
+ raise AttributeError("namespace object has no attribute '%s'" % attr)
- # if failed, create
- cpptype = cppyy._type_byname(name)
+def make_cppnamespace(name, cppns):
+ d = {}
+
+ # insert static methods into the "namespace" dictionary
+ for f in cppns.get_method_names():
+ cppol = cppns.get_overload(f)
+ d[f] = make_static_function(cppns, f, cppol.get_returntype())
+
+ # create a meta class to allow properties (for static data write access)
+ metans = type(CppyyNamespace)(name+'_meta', (type(type),), {"__getattr__"
: __ns_getattr__})
+
+ # 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_data_member_names():
+ cppdm = cppns.get_data_member(dm)
+ d[dm] = cppdm
+ setattr(metans, dm, cppdm)
+
+ # create the python-side C++ namespace representation
+ pycppns = metans(name, (type,), d)
+
+ # cache result and return
+ _existing_cppitems[name] = pycppns
+ return pycppns
+
+def make_cppclass(name, cpptype):
d = {"_cppyyclass" : cpptype}
- # insert (static) methods in the class dictionary
+ # insert (static) methods into the class dictionary
for f in cpptype.get_method_names():
cppol = cpptype.get_overload(f)
if cppol.is_static():
@@ -69,7 +103,7 @@
# get a list of base classes for class creation
bases = tuple([get_cppclass(base) for base in cpptype.get_base_names()])
if not bases:
- bases = (CppyyObject,)
+ bases = (CppyyObject,)
# create a meta class to allow properties (for static data write access)
metabases = tuple([type(base) for base in bases])
@@ -88,21 +122,41 @@
pycpptype = metacpp(name, bases, d)
# cache result and return
- _existing_classes[name] = pycpptype
+ _existing_cppitems[name] = pycpptype
return pycpptype
- # TODO: better error reporting
- # raise TypeError("no such C++ class %s" % name)
+_existing_cppitems = {} # to merge with gbl.__dict__ (?)
+def get_cppitem(name, scope=""):
+ if scope:
+ fullname = scope+"::"+name
+ else:
+ fullname = name
-class _gbl(object):
+ # lookup class
+ try:
+ return _existing_cppitems[fullname]
+ except KeyError:
+ pass
+
+ # if failed, create
+
+ cppitem = cppyy._type_byname(fullname)
+ if cppitem.is_namespace():
+ return make_cppnamespace(name, cppitem)
+ else:
+ return make_cppclass(name, cppitem)
+get_cppclass = get_cppitem # TODO: restrict to classes only (?)
+
+
+class _gbl(object): # TODO: make a CppyyNamespace object
"""Global C++ namespace, i.e. ::."""
def __getattr__(self, attr):
try:
- cppclass = get_cppclass(attr)
- self.__dict__[attr] = cppclass
- return cppclass
+ cppitem = get_cppitem(attr)
+ self.__dict__[attr] = cppitem
+ return cppitem
except TypeError, e:
import traceback
traceback.print_exc()
diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx
b/pypy/module/cppyy/src/reflexcwrapper.cxx
--- a/pypy/module/cppyy/src/reflexcwrapper.cxx
+++ b/pypy/module/cppyy/src/reflexcwrapper.cxx
@@ -6,30 +6,41 @@
/* local helpers ---------------------------------------------------------- */
-static inline char* cppstring_to_cstring( const std::string& name ) {
+static inline char* cppstring_to_cstring(const std::string& name) {
char* name_char = (char*)malloc(name.size() + 1);
strcpy(name_char, name.c_str());
return name_char;
}
+static inline Reflex::Scope scope_from_handle(cppyy_typehandle_t handle) {
+ return Reflex::Scope((Reflex::ScopeName*)handle);
+}
+
+static inline Reflex::Type type_from_handle(cppyy_typehandle_t handle) {
+ return Reflex::Scope((Reflex::ScopeName*)handle);
+}
+
/* name to handle --------------------------------------------------------- */
cppyy_typehandle_t cppyy_get_typehandle(const char* class_name) {
- return Reflex::Type::ByName(class_name).Id();
+ Reflex::Scope s = Reflex::Scope::ByName(class_name);
+ return Reflex::Scope::ByName(class_name).Id();
}
/* memory management ------------------------------------------------------ */
void* cppyy_allocate(cppyy_typehandle_t handle) {
- return Reflex::Type((Reflex::TypeName*)handle).Allocate();
+ Reflex::Type t = type_from_handle(handle);
+ return t.Allocate();
}
void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance) {
- Reflex::Type((Reflex::TypeName*)handle).Deallocate(instance);
+ Reflex::Type t = type_from_handle(handle);
+ t.Deallocate(instance);
}
void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self) {
- Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Type t = type_from_handle(handle);
t.Destruct(self, true);
}
@@ -38,10 +49,10 @@
void cppyy_call_v(cppyy_typehandle_t handle, int method_index,
cppyy_object_t self, int numargs, void* args[]) {
std::vector<void*> arguments(args, args+numargs);
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
if (self) {
- Reflex::Object o(t, self);
+ Reflex::Object o((Reflex::Type)s, self);
m.Invoke(o, 0, arguments);
} else {
m.Invoke(0, arguments);
@@ -53,10 +64,10 @@
cppyy_object_t self, int numargs, void* args[]) {
T result;
std::vector<void*> arguments(args, args+numargs);
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
if (self) {
- Reflex::Object o(t, self);
+ Reflex::Object o((Reflex::Type)s, self);
m.Invoke(o, result, arguments);
} else {
m.Invoke(result, arguments);
@@ -71,12 +82,12 @@
char cppyy_call_c(cppyy_typehandle_t handle, int method_index,
cppyy_object_t self, int numargs, void* args[]) {
- return cppyy_call_T<char>(handle, method_index, self, numargs, args);
+ return cppyy_call_T<char>(handle, method_index, self, numargs, args);
}
short cppyy_call_h(cppyy_typehandle_t handle, int method_index,
cppyy_object_t self, int numargs, void* args[]) {
- return cppyy_call_T<short>(handle, method_index, self, numargs, args);
+ return cppyy_call_T<short>(handle, method_index, self, numargs, args);
}
long cppyy_call_l(cppyy_typehandle_t handle, int method_index,
@@ -96,31 +107,43 @@
static cppyy_methptrgetter_t get_methptr_getter(Reflex::Member m) {
- Reflex::PropertyList plist = m.Properties();
- if (plist.HasProperty("MethPtrGetter")) {
- Reflex::Any& value = plist.PropertyValue("MethPtrGetter");
- return (cppyy_methptrgetter_t)Reflex::any_cast<void*>(value);
- }
- else
+ Reflex::PropertyList plist = m.Properties();
+ if (plist.HasProperty("MethPtrGetter")) {
+ Reflex::Any& value = plist.PropertyValue("MethPtrGetter");
+ return (cppyy_methptrgetter_t)Reflex::any_cast<void*>(value);
+ }
return 0;
}
cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int
method_index)
{
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
return get_methptr_getter(m);
}
+/* scope reflection information ------------------------------------------- */
+int cppyy_is_namespace(cppyy_typehandle_t handle) {
+ Reflex::Scope s = scope_from_handle(handle);
+ return s.IsNamespace();
+}
+
+
/* type/class reflection information -------------------------------------- */
+char* cppyy_final_name(cppyy_typehandle_t handle) {
+ Reflex::Scope s = scope_from_handle(handle);
+ std::string name = s.Name(Reflex::FINAL);
+ return cppstring_to_cstring(name);
+}
+
int cppyy_num_bases(cppyy_typehandle_t handle) {
- Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Type t = type_from_handle(handle);
return t.BaseSize();
}
char* cppyy_base_name(cppyy_typehandle_t handle, int base_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Type t = type_from_handle(handle);
Reflex::Base b = t.BaseAt(base_index);
std::string name = b.Name(Reflex::FINAL|Reflex::SCOPED);
return cppstring_to_cstring(name);
@@ -129,52 +152,42 @@
int cppyy_is_subtype(cppyy_typehandle_t h1, cppyy_typehandle_t h2) {
if (h1 == h2)
return 1;
- Reflex::Type t1((Reflex::TypeName*)h1);
- Reflex::Type t2((Reflex::TypeName*)h2);
+ Reflex::Type t1 = type_from_handle(h1);
+ Reflex::Type t2 = type_from_handle(h2);
return (int)t2.HasBase(t1);
}
/* method/function reflection information --------------------------------- */
int cppyy_num_methods(cppyy_typehandle_t handle) {
- Reflex::Type t((Reflex::TypeName*)handle);
- // for (int i = 0; i < (int)t.FunctionMemberSize(); i++) {
- // Reflex::Member m = t.FunctionMemberAt(i);
- // std::cout << i << " " << m.Name() << std::endl;
- // std::cout << " " << "Stubfunction: " << (void*)m.Stubfunction()
<< std::endl;
- // std::cout << " " << "MethPtrGetter: " <<
(void*)get_methptr_getter(m) << std::endl;
- // for (int j = 0; j < (int)m.FunctionParameterSize(); j++) {
- // Reflex::Type at = m.TypeOf().FunctionParameterAt(j);
- // std::cout << " " << j << " " << at.Name() << std::endl;
- // }
- // }
- return t.FunctionMemberSize();
+ Reflex::Scope s = scope_from_handle(handle);
+ return s.FunctionMemberSize();
}
char* cppyy_method_name(cppyy_typehandle_t handle, int method_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
std::string name = m.Name();
return cppstring_to_cstring(name);
}
char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
Reflex::Type rt = m.TypeOf().ReturnType();
std::string name = rt.Name(Reflex::FINAL|Reflex::SCOPED|Reflex::QUALIFIED);
return cppstring_to_cstring(name);
}
int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
return m.FunctionParameterSize();
}
char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int
arg_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
Reflex::Type at = m.TypeOf().FunctionParameterAt(arg_index);
std::string name = at.Name(Reflex::FINAL|Reflex::SCOPED|Reflex::QUALIFIED);
return cppstring_to_cstring(name);
@@ -182,52 +195,48 @@
int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
return m.IsConstructor();
}
int cppyy_is_staticmethod(cppyy_typehandle_t handle, int method_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
return m.IsStatic();
}
/* data member reflection information ------------------------------------- */
int cppyy_num_data_members(cppyy_typehandle_t handle) {
- Reflex::Type t((Reflex::TypeName*)handle);
- return t.DataMemberSize();
+ Reflex::Scope s = scope_from_handle(handle);
+ return s.DataMemberSize();
}
char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index)
{
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.DataMemberAt(data_member_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.DataMemberAt(data_member_index);
std::string name = m.Name();
- char* name_char = (char*)malloc(name.size() + 1);
- strcpy(name_char, name.c_str());
- return name_char;
+ return cppstring_to_cstring(name);
}
char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index)
{
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.DataMemberAt(data_member_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.DataMemberAt(data_member_index);
std::string name =
m.TypeOf().Name(Reflex::FINAL|Reflex::SCOPED|Reflex::QUALIFIED);
- char* name_char = (char*)malloc(name.size() + 1);
- strcpy(name_char, name.c_str());
- return name_char;
+ return cppstring_to_cstring(name);
}
size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int
data_member_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.DataMemberAt(data_member_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.DataMemberAt(data_member_index);
return m.Offset();
}
int cppyy_is_staticdata(cppyy_typehandle_t handle, int data_member_index) {
- Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.DataMemberAt(data_member_index);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.DataMemberAt(data_member_index);
return m.IsStatic();
}
diff --git a/pypy/module/cppyy/test/advancedcpp.cxx
b/pypy/module/cppyy/test/advancedcpp.cxx
--- a/pypy/module/cppyy/test/advancedcpp.cxx
+++ b/pypy/module/cppyy/test/advancedcpp.cxx
@@ -8,6 +8,15 @@
int get_d( d_class& d ) { return d.m_d; }
+// for namespace testing
+int a_ns::g_a = 11;
+int a_ns::b_class::s_b = 22;
+int a_ns::b_class::c_class::s_c = 33;
+int a_ns::d_ns::g_d = 44;
+int a_ns::d_ns::e_class::s_e = 55;
+int a_ns::d_ns::e_class::f_class::s_f = 66;
+
+
// helpers for checking pass-by-ref
void set_int_through_ref(int& i, int val) { i = val; }
int pass_int_through_const_ref(const int& i) { return i; }
diff --git a/pypy/module/cppyy/test/advancedcpp.h
b/pypy/module/cppyy/test/advancedcpp.h
--- a/pypy/module/cppyy/test/advancedcpp.h
+++ b/pypy/module/cppyy/test/advancedcpp.h
@@ -82,6 +82,42 @@
//===========================================================================
+namespace a_ns { // for namespace testing
+ extern int g_a;
+
+ struct b_class {
+ b_class() { m_b = -2; }
+ int m_b;
+ static int s_b;
+
+ struct c_class {
+ c_class() { m_c = -3; }
+ int m_c;
+ static int s_c;
+ };
+ };
+
+ namespace d_ns {
+ extern int g_d;
+
+ struct e_class {
+ e_class() { m_e = -5; }
+ int m_e;
+ static int s_e;
+
+ struct f_class {
+ f_class() { m_f = -6; }
+ int m_f;
+ static int s_f;
+ };
+ };
+
+ } // namespace d_ns
+
+} // namespace a_ns
+
+
+//===========================================================================
template< typename T > // for template testing
class T1 {
public:
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
@@ -23,7 +23,7 @@
import cppyy
return cppyy.load_lib(%r)""" % (shared_lib, ))
- def test1_simple_inheritence(self):
+ def test01_simple_inheritence(self):
"""Test binding of a basic inheritance structure"""
import cppyy
@@ -38,3 +38,22 @@
assert isinstance( c, base_class )
c.destruct()
+
+ def test02_namespaces(self):
+ """Test access to namespaces and inner classes"""
+
+ import cppyy
+
+# assert cppyy.gbl.a_ns.g_a == 11
+ assert cppyy.gbl.a_ns.b_class.s_b == 22
+ assert cppyy.gbl.a_ns.b_class().m_b == -2
+# assert cppyy.gbl.a_ns.b_class.c_class.s_c == 33
+# assert cppyy.gbl.a_ns.b_class.c_class().m_c == -3
+# assert cppyy.gbl.a_ns.d_ns.g_d == 44
+# assert cppyy.gbl.a_ns.d_ns.e_class.s_e == 55
+# assert cppyy.gbl.a_ns.d_ns.e_class().m_e == -5
+# assert cppyy.gbl.a_ns.d_ns.e_class.f_class.s_f == 66
+# assert cppyy.gbl.a_ns.d_ns.e_class.f_class().m_f == -6
+
+ assert cppyy.gbl.a_ns is cppyy.gbl.a_ns
+ assert cppyy.gbl.a_ns.d_ns is cppyy.gbl.a_ns.d_ns
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit