mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
Still further rationalized conversion registry
[SVN r14462]
This commit is contained in:
2
Jamfile
2
Jamfile
@@ -27,7 +27,7 @@ dll bpl
|
||||
src/module.cpp
|
||||
src/objects2.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
src/converter/callback.cpp
|
||||
src/converter/arg_to_python_base.cpp
|
||||
src/object/iterator.cpp
|
||||
src/object_protocol.cpp
|
||||
src/object_operators.cpp
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef ARG_FROM_PYTHON_DWA2002127_HPP
|
||||
# define ARG_FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
# include <boost/python/converter/find_from_python.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
# define CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct rvalue_from_python_stage1_data;
|
||||
struct registration;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage);
|
||||
BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, registration const&);
|
||||
BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, registration const&);
|
||||
BOOST_PYTHON_DECL void absorb_result(PyObject*);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
@@ -18,11 +18,20 @@ struct rvalue_from_python_chain;
|
||||
BOOST_PYTHON_DECL void* get_lvalue_from_python(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
|
||||
PyObject* source, registration const&);
|
||||
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
|
||||
PyObject*, rvalue_from_python_stage1_data&, void* storage);
|
||||
|
||||
BOOST_PYTHON_DECL void* reference_from_python(PyObject*, registration const&);
|
||||
BOOST_PYTHON_DECL void* pointer_from_python(PyObject*, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL void void_from_python(PyObject*);
|
||||
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef RETURN_FROM_PYTHON_DWA200265_HPP
|
||||
# define RETURN_FROM_PYTHON_DWA200265_HPP
|
||||
|
||||
# include <boost/python/converter/callback_from_python_base.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/registered_pointee.hpp>
|
||||
@@ -77,7 +77,7 @@ struct return_from_python<void>
|
||||
|
||||
result_type operator()(PyObject* x) const
|
||||
{
|
||||
converter::detail::absorb_result(x);
|
||||
converter::void_from_python(x);
|
||||
# ifdef BOOST_NO_VOID_RETURNS
|
||||
return result_type();
|
||||
# endif
|
||||
@@ -101,21 +101,21 @@ namespace detail
|
||||
inline typename return_rvalue_from_python<T>::result_type
|
||||
return_rvalue_from_python<T>::operator()(PyObject* obj)
|
||||
{
|
||||
return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes);
|
||||
return *(T*)rvalue_from_python_stage2(obj, m_data.stage1, m_data.storage.bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T return_reference_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(
|
||||
callback_convert_reference(obj, registered<T>::converters)
|
||||
reference_from_python(obj, registered<T>::converters)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return T(callback_convert_pointer(obj, registered_pointee<T>::converters));
|
||||
return T(pointer_from_python(obj, registered_pointee<T>::converters));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
58
src/converter/arg_to_python_base.cpp
Normal file
58
src/converter/arg_to_python_base.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/converter/arg_to_python_base.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace
|
||||
{
|
||||
inline PyObject* convert_to_python(void const volatile* source, registration const& converters)
|
||||
{
|
||||
if (converters.to_python == 0)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No to_python (by-value) converter found for C++ type: %s"
|
||||
, converters.target_type.name()));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
return source == 0
|
||||
? incref(Py_None)
|
||||
: converters.to_python(const_cast<void*>(source));
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
arg_to_python_base::arg_to_python_base(
|
||||
void const volatile* source, registration const& converters)
|
||||
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140
|
||||
: handle<>(converter::convert_to_python(source, converters))
|
||||
# else
|
||||
: m_ptr(converter::convert_to_python(source, converters))
|
||||
# endif
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_class_registered()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("class not registered for to_python type"));
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/converter/arg_to_python_base.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/converter/find_from_python.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/detail/none.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
inline PyObject* convert_to_python(void const volatile* source, registration const& converters)
|
||||
{
|
||||
if (converters.to_python == 0)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No to_python (by-value) converter found for C++ type: %s"
|
||||
, converters.target_type.name()));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
return source == 0
|
||||
? python::detail::none()
|
||||
: converters.to_python(const_cast<void*>(source));
|
||||
}
|
||||
}
|
||||
|
||||
arg_to_python_base::arg_to_python_base(
|
||||
void const volatile* source, registration const& converters)
|
||||
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140
|
||||
: handle<>(convert_to_python(source, converters))
|
||||
# else
|
||||
: m_ptr(convert_to_python(source, converters))
|
||||
# endif
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* callback_convert_reference(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
handle<> holder(source);
|
||||
if (source->ob_refcnt <= 2)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"Attempt to return dangling pointer/reference to object of type: %s"
|
||||
, converters.target_type.name()));
|
||||
|
||||
PyErr_SetObject(PyExc_ReferenceError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
void* result = get_lvalue_from_python(source, converters);
|
||||
if (!result)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s"
|
||||
, converters.target_type.name()
|
||||
, source->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* callback_convert_pointer(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
if (source == Py_None)
|
||||
{
|
||||
Py_DECREF(source);
|
||||
return 0;
|
||||
}
|
||||
return callback_convert_reference(source, converters);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_class_registered()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("class not registered for to_python type"));
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_from_python_stage1_data& data, void* storage)
|
||||
{
|
||||
handle<> holder(src);
|
||||
|
||||
void const* converters_ = data.convertible;
|
||||
registration const& converters = *static_cast<registration const*>(converters_);
|
||||
data = rvalue_from_python_stage1(src, converters);
|
||||
|
||||
if (!data.convertible)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s"
|
||||
, converters.target_type.name()
|
||||
, src->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
// If a construct function was registered (i.e. we found an
|
||||
// rvalue conversion), call it now.
|
||||
if (data.construct != 0)
|
||||
data.construct(src, &data);
|
||||
|
||||
// Return the address of the resulting C++ object
|
||||
return data.convertible;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void absorb_result(PyObject* o)
|
||||
{
|
||||
Py_DECREF(expect_non_null(o));
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
@@ -4,11 +4,10 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/converter/find_from_python.hpp>
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -35,6 +34,37 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
|
||||
return data;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
|
||||
PyObject* src, rvalue_from_python_stage1_data& data, void* storage)
|
||||
{
|
||||
handle<> holder(src);
|
||||
|
||||
void const* converters_ = data.convertible;
|
||||
registration const& converters = *static_cast<registration const*>(converters_);
|
||||
data = rvalue_from_python_stage1(src, converters);
|
||||
|
||||
if (!data.convertible)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s"
|
||||
, converters.target_type.name()
|
||||
, src->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
// If a construct function was registered (i.e. we found an
|
||||
// rvalue conversion), call it now.
|
||||
if (data.construct != 0)
|
||||
data.construct(src, &data);
|
||||
|
||||
// Return the address of the resulting C++ object
|
||||
return data.convertible;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* get_lvalue_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
@@ -100,4 +130,62 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
|
||||
return chain;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* reference_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
handle<> holder(source);
|
||||
if (source->ob_refcnt <= 2)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"Attempt to return dangling pointer/reference to object of type: %s"
|
||||
, converters.target_type.name()));
|
||||
|
||||
PyErr_SetObject(PyExc_ReferenceError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
void* result = get_lvalue_from_python(source, converters);
|
||||
if (!result)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
"No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s"
|
||||
, converters.target_type.name()
|
||||
, source->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* pointer_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
if (source == Py_None)
|
||||
{
|
||||
Py_DECREF(source);
|
||||
return 0;
|
||||
}
|
||||
return reference_from_python(source, converters);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_class_registered()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("class not registered for to_python type"));
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void void_from_python(PyObject* o)
|
||||
{
|
||||
Py_DECREF(expect_non_null(o));
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
Reference in New Issue
Block a user