[C++-sig] indexing suite and py++

Michał Nowotka mmmnow at gmail.com
Wed Apr 8 13:24:56 CEST 2009


Hello,

I want to expose following classes:

class A
{
public:
	A(int a, int b)
	:a_(a),b_(b)
	{}
	int a_;
	int b_;

int compute(){return a_ + b_;}

};

class C : public A
{

public:

	C(int a, int b)
	:A(a,b){}
};

struct TypeExposer // I have to add this class, otherwise Py++ won't
expose std::deque<C> - why?
{
	typedef std::deque<C> CDeque;
	CDeque deq;
};

class F :  public std::deque<C>
{
	public:
		F(){}
		int dlugosc() {return this->size();}	
};

In order to expose I use Py++ with indexing_suite_version = 2
parameter. Py++ generates code for boost.python without any warnings
and generated code compiles well.
But then in python I get TypeError:

import test
c = test.C(2,3)
f = test.F()
f.append(c)
f[0]

this causes:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: C

When class C is base class everything works well. What should I change
to get this code working with derived classes?

And another problem - why do I have to define TypeExposer class? Now i
must define it because otherwise Py++ won't expose std::deque<C>. But
IMO it should notice that F dirives from std::deque<C> so
std::deque<C> must be exposed...

Below I paste Py++ and Py++-generated code:

import os
from pyplusplus import module_builder
from pygccxml import utils
from pygccxml.declarations import matchers
from pyplusplus.module_builder import call_policies

mb = module_builder.module_builder_t( [r"test.h"]
                                      ,
gccxml_path=r"./bin_gccxml/gccxml --gccxml-compiler gcc-4.3"
                                      , working_directory=r"."
                                      , include_paths=['.']
                                      , define_symbols=[]
				      , indexing_suite_version = 2)

mb.build_code_creator( module_name='test' )

mb.code_creator.precompiled_header = 'boost/python.hpp'

mb.write_module( 'test.cpp' )

//////////////////////////////////////////////////////////////////////////////////////////////

// This file has been generated by Py++.

#include "boost/python.hpp"

#include "indexing_suite/value_traits.hpp"

#include "indexing_suite/container_suite.hpp"

#include "indexing_suite/deque.hpp"

#include "test.h"

namespace bp = boost::python;

namespace boost { namespace python { namespace indexing {

template<>
struct value_traits< C >{

    static bool const equality_comparable = false;


    static bool const less_than_comparable = false;


    template<typename PythonClass, typename Policy>
    static void visit_container_class(PythonClass &, Policy const &){

    }

};

}/*indexing*/ } /*python*/ } /*boost*/

BOOST_PYTHON_MODULE(test){
    { //::std::deque< C >
        typedef bp::class_< std::deque< C > > CDeque_exposer_t;
        CDeque_exposer_t CDeque_exposer = CDeque_exposer_t( "CDeque" );
        bp::scope CDeque_scope( CDeque_exposer );
        CDeque_exposer.def( bp::indexing::deque_suite< std::deque< C > >() );
    }

    bp::class_< A >( "A", bp::init< int, int >(( bp::arg("a"),
bp::arg("b") )) )
        .def(
            "compute"
            , (int ( ::A::* )(  ) )( &::A::compute ) )
        .def_readwrite( "a_", &A::a_ )
        .def_readwrite( "b_", &A::b_ );

    bp::class_< C, bp::bases< A >, boost::noncopyable >( "C",
bp::init< int, int >(( bp::arg("a"), bp::arg("b") )) );

    bp::class_< F, bp::bases< std::deque< C > >, boost::noncopyable >(
"F", bp::init< >() )
        .def(
            "dlugosc"
            , (int ( ::F::* )(  ) )( &::F::dlugosc ) );

    bp::class_< TypeExposer, boost::noncopyable >( "TypeExposer",
bp::no_init )
        .def_readwrite( "deq", &TypeExposer::deq );
}
-- 
Regards,

Michał Nowotka


More information about the Cplusplus-sig mailing list