mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Added std::wstring conversion support
Added std::out_of_range => Python IndexError exception conversion, thanks to Raoul Gough [SVN r20027]
This commit is contained in:
@@ -31,23 +31,33 @@
|
||||
<dl class="page-index">
|
||||
<dt>11 Sept 2003</dt>
|
||||
|
||||
<dd>Changed the response to multiple to-python converters being
|
||||
registered for the same type from a hard error into warning;
|
||||
Boost.Python now reports the offending type in the message.
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Changed the response to multiple to-python converters being
|
||||
registered for the same type from a hard error into warning;
|
||||
Boost.Python now reports the offending type in the message.</li>
|
||||
|
||||
<li>Added builtin <code>std::wstring</code> conversions</li>
|
||||
|
||||
<li>Added <code>std::out_of_range</code> => Python
|
||||
<code>IndexError</code> exception conversion, thanks to <a href=
|
||||
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>9 Sept 2003</dt>
|
||||
|
||||
<dd>Added new <code><a
|
||||
href="v2/str.html#str-spec">str</a></code></dd> constructors
|
||||
which take a range of characters, allowing strings containing
|
||||
nul (<code>'\0'</code>) characters.
|
||||
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
|
||||
|
||||
<dt>constructors which take a range of characters, allowing strings
|
||||
containing nul (<code>'\0'</code>) characters.</dt>
|
||||
|
||||
<dt>8 Sept 2003</dt>
|
||||
|
||||
<dd>Added the ability to create methods from function
|
||||
objects (with an <code>operator()</code>); see the <a
|
||||
href="v2/make_function.html#make_function-spec">make_function</a>
|
||||
docs for more info.</dd>
|
||||
<dd>Added the ability to create methods from function objects (with an
|
||||
<code>operator()</code>); see the <a href=
|
||||
"v2/make_function.html#make_function-spec">make_function</a> docs for
|
||||
more info.</dd>
|
||||
|
||||
<dt>10 August 2003</dt>
|
||||
|
||||
@@ -170,7 +180,8 @@ BOOST_PYTHON_MODULE(test)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
11 September 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
11 September 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href="../../../people/dave_abrahams.htm">Dave
|
||||
|
||||
@@ -82,16 +82,16 @@ namespace detail
|
||||
|
||||
// Specialize converters for signed and unsigned T to Python Int
|
||||
# define BOOST_PYTHON_TO_INT(T) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
|
||||
unsigned T \
|
||||
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
|
||||
std::numeric_limits<long>::max()) \
|
||||
? PyLong_FromUnsignedLong(x) \
|
||||
: PyInt_FromLong(x))
|
||||
? ::PyLong_FromUnsignedLong(x) \
|
||||
: ::PyInt_FromLong(x))
|
||||
|
||||
// Bool is not signed.
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
|
||||
|
||||
// note: handles signed char and unsigned char, but not char (see below)
|
||||
BOOST_PYTHON_TO_INT(char)
|
||||
@@ -103,23 +103,29 @@ BOOST_PYTHON_TO_INT(long)
|
||||
// using Python's macro instead of Boost's - we don't seem to get the
|
||||
// config right all the time.
|
||||
# ifdef HAVE_LONG_LONG
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, PyLong_FromLongLong(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, PyLong_FromUnsignedLongLong(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
|
||||
# endif
|
||||
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),x.size()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),x.size()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
|
||||
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
|
||||
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
|
||||
# undef BOOST_PYTHON_TO_PYTHON_BY_VALUE
|
||||
# undef BOOST_PYTHON_TO_INT
|
||||
|
||||
namespace converter
|
||||
{
|
||||
|
||||
|
||||
@@ -272,6 +272,42 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
// encode_string_unaryfunc/py_encode_string -- manufacture a unaryfunc
|
||||
// "slot" which encodes a Python string using the default encoding
|
||||
extern "C" PyObject* encode_string_unaryfunc(PyObject* x)
|
||||
{
|
||||
return PyUnicode_FromEncodedObject( x, 0, 0 );
|
||||
}
|
||||
unaryfunc py_encode_string = encode_string_unaryfunc;
|
||||
|
||||
// A SlotPolicy for extracting C++ strings from Python objects.
|
||||
struct wstring_rvalue_from_python
|
||||
{
|
||||
// If the underlying object is "string-able" this will succeed
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
return PyUnicode_Check(obj)
|
||||
? &py_object_identity
|
||||
: PyString_Check(obj)
|
||||
? &py_encode_string
|
||||
: 0;
|
||||
};
|
||||
|
||||
// Remember that this will be used to construct the result object
|
||||
static std::wstring extract(PyObject* intermediate)
|
||||
{
|
||||
std::wstring result(::PyObject_Length(intermediate), L' ');
|
||||
int err = PyUnicode_AsWideChar(
|
||||
(PyUnicodeObject *)intermediate
|
||||
, result.size() ? &result[0] : 0
|
||||
, result.size());
|
||||
|
||||
if (err == -1)
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct complex_rvalue_from_python
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
@@ -366,7 +402,8 @@ void initialize_builtin_converters()
|
||||
// Add an lvalue converter for char which gets us char const*
|
||||
registry::insert(convert_to_cstring,type_id<char>());
|
||||
|
||||
// Register by-value converters to std::string
|
||||
// Register by-value converters to std::string, std::wstring
|
||||
slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
|
||||
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
|
||||
{
|
||||
PyErr_SetString(PyExc_OverflowError, x.what());
|
||||
}
|
||||
catch(const std::out_of_range& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, x.what());
|
||||
}
|
||||
catch(const std::exception& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, x.what());
|
||||
|
||||
@@ -83,6 +83,8 @@ BOOST_PYTHON_MODULE(builtin_converters)
|
||||
def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap);
|
||||
def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap);
|
||||
def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap);
|
||||
def("rewrap_value_wstring", by_value<std::wstring>::rewrap);
|
||||
def("rewrap_value_string", by_value<std::wstring>::rewrap);
|
||||
def("rewrap_value_string", by_value<std::string>::rewrap);
|
||||
def("rewrap_value_cstring", by_value<char const*>::rewrap);
|
||||
def("rewrap_value_handle", by_value<handle<> >::rewrap);
|
||||
|
||||
@@ -75,6 +75,13 @@ r"""
|
||||
'hello, world'
|
||||
>>> rewrap_value_string('yo, wassup?')
|
||||
'yo, wassup?'
|
||||
>>> rewrap_value_wstring(u'yo, wassup?')
|
||||
u'yo, wassup?'
|
||||
|
||||
test that overloading on unicode works:
|
||||
|
||||
>>> rewrap_value_string(u'yo, wassup?')
|
||||
u'yo, wassup?'
|
||||
|
||||
wrap strings with embedded nulls:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user