[pypy-commit] pypy reflex-support: o) prepared some more tests for future dev
wlav
noreply at buildbot.pypy.org
Fri Feb 17 23:40:07 CET 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52595:074e97fc7fc9
Date: 2012-02-17 14:39 -0800
http://bitbucket.org/pypy/pypy/changeset/074e97fc7fc9/
Log: o) prepared some more tests for future dev o) std::string returns as
python str o) string comparisons
diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -130,6 +130,11 @@
[C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE,
compilation_info=backend.eci)
+c_call_s = rffi.llexternal(
+ "cppyy_call_s",
+ [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP,
+ compilation_info=backend.eci)
+
c_get_methptr_getter = rffi.llexternal(
"cppyy_get_methptr_getter",
[C_TYPEHANDLE, rffi.INT], C_METHPTRGETTER_PTR,
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -269,6 +269,18 @@
raise FastCallNotPossible
+class StdStringExecutor(InstancePtrExecutor):
+ _immutable_ = True
+
+ def execute(self, space, w_returntype, func, cppthis, num_args, args):
+ charp_result = capi.c_call_s(func.cpptype.handle, func.method_index, cppthis, num_args, args)
+ return space.wrap(capi.charp2str_free(charp_result))
+
+ def execute_libffi(self, space, w_returntype, libffifunc, argchain):
+ from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
+ raise FastCallNotPossible
+
+
_executors = {}
def get_executor(space, name):
# Matching of 'name' to an executor factory goes through up to four levels:
@@ -355,3 +367,6 @@
_executors["float*"] = FloatPtrExecutor
_executors["double"] = DoubleExecutor
_executors["double*"] = DoublePtrExecutor
+
+# special cases
+_executors["std::basic_string<char>"] = StdStringExecutor
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -30,6 +30,8 @@
double cppyy_call_f(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
double cppyy_call_d(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
+ char* cppyy_call_s(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
+
cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index);
/* handling of function argument buffer */
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
@@ -250,6 +250,15 @@
raise StopIteration
pyclass.__iter__ = __iter__
+ # string comparisons
+ if pyclass.__name__ == 'std::string':
+ def eq(self, other):
+ if type(other) == pyclass:
+ return self.c_str() == other.c_str()
+ else:
+ return self.c_str() == other
+ pyclass.__eq__ = eq
+
_loaded_dictionaries = {}
def load_reflection_info(name):
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
@@ -155,6 +155,20 @@
return cppyy_call_T<double>(handle, method_index, self, numargs, args);
}
+char* cppyy_call_s(cppyy_typehandle_t handle, int method_index,
+ cppyy_object_t self, int numargs, void* args) {
+ std::string result("");
+ std::vector<void*> arguments = build_args(numargs, args);
+ Reflex::Scope s = scope_from_handle(handle);
+ Reflex::Member m = s.FunctionMemberAt(method_index);
+ if (self) {
+ Reflex::Object o((Reflex::Type)s, self);
+ m.Invoke(o, result, arguments);
+ } else {
+ m.Invoke(result, arguments);
+ }
+ return cppstring_to_cstring(result);
+}
static cppyy_methptrgetter_t get_methptr_getter(Reflex::Member m) {
Reflex::PropertyList plist = m.Properties();
diff --git a/pypy/module/cppyy/test/stltypes.cxx b/pypy/module/cppyy/test/stltypes.cxx
--- a/pypy/module/cppyy/test/stltypes.cxx
+++ b/pypy/module/cppyy/test/stltypes.cxx
@@ -11,6 +11,16 @@
const std::STLTYPE< TTYPE >::iterator&); \
}
+
//- explicit instantiations of used types
STLTYPES_EXPLICIT_INSTANTIATION(vector, int)
STLTYPES_EXPLICIT_INSTANTIATION(vector, just_a_class)
+
+//- class with lots of std::string handling
+stringy_class::stringy_class(const char* s) : m_string(s) {}
+
+std::string stringy_class::get_string1() { return m_string; }
+void stringy_class::get_string2(std::string& s) { s = m_string; }
+
+void stringy_class::set_string1(const std::string& s) { m_string = s; }
+void stringy_class::set_string2(std::string s) { m_string = s; }
diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h
--- a/pypy/module/cppyy/test/stltypes.h
+++ b/pypy/module/cppyy/test/stltypes.h
@@ -25,3 +25,18 @@
//- explicit instantiations of used types
STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, int)
STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, just_a_class)
+
+
+//- class with lots of std::string handling
+class stringy_class {
+public:
+ stringy_class(const char* s);
+
+ std::string get_string1();
+ void get_string2(std::string& s);
+
+ void set_string1(const std::string& s);
+ void set_string2(std::string s);
+
+ std::string m_string;
+};
diff --git a/pypy/module/cppyy/test/stltypes.xml b/pypy/module/cppyy/test/stltypes.xml
--- a/pypy/module/cppyy/test/stltypes.xml
+++ b/pypy/module/cppyy/test/stltypes.xml
@@ -1,5 +1,7 @@
<lcgdict>
+ <namespace name="std" />
+
<class pattern="std::vector<*>" />
<class pattern="__gnu_cxx::__normal_iterator<*>" />
<class pattern="__gnu_cxx::new_allocator<*>" />
@@ -12,4 +14,7 @@
<class name="just_a_class" />
+ <class name="std::string" />
+ <class name="stringy_class" />
+
</lcgdict>
diff --git a/pypy/module/cppyy/test/test_overloads.py b/pypy/module/cppyy/test/test_overloads.py
--- a/pypy/module/cppyy/test/test_overloads.py
+++ b/pypy/module/cppyy/test/test_overloads.py
@@ -86,10 +86,10 @@
cc_ol = cppyy.gbl.cc_ol
# dd_ol = cppyy.gbl.dd_ol
- assert more_overloads().call(aa_ol()).c_str() == "aa_ol"
-# assert more_overloads().call(bb_ol()).c_str() == "dd_ol" # <- bb_ol has an unknown + void*
- assert more_overloads().call(cc_ol()).c_str() == "cc_ol"
-# assert more_overloads().call(dd_ol()).c_str() == "dd_ol" # <- dd_ol has an unknown
+ assert more_overloads().call(aa_ol()) == "aa_ol"
+# assert more_overloads().call(bb_ol()) == "dd_ol" # <- bb_ol has an unknown + void*
+ assert more_overloads().call(cc_ol()) == "cc_ol"
+# assert more_overloads().call(dd_ol()) == "dd_ol" # <- dd_ol has an unknown
def test04_fully_fragile_overloads(self):
"""Test that unknown* is preferred over unknown&"""
@@ -130,7 +130,7 @@
import cppyy
more_overloads = cppyy.gbl.more_overloads
-# assert more_overloads().call(1).c_str() == "int"
-# assert more_overloads().call(1.).c_str() == "double"
- assert more_overloads().call1(1).c_str() == "int"
- assert more_overloads().call1(1.).c_str() == "double"
+# assert more_overloads().call(1) == "int"
+# assert more_overloads().call(1.) == "double"
+ assert more_overloads().call1(1) == "int"
+ assert more_overloads().call1(1.) == "double"
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -253,9 +253,9 @@
# NOTE: when called through the stub, default args are fine
f = a.stringRef
s = cppyy.gbl.std.string
- assert f(s("aap"), 0, s("noot")).c_str() == "aap"
- assert f(s("noot"), 1).c_str() == "default"
- assert f(s("mies")).c_str() == "mies"
+ assert f(s("aap"), 0, s("noot")) == "aap"
+ assert f(s("noot"), 1) == "default"
+ assert f(s("mies")) == "mies"
for itype in ['short', 'ushort', 'int', 'uint', 'long', 'ulong']:
g = getattr(a, '%sValue' % itype)
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -14,13 +14,13 @@
if err:
raise OSError("'make' failed (see stderr)")
-class AppTestSTL:
+class AppTestSTLVECTOR:
def setup_class(cls):
cls.space = space
env = os.environ
cls.w_N = space.wrap(13)
cls.w_test_dct = space.wrap(test_dct)
- cls.w_datatypes = cls.space.appexec([], """():
+ cls.w_stlvector = cls.space.appexec([], """():
import cppyy
return cppyy.load_reflection_info(%r)""" % (test_dct, ))
@@ -129,3 +129,83 @@
assert list(v) == [i for i in range(self.N)]
v.destruct()
+
+
+class AppTestSTLSTRING:
+ def setup_class(cls):
+ cls.space = space
+ env = os.environ
+ cls.w_test_dct = space.wrap(test_dct)
+ cls.w_stlstring = cls.space.appexec([], """():
+ import cppyy
+ return cppyy.load_reflection_info(%r)""" % (test_dct, ))
+
+ def test01_string_argument_passing(self):
+ """Test mapping of python strings and std::string"""
+
+ import cppyy
+ std = cppyy.gbl.std
+ stringy_class = cppyy.gbl.stringy_class
+
+ c, s = stringy_class(""), std.string("test1")
+
+ # pass through const std::string&
+ c.set_string1(s)
+ assert c.get_string1() == s
+
+ return
+
+ c.set_string1("test2")
+ assert c.get_string1() == "test2"
+
+ # pass through std::string (by value)
+ s = std.string("test3")
+ c.set_string2(s)
+ assert c.get_string1() == s
+
+ c.set_string2("test4")
+ assert c.get_string1() == "test4"
+
+ # getting through std::string&
+ s2 = std.string()
+ c.get_string2(s2)
+ assert s2 == "test4"
+
+ raises(TypeError, c.get_string2, "temp string")
+
+ def test02_string_data_ccess(self):
+ """Test access to std::string object data members"""
+
+ import cppyy
+ std = cppyy.gbl.std
+ stringy_class = cppyy.gbl.stringy_class
+
+ return
+
+ c, s = stringy_class(""), std.string("test string")
+
+ c.m_string = s
+ assert c.m_string == s
+ assert c.get_string1() == s
+
+ c.m_string = "another test"
+ assert c.m_string == "another test"
+ assert c.get_string1() == "another test"
+
+ def test03_string_with_null_character(self):
+ """Test that strings with NULL do not get truncated"""
+
+ import cppyy
+ std = cppyy.gbl.std
+ stringy_class = cppyy.gbl.stringy_class
+
+ return
+
+ t0 = "aap\0noot"
+ self.assertEqual(t0, "aap\0noot")
+
+ c, s = stringy_class(""), std.string(t0, len(t0))
+
+ c.set_string1(s)
+ assert t0 == c.get_string1()
+ assert s == c.get_string1()
More information about the pypy-commit
mailing list