[C++-sig] pyplusplus bug related to boost::equality_comparable (and possibly other operators as well)

Roman Yakovenko roman.yakovenko at gmail.com
Thu Sep 9 20:08:43 CEST 2010


On Thu, Sep 9, 2010 at 2:50 PM, Jakub Zytka <kubol at kormoran.net> wrote:
> Actually, I haven't had time to investigate it deeper yet, but it seems to
> be a pyplusplus's bug. I also haven't found anything relevant on the net, so
> here we go:
>
> Test case:
> class to be exposed (file a.h)
>
> #include <boost/operators.hpp>
>
> class A: boost::equality_comparable<A>
> {
> public:
>        A(int a): a(a) {};
>
>        bool operator==(A const & other) const
>        {
>                return this->a == other.a;
>        }
> private:
>        int a;
> };
>
> generator used (gen.py):
> from pyplusplus import module_builder
>
> mb = module_builder.module_builder_t(files = ['a.h'])
>
> mb.decl('alloca').exclude()
>
> mb.build_code_creator( module_name = 'testA')
> mb.write_module('testA.cpp')
>
> file generated:
> // This file has been generated by Py++.
>
> #include "boost/python.hpp"
>
> #include "a.h"
>
> namespace bp = boost::python;
>
> BOOST_PYTHON_MODULE(testA){
>    { //::A
>        typedef bp::class_< A > A_exposer_t;
>        A_exposer_t A_exposer = A_exposer_t( "A", bp::init< int >((
> bp::arg("a") )) );
>        bp::scope A_scope( A_exposer );
>        bp::implicitly_convertible< int, A >();
>        A_exposer.def( bp::self == bp::self );
>        // OOPS! something is missing here
>    }
> }
>
>
> C++ class test:
> #include <iostream>
> #include "a.h"
>
> using namespace std;
>
> int main()
> {
>        A a1(3);
>        A a2(3);
>        cout << "a1 == a2: " << (a1 == a2) << endl;
>        cout << "a1 != a2: " << (a1 != a2) << endl;
>        return 0;
> }
>
> C++ class test result:
> a1 == a2: 1
> a1 != a2: 0
>
> python test:
>>>> import testA
>>>> a1 = testA.A(3)
>>>> a2 = testA.A(3)
>>>> a1 == a2
> True
>>>> a1 != a2
> True # drat!
>
>
> The reason: missing A_exposer.def( bp::self != bp::self ); in the generated
> code;
>
>
> If any of you think it is easy to fix in pyplusplus (Roman, perhaps you're
> the one to know best?) I may try.

I don't think fixing py++ is the right approach.

> I'm also considering a workaround of
> checking bases for all the classes and add missing "self != self" for all
> those which derive from equality_comparable;
> Perhaps there is the same problem with less_than_comparable and others.

I would implement the following solution:
1. Introduce new "def_visitor" (
http://www.boost.org/doc/libs/1_44_0/libs/python/doc/v2/def_visitor.html
) - so it will register all member function from the appropriate class
   In our case, equality_comparable, the visitor will register == and !=
  ( this code could be contributed later to the Boost.Python )

2. Apply that visitors on all relevant classes using py++

Does it help?

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/


More information about the Cplusplus-sig mailing list