Hi,
 I've found a bug where Boost.Python calls the wrong function overload. Here is a small unit test:

=====
The C++ module "_test.cpp":
=====

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

class Base { };

class Derived : public Base { };

std::string f(Base& b) {
    return "Base";
}

std::string f(Derived& d) {
    return "Derived";
}

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

    class_<Base>("Base");
    class_<Derived, bases<Base> >("Derived");
   
    def("f", static_cast<std::string (*)(Derived&)>(&f));
    def("f", static_cast<std::string (*)(Base&)>(&f));
}


=====
The small test in python:
=====

>>> from _test import *
>>> f(Base())
'Base'
>>> f(Derived())
'Base'


=====

Interestingly enough, if the function overloads are exported in the inverse order, it actually works, i.e., if using this code:

=====
BOOST_PYTHON_MODULE( _test )
{
    using namespace boost::python;

    class_<Base>("Base");
    class_<Derived, bases<Base> >("Derived");
   
    def("f", static_cast<std::string (*)(Base&)>(&f));
    def("f", static_cast<std::string (*)(Derived&)>(&f));
}
=====

I do not know very well how does the boost.python registry works, but it seems that it is selecting the first match instead of testing all matches and selecting the "best one".