The problem
Boost.Python is often used to interface c++ classes to python. It’s easy to use, handles c++ string and containers automatically and non-intrusive.
YouCompleteMe uses Boost.Python to export its c++ classes to python so users can use them in their ycm_extra_conf.py
file. Recently, I encountered the following strange problem when using CompilationDatabase.GetCompilationFlagsForFile
:
ArgumentError: Python argument types in^@
CompilationDatabase.GetCompilationInfoForFile(CompilationDatabase, unicode)^@
did not match pass:[c++] signature:^@
GetCompilationInfoForFile(YouCompleteMe::CompilationDatabase {lvalue},
std::string)^@
The solution
It’s strange that the c++ interface uses lvalue for the object for the first sign. But after digging into the problem, I find that every part of the ycm_extra_conf.py
works as expected, except that the filename is a reference file chosen randomly from the compilation_commands.json
. Then it turns out that python load json strings as unicode
objects but the c++ part only accepts std::string
, which is the real difference in the interface. after manually converting the json string to python string with str
, the error disappeared.
So it seems that Boost.Python handles lvalue well, but has problems with unicode objects and std::string
. Try to use always python string instead of unicode in Boost.Python interfaced c++ classes.