[C++-sig] Inheritance and __init__

Bue Vedel-Larsen bue.longbow at gmail.com
Mon Oct 29 19:46:47 CET 2007


I'm having a strange problem with Boost::Python. Consider the following 
Python code:

class Base:
	def foo(self, str):
		print str
		
class Derived(Base):
	def __init__(self):
		self.foo('__init__')

d = Derived()

This works as expected: When run, "__init__" is printed. My problem is 
that if Base is in a C++ module the same code fails with an 
Boost.Python.ArgumentError. See end of post for example code that 
exhibit the error.

Can anyone point out if I'm doing something wrong? I'm not using any 
virtual methods, or any kind of advanced inheritance magic. Is this a 
bug in Boost::Python?

Thanks in advance,
Bue

The exact error is:

Boost.Python.ArgumentError: Python argument types in
    Base.foo(DerivedB, str)
did not match C++ signature:
    foo(class Base {lvalue}, class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >)

Minimum example code:

#include <boost/python.hpp>
#include <string>
#include <iostream>

class Base {
public:
    Base() {}
    ~Base() {}

    void foo( const std::string& str ) {
        std::cout << "In C++: " << str << std::endl;
    }
};

BOOST_PYTHON_MODULE(test_module) {
    using namespace boost::python;

    (new class_< Base >( "Base", "Base class", init<>() ))
        ->def( "foo", &Base::foo, "method foo" )
    ;
}

void run_script( const std::string& script ) {
    if( PyRun_SimpleString( script.c_str() ) ) {
        PyErr_Print();
        PyErr_Clear();
    }
}

int main() {
    PyImport_AppendInittab( "test_module", &inittest_module );
    Py_Initialize();

    run_script( "from test_module import *\n" );

    // This works
    run_script( 
        "class DerivedA(Base):\n"
        "\tdef bar(self):\n"
        "\t\tself.foo('In Python: DerivedA.bar()')\n"
        "dA = DerivedA()\n"
        "dA.bar()\n"
        );

    // This doesn't work
    run_script( 
        "class DerivedB(Base):\n"
        "\tdef __init__(self):\n"
        "\t\tself.foo('In Python: DerivedB.__init__()')\n"
        "dB = DerivedB()\n"
        );

#ifdef WIN32
    system( "PAUSE" );
#endif
    return 0;
}




More information about the Cplusplus-sig mailing list