Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r53277:94adcd5155d2
Date: 2012-03-08 13:41 -0800
http://bitbucket.org/pypy/pypy/changeset/94adcd5155d2/
Log: prevent infinite recursion on namespace lookups
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
@@ -90,16 +90,16 @@
return property(binder, setter)
-def make_cppnamespace(namespace_name, cppns, build_in_full=True):
+def make_cppnamespace(scope, namespace_name, cppns, build_in_full=True):
# build up a representation of a C++ namespace (namespaces are classes)
# create a meta class to allow properties (for static data write access)
metans = type(CppyyNamespaceMeta)(namespace_name+'_meta',
(CppyyNamespaceMeta,), {})
if cppns:
- nsdct = {"_cpp_proxy" : cppns}
+ d = {"_cpp_proxy" : cppns}
else:
- nsdct = dict()
+ d = dict()
def cpp_proxy_loader(cls):
cpp_proxy = cppyy._type_byname(cls.__name__ != '::' and
cls.__name__ or '')
del cls.__class__._cpp_proxy
@@ -107,22 +107,27 @@
return cpp_proxy
metans._cpp_proxy = property(cpp_proxy_loader)
+ # create the python-side C++ namespace representation, cache in scope if
given
+ pycppns = metans(namespace_name, (object,), d)
+ if scope:
+ setattr(scope, namespace_name, pycppns)
+
if build_in_full: # if False, rely on lazy build-up
# insert static methods into the "namespace" dictionary
for func_name in cppns.get_method_names():
cppol = cppns.get_overload(func_name)
- nsdct[func_name] = make_static_function(cppns, func_name, cppol)
+ pyfunc = make_static_function(cppns, func_name, cppol)
+ setattr(pycppns, func_name, pyfunc)
# 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)
pydm = make_data_member(cppdm)
- nsdct[dm] = pydm
+ setattr(pycppns, dm, pydm)
setattr(metans, dm, pydm)
- # create the python-side C++ namespace representation
- return metans(namespace_name, (object,), nsdct)
+ return pycppns
def _drop_cycles(bases):
# TODO: figure this out, as it seems to be a PyPy bug?!
@@ -217,7 +222,7 @@
cppitem = cppyy._type_byname(true_name)
if cppitem:
if cppitem.is_namespace():
- pycppitem = make_cppnamespace(true_name, cppitem)
+ pycppitem = make_cppnamespace(scope, true_name, cppitem)
setattr(scope, name, pycppitem)
else:
pycppitem = make_cppclass(scope, true_name, name, cppitem)
@@ -313,7 +318,6 @@
if hasattr(pyclass, '__setitem__') and not hasattr(pyclass,
'__getitem___'):
pyclass.__getitem__ = pyclass.__setitem__
-
_loaded_dictionaries = {}
_loaded_dictionaries_isdirty = True # should be per namespace
def load_reflection_info(name):
@@ -330,7 +334,7 @@
# user interface objects (note the two-step of not calling type_byname here:
# creation of global functions may cause the creation of classes in the global
# namespace, so gbl must exist at that point to cache them)
-gbl = make_cppnamespace("::", None, False) # global C++ namespace
+gbl = make_cppnamespace(None, "::", None, False) # global C++ namespace
# mostly for the benefit of the CINT backend, which treats std as special
-gbl.std = make_cppnamespace("std", None, False)
+gbl.std = make_cppnamespace(None, "std", None, False)
diff --git a/pypy/module/cppyy/test/fragile.cxx
b/pypy/module/cppyy/test/fragile.cxx
--- a/pypy/module/cppyy/test/fragile.cxx
+++ b/pypy/module/cppyy/test/fragile.cxx
@@ -3,3 +3,5 @@
fragile::H::HH* fragile::H::HH::copy() {
return (HH*)0;
}
+
+fragile::I fragile::gI;
diff --git a/pypy/module/cppyy/test/fragile.h b/pypy/module/cppyy/test/fragile.h
--- a/pypy/module/cppyy/test/fragile.h
+++ b/pypy/module/cppyy/test/fragile.h
@@ -63,4 +63,11 @@
HH* m_h;
};
+class I {
+public:
+ operator bool() { return 0; }
+};
+
+extern I gI;
+
} // namespace fragile
diff --git a/pypy/module/cppyy/test/fragile.xml
b/pypy/module/cppyy/test/fragile.xml
--- a/pypy/module/cppyy/test/fragile.xml
+++ b/pypy/module/cppyy/test/fragile.xml
@@ -4,4 +4,6 @@
<class pattern="fragile::[A-Z]" />
+ <variable name="fragile::gI" />
+
</lcgdict>
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
@@ -14,5 +14,8 @@
#pragma link C++ class fragile::F;
#pragma link C++ class fragile::G;
#pragma link C++ class fragile::H;
+#pragma link C++ class fragile::I;
+
+#pragma link C++ variable fragile::gI;
#endif
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
@@ -145,3 +145,14 @@
assert cppyy.gbl.fragile is fragile
h = fragile.H()
+
+ def test09_operator_bool(self):
+ """Access to global vars with an operator bool() returning False"""
+
+ import cppyy
+
+ i = cppyy.gbl.fragile.I()
+ assert not i
+
+ g = cppyy.gbl.fragile.gI
+ assert not g
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit