[pypy-commit] pypy reflex-support: o) test for defaults of builtin types
wlav
noreply at buildbot.pypy.org
Wed Jul 11 09:28:21 CEST 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r56021:d65a7f633e38
Date: 2012-07-10 15:53 -0700
http://bitbucket.org/pypy/pypy/changeset/d65a7f633e38/
Log: o) test for defaults of builtin types o) tests for vector of double
o) DoubleRefExecutor, following the lines of the IntRef one o)
refactoring of executor.py
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
@@ -68,9 +68,25 @@
return space.w_None
+class NumericExecutorMixin(object):
+ _mixin_ = True
+ _immutable_ = True
+
+ def _wrap_result(self, space, result):
+ return space.wrap(rffi.cast(self.c_type, result))
+
+ def execute(self, space, cppmethod, cppthis, num_args, args):
+ result = self.c_stubcall(cppmethod, cppthis, num_args, args)
+ return self._wrap_result(space, result)
+
+ def execute_libffi(self, space, libffifunc, argchain):
+ result = libffifunc.call(argchain, self.c_type)
+ return space.wrap(result)
+
+
class BoolExecutor(FunctionExecutor):
_immutable_ = True
- libffitype = libffi.types.schar
+ libffitype = libffi.types.schar
def execute(self, space, cppmethod, cppthis, num_args, args):
result = capi.c_call_b(cppmethod, cppthis, num_args, args)
@@ -80,112 +96,6 @@
result = libffifunc.call(argchain, rffi.CHAR)
return space.wrap(bool(ord(result)))
-class CharExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.schar
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_c(cppmethod, cppthis, num_args, args)
- return space.wrap(result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.CHAR)
- return space.wrap(result)
-
-class ShortExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.sshort
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_h(cppmethod, cppthis, num_args, args)
- return space.wrap(result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.SHORT)
- return space.wrap(result)
-
-class IntExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.sint
-
- def _wrap_result(self, space, result):
- return space.wrap(result)
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_i(cppmethod, cppthis, num_args, args)
- return self._wrap_result(space, result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.INT)
- return space.wrap(result)
-
-class UnsignedIntExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.uint
-
- def _wrap_result(self, space, result):
- return space.wrap(rffi.cast(rffi.UINT, result))
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_l(cppmethod, cppthis, num_args, args)
- return self._wrap_result(space, result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.UINT)
- return space.wrap(result)
-
-class LongExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.slong
-
- def _wrap_result(self, space, result):
- return space.wrap(result)
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_l(cppmethod, cppthis, num_args, args)
- return self._wrap_result(space, result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.LONG)
- return space.wrap(result)
-
-class UnsignedLongExecutor(LongExecutor):
- _immutable_ = True
- libffitype = libffi.types.ulong
-
- def _wrap_result(self, space, result):
- return space.wrap(rffi.cast(rffi.ULONG, result))
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.ULONG)
- return space.wrap(result)
-
-class LongLongExecutor(FunctionExecutor):
- _immutable_ = True
- libffitype = libffi.types.sint64
-
- def _wrap_result(self, space, result):
- return space.wrap(result)
-
- def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_ll(cppmethod, cppthis, num_args, args)
- return self._wrap_result(space, result)
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.LONGLONG)
- return space.wrap(result)
-
-class UnsignedLongLongExecutor(LongLongExecutor):
- _immutable_ = True
- libffitype = libffi.types.uint64
-
- def _wrap_result(self, space, result):
- return space.wrap(rffi.cast(rffi.ULONGLONG, result))
-
- def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.ULONGLONG)
- return space.wrap(result)
-
class ConstIntRefExecutor(FunctionExecutor):
_immutable_ = True
libffitype = libffi.types.pointer
@@ -252,17 +162,31 @@
result = libffifunc.call(argchain, rffi.FLOAT)
return space.wrap(float(result))
-class DoubleExecutor(FunctionExecutor):
+class DoubleRefExecutor(FunctionExecutor):
_immutable_ = True
- libffitype = libffi.types.double
+ libffitype = libffi.types.pointer
+
+ def __init__(self, space, extra):
+ FunctionExecutor.__init__(self, space, extra)
+ self.do_assign = False
+ self.item = rffi.cast(rffi.DOUBLE, 0)
+
+ def set_item(self, space, w_item):
+ self.item = rffi.cast(rffi.DOUBLE, space.float_w(w_item))
+ self.do_assign = True
+
+ def _wrap_result(self, space, dptr):
+ if self.do_assign:
+ dptr[0] = self.item
+ return space.wrap(dptr[0]) # all paths, for rtyper
def execute(self, space, cppmethod, cppthis, num_args, args):
- result = capi.c_call_d(cppmethod, cppthis, num_args, args)
- return space.wrap(result)
+ result = rffi.cast(rffi.DOUBLEP, capi.c_call_r(cppmethod, cppthis, num_args, args))
+ return self._wrap_result(space, result)
def execute_libffi(self, space, libffifunc, argchain):
- result = libffifunc.call(argchain, rffi.DOUBLE)
- return space.wrap(result)
+ result = libffifunc.call(argchain, rffi.DOUBLEP)
+ return self._wrap_result(space, result)
class CStringExecutor(FunctionExecutor):
@@ -420,7 +344,7 @@
elif compound == "**" or compound == "*&":
return InstancePtrPtrExecutor(space, cppclass)
elif capi.c_is_enum(clean_name):
- return UnsignedIntExecutor(space, None)
+ return _executors['unsigned int'](space, None)
# 4) additional special cases
# ... none for now
@@ -432,20 +356,11 @@
_executors["void"] = VoidExecutor
_executors["void*"] = PtrTypeExecutor
_executors["bool"] = BoolExecutor
-_executors["char"] = CharExecutor
_executors["const char*"] = CStringExecutor
-_executors["short"] = ShortExecutor
-_executors["unsigned short"] = ShortExecutor
-_executors["int"] = IntExecutor
_executors["const int&"] = ConstIntRefExecutor
_executors["int&"] = IntRefExecutor
-_executors["unsigned"] = UnsignedIntExecutor
-_executors["long"] = LongExecutor
-_executors["unsigned long"] = UnsignedLongExecutor
-_executors["long long"] = LongLongExecutor
-_executors["unsigned long long"] = UnsignedLongLongExecutor
_executors["float"] = FloatExecutor
-_executors["double"] = DoubleExecutor
+_executors["double&"] = DoubleRefExecutor
_executors["constructor"] = ConstructorExecutor
@@ -454,24 +369,37 @@
_executors["PyObject*"] = PyObjectExecutor
+# add basic (builtin) executors
+def _build_basic_executors():
+ "NOT_RPYTHON"
+ type_info = (
+ (rffi.CHAR, libffi.types.schar, capi.c_call_c, ("char", "unsigned char")),
+ (rffi.SHORT, libffi.types.sshort, capi.c_call_h, ("short", "short int", "unsigned short", "unsigned short int")),
+ (rffi.INT, libffi.types.sint, capi.c_call_i, ("int",)),
+ (rffi.UINT, libffi.types.uint, capi.c_call_l, ("unsigned", "unsigned int")),
+ (rffi.LONG, libffi.types.slong, capi.c_call_l, ("long", "long int")),
+ (rffi.ULONG, libffi.types.ulong, capi.c_call_l, ("unsigned long", "unsigned long int")),
+ (rffi.LONGLONG, libffi.types.sint64, capi.c_call_ll, ("long long", "long long int")),
+ (rffi.ULONGLONG, libffi.types.uint64, capi.c_call_ll, ("unsigned long long", "unsigned long long int")),
+ (rffi.DOUBLE, libffi.types.double, capi.c_call_d, ("double",))
+ )
+
+ for t_rffi, t_ffi, stub, names in type_info:
+ class BasicExecutor(NumericExecutorMixin, FunctionExecutor):
+ _immutable_ = True
+ libffitype = t_ffi
+ c_type = t_rffi
+ c_stubcall = staticmethod(stub)
+ for name in names:
+ _executors[name] = BasicExecutor
+_build_basic_executors()
+
# add the set of aliased names
def _add_aliased_executors():
"NOT_RPYTHON"
alias_info = (
- ("char", ("unsigned char",)),
-
- ("short", ("short int",)),
- ("unsigned short", ("unsigned short int",)),
- ("unsigned", ("unsigned int",)),
- ("long", ("long int",)),
- ("unsigned long", ("unsigned long int",)),
- ("long long", ("long long int",)),
- ("unsigned long long", ("unsigned long long int",)),
-
("const char*", ("char*",)),
-
("std::basic_string<char>", ("string",)),
-
("PyObject*", ("_object*",)),
)
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
@@ -2,11 +2,20 @@
// for testing of default arguments
-defaulter::defaulter(int a, int b, int c ) {
- m_a = a;
- m_b = b;
- m_c = c;
+#define IMPLEMENT_DEFAULTER_CLASS(type, tname) \
+tname##_defaulter::tname##_defaulter(type a, type b, type c) { \
+ m_a = a; m_b = b; m_c = c; \
}
+IMPLEMENT_DEFAULTER_CLASS(short, short)
+IMPLEMENT_DEFAULTER_CLASS(unsigned short, ushort)
+IMPLEMENT_DEFAULTER_CLASS(int, int)
+IMPLEMENT_DEFAULTER_CLASS(unsigned, uint)
+IMPLEMENT_DEFAULTER_CLASS(long, long)
+IMPLEMENT_DEFAULTER_CLASS(unsigned long, ulong)
+IMPLEMENT_DEFAULTER_CLASS(long long, llong)
+IMPLEMENT_DEFAULTER_CLASS(unsigned long long, ullong)
+IMPLEMENT_DEFAULTER_CLASS(float, float)
+IMPLEMENT_DEFAULTER_CLASS(double, double)
// for esoteric inheritance testing
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
@@ -2,13 +2,24 @@
//===========================================================================
-class defaulter { // for testing of default arguments
-public:
- defaulter(int a = 11, int b = 22, int c = 33 );
-
-public:
- int m_a, m_b, m_c;
+#define DECLARE_DEFAULTER_CLASS(type, tname) \
+class tname##_defaulter { \
+public: \
+ tname##_defaulter(type a = 11, type b = 22, type c = 33); \
+ \
+public: \
+ type m_a, m_b, m_c; \
};
+DECLARE_DEFAULTER_CLASS(short, short) // for testing of default arguments
+DECLARE_DEFAULTER_CLASS(unsigned short, ushort)
+DECLARE_DEFAULTER_CLASS(int, int)
+DECLARE_DEFAULTER_CLASS(unsigned, uint)
+DECLARE_DEFAULTER_CLASS(long, long)
+DECLARE_DEFAULTER_CLASS(unsigned long, ulong)
+DECLARE_DEFAULTER_CLASS(long long, llong)
+DECLARE_DEFAULTER_CLASS(unsigned long long, ullong)
+DECLARE_DEFAULTER_CLASS(float, float)
+DECLARE_DEFAULTER_CLASS(double, double)
//===========================================================================
diff --git a/pypy/module/cppyy/test/advancedcpp.xml b/pypy/module/cppyy/test/advancedcpp.xml
--- a/pypy/module/cppyy/test/advancedcpp.xml
+++ b/pypy/module/cppyy/test/advancedcpp.xml
@@ -1,6 +1,6 @@
<lcgdict>
- <class name="defaulter" />
+ <class pattern="*_defaulter" />
<class name="base_class" />
<class name="derived_class" />
diff --git a/pypy/module/cppyy/test/advancedcpp_LinkDef.h b/pypy/module/cppyy/test/advancedcpp_LinkDef.h
--- a/pypy/module/cppyy/test/advancedcpp_LinkDef.h
+++ b/pypy/module/cppyy/test/advancedcpp_LinkDef.h
@@ -4,7 +4,16 @@
#pragma link off all classes;
#pragma link off all functions;
-#pragma link C++ class defaulter;
+#pragma link C++ class short_defaulter;
+#pragma link C++ class ushort_defaulter;
+#pragma link C++ class int_defaulter;
+#pragma link C++ class uint_defaulter;
+#pragma link C++ class long_defaulter;
+#pragma link C++ class ulong_defaulter;
+#pragma link C++ class llong_defaulter;
+#pragma link C++ class ullong_defaulter;
+#pragma link C++ class float_defaulter;
+#pragma link C++ class double_defaulter;
#pragma link C++ class base_class;
#pragma link C++ class derived_class;
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
@@ -14,6 +14,7 @@
//- explicit instantiations of used types
STLTYPES_EXPLICIT_INSTANTIATION(vector, int)
+STLTYPES_EXPLICIT_INSTANTIATION(vector, double)
STLTYPES_EXPLICIT_INSTANTIATION(vector, just_a_class)
//- class with lots of std::string handling
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,6 +25,7 @@
#ifndef __CINT__
//- explicit instantiations of used types
STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, int)
+STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, double)
STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, just_a_class)
#endif
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
@@ -31,31 +31,42 @@
"""Test usage of default arguments"""
import cppyy
- defaulter = cppyy.gbl.defaulter
+ def test_defaulter(n, t):
+ defaulter = getattr(cppyy.gbl, '%s_defaulter' % n)
- d = defaulter()
- assert d.m_a == 11
- assert d.m_b == 22
- assert d.m_c == 33
- d.destruct()
+ d = defaulter()
+ assert d.m_a == t(11)
+ assert d.m_b == t(22)
+ assert d.m_c == t(33)
+ d.destruct()
- d = defaulter(0)
- assert d.m_a == 0
- assert d.m_b == 22
- assert d.m_c == 33
- d.destruct()
+ d = defaulter(0)
+ assert d.m_a == t(0)
+ assert d.m_b == t(22)
+ assert d.m_c == t(33)
+ d.destruct()
- d = defaulter(1, 2)
- assert d.m_a == 1
- assert d.m_b == 2
- assert d.m_c == 33
- d.destruct()
+ d = defaulter(1, 2)
+ assert d.m_a == t(1)
+ assert d.m_b == t(2)
+ assert d.m_c == t(33)
+ d.destruct()
- d = defaulter(3, 4, 5)
- assert d.m_a == 3
- assert d.m_b == 4
- assert d.m_c == 5
- d.destruct()
+ d = defaulter(3, 4, 5)
+ assert d.m_a == t(3)
+ assert d.m_b == t(4)
+ assert d.m_c == t(5)
+ d.destruct()
+ test_defaulter('short', int)
+ test_defaulter('ushort', int)
+ test_defaulter('int', int)
+ test_defaulter('uint', int)
+ test_defaulter('long', long)
+ test_defaulter('ulong', long)
+ test_defaulter('llong', long)
+ test_defaulter('ullong', long)
+ test_defaulter('float', float)
+ test_defaulter('double', float)
def test02_simple_inheritance(self):
"""Test binding of a basic inheritance structure"""
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
@@ -26,7 +26,7 @@
func, = adddouble.functions
assert func.executor is None
func._setup(None) # creates executor
- assert isinstance(func.executor, executor.DoubleExecutor)
+ assert isinstance(func.executor, executor._executors['double'])
assert func.arg_defs == [("double", "")]
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
@@ -24,8 +24,8 @@
import cppyy
return cppyy.load_reflection_info(%r)""" % (test_dct, ))
- def test01_builtin_type_vector_type(self):
- """Test access to an std::vector<int>"""
+ def test01_builtin_type_vector_types(self):
+ """Test access to std::vector<int>/std::vector<double>"""
import cppyy
@@ -34,46 +34,54 @@
assert callable(cppyy.gbl.std.vector)
- tv1 = getattr(cppyy.gbl.std, 'vector<int>')
- tv2 = cppyy.gbl.std.vector('int')
+ tv1i = getattr(cppyy.gbl.std, 'vector<int>')
+ tv2i = cppyy.gbl.std.vector(int)
+ assert tv1i is tv2i
+ assert cppyy.gbl.std.vector(int).iterator is cppyy.gbl.std.vector('int').iterator
- assert tv1 is tv2
-
- assert cppyy.gbl.std.vector(int).iterator is cppyy.gbl.std.vector(int).iterator
+ tv1d = getattr(cppyy.gbl.std, 'vector<double>')
+ tv2d = cppyy.gbl.std.vector('double')
+ assert tv1d is tv2d
+ assert tv1d.iterator is cppyy.gbl.std.vector('double').iterator
#-----
- v = tv1(self.N)
- assert v.begin().__eq__(v.begin())
- assert v.begin() == v.begin()
- assert v.end() == v.end()
- assert v.begin() != v.end()
- assert v.end() != v.begin()
+ vi = tv1i(self.N)
+ vd = tv1d(); vd += range(self.N) # default args from Reflex are useless :/
+ def test_v(v):
+ assert v.begin().__eq__(v.begin())
+ assert v.begin() == v.begin()
+ assert v.end() == v.end()
+ assert v.begin() != v.end()
+ assert v.end() != v.begin()
+ test_v(vi)
+ test_v(vd)
#-----
- for i in range(self.N):
- v[i] = i
- assert v[i] == i
- assert v.at(i) == i
- pass
+ def test_v(v):
+ for i in range(self.N):
+ v[i] = i
+ assert v[i] == i
+ assert v.at(i) == i
- assert v.size() == self.N
- assert len(v) == self.N
- v.destruct()
+ assert v.size() == self.N
+ assert len(v) == self.N
+ test_v(vi)
+ test_v(vd)
#-----
- v = tv1()
- for i in range(self.N):
- v.push_back(i)
- assert v.size() == i+1
- assert v.at(i) == i
- assert v[i] == i
+ vi = tv1i()
+ vd = tv1d()
+ def test_v(v):
+ for i in range(self.N):
+ v.push_back(i)
+ assert v.size() == i+1
+ assert v.at(i) == i
+ assert v[i] == i
- return
-
- assert v.size() == self.N
- assert len(v) == self.N
- v.destruct()
-
+ assert v.size() == self.N
+ assert len(v) == self.N
+ test_v(vi)
+ test_v(vd)
def test02_user_type_vector_type(self):
"""Test access to an std::vector<just_a_class>"""
More information about the pypy-commit
mailing list