I was somewhat surprised when I got this error message.
TypeError: unsupported operand type(s) for <<: 'Packet' and 'int'
What I am trying to do is expose a class through boost python that overloads the __lshift__ operand to take several different object types – such as int, float, char*, etc. I am exposing the class correctly but when I try something like packet << 10 I get the aforementioned error.
I understand why this is but I’m not sure exactly how I should go about solving this. I cant exactly have an overload with a boost::python::object because then it couldn’t distinguish between packet << 10 and packet << 10.5.
One possible solution is to expose the functions as something other than the __lshift__. I could then end up with packet.saveInt(10) and packet.saveFloat(10.5) but that destroys the syntactic sugar that we all so admire in python.
Another idea I had was that I could create a very thin class around the built-in int types and take that in.
struct Int32 {
Int32(bp::object obj) {
if (PyInt_Check(obj.get()) {
value = bp::extract<int>(obj);
}
PyErr_SetObject(PyExc_ValueError, obj);
bp::throw_error_already_set();
}
int value;
}
BOOST_PYTHON_MODULE(intwrapper)
{
bp::class_<Int32>("Int32", bp::init<bp::object>)
.def("value", &Int32::value);
}
With this I could then do the following. packet << Int32(10) and similarly packet << Float(10.5). This is kind of hackish and I hope there is a better way.
Any suggestions? Thanks!
After more investigation I discovered the problem is that I was trying to pass an int by reference and Python does not support that.
I did my best to keep the syntax sugar but eventually went with exposing the different operator <<() and operator >>() methods as saveInt32(value), saveString(value), loadInt32(), loadString() and so on.