J'essaie donc de créer un convertisseur to_python qui me permettra de renvoyer un boost::optional à partir d'une fonction exposée et de le faire traiter comme T si l'optional est défini et None sinon. En me basant sur un post que j'ai trouvé sur C++Sig J'ai donc écrit le code suivant.
template<typename T>
struct optional_ : private boost::noncopyable {
struct conversion {
static PyObject* convert(boost::optional<T> const& value) {
if (value) {
return boost::python::to_python_value<T>()(*value);
}
Py_INCREF(Py_None);
return Py_None;
}
};
explicit optional_() {
boost::python::to_python_converter<boost::optional<T>, conversion>();
}
};
Pour autant que je puisse en juger, cela fonctionne pour convertir les options, mais python lance l'exception suivante "TypeError : No to_python (by-value) converter found for C++ type : std::string". Je sais que le C++ est capable de convertir des chaînes en python puisque la plupart de mes fonctions exposées renvoient des chaînes. Pourquoi boost::python::to_python_value ne le reconnaît-il pas, et comment puis-je utiliser le convertisseur qu'il possède ?
Corrigé en remplaçant le texte par le suivant (basé sur cet article ) :
template<typename T>
struct optional_ : private boost::noncopyable {
struct conversion {
static PyObject* convert(boost::optional<T> const& value) {
using namespace boost::python;
return incref((value ? object(*value) : object()).ptr());
}
};
explicit optional_() {
boost::python::to_python_converter<boost::optional<T>, conversion>();
}
};
Il ne reste plus qu'à faire l'autre version pour qu'elle soit plus propre et qu'elle fonctionne mieux.