The short answer is: "you can't". This is not a Boost.Python limitation
so much as a limitation of C++. The problem is that a Python function is
actually data, and the only way of associating data with a C++ function pointer
is to store it in a static variable of the function. The problem with that
is that you can only associate one piece of data with every C++ function,
and we have no way of compiling a new C++ function on-the-fly for every Python
function you decide to pass to foo.
In other words, this could work if the C++ function is always going to invoke
the same Python function, but you probably don't want
that.

If you have the luxury of changing the C++ code you're wrapping, pass it
an object instead and call
that; the overloaded function call operator will invoke the Python function
you pass it behind the object.