[pypy-commit] pypy reflex-support: allow default arguments and test cleanup

wlav noreply at buildbot.pypy.org
Thu Jun 30 01:25:15 CEST 2011


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r45190:362db21b87c0
Date: 2011-06-28 13:06 -0700
http://bitbucket.org/pypy/pypy/changeset/362db21b87c0/

Log:	allow default arguments and test cleanup

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
@@ -132,6 +132,10 @@
     "cppyy_method_num_args",
     [C_TYPEHANDLE, rffi.INT], rffi.INT,
     compilation_info=eci)
+c_method_req_args = rffi.llexternal(
+    "cppyy_method_req_args",
+    [C_TYPEHANDLE, rffi.INT], rffi.INT,
+    compilation_info=eci)
 c_method_arg_type = rffi.llexternal(
     "cppyy_method_arg_type",
     [C_TYPEHANDLE, rffi.INT, rffi.INT], rffi.CCHARP,
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
@@ -42,6 +42,7 @@
     char* cppyy_method_name(cppyy_typehandle_t handle, int method_index);
     char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index);
     int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index);
+    int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index);
     char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int index);
 
     /* method properties */
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
@@ -87,11 +87,12 @@
     _immutable_ = True
     _immutable_fields_ = ["arg_types[*]", "arg_converters[*]"]
     
-    def __init__(self, cpptype, method_index, result_type, arg_types):
+    def __init__(self, cpptype, method_index, result_type, arg_types, args_required):
         self.cpptype = cpptype
         self.space = cpptype.space
         self.method_index = method_index
         self.arg_types = arg_types
+        self.args_required = args_required
         self.executor = executor.get_executor(self.space, result_type)
         self.arg_converters = None
         methgetter = get_methptr_getter(self.cpptype.handle,
@@ -113,13 +114,13 @@
         try:
             return self.executor.execute(self.space, self, cppthis, len(args_w), args)
         finally:
-            self.free_arguments(args)
+            self.free_arguments(args, len(args_w))
 
     @jit.unroll_safe
     def do_fast_call(self, cppthis, args_w):
         space = self.space
         # XXX factor out
-        if len(args_w) != len(self.arg_types):
+        if len(self.arg_types) < len(args_w) or len(args_w) < self.args_required:
             raise OperationError(space.w_TypeError, space.wrap("wrong number of args"))
         if self.arg_converters is None:
             self._build_converters()
@@ -161,7 +162,7 @@
     @jit.unroll_safe
     def prepare_arguments(self, args_w):
         space = self.space
-        if len(args_w) != len(self.arg_types):
+        if len(self.arg_types) < len(args_w) or len(args_w) < self.args_required:
             raise OperationError(space.w_TypeError, space.wrap("wrong number of args"))
         if self.arg_converters is None:
             self._build_converters()
@@ -182,8 +183,8 @@
         return args
 
     @jit.unroll_safe
-    def free_arguments(self, args):
-        for i in range(len(self.arg_types)):
+    def free_arguments(self, args, nargs):
+        for i in range(nargs):
             conv = self.arg_converters[i]
             conv.free_argument(args[i])
         lltype.free(args, flavor='raw')
@@ -209,7 +210,7 @@
             return self.executor.execute(self.space, self, NULL_VOIDP,
                                          len(args_w), args)
         finally:
-            self.free_arguments(args)
+            self.free_arguments(args, len(args_w))
  
 
 class CPPConstructor(CPPMethod):
@@ -393,10 +394,12 @@
     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)
+        args_required = capi.c_method_req_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)
+            argtypes.append(argtype)
+        return CPPFunction(self, method_index, result_type, argtypes, args_required)
 
     def _find_data_members(self):
         num_data_members = capi.c_num_data_members(self.handle)
@@ -425,6 +428,7 @@
     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)
+        args_required = capi.c_method_req_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))
@@ -435,7 +439,7 @@
             cls = CPPFunction
         else:
             cls = CPPMethod
-        return cls(self, method_index, result_type, argtypes)
+        return cls(self, method_index, result_type, argtypes, args_required)
 
     def _find_data_members(self):
         num_data_members = capi.c_num_data_members(self.handle)
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
@@ -194,6 +194,12 @@
     return m.FunctionParameterSize();
 }
 
+int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index) {
+    Reflex::Scope s = scope_from_handle(handle);
+    Reflex::Member m = s.FunctionMemberAt(method_index);
+    return m.FunctionParameterSize(true);
+}
+
 char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int arg_index) {
     Reflex::Scope s = scope_from_handle(handle);
     Reflex::Member m = s.FunctionMemberAt(method_index);
@@ -236,9 +242,6 @@
     return cppstring_to_cstring(name);
 }
 
-static void* fgFakeObject  = 0;
-static void* fgFakeAddress = &fgFakeObject;
-
 size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index) {
     Reflex::Scope s = scope_from_handle(handle);
     Reflex::Member m = s.DataMemberAt(data_member_index, Reflex::INHERITEDMEMBERS_ALSO);
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
@@ -1,6 +1,14 @@
 #include "advancedcpp.h"
 
 
+// for testing of default arguments
+defaulter::defaulter(int a, int b, int c ) {
+   m_a = a;
+   m_b = b;
+   m_c = c;
+}
+
+
 // for esoteric inheritance testing
 int get_a( a_class& a ) { return a.m_a; }
 int get_b( b_class& b ) { return b.m_b; }
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,6 +2,16 @@
 
 
 //===========================================================================
+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;
+};
+
+
+//===========================================================================
 class base_class {                 // for simple inheritance testing
 public:
    base_class() { m_b = 1; m_db = 1.1; }
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,5 +1,7 @@
 <lcgdict>
 
+  <class name="defaulter" />
+
   <class name="base_class" />
   <class name="derived_class" />
 
diff --git a/pypy/module/cppyy/test/example01.cxx b/pypy/module/cppyy/test/example01.cxx
--- a/pypy/module/cppyy/test/example01.cxx
+++ b/pypy/module/cppyy/test/example01.cxx
@@ -34,7 +34,7 @@
     count--;
 }
 
-// class methods
+// class-level methods
 int example01::staticAddOneToInt(int a) {
     return a + 1;
 }
@@ -98,4 +98,5 @@
     return p;
 }
 
+// class-level data
 int example01::count = 0;
diff --git a/pypy/module/cppyy/test/example01.h b/pypy/module/cppyy/test/example01.h
--- a/pypy/module/cppyy/test/example01.h
+++ b/pypy/module/cppyy/test/example01.h
@@ -13,16 +13,13 @@
 
 class example01 {
 public:
-    static int count;
-    int m_somedata;
-
     example01();
     example01(int a);
     example01(const example01& e);
     example01& operator=(const example01& e);
     ~example01();
 
-// class methods
+public:        // class-level methods
     static int staticAddOneToInt(int a);
     static int staticAddOneToInt(int a, int b);
     static double staticAddToDouble(double a);
@@ -32,7 +29,7 @@
     static payload* staticCyclePayload(payload* p, double d);
     static int getCount();
 
-// instance methods
+public:        // instance methods
     int addDataToInt(int a);
     double addDataToDouble(double a);
     int addDataToAtoi(const char* str);
@@ -40,4 +37,10 @@
 
     void setPayload(payload* p);
     payload* cyclePayload(payload* p);
+
+public:        // class-level data
+    static int count;
+
+public:        // instance data
+    int m_somedata;
 };
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,37 @@
             import cppyy
             return cppyy.load_lib(%r)""" % (shared_lib, ))
 
-    def test01_simple_inheritance(self):
+    def test01_default_argeumetns(self):
+        """Test usage of default arguments"""
+
+        import cppyy
+        defaulter = cppyy.gbl.defaulter
+
+        d = defaulter()
+        assert d.m_a == 11
+        assert d.m_b == 22
+        assert d.m_c == 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(1, 2)
+        assert d.m_a ==  1
+        assert d.m_b ==  2
+        assert d.m_c == 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()
+
+    def test02_simple_inheritance(self):
         """Test binding of a basic inheritance structure"""
 
         import cppyy
@@ -77,7 +107,7 @@
 
         d.destruct()
 
-    def test02_namespaces(self):
+    def test03_namespaces(self):
         """Test access to namespaces and inner classes"""
 
         import cppyy
@@ -101,7 +131,7 @@
         assert gbl.a_ns.d_ns.e_class         is gbl.a_ns.d_ns.e_class
         assert gbl.a_ns.d_ns.e_class.f_class is gbl.a_ns.d_ns.e_class.f_class
 
-    def test03_template_types(self):
+    def test04_template_types(self):
         """Test bindings of templated types"""
 
         import cppyy
@@ -139,7 +169,7 @@
         assert t1.value() == 111
         t1.destruct()
 
-    def test04_abstract_classes(self):
+    def test05_abstract_classes(self):
         """Test non-instatiatability of abstract classes"""
 
         import cppyy
@@ -154,7 +184,7 @@
         assert isinstance(c, gbl.some_concrete_class)
         assert isinstance(c, gbl.some_abstract_class)
 
-    def test05_data_members(self):
+    def test06_data_members(self):
         """Test data member access when using virtual inheritence"""
 
         import cppyy
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
@@ -40,6 +40,18 @@
         assert tv1 is tv2
 
         #-----
+        v = tv1(self.N)
+        for i in range(self.N):
+          #  v[i] = i
+          #  assert v[i] == i
+          #  assert v.at(i) == i
+            pass
+
+        assert v.size() == self.N
+        assert len(v) == self.N
+        v.destruct()
+
+        #-----
         v = tv1()
         for i in range(self.N):
             v.push_back(i)


More information about the pypy-commit mailing list