[C++-sig] [Py++] First imressions

Kirill Lapshin kir at lapshin.net
Tue Sep 5 17:28:05 CEST 2006


Hello,

Recently I was charged with exposing our project to Python, and 
naturally went to Boost.Python documentation. After digging a bit, 
learning, etc, I decided to give some code generator a try -- so the 
choice was Pyste or Py++. I've decided to try the latter one first, 
since it seems to have quite powerful query language, and was offering a 
promise of doing certain operations in bulk. Another reason was that 
Py++ is actively maintained. Long story short, I dived in, and I haven't 
look back. I am quite happy with progress, albeit the initial 
development is not finished yet, so it is not a success story yet, but I 
am quite confident it will become one quite soon.

I would like to thank Roman for his hard work on Py++ and for being 
extremely helpful in our private e-mail discussion.

Just for the record I would like to post some of the problems I had and 
the way they were resolved.


1. The way overrides are generated does not compile on MSVC8 (2005). 
Looks like the problem is in conversion of return type if return type is 
bool or enum. For example


virtual bool is_representative( ) const {
bp::override func_is_representative = this->get_override(
"is_representative" );
return func_is_representative( ); // errors out
}

error C2440: 'return' : cannot convert from
'boost::python::detail::method_result' to 'bool'
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called

Don't know why is this happening, but the good news, there is a 
workaround. One can use explicit conversion of return type, i.e.

return func_is_representative()..as(&boost::type<T>());

If someone could verify this problem, I guess the solution would be to 
patch code creator.


2. How to disable function overriding.

I don't really need ability to override virtual functions from Python 
anyway, and moreover using wrapper classes does not seem to work for me, 
since I am trying to expose abstract interfaces to python and hide 
concrete implementations (hence wrapper is abstract as well and can't be 
instantiated). Maybe there is still a way to expose it with wrapper, but 
I've decided not bother for now.

Roman suggested following way to suppress overriding:


from pygccxml import declarations

members = cls.decls( declarations.virtuality_type_matcher( 
declarations.VIRTUALITY_TYPES.VIRTUAL )
                                 , decl_type=pd.member_calldef_t
                                 , allow_empty=True)
members.set_virtuality( declarations.VIRTUALITY_TYPES.NOT_VIRTUAL )


Note that Py++ differentiates between VIRTUAL and PURE_VIRTUAL, so above 
listed code does not cover pure virtual functions.

3. Observation: Py++ generates wrappers even if there is no virtual 
functions, but there is nested class/struct. Nested enums are Ok.

4. Gccxml is buggy, especially with respect to default arguments. See 
http://language-binding.net/pygccxml/design.html#patchers. In my case I 
had problems with default std::vector<T> arguments. Those can be worked 
around manually with

mb = module_builder_t( ... )
Foo = mb.class_( 'Foo' )
Foo_constructor = Foo.constructor( select write constructor )
#help: http://language-binding.net/pygccxml/query_interface.html

Foo_constructor.arguments[0].default_value = fixed default value

5. Precompiled header support is not implemented even though 
documentation claims it is. Roman says it is in works. For a meantime 
one can use following workaround:

mb.code_creator.adopt_creator(
code_creators.include_t(header='_pch.hpp'), 0)
md.split_module(...)

6. shared_ptr<T> works out of the box, while shared_ptr<const T> does 
not. Roman gave me following pointers:

http://boost.org/libs/python/doc/v2/register_ptr_to_python.html

Also read this:
http://language-binding.net/pygccxml/apidocs/pygccxml.declarations.type_traits.smart_pointer_traits-class.html

Now you can implement some general solution similar to
http://python-ogre.python-hosting.com/file/trunk/python-ogre/shared_ptr.py

I did not have time to try it yet, but planning to do it soon.

Cheers,
Kirill




More information about the Cplusplus-sig mailing list