[Boost.Python] Infinite recursion attempting to_python conversion

For some purposes we have a special string class derived from std::wstring. Simplified declaration: class cbstring: public std::wstring { public: cbstring(const wchar_t* that): std::wstring(that) {} cbstring(const std::wstring& that): std::wstring(that) {} ... }; I want to return such objects from C++ as Python Unicode strings, e.g.: cbstring produceWString() { return L"This is a test Unicode string"; } If produceWString() returns std::wstring, the conversion happens by magic. But with the cbstring return type, I get: TypeError: No to_python (by-value) converter found for C++ type: class cbstring The corresponding conversion problem (passing u"Foo" from Python to a function accepting const cbstring&) can be handled with the following call in the extension module: implicitly_convertible<std::wstring, cbstring>(); However, implicitly_convertible<cbstring, std::wstring>(); does NOT allow the produceWString() function to succeed: I still get the aforementioned TypeError. So I declared a type converter: struct cbstring_to_python { static PyObject* convert(const cbstring& cbs) { return PyUnicode_FromUnicode(cbs.c_str(), cbs.length()); } }; and registered it with: to_python_converter<cbstring, cbstring_to_python>(); The result is a stack overflow. I'm not clear on exactly why it happens, but something inside the cbstring_to_python converter is apparently recursively invoking cbstring_to_python::convert(). How *should* I go about returning our specialized string type as a Python Unicode string? OS: Microsoft Windows XP Pro, SP1 Compiler: Microsoft VC++ 7.1 with STLport 4.6 Boost version: 1.31

This post belongs on the C++-sig; followups directed thence. "Nat Goodspeed" <ngoodspeed@solidworks.com> writes:
For some purposes we have a special string class derived from std::wstring. Simplified declaration:
class cbstring: public std::wstring { public: cbstring(const wchar_t* that): std::wstring(that) {} cbstring(const std::wstring& that): std::wstring(that) {} ... };
I want to return such objects from C++ as Python Unicode strings, e.g.:
cbstring produceWString() { return L"This is a test Unicode string"; }
If produceWString() returns std::wstring, the conversion happens by magic. But with the cbstring return type, I get:
TypeError: No to_python (by-value) converter found for C++ type: class cbstring
The corresponding conversion problem (passing u"Foo" from Python to a function accepting const cbstring&) can be handled with the following call in the extension module:
implicitly_convertible<std::wstring, cbstring>();
However,
implicitly_convertible<cbstring, std::wstring>();
does NOT allow the produceWString() function to succeed: I still get the aforementioned TypeError.
Right. implicitly_convertible is only used when converting from Python to C++.
So I declared a type converter:
struct cbstring_to_python { static PyObject* convert(const cbstring& cbs) { return PyUnicode_FromUnicode(cbs.c_str(), cbs.length()); } };
and registered it with:
to_python_converter<cbstring, cbstring_to_python>();
Good.
The result is a stack overflow.
Bad.
I'm not clear on exactly why it happens, but something inside the cbstring_to_python converter is apparently recursively invoking cbstring_to_python::convert().
It's hard to imagine; as you can see cbstring_to_python::convert just calls Python's routine to create a new string. There's no reason for that function to call back into your code. I'm guessing you are blowing the stack somewhere else in your code. I suggest you try to use a debugger and try to track down the real cause of the error. If you can't do that, I suggest you reduce your example to a *minimal* but complete test case. If the answer doesn't jump out at you once you've done that, post it on the C++-sig and someone (maybe me) can try to take a look at it.
How *should* I go about returning our specialized string type as a Python Unicode string?
Your basic approach looks fine. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams
-
Nat Goodspeed