Author: Wim Lavrijsen <wlavrij...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit