summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/boost/libs/python/src/converter/from_python.cpp
diff options
context:
space:
mode:
authorneksard <[email protected]>2022-02-10 16:45:33 +0300
committerDaniil Cherednik <[email protected]>2022-02-10 16:45:33 +0300
commit1d9c550e7c38e051d7961f576013a482003a70d9 (patch)
treeb2cc84ee7850122e7ccf51d0ea21e4fa7e7a5685 /contrib/restricted/boost/libs/python/src/converter/from_python.cpp
parent8f7cf138264e0caa318144bf8a2c950e0b0a8593 (diff)
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/boost/libs/python/src/converter/from_python.cpp')
-rw-r--r--contrib/restricted/boost/libs/python/src/converter/from_python.cpp606
1 files changed, 303 insertions, 303 deletions
diff --git a/contrib/restricted/boost/libs/python/src/converter/from_python.cpp b/contrib/restricted/boost/libs/python/src/converter/from_python.cpp
index 31aebb476fd..9678be1cb69 100644
--- a/contrib/restricted/boost/libs/python/src/converter/from_python.cpp
+++ b/contrib/restricted/boost/libs/python/src/converter/from_python.cpp
@@ -1,303 +1,303 @@
-// Copyright David Abrahams 2002.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#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/object/find_instance.hpp>
-
-#include <boost/python/handle.hpp>
-#include <boost/python/detail/raw_pyobject.hpp>
-#include <boost/python/cast.hpp>
-
-#include <vector>
-#include <algorithm>
-
-namespace boost { namespace python { namespace converter {
-
-// rvalue_from_python_stage1 -- do the first stage of a conversion
-// from a Python object to a C++ rvalue.
-//
-// source - the Python object to be converted
-// converters - the registry entry for the target type T
-//
-// Postcondition: where x is the result, one of:
-//
-// 1. x.convertible == 0, indicating failure
-//
-// 2. x.construct == 0, x.convertible is the address of an object of
-// type T. Indicates a successful lvalue conversion
-//
-// 3. where y is of type rvalue_from_python_data<T>,
-// x.construct(source, y) constructs an object of type T
-// in y.storage.bytes and then sets y.convertible == y.storage.bytes,
-// or else throws an exception and has no effect.
-BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
- PyObject* source
- , registration const& converters)
-{
- rvalue_from_python_stage1_data data;
-
- // First check to see if it's embedded in an extension class
- // instance, as a special case.
- data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
- data.construct = 0;
- if (!data.convertible)
- {
- for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
- chain != 0;
- chain = chain->next)
- {
- void* r = chain->convertible(source);
- if (r != 0)
- {
- data.convertible = r;
- data.construct = chain->construct;
- break;
- }
- }
- }
- return data;
-}
-
-// rvalue_result_from_python -- return the address of a C++ object which
-// can be used as the result of calling a Python function.
-//
-// src - the Python object to be converted
-//
-// data - a reference to the base part of a
-// rvalue_from_python_data<T> object, where T is the
-// target type of the conversion.
-//
-// Requires: data.convertible == &registered<T>::converters
-//
-BOOST_PYTHON_DECL void* rvalue_result_from_python(
- PyObject* src, rvalue_from_python_stage1_data& data)
-{
- // Retrieve the registration
- // Cast in two steps for less-capable compilers
- void const* converters_ = data.convertible;
- registration const& converters = *static_cast<registration const*>(converters_);
-
- // Look for an eligible converter
- data = rvalue_from_python_stage1(src, converters);
- return rvalue_from_python_stage2(src, data, converters);
-}
-
-BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
- PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters)
-{
- if (!data.convertible)
- {
- handle<> msg(
-#if PY_VERSION_HEX >= 0x03000000
- ::PyUnicode_FromFormat
-#else
- ::PyString_FromFormat
-#endif
- (
- "No registered converter was able to produce a C++ rvalue 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();
- }
-
- // If a construct function was registered (i.e. we found an
- // rvalue conversion), call it now.
- if (data.construct != 0)
- data.construct(source, &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)
-{
- // Check to see if it's embedded in a class instance
- void* x = objects::find_instance_impl(source, converters.target_type);
- if (x)
- return x;
-
- lvalue_from_python_chain const* chain = converters.lvalue_chain;
- for (;chain != 0; chain = chain->next)
- {
- void* r = chain->convert(source);
- if (r != 0)
- return r;
- }
- return 0;
-}
-
-namespace
-{
- // Prevent looping in implicit conversions. This could/should be
- // much more efficient, but will work for now.
- typedef std::vector<rvalue_from_python_chain const*> visited_t;
- static visited_t visited;
-
- inline bool visit(rvalue_from_python_chain const* chain)
- {
- visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
- if (p != visited.end() && *p == chain)
- return false;
- visited.insert(p, chain);
- return true;
- }
-
- // RAII class for managing global visited marks.
- struct unvisit
- {
- unvisit(rvalue_from_python_chain const* chain)
- : chain(chain) {}
-
- ~unvisit()
- {
- visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
- assert(p != visited.end());
- visited.erase(p);
- }
- private:
- rvalue_from_python_chain const* chain;
- };
-}
-
-
-BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
- PyObject* source
- , registration const& converters)
-{
- if (objects::find_instance_impl(source, converters.target_type))
- return true;
-
- rvalue_from_python_chain const* chain = converters.rvalue_chain;
-
- if (!visit(chain))
- return false;
-
- unvisit protect(chain);
-
- for (;chain != 0; chain = chain->next)
- {
- if (chain->convertible(source))
- return true;
- }
-
- return false;
-}
-
-namespace
-{
- void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
- {
- handle<> msg(
-#if PY_VERSION_HEX >= 0x03000000
- ::PyUnicode_FromFormat
-#else
- ::PyString_FromFormat
-#endif
- (
- "No registered converter was able to extract a C++ %s to type %s"
- " from this Python object of type %s"
- , ref_type
- , converters.target_type.name()
- , source->ob_type->tp_name
- ));
-
- PyErr_SetObject(PyExc_TypeError, msg.get());
-
- throw_error_already_set();
- }
-
- void* lvalue_result_from_python(
- PyObject* source
- , registration const& converters
- , char const* ref_type)
- {
- handle<> holder(source);
- if (source->ob_refcnt <= 1)
- {
- handle<> msg(
-#if PY_VERSION_HEX >= 0x3000000
- ::PyUnicode_FromFormat
-#else
- ::PyString_FromFormat
-#endif
- (
- "Attempt to return dangling %s to object of type: %s"
- , ref_type
- , converters.target_type.name()));
-
- PyErr_SetObject(PyExc_ReferenceError, msg.get());
-
- throw_error_already_set();
- }
-
- void* result = get_lvalue_from_python(source, converters);
- if (!result)
- (throw_no_lvalue_from_python)(source, converters, ref_type);
- return result;
- }
-
-}
-
-BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters)
-{
- (throw_no_lvalue_from_python)(source, converters, "pointer");
-}
-
-BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters)
-{
- (throw_no_lvalue_from_python)(source, converters, "reference");
-}
-
-BOOST_PYTHON_DECL void* reference_result_from_python(
- PyObject* source
- , registration const& converters)
-{
- return (lvalue_result_from_python)(source, converters, "reference");
-}
-
-BOOST_PYTHON_DECL void* pointer_result_from_python(
- PyObject* source
- , registration const& converters)
-{
- if (source == Py_None)
- {
- Py_DECREF(source);
- return 0;
- }
- return (lvalue_result_from_python)(source, converters, "pointer");
-}
-
-BOOST_PYTHON_DECL void void_result_from_python(PyObject* o)
-{
- Py_DECREF(expect_non_null(o));
-}
-
-} // namespace boost::python::converter
-
-BOOST_PYTHON_DECL PyObject*
-pytype_check(PyTypeObject* type_, PyObject* source)
-{
- if (!PyObject_IsInstance(source, python::upcast<PyObject>(type_)))
- {
- ::PyErr_Format(
- PyExc_TypeError
- , "Expecting an object of type %s; got an object of type %s instead"
- , type_->tp_name
- , source->ob_type->tp_name
- );
- throw_error_already_set();
- }
- return source;
-}
-
-}} // namespace boost::python
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#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/object/find_instance.hpp>
+
+#include <boost/python/handle.hpp>
+#include <boost/python/detail/raw_pyobject.hpp>
+#include <boost/python/cast.hpp>
+
+#include <vector>
+#include <algorithm>
+
+namespace boost { namespace python { namespace converter {
+
+// rvalue_from_python_stage1 -- do the first stage of a conversion
+// from a Python object to a C++ rvalue.
+//
+// source - the Python object to be converted
+// converters - the registry entry for the target type T
+//
+// Postcondition: where x is the result, one of:
+//
+// 1. x.convertible == 0, indicating failure
+//
+// 2. x.construct == 0, x.convertible is the address of an object of
+// type T. Indicates a successful lvalue conversion
+//
+// 3. where y is of type rvalue_from_python_data<T>,
+// x.construct(source, y) constructs an object of type T
+// in y.storage.bytes and then sets y.convertible == y.storage.bytes,
+// or else throws an exception and has no effect.
+BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
+ PyObject* source
+ , registration const& converters)
+{
+ rvalue_from_python_stage1_data data;
+
+ // First check to see if it's embedded in an extension class
+ // instance, as a special case.
+ data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
+ data.construct = 0;
+ if (!data.convertible)
+ {
+ for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
+ chain != 0;
+ chain = chain->next)
+ {
+ void* r = chain->convertible(source);
+ if (r != 0)
+ {
+ data.convertible = r;
+ data.construct = chain->construct;
+ break;
+ }
+ }
+ }
+ return data;
+}
+
+// rvalue_result_from_python -- return the address of a C++ object which
+// can be used as the result of calling a Python function.
+//
+// src - the Python object to be converted
+//
+// data - a reference to the base part of a
+// rvalue_from_python_data<T> object, where T is the
+// target type of the conversion.
+//
+// Requires: data.convertible == &registered<T>::converters
+//
+BOOST_PYTHON_DECL void* rvalue_result_from_python(
+ PyObject* src, rvalue_from_python_stage1_data& data)
+{
+ // Retrieve the registration
+ // Cast in two steps for less-capable compilers
+ void const* converters_ = data.convertible;
+ registration const& converters = *static_cast<registration const*>(converters_);
+
+ // Look for an eligible converter
+ data = rvalue_from_python_stage1(src, converters);
+ return rvalue_from_python_stage2(src, data, converters);
+}
+
+BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
+ PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters)
+{
+ if (!data.convertible)
+ {
+ handle<> msg(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "No registered converter was able to produce a C++ rvalue 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();
+ }
+
+ // If a construct function was registered (i.e. we found an
+ // rvalue conversion), call it now.
+ if (data.construct != 0)
+ data.construct(source, &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)
+{
+ // Check to see if it's embedded in a class instance
+ void* x = objects::find_instance_impl(source, converters.target_type);
+ if (x)
+ return x;
+
+ lvalue_from_python_chain const* chain = converters.lvalue_chain;
+ for (;chain != 0; chain = chain->next)
+ {
+ void* r = chain->convert(source);
+ if (r != 0)
+ return r;
+ }
+ return 0;
+}
+
+namespace
+{
+ // Prevent looping in implicit conversions. This could/should be
+ // much more efficient, but will work for now.
+ typedef std::vector<rvalue_from_python_chain const*> visited_t;
+ static visited_t visited;
+
+ inline bool visit(rvalue_from_python_chain const* chain)
+ {
+ visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
+ if (p != visited.end() && *p == chain)
+ return false;
+ visited.insert(p, chain);
+ return true;
+ }
+
+ // RAII class for managing global visited marks.
+ struct unvisit
+ {
+ unvisit(rvalue_from_python_chain const* chain)
+ : chain(chain) {}
+
+ ~unvisit()
+ {
+ visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
+ assert(p != visited.end());
+ visited.erase(p);
+ }
+ private:
+ rvalue_from_python_chain const* chain;
+ };
+}
+
+
+BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
+ PyObject* source
+ , registration const& converters)
+{
+ if (objects::find_instance_impl(source, converters.target_type))
+ return true;
+
+ rvalue_from_python_chain const* chain = converters.rvalue_chain;
+
+ if (!visit(chain))
+ return false;
+
+ unvisit protect(chain);
+
+ for (;chain != 0; chain = chain->next)
+ {
+ if (chain->convertible(source))
+ return true;
+ }
+
+ return false;
+}
+
+namespace
+{
+ void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
+ {
+ handle<> msg(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "No registered converter was able to extract a C++ %s to type %s"
+ " from this Python object of type %s"
+ , ref_type
+ , converters.target_type.name()
+ , source->ob_type->tp_name
+ ));
+
+ PyErr_SetObject(PyExc_TypeError, msg.get());
+
+ throw_error_already_set();
+ }
+
+ void* lvalue_result_from_python(
+ PyObject* source
+ , registration const& converters
+ , char const* ref_type)
+ {
+ handle<> holder(source);
+ if (source->ob_refcnt <= 1)
+ {
+ handle<> msg(
+#if PY_VERSION_HEX >= 0x3000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "Attempt to return dangling %s to object of type: %s"
+ , ref_type
+ , converters.target_type.name()));
+
+ PyErr_SetObject(PyExc_ReferenceError, msg.get());
+
+ throw_error_already_set();
+ }
+
+ void* result = get_lvalue_from_python(source, converters);
+ if (!result)
+ (throw_no_lvalue_from_python)(source, converters, ref_type);
+ return result;
+ }
+
+}
+
+BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters)
+{
+ (throw_no_lvalue_from_python)(source, converters, "pointer");
+}
+
+BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters)
+{
+ (throw_no_lvalue_from_python)(source, converters, "reference");
+}
+
+BOOST_PYTHON_DECL void* reference_result_from_python(
+ PyObject* source
+ , registration const& converters)
+{
+ return (lvalue_result_from_python)(source, converters, "reference");
+}
+
+BOOST_PYTHON_DECL void* pointer_result_from_python(
+ PyObject* source
+ , registration const& converters)
+{
+ if (source == Py_None)
+ {
+ Py_DECREF(source);
+ return 0;
+ }
+ return (lvalue_result_from_python)(source, converters, "pointer");
+}
+
+BOOST_PYTHON_DECL void void_result_from_python(PyObject* o)
+{
+ Py_DECREF(expect_non_null(o));
+}
+
+} // namespace boost::python::converter
+
+BOOST_PYTHON_DECL PyObject*
+pytype_check(PyTypeObject* type_, PyObject* source)
+{
+ if (!PyObject_IsInstance(source, python::upcast<PyObject>(type_)))
+ {
+ ::PyErr_Format(
+ PyExc_TypeError
+ , "Expecting an object of type %s; got an object of type %s instead"
+ , type_->tp_name
+ , source->ob_type->tp_name
+ );
+ throw_error_already_set();
+ }
+ return source;
+}
+
+}} // namespace boost::python