mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
4 Commits
python
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f77be9a3c | ||
|
|
daf6d97640 | ||
|
|
8c70f0540a | ||
|
|
9630425051 |
@@ -7,13 +7,14 @@ import modules ;
|
|||||||
|
|
||||||
import python ;
|
import python ;
|
||||||
|
|
||||||
if [ python.configured ] {
|
|
||||||
|
|
||||||
|
|
||||||
project boost/python
|
project boost/python
|
||||||
: source-location ../src
|
: source-location ../src
|
||||||
;
|
;
|
||||||
|
|
||||||
|
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||||
|
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||||
|
|
||||||
lib boost_python
|
lib boost_python
|
||||||
: # sources
|
: # sources
|
||||||
numeric.cpp
|
numeric.cpp
|
||||||
@@ -45,6 +46,7 @@ lib boost_python
|
|||||||
wrapper.cpp
|
wrapper.cpp
|
||||||
import.cpp
|
import.cpp
|
||||||
exec.cpp
|
exec.cpp
|
||||||
|
object/function_doc_signature.cpp
|
||||||
: # requirements
|
: # requirements
|
||||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||||
<define>BOOST_PYTHON_SOURCE
|
<define>BOOST_PYTHON_SOURCE
|
||||||
@@ -61,7 +63,12 @@ lib boost_python
|
|||||||
# python_for_extensions is a target defined by Boost.Build to
|
# python_for_extensions is a target defined by Boost.Build to
|
||||||
# provide the Python include paths, and on Windows, the Python
|
# provide the Python include paths, and on Windows, the Python
|
||||||
# import library, as usage requirements.
|
# import library, as usage requirements.
|
||||||
<library>/python//python_for_extensions
|
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
|
||||||
|
|
||||||
|
# we prevent building when there is no python available
|
||||||
|
# as it's not possible anyway, and to cause dependents to
|
||||||
|
# fail to build
|
||||||
|
[ unless [ python.configured ] : <build>no ]
|
||||||
|
|
||||||
: # default build
|
: # default build
|
||||||
<link>shared
|
<link>shared
|
||||||
@@ -69,9 +76,3 @@ lib boost_python
|
|||||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||||
<link>shared:<define>BOOST_PYTHON_DYNAMIC_LIB
|
<link>shared:<define>BOOST_PYTHON_DYNAMIC_LIB
|
||||||
;
|
;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ECHO "warning: Python location is not configured" ;
|
|
||||||
ECHO "warning: the Boost.Python library won't be built" ;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -32,7 +32,43 @@
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<dl class="page-index">
|
<dl class="page-index">
|
||||||
<dt>Current CVS</dt>
|
<dt>Current SVN</dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<ul>
|
||||||
|
<li>Pythonic signatures are now automatically appended to the
|
||||||
|
docstrings.
|
||||||
|
|
||||||
|
<li>Use <a href="v2/docstring_options.html"
|
||||||
|
><code>docstring_options.hpp</code></a> header
|
||||||
|
control the content of docstrings.
|
||||||
|
|
||||||
|
<li>This new feature increases the size of the modules by about 14%.
|
||||||
|
If this is not acceptable it can be turned off by defining the macro
|
||||||
|
BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
|
||||||
|
defined are compatible.
|
||||||
|
</li>
|
||||||
|
<li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
|
||||||
|
macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
|
||||||
|
with older version of Boost.Python (see <a href="v2/pytype_function.html#examples">here</a>).
|
||||||
|
</li>
|
||||||
|
<li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
|
||||||
|
of another 14% size increase, proper pythonic type is generated for the "self"
|
||||||
|
parameter of the __init__ methods.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li> To support this new feature changes were made to the
|
||||||
|
<a href="v2/to_python_converter.html"><code>to_python_converter.hpp</code></a>,
|
||||||
|
<a href="v2/default_call_policies.html"><code>default_call_policies</code></a>,
|
||||||
|
<a href="v2/ResultConverter.html"><code>ResultConverter</code></a>,
|
||||||
|
<a href="v2/CallPolicies.html"><code>CallPolicies</code></a> and some others.
|
||||||
|
Efforts were made not to have interface breaking changes.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>12 May 2007 - 1.34.0 release</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<meta name="generator" content=
|
<meta name="generator" content=
|
||||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||||
|
|
||||||
<title>Boost.Python - CallPolicies Concept</title>
|
<title>Boost.Python - CallPolicies Concept</title>
|
||||||
</head>
|
</head>
|
||||||
@@ -60,6 +60,7 @@
|
|||||||
|
|
||||||
<li><code>postcall</code> - Python argument tuple and result management
|
<li><code>postcall</code> - Python argument tuple and result management
|
||||||
after the wrapped object is invoked</li>
|
after the wrapped object is invoked</li>
|
||||||
|
<li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h2><a name="composition"></a>CallPolicies Composition</h2>
|
<h2><a name="composition"></a>CallPolicies Composition</h2>
|
||||||
@@ -132,6 +133,15 @@
|
|||||||
reference count must be decremented; if another existing object is
|
reference count must be decremented; if another existing object is
|
||||||
returned, its reference count must be incremented.</td>
|
returned, its reference count must be incremented.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><code>P::extract_return_type</code></td>
|
||||||
|
|
||||||
|
<td>A model of <a href=
|
||||||
|
"../../../doc/refmanual/metafunction.html">Metafunction</a>.</td>
|
||||||
|
|
||||||
|
<td>An MPL unary <a href=
|
||||||
|
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
Models of CallPolicies are required to be <a href=
|
Models of CallPolicies are required to be <a href=
|
||||||
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
|
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||||
<!-- Software License, Version 1.0. (See accompanying -->
|
<!-- Software License, Version 1.0. (See accompanying -->
|
||||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||||
<title>Boost.Python - ResultConverter Concept</title>
|
<title>Boost.Python - ResultConverter Concept</title>
|
||||||
</head>
|
</head>
|
||||||
<body link="#0000ff" vlink="#800080">
|
<body link="#0000ff" vlink="#800080">
|
||||||
@@ -24,10 +26,12 @@
|
|||||||
<dl class="page-index">
|
<dl class="page-index">
|
||||||
<dt><a href="#introduction">Introduction</a></dt>
|
<dt><a href="#introduction">Introduction</a></dt>
|
||||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||||
|
<dd>
|
||||||
<dl class="page-index">
|
<dl class="page-index">
|
||||||
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
|
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
|
||||||
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
|
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
|
||||||
</dl>
|
</dl>
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h2><a name="introduction"></a>Introduction</h2>
|
<h2><a name="introduction"></a>Introduction</h2>
|
||||||
@@ -79,6 +83,13 @@ denotes an object of type <code><b>R</b></code>.
|
|||||||
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
|
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
|
||||||
should return non-zero.</td>
|
should return non-zero.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><code>c.get_pytype()</code></td>
|
||||||
|
<td><code>PyTypeObject const*</code></td>
|
||||||
|
<td>A pointer to a Python Type object corresponding to result of the conversion,
|
||||||
|
or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
|
||||||
|
the generated type in the documentation will be <b>object</b> .</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>
|
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>
|
||||||
|
|||||||
@@ -139,6 +139,41 @@
|
|||||||
compares <code>typeid(T).name()</code> instead of using and comparing
|
compares <code>typeid(T).name()</code> instead of using and comparing
|
||||||
the <code>std::type_info</code> objects directly.</td>
|
the <code>std::type_info</code> objects directly.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
|
||||||
|
|
||||||
|
<td valign="top" align="center"><i>not defined</i></td>
|
||||||
|
|
||||||
|
<td valign="top">If defined for a module no pythonic signatures are generated
|
||||||
|
for the docstrings of the module functions, and no python type is associated with any
|
||||||
|
of the converters registered by the module. This also reduces the binary size of the
|
||||||
|
module by about 14% (gcc compiled).<br>
|
||||||
|
If defined for the boost_python runtime library, the default for the
|
||||||
|
<code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
|
||||||
|
|
||||||
|
<td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
|
||||||
|
|
||||||
|
<td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
|
||||||
|
which do not support pythonic signatures. For example usage see
|
||||||
|
<a href="pytype_function.html#examples">here</a>.
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
|
||||||
|
|
||||||
|
<td valign="top" align="center"><i>not defined</i></td>
|
||||||
|
|
||||||
|
<td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
|
||||||
|
is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
|
||||||
|
by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ namespace boost { namespace python
|
|||||||
static PyObject* postcall(PyObject*, PyObject* result);
|
static PyObject* postcall(PyObject*, PyObject* result);
|
||||||
typedef <a href=
|
typedef <a href=
|
||||||
"#default_result_converter-spec">default_result_converter</a> result_converter;
|
"#default_result_converter-spec">default_result_converter</a> result_converter;
|
||||||
|
template <class Sig> struct extract_return_type : mpl::front<Sig>{};
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
</pre>
|
</pre>
|
||||||
@@ -161,7 +162,7 @@ struct return_value_policy : Base
|
|||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||||
13 November, 2002
|
11 June, 2007
|
||||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ namespace boost { namespace python {
|
|||||||
|
|
||||||
docstring_options(bool show_user_defined, bool show_signatures);
|
docstring_options(bool show_user_defined, bool show_signatures);
|
||||||
|
|
||||||
|
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||||
|
|
||||||
~docstring_options();
|
~docstring_options();
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -117,6 +119,18 @@ namespace boost { namespace python {
|
|||||||
void
|
void
|
||||||
enable_signatures();
|
enable_signatures();
|
||||||
|
|
||||||
|
void
|
||||||
|
disable_py_signatures();
|
||||||
|
|
||||||
|
void
|
||||||
|
enable_py_signatures();
|
||||||
|
|
||||||
|
void
|
||||||
|
disable_cpp_signatures();
|
||||||
|
|
||||||
|
void
|
||||||
|
enable_cpp_signatures();
|
||||||
|
|
||||||
void
|
void
|
||||||
disable_all();
|
disable_all();
|
||||||
|
|
||||||
@@ -139,7 +153,7 @@ docstring_options(bool show_all=true);
|
|||||||
object which controls the appearance of function and
|
object which controls the appearance of function and
|
||||||
member-function docstrings defined in the code that follows. If
|
member-function docstrings defined in the code that follows. If
|
||||||
<code>show_all</code> is <code>true</code>, both the
|
<code>show_all</code> is <code>true</code>, both the
|
||||||
user-defined docstrings and the automatically generated C++
|
user-defined docstrings and the automatically generated Python and C++
|
||||||
signatures are shown. If <code>show_all</code> is
|
signatures are shown. If <code>show_all</code> is
|
||||||
<code>false</code> the <code>__doc__</code> attributes are
|
<code>false</code> the <code>__doc__</code> attributes are
|
||||||
<code>None</code>.</dt>
|
<code>None</code>.</dt>
|
||||||
@@ -154,12 +168,29 @@ docstring_options(bool show_user_defined, bool show_signatures);
|
|||||||
member-function docstrings defined in the code that follows.
|
member-function docstrings defined in the code that follows.
|
||||||
Iff <code>show_user_defined</code> is <code>true</code>, the
|
Iff <code>show_user_defined</code> is <code>true</code>, the
|
||||||
user-defined docstrings are shown. Iff
|
user-defined docstrings are shown. Iff
|
||||||
<code>show_signatures</code> is <code>true</code>, C++
|
<code>show_signatures</code> is <code>true</code>, Python and C++
|
||||||
signatures are automatically added. If both
|
signatures are automatically added. If both
|
||||||
<code>show_user_defined</code> and <code>show_signatures</code>
|
<code>show_user_defined</code> and <code>show_signatures</code>
|
||||||
are <code>false</code>, the <code>__doc__</code> attributes are
|
are <code>false</code>, the <code>__doc__</code> attributes are
|
||||||
<code>None</code>.</dt>
|
<code>None</code>.</dt>
|
||||||
</dl>
|
</dl>
|
||||||
|
<pre>
|
||||||
|
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<dl class="function-semantics">
|
||||||
|
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
|
||||||
|
object which controls the appearance of function and
|
||||||
|
member-function docstrings defined in the code that follows.
|
||||||
|
Iff <code>show_user_defined</code> is <code>true</code>, the
|
||||||
|
user-defined docstrings are shown. Iff
|
||||||
|
<code>show_py_signatures</code> is <code>true</code>, Python
|
||||||
|
signatures are automatically added. Iff
|
||||||
|
<code>show_cpp_signatures</code> is <code>true</code>, C++
|
||||||
|
signatures are automatically added. If all parameters are
|
||||||
|
<code>false</code>, the <code>__doc__</code> attributes are
|
||||||
|
<code>None</code>.</dt>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<h4><a name="docstring_options-spec-dtors" id=
|
<h4><a name="docstring_options-spec-dtors" id=
|
||||||
"docstring_options-spec-dtors"></a>Class
|
"docstring_options-spec-dtors"></a>Class
|
||||||
@@ -186,6 +217,10 @@ void disable_user_defined();
|
|||||||
void enable_user_defined();
|
void enable_user_defined();
|
||||||
void disable_signatures();
|
void disable_signatures();
|
||||||
void enable_signatures();
|
void enable_signatures();
|
||||||
|
void disable_py_signatures();
|
||||||
|
void enable_py_signatures();
|
||||||
|
void disable_cpp_signatures();
|
||||||
|
void enable_cpp_signatures();
|
||||||
void disable_all();
|
void disable_all();
|
||||||
void enable_all();
|
void enable_all();
|
||||||
</pre>
|
</pre>
|
||||||
@@ -196,7 +231,7 @@ void enable_all();
|
|||||||
<code>*_user_defined()</code> and <code>*_signatures()</code>
|
<code>*_user_defined()</code> and <code>*_signatures()</code>
|
||||||
member functions are provided for fine-grained control. The
|
member functions are provided for fine-grained control. The
|
||||||
<code>*_all()</code> member functions are convenient shortcuts
|
<code>*_all()</code> member functions are convenient shortcuts
|
||||||
to manipulate both settings simultaneously.</dt>
|
to manipulate all settings simultaneously.</dt>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h2><a name="examples" id="examples"></a>Examples</h2>
|
<h2><a name="examples" id="examples"></a>Examples</h2>
|
||||||
@@ -219,7 +254,7 @@ BOOST_PYTHON_MODULE(demo)
|
|||||||
<pre>
|
<pre>
|
||||||
>>> import demo
|
>>> import demo
|
||||||
>>> print demo.foo.__doc__
|
>>> print demo.foo.__doc__
|
||||||
foo doc
|
foo() -> None : foo doc
|
||||||
C++ signature:
|
C++ signature:
|
||||||
foo(void) -> void
|
foo(void) -> void
|
||||||
</pre>If compiled with
|
</pre>If compiled with
|
||||||
@@ -253,21 +288,33 @@ BOOST_PYTHON_MODULE(demo)
|
|||||||
def("foo3", foo3, arg("f"), "foo3 doc");
|
def("foo3", foo3, arg("f"), "foo3 doc");
|
||||||
doc_options.enable_user_defined();
|
doc_options.enable_user_defined();
|
||||||
def("foo4", foo4, arg("d"), "foo4 doc");
|
def("foo4", foo4, arg("d"), "foo4 doc");
|
||||||
|
doc_options.enable_py_signatures();
|
||||||
|
def("foo5", foo4, arg("d"), "foo5 doc");
|
||||||
|
doc_options.disable_py_signatures();
|
||||||
|
doc_options.enable_cpp_signatures();
|
||||||
|
def("foo6", foo4, arg("d"), "foo6 doc");
|
||||||
}
|
}
|
||||||
</pre>Python code:
|
</pre>Python code:
|
||||||
<pre>
|
<pre>
|
||||||
>>> import demo
|
>>> import demo
|
||||||
>>> print demo.foo1.__doc__
|
>>> print demo.foo1.__doc__
|
||||||
foo1 doc
|
foo1( (int)i) -> int : foo1 doc
|
||||||
C++ signature:
|
C++ signature:
|
||||||
foo1(int i) -> int
|
foo1(int i) -> int
|
||||||
>>> print demo.foo2.__doc__
|
>>> print demo.foo2.__doc__
|
||||||
|
foo2( (int)l) -> int :
|
||||||
C++ signature:
|
C++ signature:
|
||||||
foo2(long l) -> int
|
foo2(long l) -> int
|
||||||
>>> print demo.foo3.__doc__
|
>>> print demo.foo3.__doc__
|
||||||
None
|
None
|
||||||
>>> print demo.foo4.__doc__
|
>>> print demo.foo4.__doc__
|
||||||
foo4 doc
|
foo4 doc
|
||||||
|
>>> print demo.foo5.__doc__
|
||||||
|
foo5( (float)d) -> int : foo5 doc
|
||||||
|
>>> print demo.foo6.__doc__
|
||||||
|
foo6 doc
|
||||||
|
C++ signature:
|
||||||
|
foo6(double d) -> int
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h4>Wrapping from multiple C++ scopes</h4>
|
<h4>Wrapping from multiple C++ scopes</h4>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace boost { namespace python
|
|||||||
template <class T>
|
template <class T>
|
||||||
class enum_ : public <a href="object.html#object-spec">object</a>
|
class enum_ : public <a href="object.html#object-spec">object</a>
|
||||||
{
|
{
|
||||||
enum_(char const* name);
|
enum_(char const* name, char const* doc = 0);
|
||||||
enum_<T>& value(char const* name, T);
|
enum_<T>& value(char const* name, T);
|
||||||
enum_<T>& export_values();
|
enum_<T>& export_values();
|
||||||
};
|
};
|
||||||
@@ -99,7 +99,7 @@ namespace boost { namespace python
|
|||||||
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
|
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
|
||||||
constructors</h4>
|
constructors</h4>
|
||||||
<pre>
|
<pre>
|
||||||
enum_(char const* name);
|
enum_(char const* name, char const* doc=0);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<dl class="function-semantics">
|
<dl class="function-semantics">
|
||||||
@@ -131,7 +131,7 @@ inline enum_<T>& value(char const* name, T x);
|
|||||||
|
|
||||||
<dt><b>Effects:</b> adds an instance of the wrapped enumeration
|
<dt><b>Effects:</b> adds an instance of the wrapped enumeration
|
||||||
type with value <code>x</code> to the type's dictionary as the
|
type with value <code>x</code> to the type's dictionary as the
|
||||||
<code>name</code>d attribute</dt>.
|
<code>name</code>d attribute.</dt>
|
||||||
|
|
||||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ inline enum_<T>& export_values();
|
|||||||
<dt><b>Effects:</b> sets attributes in the current <a
|
<dt><b>Effects:</b> sets attributes in the current <a
|
||||||
href="scope.html#scope-spec"><code>scope</code></a> with the
|
href="scope.html#scope-spec"><code>scope</code></a> with the
|
||||||
same names and values as all enumeration values exposed so far
|
same names and values as all enumeration values exposed so far
|
||||||
by calling <code>value()</code></dt>.
|
by calling <code>value()</code>.</dt>
|
||||||
|
|
||||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||||
|
|
||||||
|
|||||||
216
doc/v2/function_doc_signature.html
Normal file
216
doc/v2/function_doc_signature.html
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
|
<!-- Copyright Nikolay Mladenov 2007. 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) -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content=
|
||||||
|
"text/html; charset=us-ascii">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||||
|
|
||||||
|
<title>Boost.Python -
|
||||||
|
<boost/python/doobject/function_doc_signature.hpp></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table border="0" cellpadding="7" cellspacing="0" width="100%"
|
||||||
|
summary="header">
|
||||||
|
<tr>
|
||||||
|
<td valign="top" width="300">
|
||||||
|
<h3><a href="../../../../index.htm"><img height="86" width=
|
||||||
|
"277" alt="C++ Boost" src="../../../../boost.png" border=
|
||||||
|
"0"></a></h3>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td valign="top">
|
||||||
|
<h1 align="center"><a href=
|
||||||
|
"../index.html">Boost.Python</a></h1>
|
||||||
|
|
||||||
|
<h2 align="center">Header
|
||||||
|
<boost/python/object/function_doc_signature.hpp></h2>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Contents</h2>
|
||||||
|
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#introduction">Introduction</a></dt>
|
||||||
|
|
||||||
|
<dt><a href="#classes">Classes</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#function_doc_signature_generator-spec">Class
|
||||||
|
<code>function_doc_signature_generator</code></a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#function_doc_signature_generator-spec-synopsis">Class
|
||||||
|
<code>function_doc_signature_generator</code> synopsis</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><a href="#examples">Examples</a></dt>
|
||||||
|
</dl>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2><a name="introduction" id=
|
||||||
|
"introduction"></a>Introduction</h2>
|
||||||
|
|
||||||
|
<p>Boost.Python supports docstrings with automatic
|
||||||
|
appending of Pythonic and C++ signatures. This feature is implemented
|
||||||
|
by <code>class function_doc_signature_generator</code>
|
||||||
|
The class uses all of the overloads, supplied arg names and default values, as well as
|
||||||
|
the user-defined docstrings, to generate documentation for a given function.</p>
|
||||||
|
|
||||||
|
<h2><a name="classes" id="classes"></a>Classes</h2>
|
||||||
|
|
||||||
|
<h3><a name="function_doc_signature_generator-spec" id=
|
||||||
|
"function_doc_signature_generator-spec"></a>Class
|
||||||
|
<code>function_doc_signature_generator</code></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The class has only one public function which returns a list of strings documenting the
|
||||||
|
overloads of a function.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4><a name="function_doc_signature_generator-spec-synopsis" id=
|
||||||
|
"function_doc_signature_generator-spec-synopsis"></a>Class
|
||||||
|
<code>function_doc_signature_generator</code> synopsis</h4>
|
||||||
|
<pre>
|
||||||
|
namespace boost { namespace python { namespace objects {
|
||||||
|
|
||||||
|
class function_doc_signature_generator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static list function_doc_signatures(function const *f);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h2><a name="examples" id="examples"></a>Examples</h2>
|
||||||
|
|
||||||
|
<h4>Docstrings generated with <code>function_doc_signature_generator</code></h4>
|
||||||
|
<pre>
|
||||||
|
#include <boost/python/module.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/python/args.hpp>
|
||||||
|
#include <boost/python/tuple.hpp>
|
||||||
|
#include <boost/python/class.hpp>
|
||||||
|
#include <boost/python/overloads.hpp>
|
||||||
|
#include <boost/python/raw_function.hpp>
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||||
|
{
|
||||||
|
return make_tuple(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
|
||||||
|
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||||
|
{
|
||||||
|
return make_tuple(x, y, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
|
||||||
|
|
||||||
|
tuple raw_func(tuple args, dict kw)
|
||||||
|
{
|
||||||
|
return make_tuple(args, kw);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(args_ext)
|
||||||
|
{
|
||||||
|
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
|
||||||
|
, "This is f's docstring"
|
||||||
|
);
|
||||||
|
|
||||||
|
def("raw", raw_function(raw_func));
|
||||||
|
|
||||||
|
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
|
||||||
|
|
||||||
|
|
||||||
|
class_<X>("X", "This is X's docstring", init<>(args("self")))
|
||||||
|
.def("f", &X::f
|
||||||
|
, "This is X.f's docstring"
|
||||||
|
, args("self","x", "y", "z"))
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
Python code:
|
||||||
|
<pre>
|
||||||
|
>>> import args_ext
|
||||||
|
>>> help(args_ext)
|
||||||
|
Help on module args_ext:
|
||||||
|
|
||||||
|
NAME
|
||||||
|
args_ext
|
||||||
|
|
||||||
|
FILE
|
||||||
|
args_ext.pyd
|
||||||
|
|
||||||
|
CLASSES
|
||||||
|
Boost.Python.instance(__builtin__.object)
|
||||||
|
X
|
||||||
|
|
||||||
|
class X(Boost.Python.instance)
|
||||||
|
| This is X's docstring
|
||||||
|
|
|
||||||
|
| Method resolution order:
|
||||||
|
| X
|
||||||
|
| Boost.Python.instance
|
||||||
|
| __builtin__.object
|
||||||
|
|
|
||||||
|
| Methods defined here:
|
||||||
|
|
|
||||||
|
| __init__(...)
|
||||||
|
| __init__( (object)self) -> None :
|
||||||
|
| C++ signature:
|
||||||
|
| void __init__(struct _object *)
|
||||||
|
|
|
||||||
|
| f(...)
|
||||||
|
| f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring
|
||||||
|
| C++ signature:
|
||||||
|
| class boost::python::tuple f(struct X {lvalue},int,double,char const *)
|
||||||
|
|
|
||||||
|
| .................
|
||||||
|
|
|
||||||
|
FUNCTIONS
|
||||||
|
f(...)
|
||||||
|
f([ (int)x=1 [, (float)y=4.25 [, (str)z='wow']]]) -> tuple : This is f's docstring
|
||||||
|
C++ signature:
|
||||||
|
class boost::python::tuple f([ int=1 [,double=4.25 [,char const *='wow']]])
|
||||||
|
|
||||||
|
f1(...)
|
||||||
|
f1([ (int)x [, (float)y [, (str)z]]]) -> tuple : f1's docstring
|
||||||
|
C++ signature:
|
||||||
|
class boost::python::tuple f1([ int [,double [,char const *]]])
|
||||||
|
|
||||||
|
raw(...)
|
||||||
|
object raw(tuple args, dict kwds) :
|
||||||
|
C++ signature:
|
||||||
|
object raw(tuple args, dict kwds)
|
||||||
|
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p><i>© Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
370
doc/v2/pytype_function.html
Normal file
370
doc/v2/pytype_function.html
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
|
<!-- Copyright Nikolay Mladenov 2007. 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) -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content=
|
||||||
|
"text/html; charset=us-ascii">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||||
|
|
||||||
|
<title>Boost.Python -
|
||||||
|
<boost/python/doobject/pytype_function.hpp></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table border="0" cellpadding="7" cellspacing="0" width="100%"
|
||||||
|
summary="header">
|
||||||
|
<tr>
|
||||||
|
<td valign="top" width="300">
|
||||||
|
<h3><a href="../../../../index.htm"><img height="86" width=
|
||||||
|
"277" alt="C++ Boost" src="../../../../boost.png" border=
|
||||||
|
"0"></a></h3>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td valign="top">
|
||||||
|
<h1 align="center"><a href=
|
||||||
|
"../index.html">Boost.Python</a></h1>
|
||||||
|
|
||||||
|
<h2 align="center">Header
|
||||||
|
<boost/python/converter/pytype_function.hpp></h2>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Contents</h2>
|
||||||
|
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#introduction">Introduction</a></dt>
|
||||||
|
|
||||||
|
<dt><a href="#classes">Classes</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#wrap_pytype-spec">Class
|
||||||
|
<code>wrap_pytype</code></a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#wrap_pytype-spec-synopsis">Class
|
||||||
|
<code>wrap_pytype</code> synopsis</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#registered_pytype-spec">Class
|
||||||
|
<code>registered_pytype</code></a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#registered_pytype-spec-synopsis">Class
|
||||||
|
<code>registered_pytype</code> synopsis</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#expected_from_python_type-spec">Class
|
||||||
|
<code>expected_from_python_type</code></a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#expected_from_python_type-spec-synopsis">Class
|
||||||
|
<code>expected_from_python_type</code> synopsis</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#to_python_target_type-spec">Class
|
||||||
|
<code>to_python_target_type</code></a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="page-index">
|
||||||
|
<dt><a href="#to_python_target_type-spec-synopsis">Class
|
||||||
|
<code>to_python_target_type</code> synopsis</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><a href="#examples">Examples</a></dt>
|
||||||
|
</dl>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2><a name="introduction" id=
|
||||||
|
"introduction"></a>Introduction</h2>
|
||||||
|
|
||||||
|
<p>To support Pythonic signatures the converters should supply a <code>get_pytype</code> function
|
||||||
|
returning a pointer to the associated <code>PyTypeObject</code>. See for example
|
||||||
|
<a href="ResultConverter.html#ResultConverter-concept">ResultConverter</a> or
|
||||||
|
<a href="to_python_converter.html#to_python_converter-spec">to_python_converter</a>.
|
||||||
|
The classes in this header file are meant to be used when implmenting <code>get_pytype</code>.
|
||||||
|
There are also <code>_direct</code> versions of the templates of <code>class T</code> which
|
||||||
|
should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2><a name="classes" id="classes"></a>Classes</h2>
|
||||||
|
|
||||||
|
<h3><a name="wrap_pytype-spec" id=
|
||||||
|
"wrap_pytype-spec"></a>Class
|
||||||
|
<code>wrap_pytype</code></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This template generates a static <code>get_pytype</code> member returning the template parameter.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4><a name="wrap_pytype-spec-synopsis" id=
|
||||||
|
"wrap_pytype-spec-synopsis"></a>Class
|
||||||
|
<code>wrap_pytype</code> synopsis</h4>
|
||||||
|
<pre>
|
||||||
|
namespace boost { namespace python { namespace converter{
|
||||||
|
|
||||||
|
template < PyTypeObject const *pytype >
|
||||||
|
class wrap_pytype
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static PyTypeObject const *get_pytype(){return pytype; }
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3><a name="registered_pytype-spec" id=
|
||||||
|
"registered_pytype-spec"></a>Class
|
||||||
|
<code>registered_pytype</code></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This template should be used with template parameters which are (possibly decorated)
|
||||||
|
types exported to python using <a href="class.html"><code>class_</code></a>.
|
||||||
|
The generated a static <code>get_pytype</code> member
|
||||||
|
returns the corresponding python type.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4><a name="registered_pytype-spec-synopsis" id=
|
||||||
|
"registered_pytype-spec-synopsis"></a>Class
|
||||||
|
<code>registered_pytype</code> synopsis</h4>
|
||||||
|
<pre>
|
||||||
|
namespace boost { namespace python { namespace converter{
|
||||||
|
|
||||||
|
template < class T >
|
||||||
|
class registered_pytype
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static PyTypeObject const *get_pytype();
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3><a name="expected_from_python_type-spec" id=
|
||||||
|
"expected_from_python_type-spec"></a>Class
|
||||||
|
<code>expected_from_python_type</code></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This template generates a static <code>get_pytype</code> member which inspects the registered
|
||||||
|
<code>from_python</code> converters for the type <code>T</code> and returns a matching python type.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4><a name="expected_from_python_type-spec-synopsis" id=
|
||||||
|
"expected_from_python_type-spec-synopsis"></a>Class
|
||||||
|
<code>expected_from_python_type</code> synopsis</h4>
|
||||||
|
<pre>
|
||||||
|
namespace boost { namespace python { namespace converter{
|
||||||
|
|
||||||
|
template < class T >
|
||||||
|
class expected_from_python_type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static PyTypeObject const *get_pytype();
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3><a name="to_python_target_type-spec" id=
|
||||||
|
"to_python_target_type-spec"></a>Class
|
||||||
|
<code>to_python_target_type</code></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This template generates a static <code>get_pytype</code> member returning the
|
||||||
|
python type to which T can be converted.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4><a name="to_python_target_type-spec-synopsis" id=
|
||||||
|
"to_python_target_type-spec-synopsis"></a>Class
|
||||||
|
<code>to_python_target_type</code> synopsis</h4>
|
||||||
|
<pre>
|
||||||
|
namespace boost { namespace python { namespace converter{
|
||||||
|
|
||||||
|
template < class T >
|
||||||
|
class to_python_target_type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static PyTypeObject const *get_pytype();
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h2><a name="examples" id="examples"></a>Examples</h2>
|
||||||
|
|
||||||
|
This example presumes that someone has implemented the standard <a href=
|
||||||
|
"http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
|
||||||
|
module</a> from the Python documentation, and placed the corresponding
|
||||||
|
declarations in <code>"noddy.h"</code>. Because
|
||||||
|
<code>noddy_NoddyObject</code> is the ultimate trivial extension type,
|
||||||
|
the example is a bit contrived: it wraps a function for which all
|
||||||
|
information is contained in the <i>type</i> of its return value.
|
||||||
|
|
||||||
|
<h3>C++ module definition</h3>
|
||||||
|
<pre>
|
||||||
|
#include <boost/python/reference.hpp>
|
||||||
|
#include <boost/python/module.hpp>
|
||||||
|
#include "noddy.h"
|
||||||
|
|
||||||
|
struct tag {};
|
||||||
|
tag make_tag() { return tag(); }
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
struct tag_to_noddy
|
||||||
|
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
|
||||||
|
: wrap_pytype<&noddy_NoddyType> //inherits get_pytype from wrap_pytype
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
static PyObject* convert(tag const& x)
|
||||||
|
{
|
||||||
|
return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(to_python_converter)
|
||||||
|
{
|
||||||
|
def("make_tag", make_tag);
|
||||||
|
to_python_converter<tag, tag_to_noddy
|
||||||
|
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
|
||||||
|
, true
|
||||||
|
#endif
|
||||||
|
>(); //"true" because tag_to_noddy has member get_pytype
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<p>The following example registers to and from python converters using the templates
|
||||||
|
<code>expected_from_python_type</code> and <code>to_pyhton_target_type</code>.
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
#include <boost/python/module.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/python/extract.hpp>
|
||||||
|
#include <boost/python/to_python_converter.hpp>
|
||||||
|
#include <boost/python/class.hpp>
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B(const A& a_):a(a_){}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Converter from A to python int
|
||||||
|
struct BToPython
|
||||||
|
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
|
||||||
|
: converter::to_python_target_type<A> //inherits get_pytype
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
static PyObject* convert(const B& b)
|
||||||
|
{
|
||||||
|
return incref(object(b.a).ptr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Conversion from python int to A
|
||||||
|
struct BFromPython
|
||||||
|
{
|
||||||
|
BFromPython()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back
|
||||||
|
( &convertible
|
||||||
|
, &construct
|
||||||
|
, type_id< B >()
|
||||||
|
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
|
||||||
|
, &converter::expected_from_python_type<A>::get_pytype//convertible to A can be converted to B
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
extract<const A&> ex(obj_ptr);
|
||||||
|
if (!ex.check()) return 0;
|
||||||
|
return obj_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
void* storage = (
|
||||||
|
(converter::rvalue_from_python_storage< B >*)data)-> storage.bytes;
|
||||||
|
|
||||||
|
extract<const A&> ex(obj_ptr);
|
||||||
|
new (storage) B(ex());
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
B func(const B& b) { return b ; }
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(pytype_function_ext)
|
||||||
|
{
|
||||||
|
to_python_converter< B , BToPython
|
||||||
|
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
|
||||||
|
,true
|
||||||
|
#endif
|
||||||
|
>(); //has get_pytype
|
||||||
|
BFromPython();
|
||||||
|
|
||||||
|
class_<A>("A") ;
|
||||||
|
|
||||||
|
def("func", &func);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>>> from pytype_function_ext import *
|
||||||
|
>>> print func.__doc__
|
||||||
|
func( (A)arg1) -> A :
|
||||||
|
C++ signature:
|
||||||
|
struct B func(struct B)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<p><i>© Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -609,6 +609,66 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<a name="function_documentation"></a>
|
||||||
|
|
||||||
|
<h3>Function documentation</h3>
|
||||||
|
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"function_doc_signature.html">function_doc_signature.hpp</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"function_doc_signature.html#classes">Classes</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"function_doc_signature.html#function_doc_signature_generator-spec">function_doc_signature_generator</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html">pytype_function.hpp</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html#classes">Classes</a></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html#wrap_pytype-spec">wrap_pytype</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html#expected_from_python_type-spec">expected_from_python_type</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html#to_python_target_type-spec">to_python_target_type</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
<dl class="index">
|
||||||
|
<dt><a href=
|
||||||
|
"pytype_function.html#registered_pytype-spec">registered_pytype</a></dt>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
<a name="models_of_call_policies"></a>
|
<a name="models_of_call_policies"></a>
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,8 @@ namespace boost { namespace python
|
|||||||
{
|
{
|
||||||
static PyObject* postcall(PyObject*, PyObject* result);
|
static PyObject* postcall(PyObject*, PyObject* result);
|
||||||
struct result_converter{ template <class T> struct apply; };
|
struct result_converter{ template <class T> struct apply; };
|
||||||
|
template <class Sig> struct extract_return_type : mpl::at_c<Sig, arg_pos>{};
|
||||||
|
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
</pre>
|
</pre>
|
||||||
|
|||||||
@@ -108,6 +108,23 @@
|
|||||||
<td>A class type whose static member function <code>convert</code>
|
<td>A class type whose static member function <code>convert</code>
|
||||||
does the real work of the conversion.</td>
|
does the real work of the conversion.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>bool has_get_pytype = false</code></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<code>PyTypeObject const * p = Conversion::get_pytype() </code>.</td>
|
||||||
|
|
||||||
|
<td><b>Optional member</b> - if <code>Conversion</code> has <code>get_pytype</code> member supply
|
||||||
|
<code>true</code> for this parameters.
|
||||||
|
If present <code>get_pytype</code> is used to document the return type
|
||||||
|
of functions using this conversion. The <code>get_pytype</code> may be implemented
|
||||||
|
using the classes and functions
|
||||||
|
from <a href="pytype_function.html"><code>pytype_function.hpp</code></a>
|
||||||
|
<b>NOTE :</b> For backward compatibility this parameter may be passed after
|
||||||
|
checking if <code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code> is defined (see
|
||||||
|
<a href="pytype_function.html#examples">here</a>).
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h4><a name="to_python_converter-spec-synopsis"></a>Class template
|
<h4><a name="to_python_converter-spec-synopsis"></a>Class template
|
||||||
@@ -115,7 +132,7 @@
|
|||||||
<pre>
|
<pre>
|
||||||
namespace boost { namespace python
|
namespace boost { namespace python
|
||||||
{
|
{
|
||||||
template <class T, class Conversion>
|
template <class T, class Conversion, bool convertion_has_get_pytype_member=false>
|
||||||
struct to_python_converter
|
struct to_python_converter
|
||||||
{
|
{
|
||||||
to_python_converter();
|
to_python_converter();
|
||||||
@@ -160,12 +177,16 @@ struct tag_to_noddy
|
|||||||
{
|
{
|
||||||
return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
|
return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
return &noddy_NoddyType;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(to_python_converter)
|
BOOST_PYTHON_MODULE(to_python_converter)
|
||||||
{
|
{
|
||||||
def("make_tag", make_tag);
|
def("make_tag", make_tag);
|
||||||
to_python_converter<tag, tag_to_noddy>();
|
to_python_converter<tag, tag_to_noddy, true>(); //"true" because tag_to_noddy has member get_pytype
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -195,7 +216,7 @@ BOOST_PYTHON_MODULE(to_python_converter)
|
|||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||||
13 November, 2002
|
11 June, 2007
|
||||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace { // Avoid cluttering the global namespace.
|
|||||||
return boost::python::incref(
|
return boost::python::incref(
|
||||||
boost::python::make_tuple(p.first, p.second).ptr());
|
boost::python::make_tuple(p.first, p.second).ptr());
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper for convenience.
|
// Helper for convenience.
|
||||||
@@ -28,7 +29,9 @@ namespace { // Avoid cluttering the global namespace.
|
|||||||
{
|
{
|
||||||
boost::python::to_python_converter<
|
boost::python::to_python_converter<
|
||||||
std::pair<T1, T2>,
|
std::pair<T1, T2>,
|
||||||
std_pair_to_tuple<T1, T2> >();
|
std_pair_to_tuple<T1, T2>,
|
||||||
|
true //std_pair_to_tuple has get_pytype
|
||||||
|
>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ struct as_to_python_function
|
|||||||
// but c'est la vie.
|
// but c'est la vie.
|
||||||
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
|
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}}} // namespace boost::python::converter
|
}}} // namespace boost::python::converter
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use expr to create the PyObject corresponding to x
|
// Use expr to create the PyObject corresponding to x
|
||||||
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
|
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
|
||||||
template <> struct to_python_value<T&> \
|
template <> struct to_python_value<T&> \
|
||||||
: detail::builtin_to_python \
|
: detail::builtin_to_python \
|
||||||
{ \
|
{ \
|
||||||
@@ -55,6 +55,10 @@ namespace detail
|
|||||||
{ \
|
{ \
|
||||||
return (expr); \
|
return (expr); \
|
||||||
} \
|
} \
|
||||||
|
inline PyTypeObject const* get_pytype() const \
|
||||||
|
{ \
|
||||||
|
return (pytype); \
|
||||||
|
} \
|
||||||
}; \
|
}; \
|
||||||
template <> struct to_python_value<T const&> \
|
template <> struct to_python_value<T const&> \
|
||||||
: detail::builtin_to_python \
|
: detail::builtin_to_python \
|
||||||
@@ -63,6 +67,10 @@ namespace detail
|
|||||||
{ \
|
{ \
|
||||||
return (expr); \
|
return (expr); \
|
||||||
} \
|
} \
|
||||||
|
inline PyTypeObject const* get_pytype() const \
|
||||||
|
{ \
|
||||||
|
return (pytype); \
|
||||||
|
} \
|
||||||
};
|
};
|
||||||
|
|
||||||
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
|
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
|
||||||
@@ -77,25 +85,25 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specialize argument and return value converters for T using expr
|
// Specialize argument and return value converters for T using expr
|
||||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
|
||||||
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
|
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
|
||||||
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
|
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
|
||||||
|
|
||||||
// Specialize converters for signed and unsigned T to Python Int
|
// Specialize converters for signed and unsigned T to Python Int
|
||||||
# define BOOST_PYTHON_TO_INT(T) \
|
# 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), &PyInt_Type) \
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
|
||||||
unsigned T \
|
unsigned T \
|
||||||
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
|
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
|
||||||
(std::numeric_limits<long>::max)()) \
|
(std::numeric_limits<long>::max)()) \
|
||||||
? ::PyLong_FromUnsignedLong(x) \
|
? ::PyLong_FromUnsignedLong(x) \
|
||||||
: ::PyInt_FromLong(x))
|
: ::PyInt_FromLong(x), &PyInt_Type)
|
||||||
|
|
||||||
// Bool is not signed.
|
// Bool is not signed.
|
||||||
#if PY_VERSION_HEX >= 0x02030000
|
#if PY_VERSION_HEX >= 0x02030000
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
|
||||||
#else
|
#else
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// note: handles signed char and unsigned char, but not char (see below)
|
// note: handles signed char and unsigned char, but not char (see below)
|
||||||
@@ -108,25 +116,25 @@ BOOST_PYTHON_TO_INT(long)
|
|||||||
// using Python's macro instead of Boost's - we don't seem to get the
|
// using Python's macro instead of Boost's - we don't seem to get the
|
||||||
// config right all the time.
|
// config right all the time.
|
||||||
# ifdef HAVE_LONG_LONG
|
# ifdef HAVE_LONG_LONG
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# undef BOOST_TO_PYTHON_INT
|
# 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, converter::do_return_to_python(x), &PyString_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
|
||||||
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
|
||||||
# endif
|
# endif
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
|
||||||
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
|
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
|
||||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
|
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
|
||||||
|
|
||||||
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
|
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
|
||||||
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
|
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ struct pyobject_traits<PyObject>
|
|||||||
// All objects are convertible to PyObject
|
// All objects are convertible to PyObject
|
||||||
static bool check(PyObject*) { return true; }
|
static bool check(PyObject*) { return true; }
|
||||||
static PyObject* checked_downcast(PyObject* x) { return x; }
|
static PyObject* checked_downcast(PyObject* x) { return x; }
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const* get_pytype() { return 0; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ struct pyobject_type
|
|||||||
(checked_downcast_impl)(x, pytype)
|
(checked_downcast_impl)(x, pytype)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const* get_pytype() { return pytype; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}}} // namespace boost::python::converter
|
}}} // namespace boost::python::converter
|
||||||
|
|||||||
132
include/boost/python/converter/pytype_function.hpp
Executable file
132
include/boost/python/converter/pytype_function.hpp
Executable file
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
|
||||||
|
// 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)
|
||||||
|
#ifndef WRAP_PYTYPE_NM20070606_HPP
|
||||||
|
# define WRAP_PYTYPE_NM20070606_HPP
|
||||||
|
|
||||||
|
# include <boost/python/detail/prefix.hpp>
|
||||||
|
# include <boost/python/converter/registered.hpp>
|
||||||
|
# include <boost/python/detail/unwind_type.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost { namespace python {
|
||||||
|
|
||||||
|
namespace converter
|
||||||
|
{
|
||||||
|
template <PyTypeObject const* python_type>
|
||||||
|
struct wrap_pytype
|
||||||
|
{
|
||||||
|
static PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
return python_type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef PyTypeObject const* (*pytype_function)();
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct unwind_type_id_helper{
|
||||||
|
typedef python::type_info result_type;
|
||||||
|
template <class U>
|
||||||
|
static result_type execute(U* ){
|
||||||
|
return python::type_id<U>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
|
||||||
|
{
|
||||||
|
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
|
||||||
|
{
|
||||||
|
return type_id<void>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline python::type_info unwind_type_id(boost::type<T>* p= 0)
|
||||||
|
{
|
||||||
|
return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct expected_pytype_for_arg
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
const converter::registration *r=converter::registry::query(
|
||||||
|
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
|
||||||
|
);
|
||||||
|
return r ? r->expected_from_python_type(): 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct registered_pytype
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
const converter::registration *r=converter::registry::query(
|
||||||
|
detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
|
||||||
|
);
|
||||||
|
return r ? r->m_class_object: 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct registered_pytype_direct
|
||||||
|
{
|
||||||
|
static PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
return registered<T>::converters.m_class_object;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct expected_from_python_type : expected_pytype_for_arg<T>{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct expected_from_python_type_direct
|
||||||
|
{
|
||||||
|
static PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
return registered<T>::converters.expected_from_python_type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct to_python_target_type
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
const converter::registration *r=converter::registry::query(
|
||||||
|
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
|
||||||
|
);
|
||||||
|
return r ? r->to_python_target_type(): 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct to_python_target_type_direct
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
return registered<T>::converters.to_python_target_type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}}} // namespace boost::python
|
||||||
|
|
||||||
|
#endif // WRAP_PYTYPE_NM20070606_HPP
|
||||||
@@ -27,6 +27,7 @@ struct rvalue_from_python_chain
|
|||||||
{
|
{
|
||||||
convertible_function convertible;
|
convertible_function convertible;
|
||||||
constructor_function construct;
|
constructor_function construct;
|
||||||
|
PyTypeObject const* (*expected_pytype)();
|
||||||
rvalue_from_python_chain* next;
|
rvalue_from_python_chain* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,6 +44,11 @@ struct BOOST_PYTHON_DECL registration
|
|||||||
// exception if no class has been registered.
|
// exception if no class has been registered.
|
||||||
PyTypeObject* get_class_object() const;
|
PyTypeObject* get_class_object() const;
|
||||||
|
|
||||||
|
// Return common denominator of the python class objects,
|
||||||
|
// convertable to target. Inspects the m_class_object and the value_chains.
|
||||||
|
PyTypeObject const* expected_from_python_type() const;
|
||||||
|
PyTypeObject const* to_python_target_type() const;
|
||||||
|
|
||||||
public: // data members. So sue me.
|
public: // data members. So sue me.
|
||||||
const python::type_info target_type;
|
const python::type_info target_type;
|
||||||
|
|
||||||
@@ -57,6 +63,8 @@ struct BOOST_PYTHON_DECL registration
|
|||||||
|
|
||||||
// The unique to_python converter for the associated C++ type.
|
// The unique to_python converter for the associated C++ type.
|
||||||
to_python_function_t m_to_python;
|
to_python_function_t m_to_python;
|
||||||
|
PyTypeObject const* (*m_to_python_target_type)();
|
||||||
|
|
||||||
|
|
||||||
// True iff this type is a shared_ptr. Needed for special rvalue
|
// True iff this type is a shared_ptr. Needed for special rvalue
|
||||||
// from_python handling.
|
// from_python handling.
|
||||||
@@ -77,6 +85,7 @@ inline registration::registration(type_info target_type, bool is_shared_ptr)
|
|||||||
, rvalue_chain(0)
|
, rvalue_chain(0)
|
||||||
, m_class_object(0)
|
, m_class_object(0)
|
||||||
, m_to_python(0)
|
, m_to_python(0)
|
||||||
|
, m_to_python_target_type(0)
|
||||||
, is_shared_ptr(is_shared_ptr)
|
, is_shared_ptr(is_shared_ptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,17 @@ namespace registry
|
|||||||
// Return a pointer to the corresponding registration, if one exists
|
// Return a pointer to the corresponding registration, if one exists
|
||||||
BOOST_PYTHON_DECL registration const* query(type_info);
|
BOOST_PYTHON_DECL registration const* query(type_info);
|
||||||
|
|
||||||
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
|
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info, PyTypeObject const* (*to_python_target_type)() = 0);
|
||||||
|
|
||||||
// Insert an lvalue from_python converter
|
// Insert an lvalue from_python converter
|
||||||
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
|
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info, PyTypeObject const* (*expected_pytype)() = 0);
|
||||||
|
|
||||||
// Insert an rvalue from_python converter
|
// Insert an rvalue from_python converter
|
||||||
BOOST_PYTHON_DECL void insert(
|
BOOST_PYTHON_DECL void insert(
|
||||||
convertible_function
|
convertible_function
|
||||||
, constructor_function
|
, constructor_function
|
||||||
, type_info
|
, type_info
|
||||||
|
, PyTypeObject const* (*expected_pytype)() = 0
|
||||||
);
|
);
|
||||||
|
|
||||||
// Insert an rvalue from_python converter at the tail of the
|
// Insert an rvalue from_python converter at the tail of the
|
||||||
@@ -45,6 +46,7 @@ namespace registry
|
|||||||
convertible_function
|
convertible_function
|
||||||
, constructor_function
|
, constructor_function
|
||||||
, type_info
|
, type_info
|
||||||
|
, PyTypeObject const* (*expected_pytype)() = 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
# include <boost/python/converter/from_python.hpp>
|
# include <boost/python/converter/from_python.hpp>
|
||||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||||
# include <boost/python/converter/registered.hpp>
|
# include <boost/python/converter/registered.hpp>
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
# include <boost/shared_ptr.hpp>
|
# include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python { namespace converter {
|
namespace boost { namespace python { namespace converter {
|
||||||
@@ -19,7 +22,11 @@ struct shared_ptr_from_python
|
|||||||
{
|
{
|
||||||
shared_ptr_from_python()
|
shared_ptr_from_python()
|
||||||
{
|
{
|
||||||
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
|
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
, &converter::expected_from_python_type_direct<T>::get_pytype
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
# include <boost/type_traits/is_pointer.hpp>
|
# include <boost/type_traits/is_pointer.hpp>
|
||||||
# include <boost/type_traits/is_reference.hpp>
|
# include <boost/type_traits/is_reference.hpp>
|
||||||
# include <boost/mpl/or.hpp>
|
# include <boost/mpl/or.hpp>
|
||||||
|
# include <boost/mpl/front.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
|
|
||||||
@@ -49,6 +50,12 @@ struct default_call_policies
|
|||||||
|
|
||||||
typedef default_result_converter result_converter;
|
typedef default_result_converter result_converter;
|
||||||
typedef PyObject* argument_package;
|
typedef PyObject* argument_package;
|
||||||
|
|
||||||
|
template <class Sig>
|
||||||
|
struct extract_return_type : mpl::front<Sig>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct default_result_converter
|
struct default_result_converter
|
||||||
|
|||||||
@@ -11,12 +11,15 @@
|
|||||||
# include <boost/python/type_id.hpp>
|
# include <boost/python/type_id.hpp>
|
||||||
# include <boost/python/handle.hpp>
|
# include <boost/python/handle.hpp>
|
||||||
|
|
||||||
|
# include <boost/detail/indirect_traits.hpp>
|
||||||
|
|
||||||
# include <boost/python/detail/invoke.hpp>
|
# include <boost/python/detail/invoke.hpp>
|
||||||
# include <boost/python/detail/signature.hpp>
|
# include <boost/python/detail/signature.hpp>
|
||||||
# include <boost/python/detail/preprocessor.hpp>
|
# include <boost/python/detail/preprocessor.hpp>
|
||||||
|
|
||||||
# include <boost/python/arg_from_python.hpp>
|
# include <boost/python/arg_from_python.hpp>
|
||||||
# include <boost/python/converter/context_result_converter.hpp>
|
# include <boost/python/converter/context_result_converter.hpp>
|
||||||
|
# include <boost/python/converter/builtin_converters.hpp>
|
||||||
|
|
||||||
# include <boost/preprocessor/iterate.hpp>
|
# include <boost/preprocessor/iterate.hpp>
|
||||||
# include <boost/preprocessor/cat.hpp>
|
# include <boost/preprocessor/cat.hpp>
|
||||||
@@ -90,6 +93,27 @@ inline ResultConverter create_result_converter(
|
|||||||
return ResultConverter();
|
return ResultConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
template <class ResultConverter>
|
||||||
|
struct converter_target_type
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template < >
|
||||||
|
struct converter_target_type <void_result_to_python >
|
||||||
|
{
|
||||||
|
static PyTypeObject const *get_pytype()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template <unsigned> struct caller_arity;
|
template <unsigned> struct caller_arity;
|
||||||
|
|
||||||
template <class F, class CallPolicies, class Sig>
|
template <class F, class CallPolicies, class Sig>
|
||||||
@@ -203,11 +227,26 @@ struct caller_arity<N>
|
|||||||
|
|
||||||
static unsigned min_arity() { return N; }
|
static unsigned min_arity() { return N; }
|
||||||
|
|
||||||
static signature_element const* signature()
|
static py_func_sig_info signature()
|
||||||
{
|
{
|
||||||
return detail::signature<Sig>::elements();
|
const signature_element * sig = detail::signature<Sig>::elements();
|
||||||
}
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
|
||||||
|
typedef typename select_result_converter<Policies, rtype>::type result_converter;
|
||||||
|
|
||||||
|
static const signature_element ret = {
|
||||||
|
(boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
|
||||||
|
, &detail::converter_target_type<result_converter>::get_pytype
|
||||||
|
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
|
||||||
|
};
|
||||||
|
py_func_sig_info res = {sig, &ret };
|
||||||
|
#else
|
||||||
|
py_func_sig_info res = {sig, sig };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
compressed_pair<F,Policies> m_data;
|
compressed_pair<F,Policies> m_data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,4 +134,8 @@
|
|||||||
#include <boost/config/auto_link.hpp>
|
#include <boost/config/auto_link.hpp>
|
||||||
#endif // auto-linking disabled
|
#endif // auto-linking disabled
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONFIG_DWA052200_H_
|
#endif // CONFIG_DWA052200_H_
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace detail
|
|||||||
, T3 const&
|
, T3 const&
|
||||||
, T4 const&
|
, T4 const&
|
||||||
, default_call_policies
|
, default_call_policies
|
||||||
, keywords<0>
|
, detail::keywords<0>
|
||||||
, char const*
|
, char const*
|
||||||
, void(not_specified::*)() // A function pointer type which is never an
|
, void(not_specified::*)() // A function pointer type which is never an
|
||||||
// appropriate default implementation
|
// appropriate default implementation
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ namespace detail
|
|||||||
char const* doc)
|
char const* doc)
|
||||||
{
|
{
|
||||||
// define the NTH stub function of stubs
|
// define the NTH stub function of stubs
|
||||||
define_stub_function<N>::define(name, stubs, kw, policies, name_space, 0);
|
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
|
||||||
|
|
||||||
if (kw.second > kw.first)
|
if (kw.second > kw.first)
|
||||||
--kw.second;
|
--kw.second;
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ namespace detail
|
|||||||
BOOST_PYTHON_GEN_MEM_FUNCTION( \
|
BOOST_PYTHON_GEN_MEM_FUNCTION( \
|
||||||
fname, void_return_type, n_args, n_dflts, ;) \
|
fname, void_return_type, n_args, n_dflts, ;) \
|
||||||
\
|
\
|
||||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
|
||||||
};
|
};
|
||||||
|
|
||||||
# else // !defined(BOOST_NO_VOID_RETURNS)
|
# else // !defined(BOOST_NO_VOID_RETURNS)
|
||||||
@@ -273,7 +273,7 @@ namespace detail
|
|||||||
fname, non_void_return_type, n_args, n_dflts, return) \
|
fname, non_void_return_type, n_args, n_dflts, return) \
|
||||||
\
|
\
|
||||||
typedef non_void_return_type void_return_type; \
|
typedef non_void_return_type void_return_type; \
|
||||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
|
||||||
};
|
};
|
||||||
|
|
||||||
# endif // !defined(BOOST_NO_VOID_RETURNS)
|
# endif // !defined(BOOST_NO_VOID_RETURNS)
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ object make_keyword_range_constructor(
|
|||||||
, Holder* = 0
|
, Holder* = 0
|
||||||
, ArgList* = 0, Arity* = 0)
|
, ArgList* = 0, Arity* = 0)
|
||||||
{
|
{
|
||||||
|
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||||
|
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
|
||||||
|
#endif
|
||||||
return detail::make_keyword_range_function(
|
return detail::make_keyword_range_function(
|
||||||
objects::make_holder<Arity::value>
|
objects::make_holder<Arity::value>
|
||||||
::template apply<Holder,ArgList>::execute
|
::template apply<Holder,ArgList>::execute
|
||||||
|
|||||||
37
include/boost/python/detail/python_type.hpp
Executable file
37
include/boost/python/detail/python_type.hpp
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright Nikolay Mladenov 2007.
|
||||||
|
// 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)
|
||||||
|
#ifndef BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
|
||||||
|
#define BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
|
||||||
|
|
||||||
|
#include <boost/python/converter/registered.hpp>
|
||||||
|
|
||||||
|
namespace boost {namespace python {namespace detail{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> struct python_class : PyObject
|
||||||
|
{
|
||||||
|
typedef python_class<T> this_type;
|
||||||
|
|
||||||
|
typedef T type;
|
||||||
|
|
||||||
|
static void *converter (PyObject *p){
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_()
|
||||||
|
{
|
||||||
|
static bool first_time = true;
|
||||||
|
|
||||||
|
if ( !first_time ) return;
|
||||||
|
|
||||||
|
first_time = false;
|
||||||
|
converter::registry::insert(&converter, boost::python::type_id<this_type>(), &converter::registered_pytype_direct<T>::get_pytype);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}}} //namespace boost :: python :: detail
|
||||||
|
|
||||||
|
#endif //BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
# include <boost/python/detail/preprocessor.hpp>
|
# include <boost/python/detail/preprocessor.hpp>
|
||||||
# include <boost/python/detail/indirect_traits.hpp>
|
# include <boost/python/detail/indirect_traits.hpp>
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
|
||||||
# include <boost/preprocessor/iterate.hpp>
|
# include <boost/preprocessor/iterate.hpp>
|
||||||
# include <boost/preprocessor/iteration/local.hpp>
|
# include <boost/preprocessor/iteration/local.hpp>
|
||||||
@@ -24,9 +25,16 @@ namespace boost { namespace python { namespace detail {
|
|||||||
struct signature_element
|
struct signature_element
|
||||||
{
|
{
|
||||||
char const* basename;
|
char const* basename;
|
||||||
|
converter::pytype_function pytype_f;
|
||||||
bool lvalue;
|
bool lvalue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct py_func_sig_info
|
||||||
|
{
|
||||||
|
signature_element const *signature;
|
||||||
|
signature_element const *ret;
|
||||||
|
};
|
||||||
|
|
||||||
template <unsigned> struct signature_arity;
|
template <unsigned> struct signature_arity;
|
||||||
|
|
||||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||||
@@ -68,15 +76,25 @@ struct signature_arity<N>
|
|||||||
{
|
{
|
||||||
static signature_element const result[N+2] = {
|
static signature_element const result[N+2] = {
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
# define BOOST_PP_LOCAL_MACRO(i) \
|
# define BOOST_PP_LOCAL_MACRO(i) \
|
||||||
{ \
|
{ \
|
||||||
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
|
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
|
||||||
|
, &converter::expected_pytype_for_arg<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::get_pytype \
|
||||||
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
|
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
|
||||||
},
|
},
|
||||||
|
#else
|
||||||
|
# define BOOST_PP_LOCAL_MACRO(i) \
|
||||||
|
{ \
|
||||||
|
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
|
||||||
|
, 0 \
|
||||||
|
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
# define BOOST_PP_LOCAL_LIMITS (0, N)
|
# define BOOST_PP_LOCAL_LIMITS (0, N)
|
||||||
# include BOOST_PP_LOCAL_ITERATE()
|
# include BOOST_PP_LOCAL_ITERATE()
|
||||||
{0,0}
|
{0,0,0}
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
170
include/boost/python/detail/unwind_type.hpp
Executable file
170
include/boost/python/detail/unwind_type.hpp
Executable file
@@ -0,0 +1,170 @@
|
|||||||
|
// 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)
|
||||||
|
#ifndef UNWIND_TYPE_DWA200222_HPP
|
||||||
|
# define UNWIND_TYPE_DWA200222_HPP
|
||||||
|
|
||||||
|
# include <boost/python/detail/cv_category.hpp>
|
||||||
|
# include <boost/python/detail/indirect_traits.hpp>
|
||||||
|
# include <boost/type_traits/object_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost { namespace python { namespace detail {
|
||||||
|
|
||||||
|
#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
|
||||||
|
// forward declaration, required (at least) by Tru64 cxx V6.5-042
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type(U const& p, Generator* = 0);
|
||||||
|
|
||||||
|
// forward declaration, required (at least) by Tru64 cxx V6.5-042
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type(boost::type<U>*p = 0, Generator* = 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
|
||||||
|
{
|
||||||
|
return Generator::execute(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type_cv(U const* p, const_, Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
unwind_ptr_type(U* p, Generator* = 0)
|
||||||
|
{
|
||||||
|
typedef typename cv_category<U>::type tag;
|
||||||
|
return unwind_type_cv<Generator>(p, tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool is_ptr>
|
||||||
|
struct unwind_helper
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U p, Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type(p, (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unwind_helper<false>
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U& p, Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type(&p, (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
unwind_type(U const& p, Generator*)
|
||||||
|
#else
|
||||||
|
unwind_type(U const& p, Generator* = 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
|
||||||
|
template <int indirection> struct unwind_helper2;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unwind_helper2<direct_>
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U(*)(), Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unwind_helper2<pointer_>
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U*(*)(), Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unwind_helper2<reference_>
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U&(*)(), Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unwind_helper2<reference_to_pointer_>
|
||||||
|
{
|
||||||
|
template <class Generator, class U>
|
||||||
|
static typename Generator::result_type
|
||||||
|
execute(U&(*)(), Generator* = 0)
|
||||||
|
{
|
||||||
|
return unwind_ptr_type(U(0), (Generator*)0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call this one with both template parameters explicitly specified
|
||||||
|
// and no function arguments:
|
||||||
|
//
|
||||||
|
// return unwind_type<my_generator,T>();
|
||||||
|
//
|
||||||
|
// Doesn't work if T is an array type; we could handle that case, but
|
||||||
|
// why bother?
|
||||||
|
template <class Generator, class U>
|
||||||
|
inline typename Generator::result_type
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
unwind_type(boost::type<U>*p, Generator*)
|
||||||
|
#else
|
||||||
|
unwind_type(boost::type<U>*p =0, Generator* =0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(int, indirection
|
||||||
|
= (boost::is_pointer<U>::value ? pointer_ : 0)
|
||||||
|
+ (indirect_traits::is_reference_to_pointer<U>::value
|
||||||
|
? reference_to_pointer_
|
||||||
|
: boost::is_reference<U>::value
|
||||||
|
? reference_
|
||||||
|
: 0));
|
||||||
|
|
||||||
|
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}}} // namespace boost::python::detail
|
||||||
|
|
||||||
|
#endif // UNWIND_TYPE_DWA200222_HPP
|
||||||
@@ -17,23 +17,38 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
|
|||||||
docstring_options(bool show_all=true)
|
docstring_options(bool show_all=true)
|
||||||
{
|
{
|
||||||
previous_show_user_defined_ = show_user_defined_;
|
previous_show_user_defined_ = show_user_defined_;
|
||||||
previous_show_signatures_ = show_signatures_;
|
previous_show_py_signatures_ = show_py_signatures_;
|
||||||
|
previous_show_cpp_signatures_ = show_cpp_signatures_;
|
||||||
show_user_defined_ = show_all;
|
show_user_defined_ = show_all;
|
||||||
show_signatures_ = show_all;
|
show_cpp_signatures_ = show_all;
|
||||||
|
show_py_signatures_ = show_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
docstring_options(bool show_user_defined, bool show_signatures)
|
docstring_options(bool show_user_defined, bool show_signatures)
|
||||||
{
|
{
|
||||||
previous_show_user_defined_ = show_user_defined_;
|
previous_show_user_defined_ = show_user_defined_;
|
||||||
previous_show_signatures_ = show_signatures_;
|
previous_show_cpp_signatures_ = show_cpp_signatures_;
|
||||||
|
previous_show_py_signatures_ = show_py_signatures_;
|
||||||
show_user_defined_ = show_user_defined;
|
show_user_defined_ = show_user_defined;
|
||||||
show_signatures_ = show_signatures;
|
show_cpp_signatures_ = show_signatures;
|
||||||
|
show_py_signatures_ = show_signatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures)
|
||||||
|
{
|
||||||
|
previous_show_user_defined_ = show_user_defined_;
|
||||||
|
previous_show_cpp_signatures_ = show_cpp_signatures_;
|
||||||
|
previous_show_py_signatures_ = show_py_signatures_;
|
||||||
|
show_user_defined_ = show_user_defined;
|
||||||
|
show_cpp_signatures_ = show_cpp_signatures;
|
||||||
|
show_py_signatures_ = show_py_signatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
~docstring_options()
|
~docstring_options()
|
||||||
{
|
{
|
||||||
show_user_defined_ = previous_show_user_defined_;
|
show_user_defined_ = previous_show_user_defined_;
|
||||||
show_signatures_ = previous_show_signatures_;
|
show_cpp_signatures_ = previous_show_cpp_signatures_;
|
||||||
|
show_py_signatures_ = previous_show_py_signatures_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -43,32 +58,68 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
|
|||||||
enable_user_defined() { show_user_defined_ = true; }
|
enable_user_defined() { show_user_defined_ = true; }
|
||||||
|
|
||||||
void
|
void
|
||||||
disable_signatures() { show_signatures_ = false; }
|
disable_py_signatures()
|
||||||
|
{
|
||||||
|
show_py_signatures_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enable_signatures() { show_signatures_ = true; }
|
enable_py_signatures()
|
||||||
|
{
|
||||||
|
show_py_signatures_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
disable_cpp_signatures()
|
||||||
|
{
|
||||||
|
show_cpp_signatures_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enable_cpp_signatures()
|
||||||
|
{
|
||||||
|
show_cpp_signatures_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
disable_signatures()
|
||||||
|
{
|
||||||
|
show_cpp_signatures_ = false;
|
||||||
|
show_py_signatures_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enable_signatures()
|
||||||
|
{
|
||||||
|
show_cpp_signatures_ = true;
|
||||||
|
show_py_signatures_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
disable_all()
|
disable_all()
|
||||||
{
|
{
|
||||||
show_user_defined_ = false;
|
show_user_defined_ = false;
|
||||||
show_signatures_ = false;
|
show_cpp_signatures_ = false;
|
||||||
|
show_py_signatures_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enable_all()
|
enable_all()
|
||||||
{
|
{
|
||||||
show_user_defined_ = true;
|
show_user_defined_ = true;
|
||||||
show_signatures_ = true;
|
show_cpp_signatures_ = true;
|
||||||
|
show_py_signatures_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend struct objects::function;
|
friend struct objects::function;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static volatile bool show_user_defined_;
|
static volatile bool show_user_defined_;
|
||||||
static volatile bool show_signatures_;
|
static volatile bool show_cpp_signatures_;
|
||||||
|
static volatile bool show_py_signatures_;
|
||||||
bool previous_show_user_defined_;
|
bool previous_show_user_defined_;
|
||||||
bool previous_show_signatures_;
|
bool previous_show_cpp_signatures_;
|
||||||
|
bool previous_show_py_signatures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace boost::python
|
}} // namespace boost::python
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct enum_ : public objects::enum_base
|
|||||||
typedef objects::enum_base base;
|
typedef objects::enum_base base;
|
||||||
|
|
||||||
// Declare a new enumeration type in the current scope()
|
// Declare a new enumeration type in the current scope()
|
||||||
enum_(char const* name);
|
enum_(char const* name, char const* doc = 0);
|
||||||
|
|
||||||
// Add a new enumeration value with the given name and value.
|
// Add a new enumeration value with the given name and value.
|
||||||
inline enum_<T>& value(char const* name, T);
|
inline enum_<T>& value(char const* name, T);
|
||||||
@@ -34,13 +34,15 @@ struct enum_ : public objects::enum_base
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline enum_<T>::enum_(char const* name)
|
inline enum_<T>::enum_(char const* name, char const* doc )
|
||||||
: base(
|
: base(
|
||||||
name
|
name
|
||||||
, &enum_<T>::to_python
|
, &enum_<T>::to_python
|
||||||
, &enum_<T>::convertible_from_python
|
, &enum_<T>::convertible_from_python
|
||||||
, &enum_<T>::construct
|
, &enum_<T>::construct
|
||||||
, type_id<T>())
|
, type_id<T>()
|
||||||
|
, doc
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
# include <boost/type.hpp>
|
# include <boost/type.hpp>
|
||||||
# include <boost/python/converter/implicit.hpp>
|
# include <boost/python/converter/implicit.hpp>
|
||||||
# include <boost/python/converter/registry.hpp>
|
# include <boost/python/converter/registry.hpp>
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
# include <boost/python/type_id.hpp>
|
# include <boost/python/type_id.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
@@ -21,7 +24,11 @@ void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
|
|||||||
converter::registry::push_back(
|
converter::registry::push_back(
|
||||||
&functions::convertible
|
&functions::convertible
|
||||||
, &functions::construct
|
, &functions::construct
|
||||||
, type_id<Target>());
|
, type_id<Target>()
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
, &converter::expected_from_python_type_direct<Source>::get_pytype
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace boost::python
|
}} // namespace boost::python
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
|||||||
: base(doc_, kw.range())
|
: base(doc_, kw.range())
|
||||||
{
|
{
|
||||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||||
N, n_arguments::value
|
N, n_arguments::value + 1
|
||||||
>::too_many_keywords assertion;
|
>::too_many_keywords assertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
|||||||
: base(doc_, kw.range())
|
: base(doc_, kw.range())
|
||||||
{
|
{
|
||||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||||
N, n_arguments::value
|
N, n_arguments::value + 1
|
||||||
>::too_many_keywords assertion;
|
>::too_many_keywords assertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ namespace detail
|
|||||||
, char const* doc
|
, char const* doc
|
||||||
, detail::keyword_range keywords)
|
, detail::keyword_range keywords)
|
||||||
{
|
{
|
||||||
detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
|
detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
|
||||||
|
|
||||||
if (keywords.second > keywords.first)
|
if (keywords.second > keywords.first)
|
||||||
--keywords.second;
|
--keywords.second;
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||||||
|
|
||||||
# include <boost/python/detail/prefix.hpp>
|
# include <boost/python/detail/prefix.hpp>
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <boost/python/type_id.hpp>
|
# include <boost/python/type_id.hpp>
|
||||||
# include <boost/python/converter/registry.hpp>
|
# include <boost/python/converter/registry.hpp>
|
||||||
@@ -85,8 +88,13 @@ struct lvalue_from_pytype
|
|||||||
{
|
{
|
||||||
lvalue_from_pytype()
|
lvalue_from_pytype()
|
||||||
{
|
{
|
||||||
converter::registry::insert(
|
converter::registry::insert
|
||||||
&extract, detail::extractor_type_id(&Extractor::execute));
|
( &extract
|
||||||
|
, detail::extractor_type_id(&Extractor::execute)
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
, &get_pytype
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static void* extract(PyObject* op)
|
static void* extract(PyObject* op)
|
||||||
@@ -98,6 +106,9 @@ struct lvalue_from_pytype
|
|||||||
: 0
|
: 0
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const*get_pytype() { return python_type; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace boost::python
|
}} // namespace boost::python
|
||||||
|
|||||||
@@ -104,6 +104,14 @@ namespace detail
|
|||||||
|
|
||||||
// If the BasePolicy_ supplied a result converter it would be
|
// If the BasePolicy_ supplied a result converter it would be
|
||||||
// ignored; issue an error if it's not the default.
|
// ignored; issue an error if it's not the default.
|
||||||
|
#if defined _MSC_VER && _MSC_VER < 1300
|
||||||
|
typedef is_same<
|
||||||
|
typename BasePolicy_::result_converter
|
||||||
|
, default_result_converter
|
||||||
|
> same_result_converter;
|
||||||
|
//see above for explanation
|
||||||
|
BOOST_STATIC_ASSERT(same_result_converter::value) ;
|
||||||
|
#else
|
||||||
BOOST_MPL_ASSERT_MSG(
|
BOOST_MPL_ASSERT_MSG(
|
||||||
(is_same<
|
(is_same<
|
||||||
typename BasePolicy_::result_converter
|
typename BasePolicy_::result_converter
|
||||||
@@ -112,7 +120,7 @@ namespace detail
|
|||||||
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
|
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
|
||||||
, (typename BasePolicy_::result_converter)
|
, (typename BasePolicy_::result_converter)
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
typedef constructor_result_converter result_converter;
|
typedef constructor_result_converter result_converter;
|
||||||
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
|
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -238,6 +238,14 @@ struct class_metadata
|
|||||||
//
|
//
|
||||||
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
|
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||||
|
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
|
||||||
|
{
|
||||||
|
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
|
||||||
|
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class T2>
|
template <class T2>
|
||||||
inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
|
inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
|
||||||
{
|
{
|
||||||
@@ -247,6 +255,10 @@ struct class_metadata
|
|||||||
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
|
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
|
||||||
>()
|
>()
|
||||||
);
|
);
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||||
|
// explicit qualification of type_id makes msvc6 happy
|
||||||
|
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Support for registering to-python converters
|
// Support for registering to-python converters
|
||||||
@@ -258,6 +270,10 @@ struct class_metadata
|
|||||||
inline static void maybe_register_class_to_python(T2*, mpl::false_)
|
inline static void maybe_register_class_to_python(T2*, mpl::false_)
|
||||||
{
|
{
|
||||||
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
|
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||||
|
// explicit qualification of type_id makes msvc6 happy
|
||||||
|
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
# define CLASS_WRAPPER_DWA20011221_HPP
|
# define CLASS_WRAPPER_DWA20011221_HPP
|
||||||
|
|
||||||
# include <boost/python/to_python_converter.hpp>
|
# include <boost/python/to_python_converter.hpp>
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
# include <boost/ref.hpp>
|
# include <boost/ref.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python { namespace objects {
|
namespace boost { namespace python { namespace objects {
|
||||||
@@ -19,22 +22,28 @@ namespace boost { namespace python { namespace objects {
|
|||||||
|
|
||||||
template <class Src, class MakeInstance>
|
template <class Src, class MakeInstance>
|
||||||
struct class_cref_wrapper
|
struct class_cref_wrapper
|
||||||
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> >
|
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> ,true>
|
||||||
{
|
{
|
||||||
static PyObject* convert(Src const& x)
|
static PyObject* convert(Src const& x)
|
||||||
{
|
{
|
||||||
return MakeInstance::execute(boost::ref(x));
|
return MakeInstance::execute(boost::ref(x));
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const *get_pytype() { return converter::registered_pytype_direct<Src>::get_pytype(); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Src, class MakeInstance>
|
template <class Src, class MakeInstance>
|
||||||
struct class_value_wrapper
|
struct class_value_wrapper
|
||||||
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> >
|
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> ,true>
|
||||||
{
|
{
|
||||||
static PyObject* convert(Src x)
|
static PyObject* convert(Src x)
|
||||||
{
|
{
|
||||||
return MakeInstance::execute(x);
|
return MakeInstance::execute(x);
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const *get_pytype() { return MakeInstance::get_pytype(); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}}} // namespace boost::python::objects
|
}}} // namespace boost::python::objects
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ struct BOOST_PYTHON_DECL enum_base : python::api::object
|
|||||||
, converter::to_python_function_t
|
, converter::to_python_function_t
|
||||||
, converter::convertible_function
|
, converter::convertible_function
|
||||||
, converter::constructor_function
|
, converter::constructor_function
|
||||||
, type_info);
|
, type_info
|
||||||
|
, const char *doc = 0
|
||||||
|
);
|
||||||
|
|
||||||
void add_value(char const* name, long value);
|
void add_value(char const* name, long value);
|
||||||
void export_values();
|
void export_values();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
namespace boost { namespace python { namespace objects {
|
namespace boost { namespace python { namespace objects {
|
||||||
|
|
||||||
|
|
||||||
struct BOOST_PYTHON_DECL function : PyObject
|
struct BOOST_PYTHON_DECL function : PyObject
|
||||||
{
|
{
|
||||||
function(
|
function(
|
||||||
@@ -53,6 +54,7 @@ struct BOOST_PYTHON_DECL function : PyObject
|
|||||||
object m_doc;
|
object m_doc;
|
||||||
object m_arg_names;
|
object m_arg_names;
|
||||||
unsigned m_nkeyword_values;
|
unsigned m_nkeyword_values;
|
||||||
|
friend class function_doc_signature_generator;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
36
include/boost/python/object/function_doc_signature.hpp
Executable file
36
include/boost/python/object/function_doc_signature.hpp
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright Nikolay Mladenov 2007.
|
||||||
|
// 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)
|
||||||
|
#ifndef FUNCTION_SIGNATURE_20070531_HPP
|
||||||
|
# define FUNCTION_SIGNATURE_20070531_HPP
|
||||||
|
|
||||||
|
#include <boost/python/object/function.hpp>
|
||||||
|
#include <boost/python/converter/registrations.hpp>
|
||||||
|
#include <boost/python/str.hpp>
|
||||||
|
#include <boost/python/tuple.hpp>
|
||||||
|
|
||||||
|
#include <boost/python/detail/signature.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost { namespace python { namespace objects {
|
||||||
|
|
||||||
|
class function_doc_signature_generator{
|
||||||
|
static const char * py_type_str(const python::detail::signature_element &s);
|
||||||
|
static bool arity_cmp( function const *f1, function const *f2 );
|
||||||
|
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
|
||||||
|
static std::vector<function const*> flatten(function const *f);
|
||||||
|
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
|
||||||
|
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
|
||||||
|
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
|
||||||
|
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static list function_doc_signatures( function const * f);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}//end of namespace boost::python::objects
|
||||||
|
|
||||||
|
#endif //FUNCTION_SIGNATURE_20070531_HPP
|
||||||
@@ -11,6 +11,10 @@
|
|||||||
# include <boost/python/detail/prefix.hpp>
|
# include <boost/python/detail/prefix.hpp>
|
||||||
|
|
||||||
# include <boost/python/object/instance.hpp>
|
# include <boost/python/object/instance.hpp>
|
||||||
|
# include <boost/python/converter/registry.hpp>
|
||||||
|
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||||
|
# include <boost/python/detail/python_type.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <boost/python/object/forward.hpp>
|
# include <boost/python/object/forward.hpp>
|
||||||
# include <boost/python/detail/preprocessor.hpp>
|
# include <boost/python/detail/preprocessor.hpp>
|
||||||
@@ -74,7 +78,11 @@ struct make_holder<N>
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
static void execute(
|
static void execute(
|
||||||
|
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||||
|
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
|
||||||
|
#else
|
||||||
PyObject *p
|
PyObject *p
|
||||||
|
#endif
|
||||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
|
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
|
||||||
{
|
{
|
||||||
typedef instance<Holder> instance_t;
|
typedef instance<Holder> instance_t;
|
||||||
|
|||||||
@@ -29,7 +29,12 @@ struct make_ptr_instance
|
|||||||
{
|
{
|
||||||
return get_class_object_impl(get_pointer(x));
|
return get_class_object_impl(get_pointer(x));
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static inline PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
return converter::registered<T>::converters.get_class_object();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
template <class U>
|
template <class U>
|
||||||
static inline PyTypeObject* get_class_object_impl(U const volatile* p)
|
static inline PyTypeObject* get_class_object_impl(U const volatile* p)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct BOOST_PYTHON_DECL py_function_impl_base
|
|||||||
virtual PyObject* operator()(PyObject*, PyObject*) = 0;
|
virtual PyObject* operator()(PyObject*, PyObject*) = 0;
|
||||||
virtual unsigned min_arity() const = 0;
|
virtual unsigned min_arity() const = 0;
|
||||||
virtual unsigned max_arity() const;
|
virtual unsigned max_arity() const;
|
||||||
virtual python::detail::signature_element const* signature() const = 0;
|
virtual python::detail::py_func_sig_info signature() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Caller>
|
template <class Caller>
|
||||||
@@ -43,7 +43,7 @@ struct caller_py_function_impl : py_function_impl_base
|
|||||||
return m_caller.min_arity();
|
return m_caller.min_arity();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual python::detail::signature_element const* signature() const
|
virtual python::detail::py_func_sig_info signature() const
|
||||||
{
|
{
|
||||||
return m_caller.signature();
|
return m_caller.signature();
|
||||||
}
|
}
|
||||||
@@ -69,9 +69,11 @@ struct signature_py_function_impl : py_function_impl_base
|
|||||||
return mpl::size<Sig>::value - 1;
|
return mpl::size<Sig>::value - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual python::detail::signature_element const* signature() const
|
virtual python::detail::py_func_sig_info signature() const
|
||||||
{
|
{
|
||||||
return python::detail::signature<Sig>::elements();
|
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
|
||||||
|
python::detail::py_func_sig_info res = {sig, sig};
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -102,9 +104,11 @@ struct full_py_function_impl : py_function_impl_base
|
|||||||
return m_max_arity;
|
return m_max_arity;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual python::detail::signature_element const* signature() const
|
virtual python::detail::py_func_sig_info signature() const
|
||||||
{
|
{
|
||||||
return python::detail::signature<Sig>::elements();
|
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
|
||||||
|
python::detail::py_func_sig_info res = {sig, sig};
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -151,7 +155,12 @@ struct py_function
|
|||||||
|
|
||||||
python::detail::signature_element const* signature() const
|
python::detail::signature_element const* signature() const
|
||||||
{
|
{
|
||||||
return m_impl->signature();
|
return m_impl->signature().signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
python::detail::signature_element const& get_return_type() const
|
||||||
|
{
|
||||||
|
return *m_impl->signature().ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -470,6 +470,9 @@ namespace converter
|
|||||||
{
|
{
|
||||||
return python::detail::new_non_null_reference(x);
|
return python::detail::new_non_null_reference(x);
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const *get_pytype() {return 0;}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,8 +93,13 @@ private:
|
|||||||
|
|
||||||
if ((existing == 0) || (existing->m_to_python == 0))
|
if ((existing == 0) || (existing->m_to_python == 0))
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
|
||||||
|
converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
|
||||||
|
#else
|
||||||
converter::registry::insert(&extract, type_id<Pointee>());
|
converter::registry::insert(&extract, type_id<Pointee>());
|
||||||
converter::registry::insert(&wrap, type_id<Pointee*>());
|
converter::registry::insert(&wrap, type_id<Pointee*>());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +110,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject type_object;
|
static PyTypeObject type_object;
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
static PyTypeObject const *get_pytype(){return &type_object; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Pointee>
|
template <class Pointee>
|
||||||
|
|||||||
@@ -8,10 +8,15 @@
|
|||||||
# include <boost/python/detail/none.hpp>
|
# include <boost/python/detail/none.hpp>
|
||||||
# include <boost/python/detail/value_arg.hpp>
|
# include <boost/python/detail/value_arg.hpp>
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <boost/type_traits/add_reference.hpp>
|
# include <boost/type_traits/add_reference.hpp>
|
||||||
# include <boost/type_traits/add_const.hpp>
|
# include <boost/type_traits/add_const.hpp>
|
||||||
|
|
||||||
# include <boost/mpl/int.hpp>
|
# include <boost/mpl/int.hpp>
|
||||||
|
# include <boost/mpl/at.hpp>
|
||||||
|
|
||||||
# include <boost/static_assert.hpp>
|
# include <boost/static_assert.hpp>
|
||||||
# include <boost/python/refcount.hpp>
|
# include <boost/python/refcount.hpp>
|
||||||
@@ -44,6 +49,9 @@ namespace detail
|
|||||||
{
|
{
|
||||||
return none();
|
return none();
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
PyTypeObject const *get_pytype() const { return converter::expected_pytype_for_arg<T>::get_pytype() ; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -82,6 +90,12 @@ struct return_arg : Base
|
|||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
|
return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Sig>
|
||||||
|
struct extract_return_type : mpl::at_c<Sig, arg_pos>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <
|
template <
|
||||||
|
|||||||
@@ -9,13 +9,67 @@
|
|||||||
|
|
||||||
# include <boost/python/converter/registry.hpp>
|
# include <boost/python/converter/registry.hpp>
|
||||||
# include <boost/python/converter/as_to_python_function.hpp>
|
# include <boost/python/converter/as_to_python_function.hpp>
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
# include <boost/python/type_id.hpp>
|
# include <boost/python/type_id.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
|
|
||||||
template <class T, class Conversion>
|
#if 0 //get_pytype member detection
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
typedef char yes_type;
|
||||||
|
typedef struct {char a[2]; } no_type;
|
||||||
|
template<PyTypeObject const * (*f)()> struct test_get_pytype1 { };
|
||||||
|
template<PyTypeObject * (*f)()> struct test_get_pytype2 { };
|
||||||
|
|
||||||
|
template<class T> yes_type tester(test_get_pytype1<&T::get_pytype>*);
|
||||||
|
|
||||||
|
template<class T> yes_type tester(test_get_pytype2<&T::get_pytype>*);
|
||||||
|
|
||||||
|
template<class T> no_type tester(...);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct test_get_pytype_base
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value= (sizeof(detail::tester<T>(0)) == sizeof(yes_type)));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct test_get_pytype : boost::mpl::bool_<test_get_pytype_base<T>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < class T, class Conversion, bool has_get_pytype=false >
|
||||||
struct to_python_converter
|
struct to_python_converter
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
#if 0 //defined _MSC_VER && _MSC_VER >=1310
|
||||||
|
//probably other compilers could come here as well
|
||||||
|
typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
|
||||||
|
#else
|
||||||
|
typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
|
||||||
|
{
|
||||||
|
return Conversion::get_pytype();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyTypeObject const* get_pytype_1(boost::mpl::false_ *)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static PyTypeObject const* get_pytype_impl()
|
||||||
|
{
|
||||||
|
return get_pytype_1((HasGetPytype*)0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
to_python_converter();
|
to_python_converter();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,8 +77,8 @@ struct to_python_converter
|
|||||||
// implementation
|
// implementation
|
||||||
//
|
//
|
||||||
|
|
||||||
template <class T, class Conversion>
|
template <class T, class Conversion ,bool has_get_pytype>
|
||||||
to_python_converter<T,Conversion>::to_python_converter()
|
to_python_converter<T,Conversion, has_get_pytype>::to_python_converter()
|
||||||
{
|
{
|
||||||
typedef converter::as_to_python_function<
|
typedef converter::as_to_python_function<
|
||||||
T, Conversion
|
T, Conversion
|
||||||
@@ -32,9 +86,14 @@ to_python_converter<T,Conversion>::to_python_converter()
|
|||||||
|
|
||||||
converter::registry::insert(
|
converter::registry::insert(
|
||||||
&normalized::convert
|
&normalized::convert
|
||||||
, type_id<T>());
|
, type_id<T>()
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
, &get_pytype_impl
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace boost::python
|
}} // namespace boost::python
|
||||||
|
|
||||||
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP
|
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
|
|
||||||
# include <boost/python/detail/none.hpp>
|
# include <boost/python/detail/none.hpp>
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
# include <boost/python/converter/pytype_function.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <boost/python/refcount.hpp>
|
# include <boost/python/refcount.hpp>
|
||||||
|
|
||||||
# include <boost/type_traits/is_pointer.hpp>
|
# include <boost/type_traits/is_pointer.hpp>
|
||||||
@@ -36,7 +40,13 @@ struct to_python_indirect
|
|||||||
{
|
{
|
||||||
return this->execute(const_cast<U&>(ref), is_pointer<U>());
|
return this->execute(const_cast<U&>(ref), is_pointer<U>());
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
inline PyTypeObject const*
|
||||||
|
get_pytype()const
|
||||||
|
{
|
||||||
|
return converter::registered_pytype<T>::get_pytype();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
template <class U>
|
template <class U>
|
||||||
inline PyObject* execute(U* ptr, mpl::true_) const
|
inline PyObject* execute(U* ptr, mpl::true_) const
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
|
|
||||||
# include <boost/python/refcount.hpp>
|
# include <boost/python/refcount.hpp>
|
||||||
# include <boost/python/tag.hpp>
|
# include <boost/python/tag.hpp>
|
||||||
|
# include <boost/python/handle.hpp>
|
||||||
|
|
||||||
# include <boost/python/converter/registry.hpp>
|
# include <boost/python/converter/registry.hpp>
|
||||||
# include <boost/python/converter/registered.hpp>
|
# include <boost/python/converter/registered.hpp>
|
||||||
# include <boost/python/converter/builtin_converters.hpp>
|
# include <boost/python/converter/builtin_converters.hpp>
|
||||||
# include <boost/python/converter/object_manager.hpp>
|
# include <boost/python/converter/object_manager.hpp>
|
||||||
# include <boost/python/converter/object_manager.hpp>
|
|
||||||
# include <boost/python/converter/shared_ptr_to_python.hpp>
|
# include <boost/python/converter/shared_ptr_to_python.hpp>
|
||||||
|
|
||||||
# include <boost/python/detail/value_is_shared_ptr.hpp>
|
# include <boost/python/detail/value_is_shared_ptr.hpp>
|
||||||
@@ -24,17 +24,57 @@
|
|||||||
|
|
||||||
# include <boost/mpl/if.hpp>
|
# include <boost/mpl/if.hpp>
|
||||||
# include <boost/mpl/or.hpp>
|
# include <boost/mpl/or.hpp>
|
||||||
|
# include <boost/type_traits/is_const.hpp>
|
||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
|
||||||
|
template <bool is_const_ref>
|
||||||
|
struct object_manager_get_pytype
|
||||||
|
{
|
||||||
|
template <class U>
|
||||||
|
static PyTypeObject const* get( U& (*p)() =0)
|
||||||
|
{
|
||||||
|
return converter::object_manager_traits<U>::get_pytype();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct object_manager_get_pytype<true>
|
||||||
|
{
|
||||||
|
template <class U>
|
||||||
|
static PyTypeObject const* get( U const& (*p)() =0)
|
||||||
|
{
|
||||||
|
return converter::object_manager_traits<U>::get_pytype();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct object_manager_to_python_value
|
struct object_manager_to_python_value
|
||||||
{
|
{
|
||||||
typedef typename value_arg<T>::type argument_type;
|
typedef typename value_arg<T>::type argument_type;
|
||||||
|
|
||||||
PyObject* operator()(argument_type) const;
|
PyObject* operator()(argument_type) const;
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
|
||||||
|
typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
|
||||||
|
PyTypeObject const* get_pytype() const {
|
||||||
|
return get_pytype_aux((is_t_handle*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
|
||||||
|
|
||||||
|
inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
|
||||||
|
{
|
||||||
|
return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// This information helps make_getter() decide whether to try to
|
// This information helps make_getter() decide whether to try to
|
||||||
// return an internal reference or not. I don't like it much,
|
// return an internal reference or not. I don't like it much,
|
||||||
@@ -49,6 +89,9 @@ namespace detail
|
|||||||
typedef typename value_arg<T>::type argument_type;
|
typedef typename value_arg<T>::type argument_type;
|
||||||
|
|
||||||
PyObject* operator()(argument_type) const;
|
PyObject* operator()(argument_type) const;
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
|
||||||
|
#endif
|
||||||
|
|
||||||
// This information helps make_getter() decide whether to try to
|
// This information helps make_getter() decide whether to try to
|
||||||
// return an internal reference or not. I don't like it much,
|
// return an internal reference or not. I don't like it much,
|
||||||
@@ -62,11 +105,20 @@ namespace detail
|
|||||||
typedef typename value_arg<T>::type argument_type;
|
typedef typename value_arg<T>::type argument_type;
|
||||||
|
|
||||||
PyObject* operator()(argument_type) const;
|
PyObject* operator()(argument_type) const;
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
|
||||||
|
#endif
|
||||||
// This information helps make_getter() decide whether to try to
|
// This information helps make_getter() decide whether to try to
|
||||||
// return an internal reference or not. I don't like it much,
|
// return an internal reference or not. I don't like it much,
|
||||||
// but it will have to serve for now.
|
// but it will have to serve for now.
|
||||||
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
||||||
|
private:
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
template <class U>
|
||||||
|
PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||||
|
template <class U>
|
||||||
|
PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <boost/python/converter/registry.hpp>
|
#include <boost/python/converter/registry.hpp>
|
||||||
#include <boost/python/converter/registrations.hpp>
|
#include <boost/python/converter/registrations.hpp>
|
||||||
#include <boost/python/converter/shared_ptr_deleter.hpp>
|
#include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||||
|
#include <boost/python/converter/pytype_function.hpp>
|
||||||
|
|
||||||
#include <boost/cast.hpp>
|
#include <boost/cast.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -56,6 +57,7 @@ namespace
|
|||||||
&slot_rvalue_from_python<T,SlotPolicy>::convertible
|
&slot_rvalue_from_python<T,SlotPolicy>::convertible
|
||||||
, &slot_rvalue_from_python<T,SlotPolicy>::construct
|
, &slot_rvalue_from_python<T,SlotPolicy>::construct
|
||||||
, type_id<T>()
|
, type_id<T>()
|
||||||
|
, &SlotPolicy::get_pytype
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +102,7 @@ namespace
|
|||||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||||
? &number_methods->nb_int : 0;
|
? &number_methods->nb_int : 0;
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -135,6 +138,7 @@ namespace
|
|||||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||||
? &py_object_identity : 0;
|
? &py_object_identity : 0;
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -173,6 +177,7 @@ namespace
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
|
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
|
||||||
@@ -228,6 +233,15 @@ namespace
|
|||||||
{
|
{
|
||||||
return PyObject_IsTrue(intermediate);
|
return PyObject_IsTrue(intermediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyTypeObject const* get_pytype()
|
||||||
|
{
|
||||||
|
#if PY_VERSION_HEX >= 0x02030000
|
||||||
|
return &PyBool_Type;
|
||||||
|
#else
|
||||||
|
return &PyInt_Type;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SlotPolicy for extracting floating types from Python objects.
|
// A SlotPolicy for extracting floating types from Python objects.
|
||||||
@@ -259,6 +273,7 @@ namespace
|
|||||||
return PyFloat_AS_DOUBLE(intermediate);
|
return PyFloat_AS_DOUBLE(intermediate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SlotPolicy for extracting C++ strings from Python objects.
|
// A SlotPolicy for extracting C++ strings from Python objects.
|
||||||
@@ -276,6 +291,7 @@ namespace
|
|||||||
{
|
{
|
||||||
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
|
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyString_Type;}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
||||||
@@ -316,6 +332,7 @@ namespace
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -346,6 +363,7 @@ namespace
|
|||||||
return PyFloat_AS_DOUBLE(intermediate);
|
return PyFloat_AS_DOUBLE(intermediate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +429,7 @@ void initialize_builtin_converters()
|
|||||||
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
|
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
|
||||||
|
|
||||||
// Add an lvalue converter for char which gets us char const*
|
// Add an lvalue converter for char which gets us char const*
|
||||||
registry::insert(convert_to_cstring,type_id<char>());
|
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
|
||||||
|
|
||||||
// Register by-value converters to std::string, std::wstring
|
// Register by-value converters to std::string, std::wstring
|
||||||
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
||||||
|
|||||||
@@ -20,6 +20,35 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace boost { namespace python { namespace converter {
|
namespace boost { namespace python { namespace converter {
|
||||||
|
BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
|
||||||
|
{
|
||||||
|
if (this->m_class_object != 0)
|
||||||
|
return this->m_class_object;
|
||||||
|
|
||||||
|
std::set<PyTypeObject const*> pool;
|
||||||
|
|
||||||
|
for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
|
||||||
|
if(r->expected_pytype)
|
||||||
|
pool.insert(r->expected_pytype());
|
||||||
|
|
||||||
|
//for now I skip the search for common base
|
||||||
|
if (pool.size()==1)
|
||||||
|
return *pool.begin();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
|
||||||
|
{
|
||||||
|
if (this->m_class_object != 0)
|
||||||
|
return this->m_class_object;
|
||||||
|
|
||||||
|
if (this->m_to_python_target_type != 0)
|
||||||
|
return this->m_to_python_target_type();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
|
BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
|
||||||
{
|
{
|
||||||
@@ -168,15 +197,15 @@ namespace // <unnamed>
|
|||||||
|
|
||||||
namespace registry
|
namespace registry
|
||||||
{
|
{
|
||||||
void insert(to_python_function_t f, type_info source_t)
|
void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
|
||||||
{
|
{
|
||||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||||
std::cout << "inserting to_python " << source_t << "\n";
|
std::cout << "inserting to_python " << source_t << "\n";
|
||||||
# endif
|
# endif
|
||||||
to_python_function_t& slot = get(source_t)->m_to_python;
|
entry* slot = get(source_t);
|
||||||
|
|
||||||
assert(slot == 0); // we have a problem otherwise
|
assert(slot->m_to_python == 0); // we have a problem otherwise
|
||||||
if (slot != 0)
|
if (slot->m_to_python != 0)
|
||||||
{
|
{
|
||||||
std::string msg = (
|
std::string msg = (
|
||||||
std::string("to-Python converter for ")
|
std::string("to-Python converter for ")
|
||||||
@@ -189,11 +218,12 @@ namespace registry
|
|||||||
throw_error_already_set();
|
throw_error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slot = f;
|
slot->m_to_python = f;
|
||||||
|
slot->m_to_python_target_type = to_python_target_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert an lvalue from_python converter
|
// Insert an lvalue from_python converter
|
||||||
void insert(convertible_function convert, type_info key)
|
void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
|
||||||
{
|
{
|
||||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||||
std::cout << "inserting lvalue from_python " << key << "\n";
|
std::cout << "inserting lvalue from_python " << key << "\n";
|
||||||
@@ -204,13 +234,14 @@ namespace registry
|
|||||||
registration->next = found->lvalue_chain;
|
registration->next = found->lvalue_chain;
|
||||||
found->lvalue_chain = registration;
|
found->lvalue_chain = registration;
|
||||||
|
|
||||||
insert(convert, 0, key);
|
insert(convert, 0, key,exp_pytype);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert an rvalue from_python converter
|
// Insert an rvalue from_python converter
|
||||||
void insert(void* (*convertible)(PyObject*)
|
void insert(void* (*convertible)(PyObject*)
|
||||||
, constructor_function construct
|
, constructor_function construct
|
||||||
, type_info key)
|
, type_info key
|
||||||
|
, PyTypeObject const* (*exp_pytype)())
|
||||||
{
|
{
|
||||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||||
std::cout << "inserting rvalue from_python " << key << "\n";
|
std::cout << "inserting rvalue from_python " << key << "\n";
|
||||||
@@ -219,6 +250,7 @@ namespace registry
|
|||||||
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
||||||
registration->convertible = convertible;
|
registration->convertible = convertible;
|
||||||
registration->construct = construct;
|
registration->construct = construct;
|
||||||
|
registration->expected_pytype = exp_pytype;
|
||||||
registration->next = found->rvalue_chain;
|
registration->next = found->rvalue_chain;
|
||||||
found->rvalue_chain = registration;
|
found->rvalue_chain = registration;
|
||||||
}
|
}
|
||||||
@@ -226,7 +258,8 @@ namespace registry
|
|||||||
// Insert an rvalue from_python converter
|
// Insert an rvalue from_python converter
|
||||||
void push_back(void* (*convertible)(PyObject*)
|
void push_back(void* (*convertible)(PyObject*)
|
||||||
, constructor_function construct
|
, constructor_function construct
|
||||||
, type_info key)
|
, type_info key
|
||||||
|
, PyTypeObject const* (*exp_pytype)())
|
||||||
{
|
{
|
||||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||||
std::cout << "push_back rvalue from_python " << key << "\n";
|
std::cout << "push_back rvalue from_python " << key << "\n";
|
||||||
@@ -238,6 +271,7 @@ namespace registry
|
|||||||
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
||||||
registration->convertible = convertible;
|
registration->convertible = convertible;
|
||||||
registration->construct = construct;
|
registration->construct = construct;
|
||||||
|
registration->expected_pytype = exp_pytype;
|
||||||
registration->next = 0;
|
registration->next = 0;
|
||||||
*found = registration;
|
*found = registration;
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/dict.cpp
10
src/dict.cpp
@@ -171,4 +171,14 @@ list dict_base::values() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct register_dict_pytype_ptr
|
||||||
|
{
|
||||||
|
register_dict_pytype_ptr()
|
||||||
|
{
|
||||||
|
const_cast<converter::registration &>(
|
||||||
|
converter::registry::lookup(boost::python::type_id<boost::python::dict>())
|
||||||
|
).m_class_object = &PyDict_Type;
|
||||||
|
}
|
||||||
|
}register_dict_pytype_ptr_;
|
||||||
|
|
||||||
}}} // namespace boost::python
|
}}} // namespace boost::python
|
||||||
|
|||||||
10
src/list.cpp
10
src/list.cpp
@@ -137,4 +137,14 @@ long list_base::count(object_cref value) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct register_list_pytype_ptr
|
||||||
|
{
|
||||||
|
register_list_pytype_ptr()
|
||||||
|
{
|
||||||
|
const_cast<converter::registration &>(
|
||||||
|
converter::registry::lookup(boost::python::type_id<boost::python::list>())
|
||||||
|
).m_class_object = &PyList_Type;
|
||||||
|
}
|
||||||
|
}register_list_pytype_ptr_;
|
||||||
|
|
||||||
}}} // namespace boost::python
|
}}} // namespace boost::python
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ object module_prefix();
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
object new_enum_type(char const* name)
|
object new_enum_type(char const* name, char const *doc)
|
||||||
{
|
{
|
||||||
if (enum_type_object.tp_dict == 0)
|
if (enum_type_object.tp_dict == 0)
|
||||||
{
|
{
|
||||||
@@ -143,6 +143,8 @@ namespace
|
|||||||
object module_name = module_prefix();
|
object module_name = module_prefix();
|
||||||
if (module_name)
|
if (module_name)
|
||||||
d["__module__"] = module_name;
|
d["__module__"] = module_name;
|
||||||
|
if (doc)
|
||||||
|
d["__doc__"] = doc;
|
||||||
|
|
||||||
object result = (object(metatype))(name, make_tuple(base), d);
|
object result = (object(metatype))(name, make_tuple(base), d);
|
||||||
|
|
||||||
@@ -158,8 +160,9 @@ enum_base::enum_base(
|
|||||||
, converter::convertible_function convertible
|
, converter::convertible_function convertible
|
||||||
, converter::constructor_function construct
|
, converter::constructor_function construct
|
||||||
, type_info id
|
, type_info id
|
||||||
|
, char const *doc
|
||||||
)
|
)
|
||||||
: object(new_enum_type(name))
|
: object(new_enum_type(name, doc))
|
||||||
{
|
{
|
||||||
converter::registration& converters
|
converter::registration& converters
|
||||||
= const_cast<converter::registration&>(
|
= const_cast<converter::registration&>(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <boost/python/docstring_options.hpp>
|
#include <boost/python/docstring_options.hpp>
|
||||||
#include <boost/python/object/function_object.hpp>
|
#include <boost/python/object/function_object.hpp>
|
||||||
#include <boost/python/object/function_handle.hpp>
|
#include <boost/python/object/function_handle.hpp>
|
||||||
|
#include <boost/python/object/function_doc_signature.hpp>
|
||||||
#include <boost/python/errors.hpp>
|
#include <boost/python/errors.hpp>
|
||||||
#include <boost/python/str.hpp>
|
#include <boost/python/str.hpp>
|
||||||
#include <boost/python/object_attributes.hpp>
|
#include <boost/python/object_attributes.hpp>
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
#include <boost/python/ssize_t.hpp>
|
#include <boost/python/ssize_t.hpp>
|
||||||
|
|
||||||
#include <boost/python/detail/signature.hpp>
|
#include <boost/python/detail/signature.hpp>
|
||||||
|
#include <boost/python/detail/none.hpp>
|
||||||
#include <boost/mpl/vector/vector10.hpp>
|
#include <boost/mpl/vector/vector10.hpp>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
@@ -30,7 +32,12 @@
|
|||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
volatile bool docstring_options::show_user_defined_ = true;
|
volatile bool docstring_options::show_user_defined_ = true;
|
||||||
volatile bool docstring_options::show_signatures_ = true;
|
volatile bool docstring_options::show_cpp_signatures_ = true;
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
volatile bool docstring_options::show_py_signatures_ = true;
|
||||||
|
#else
|
||||||
|
volatile bool docstring_options::show_py_signatures_ = false;
|
||||||
|
#endif
|
||||||
}}
|
}}
|
||||||
|
|
||||||
namespace boost { namespace python { namespace objects {
|
namespace boost { namespace python { namespace objects {
|
||||||
@@ -411,6 +418,12 @@ void function::add_to_namespace(
|
|||||||
add_to_namespace(name_space, name_, attribute, 0);
|
add_to_namespace(name_space, name_, attribute, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
extern char py_signature_tag[];
|
||||||
|
extern char cpp_signature_tag[];
|
||||||
|
}
|
||||||
|
|
||||||
void function::add_to_namespace(
|
void function::add_to_namespace(
|
||||||
object const& name_space, char const* name_, object const& attribute, char const* doc)
|
object const& name_space, char const* name_, object const& attribute, char const* doc)
|
||||||
{
|
{
|
||||||
@@ -487,6 +500,7 @@ void function::add_to_namespace(
|
|||||||
throw_error_already_set();
|
throw_error_already_set();
|
||||||
|
|
||||||
object mutable_attribute(attribute);
|
object mutable_attribute(attribute);
|
||||||
|
/*
|
||||||
if (doc != 0 && docstring_options::show_user_defined_)
|
if (doc != 0 && docstring_options::show_user_defined_)
|
||||||
{
|
{
|
||||||
// Accumulate documentation
|
// Accumulate documentation
|
||||||
@@ -517,6 +531,28 @@ void function::add_to_namespace(
|
|||||||
mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
|
mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
|
||||||
"C++ signature:", f->signature(true)));
|
"C++ signature:", f->signature(true)));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
str _doc;
|
||||||
|
|
||||||
|
if (docstring_options::show_py_signatures_)
|
||||||
|
{
|
||||||
|
_doc += str(reinterpret_cast<const char*>(detail::py_signature_tag));
|
||||||
|
}
|
||||||
|
if (doc != 0 && docstring_options::show_user_defined_)
|
||||||
|
_doc += doc;
|
||||||
|
|
||||||
|
if (docstring_options::show_cpp_signatures_)
|
||||||
|
{
|
||||||
|
// if(len(_doc))
|
||||||
|
// _doc += "\n"+str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
|
||||||
|
// else
|
||||||
|
_doc += str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
|
||||||
|
}
|
||||||
|
if(_doc)
|
||||||
|
{
|
||||||
|
object mutable_attribute(attribute);
|
||||||
|
mutable_attribute.attr("__doc__")= _doc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PYTHON_DECL void add_to_namespace(
|
BOOST_PYTHON_DECL void add_to_namespace(
|
||||||
@@ -591,7 +627,10 @@ extern "C"
|
|||||||
static PyObject* function_get_doc(PyObject* op, void*)
|
static PyObject* function_get_doc(PyObject* op, void*)
|
||||||
{
|
{
|
||||||
function* f = downcast<function>(op);
|
function* f = downcast<function>(op);
|
||||||
return python::incref(f->doc().ptr());
|
list signatures = function_doc_signature_generator::function_doc_signatures(f);
|
||||||
|
if(!signatures) return python::detail::none();
|
||||||
|
signatures.reverse();
|
||||||
|
return python::incref( str("\n").join(signatures).ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int function_set_doc(PyObject* op, PyObject* doc, void*)
|
static int function_set_doc(PyObject* op, PyObject* doc, void*)
|
||||||
|
|||||||
342
src/object/function_doc_signature.cpp
Executable file
342
src/object/function_doc_signature.cpp
Executable file
@@ -0,0 +1,342 @@
|
|||||||
|
// Copyright Nikolay Mladenov 2007.
|
||||||
|
// 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/registrations.hpp>
|
||||||
|
#include <boost/python/object/function_doc_signature.hpp>
|
||||||
|
#include <boost/python/errors.hpp>
|
||||||
|
#include <boost/python/str.hpp>
|
||||||
|
#include <boost/python/args.hpp>
|
||||||
|
#include <boost/python/tuple.hpp>
|
||||||
|
|
||||||
|
#include <boost/python/detail/signature.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost { namespace python { namespace objects {
|
||||||
|
|
||||||
|
bool function_doc_signature_generator::arity_cmp( function const *f1, function const *f2 )
|
||||||
|
{
|
||||||
|
return f1->m_fn.max_arity() < f2->m_fn.max_arity();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool function_doc_signature_generator::are_seq_overloads( function const *f1, function const *f2 , bool check_docs)
|
||||||
|
{
|
||||||
|
py_function const & impl1 = f1->m_fn;
|
||||||
|
py_function const & impl2 = f2->m_fn;
|
||||||
|
|
||||||
|
//the number of parameters differs by 1
|
||||||
|
if (impl2.max_arity()-impl1.max_arity() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if check docs then f1 shold not have docstring or have the same docstring as f2
|
||||||
|
if (check_docs && f2->doc() != f1->doc() && f1->doc())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
python::detail::signature_element const* s1 = impl1.signature();
|
||||||
|
python::detail::signature_element const* s2 = impl2.signature();
|
||||||
|
|
||||||
|
unsigned size = impl1.max_arity()+1;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i != size; ++i)
|
||||||
|
{
|
||||||
|
//check if the argument types are the same
|
||||||
|
if (s1[i].basename != s2[i].basename)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//return type
|
||||||
|
if (!i) continue;
|
||||||
|
|
||||||
|
//check if the argument default values are the same
|
||||||
|
bool f1_has_names = bool(f1->m_arg_names);
|
||||||
|
bool f2_has_names = bool(f2->m_arg_names);
|
||||||
|
if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
|
||||||
|
|| f1_has_names && !f2_has_names
|
||||||
|
|| !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<function const*> function_doc_signature_generator::flatten(function const *f)
|
||||||
|
{
|
||||||
|
object name = f->name();
|
||||||
|
|
||||||
|
std::vector<function const*> res;
|
||||||
|
|
||||||
|
while (f) {
|
||||||
|
|
||||||
|
//this if takes out the not_implemented_function
|
||||||
|
if (f->name() == name)
|
||||||
|
res.push_back(f);
|
||||||
|
|
||||||
|
f=f->m_overloads.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::sort(res.begin(),res.end(), &arity_cmp);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
std::vector<function const*> function_doc_signature_generator::split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change)
|
||||||
|
{
|
||||||
|
std::vector<function const*> res;
|
||||||
|
|
||||||
|
std::vector<function const*>::const_iterator fi = funcs.begin();
|
||||||
|
|
||||||
|
function const * last = *fi;
|
||||||
|
|
||||||
|
while (++fi != funcs.end()){
|
||||||
|
|
||||||
|
//check if fi starts a new chain of overloads
|
||||||
|
if (!are_seq_overloads( last, *fi, split_on_doc_change ))
|
||||||
|
res.push_back(last);
|
||||||
|
|
||||||
|
last = *fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
res.push_back(last);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
str function_doc_signature_generator::raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
|
||||||
|
{
|
||||||
|
str res("object");
|
||||||
|
|
||||||
|
res = str("%s %s(%s)" % make_tuple( res, f->m_name, str("tuple args, dict kwds")) );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
|
||||||
|
{
|
||||||
|
if (s.basename==std::string("void")){
|
||||||
|
static const char * none = "None";
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
|
||||||
|
if ( py_type )
|
||||||
|
return py_type->tp_name;
|
||||||
|
else{
|
||||||
|
static const char * object = "object";
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
|
||||||
|
{
|
||||||
|
str param;
|
||||||
|
|
||||||
|
python::detail::signature_element const * s = f.signature();
|
||||||
|
if (cpp_types)
|
||||||
|
{
|
||||||
|
if(!n)
|
||||||
|
s = &f.get_return_type();
|
||||||
|
if (s[n].basename == 0)
|
||||||
|
{
|
||||||
|
return str("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
param = str(s[n].basename);
|
||||||
|
|
||||||
|
if (s[n].lvalue)
|
||||||
|
param += " {lvalue}";
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (n) //we are processing an argument and trying to come up with a name for it
|
||||||
|
{
|
||||||
|
object kv;
|
||||||
|
if ( arg_names && (kv = arg_names[n-1]) )
|
||||||
|
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
|
||||||
|
else
|
||||||
|
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
|
||||||
|
}
|
||||||
|
else //we are processing the return type
|
||||||
|
param = py_type_str(f.get_return_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
//an argument - check for default value and append it
|
||||||
|
if(n && arg_names)
|
||||||
|
{
|
||||||
|
object kv(arg_names[n-1]);
|
||||||
|
if (kv && len(kv) == 2)
|
||||||
|
{
|
||||||
|
param = str("%s=%r" % make_tuple(param, kv[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
str function_doc_signature_generator::pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
|
||||||
|
{
|
||||||
|
py_function
|
||||||
|
const& impl = f->m_fn;
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned arity = impl.max_arity();
|
||||||
|
|
||||||
|
if(arity == unsigned(-1))// is this the proper raw function test?
|
||||||
|
{
|
||||||
|
return raw_function_pretty_signature(f,n_overloads,cpp_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
list formal_params;
|
||||||
|
|
||||||
|
size_t n_extra_default_args=0;
|
||||||
|
|
||||||
|
for (unsigned n = 0; n <= arity; ++n)
|
||||||
|
{
|
||||||
|
str param;
|
||||||
|
|
||||||
|
formal_params.append(
|
||||||
|
parameter_string(impl, n, f->m_arg_names, cpp_types)
|
||||||
|
);
|
||||||
|
|
||||||
|
// find all the arguments with default values preceeding the arity-n_overloads
|
||||||
|
if (n && f->m_arg_names)
|
||||||
|
{
|
||||||
|
object kv(f->m_arg_names[n-1]);
|
||||||
|
|
||||||
|
if (kv && len(kv) == 2)
|
||||||
|
{
|
||||||
|
//default argument preceeding the arity-n_overloads
|
||||||
|
if( n <= arity-n_overloads)
|
||||||
|
++n_extra_default_args;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
//argument without default, preceeding the arity-n_overloads
|
||||||
|
if( n <= arity-n_overloads)
|
||||||
|
n_extra_default_args = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n_overloads+=n_extra_default_args;
|
||||||
|
|
||||||
|
if (!arity && cpp_types)
|
||||||
|
formal_params.append("void");
|
||||||
|
|
||||||
|
str ret_type (formal_params.pop(0));
|
||||||
|
if (cpp_types )
|
||||||
|
{
|
||||||
|
return str(
|
||||||
|
"%s %s(%s%s%s%s)"
|
||||||
|
% make_tuple
|
||||||
|
( ret_type
|
||||||
|
, f->m_name
|
||||||
|
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||||
|
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||||
|
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||||
|
, std::string(n_overloads,']')
|
||||||
|
));
|
||||||
|
}else{
|
||||||
|
return str(
|
||||||
|
"%s(%s%s%s%s) -> %s"
|
||||||
|
% make_tuple
|
||||||
|
( f->m_name
|
||||||
|
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||||
|
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||||
|
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||||
|
, std::string(n_overloads,']')
|
||||||
|
, ret_type
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return str(
|
||||||
|
"%s %s(%s%s%s%s) %s"
|
||||||
|
% make_tuple
|
||||||
|
( cpp_types?ret_type:str("")
|
||||||
|
, f->m_name
|
||||||
|
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||||
|
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||||
|
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||||
|
, std::string(n_overloads,']')
|
||||||
|
, cpp_types?str(""):ret_type
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
char py_signature_tag[] = "PY signature :";
|
||||||
|
char cpp_signature_tag[] = "C++ signature :";
|
||||||
|
}
|
||||||
|
|
||||||
|
list function_doc_signature_generator::function_doc_signatures( function const * f)
|
||||||
|
{
|
||||||
|
list signatures;
|
||||||
|
std::vector<function const*> funcs = flatten( f);
|
||||||
|
std::vector<function const*> split_funcs = split_seq_overloads( funcs, true);
|
||||||
|
std::vector<function const*>::const_iterator sfi=split_funcs.begin(), fi;
|
||||||
|
size_t n_overloads=0;
|
||||||
|
for (fi=funcs.begin(); fi!=funcs.end(); ++fi)
|
||||||
|
{
|
||||||
|
if(*sfi == *fi){
|
||||||
|
if((*fi)->doc())
|
||||||
|
{
|
||||||
|
str func_doc = str((*fi)->doc());
|
||||||
|
|
||||||
|
int doc_len = len(func_doc);
|
||||||
|
|
||||||
|
bool show_py_signature = doc_len >= int(sizeof(detail::py_signature_tag)/sizeof(char)-1)
|
||||||
|
&& str(detail::py_signature_tag) == func_doc.slice(0, int(sizeof(detail::py_signature_tag)/sizeof(char))-1);
|
||||||
|
if(show_py_signature)
|
||||||
|
{
|
||||||
|
func_doc = str(func_doc.slice(int(sizeof(detail::py_signature_tag)/sizeof(char))-1, _));
|
||||||
|
doc_len = len(func_doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool show_cpp_signature = doc_len >= int(sizeof(detail::cpp_signature_tag)/sizeof(char)-1)
|
||||||
|
&& str(detail::cpp_signature_tag) == func_doc.slice( 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char)), _);
|
||||||
|
|
||||||
|
if(show_cpp_signature)
|
||||||
|
{
|
||||||
|
func_doc = str(func_doc.slice(_, 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char))));
|
||||||
|
doc_len = len(func_doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
str res="\n";
|
||||||
|
str pad = "\n";
|
||||||
|
|
||||||
|
if(show_py_signature)
|
||||||
|
{
|
||||||
|
str sig = pretty_signature(*fi, n_overloads,false);
|
||||||
|
res+=sig;
|
||||||
|
if(doc_len || show_cpp_signature )res+=" :";
|
||||||
|
pad+= str(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(doc_len)
|
||||||
|
{
|
||||||
|
if(show_py_signature)
|
||||||
|
res+=pad;
|
||||||
|
res+= pad.join(func_doc.split("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if( show_cpp_signature)
|
||||||
|
{
|
||||||
|
if(len(res)>1)
|
||||||
|
res+="\n"+pad;
|
||||||
|
res+=detail::cpp_signature_tag+pad+" "+pretty_signature(*fi, n_overloads,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
signatures.append(res);
|
||||||
|
}
|
||||||
|
++sfi;
|
||||||
|
n_overloads = 0;
|
||||||
|
}else
|
||||||
|
++n_overloads ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
10
src/str.cpp
10
src/str.cpp
@@ -350,4 +350,14 @@ BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1)
|
|||||||
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2)
|
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2)
|
||||||
BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0)
|
BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0)
|
||||||
|
|
||||||
|
static struct register_str_pytype_ptr
|
||||||
|
{
|
||||||
|
register_str_pytype_ptr()
|
||||||
|
{
|
||||||
|
const_cast<converter::registration &>(
|
||||||
|
converter::registry::lookup(boost::python::type_id<boost::python::str>())
|
||||||
|
).m_class_object = &PyString_Type;
|
||||||
|
}
|
||||||
|
}register_str_pytype_ptr_;
|
||||||
|
|
||||||
}}} // namespace boost::python
|
}}} // namespace boost::python
|
||||||
|
|||||||
@@ -21,4 +21,15 @@ tuple_base::tuple_base(object_cref sequence)
|
|||||||
: object(call(sequence))
|
: object(call(sequence))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
static struct register_tuple_pytype_ptr
|
||||||
|
{
|
||||||
|
register_tuple_pytype_ptr()
|
||||||
|
{
|
||||||
|
const_cast<converter::registration &>(
|
||||||
|
converter::registry::lookup(boost::python::type_id<boost::python::tuple>())
|
||||||
|
).m_class_object = &PyTuple_Type;
|
||||||
|
}
|
||||||
|
}register_tuple_pytype_ptr_;
|
||||||
|
|
||||||
|
|
||||||
}}} // namespace boost::python
|
}}} // namespace boost::python
|
||||||
|
|||||||
@@ -2,12 +2,20 @@
|
|||||||
# Software License, Version 1.0. (See accompanying
|
# Software License, Version 1.0. (See accompanying
|
||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
import python ;
|
||||||
|
|
||||||
use-project /boost/python : ../build ;
|
use-project /boost/python : ../build ;
|
||||||
project /boost/python/test ;
|
project /boost/python/test ;
|
||||||
|
|
||||||
|
local PY = ;
|
||||||
|
if [ python.configured ]
|
||||||
|
{
|
||||||
|
PY = /python//python ;
|
||||||
|
}
|
||||||
|
|
||||||
rule py-run ( sources * : input-file ? )
|
rule py-run ( sources * : input-file ? )
|
||||||
{
|
{
|
||||||
return [ run $(sources) /boost/python//boost_python /python//python
|
return [ run $(sources) /boost/python//boost_python $(PY)
|
||||||
: # args
|
: # args
|
||||||
: $(input-file)
|
: $(input-file)
|
||||||
: #requirements
|
: #requirements
|
||||||
@@ -39,7 +47,7 @@ test-suite python
|
|||||||
:
|
:
|
||||||
|
|
||||||
[
|
[
|
||||||
run exec.cpp ../build//boost_python/<link>static /python//python
|
run exec.cpp ../build//boost_python/<link>static $(PY)
|
||||||
: # program args
|
: # program args
|
||||||
: exec.py
|
: exec.py
|
||||||
: # requirements
|
: # requirements
|
||||||
@@ -135,6 +143,7 @@ bpl-test crossmod_opaque
|
|||||||
[ bpl-test nested ]
|
[ bpl-test nested ]
|
||||||
|
|
||||||
[ bpl-test docstring ]
|
[ bpl-test docstring ]
|
||||||
|
[ bpl-test pytype_function ]
|
||||||
|
|
||||||
[ bpl-test vector_indexing_suite ]
|
[ bpl-test vector_indexing_suite ]
|
||||||
|
|
||||||
@@ -147,7 +156,7 @@ bpl-test crossmod_opaque
|
|||||||
<toolset>hp_cxx:<build>no ]
|
<toolset>hp_cxx:<build>no ]
|
||||||
|
|
||||||
[ python-extension map_indexing_suite_ext
|
[ python-extension map_indexing_suite_ext
|
||||||
: map_indexing_suite.cpp int_map_indexing_suite.cpp
|
: map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
|
||||||
/boost/python//boost_python ]
|
/boost/python//boost_python ]
|
||||||
[ bpl-test
|
[ bpl-test
|
||||||
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
|
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
|
||||||
@@ -182,7 +191,7 @@ bpl-test crossmod_opaque
|
|||||||
:
|
:
|
||||||
:
|
:
|
||||||
: <define>BOOST_PYTHON_STATIC_LIB
|
: <define>BOOST_PYTHON_STATIC_LIB
|
||||||
<use>/python//python
|
<use>$(PY)
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
84
test/a_map_indexing_suite.cpp
Executable file
84
test/a_map_indexing_suite.cpp
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
// Copyright Joel de Guzman 2004. 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/suite/indexing/map_indexing_suite.hpp>
|
||||||
|
#include <boost/python/module.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/python/implicit.hpp>
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
A() : value(0){};
|
||||||
|
A(int v) : value(v) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const A& v1, const A& v2)
|
||||||
|
{
|
||||||
|
return (v1.value == v2.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Converter from A to python int
|
||||||
|
struct AToPython
|
||||||
|
{
|
||||||
|
static PyObject* convert(const A& s)
|
||||||
|
{
|
||||||
|
return boost::python::incref(boost::python::object((int)s.value).ptr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Conversion from python int to A
|
||||||
|
struct AFromPython
|
||||||
|
{
|
||||||
|
AFromPython()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back(
|
||||||
|
&convertible,
|
||||||
|
&construct,
|
||||||
|
boost::python::type_id< A >());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
if (!PyInt_Check(obj_ptr)) return 0;
|
||||||
|
return obj_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
boost::python::converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
void* storage = (
|
||||||
|
(boost::python::converter::rvalue_from_python_storage< A >*)
|
||||||
|
data)-> storage.bytes;
|
||||||
|
|
||||||
|
new (storage) A((int)PyInt_AsLong(obj_ptr));
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void a_map_indexing_suite()
|
||||||
|
{
|
||||||
|
|
||||||
|
to_python_converter< A , AToPython >();
|
||||||
|
AFromPython();
|
||||||
|
|
||||||
|
class_< std::map<int, A> >("AMap")
|
||||||
|
.def(map_indexing_suite<std::map<int, A>, true >())
|
||||||
|
;
|
||||||
|
|
||||||
|
class_< B >("B")
|
||||||
|
.add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
|
||||||
|
make_setter(&B::a, return_value_policy<return_by_value>()))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ tuple raw_func(tuple args, dict kw)
|
|||||||
|
|
||||||
BOOST_PYTHON_MODULE(args_ext)
|
BOOST_PYTHON_MODULE(args_ext)
|
||||||
{
|
{
|
||||||
def("f", f, args("x", "y", "z")
|
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
|
||||||
, "This is f's docstring"
|
, "This is f's docstring"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -72,24 +72,24 @@ BOOST_PYTHON_MODULE(args_ext)
|
|||||||
.def("raw", raw_function(raw_func))
|
.def("raw", raw_function(raw_func))
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<X>("X", "This is X's docstring")
|
class_<X>("X", "This is X's docstring", init<>(args("self")))
|
||||||
.def(init<int, optional<int> >(args("a0", "a1")))
|
.def(init<int, optional<int> >(args("self", "a0", "a1")))
|
||||||
.def("f", &X::f
|
.def("f", &X::f
|
||||||
, "This is X.f's docstring"
|
, "This is X.f's docstring"
|
||||||
, args("x", "y", "z"))
|
, args("self","x", "y", "z"))
|
||||||
|
|
||||||
// Just to prove that all the different argument combinations work
|
// Just to prove that all the different argument combinations work
|
||||||
.def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring")
|
.def("inner0", &X::inner, return_internal_reference<>(), args("self", "n"), "docstring")
|
||||||
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n"))
|
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("self", "n"))
|
||||||
|
|
||||||
.def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring")
|
.def("inner2", &X::inner, args("self", "n"), return_internal_reference<>(), "docstring")
|
||||||
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n"))
|
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("self", "n"))
|
||||||
|
|
||||||
.def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>())
|
.def("inner4", &X::inner, args("self", "n"), "docstring", return_internal_reference<>())
|
||||||
.def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>())
|
.def("inner5", &X::inner, "docstring", args("self", "n"), return_internal_reference<>())
|
||||||
|
|
||||||
.def("f1", &X::f, X_f_overloads(args("x", "y", "z")))
|
.def("f1", &X::f, X_f_overloads(args("self", "x", "y", "z")))
|
||||||
.def("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
|
.def("f2", &X::f, X_f_overloads(args("self", "x", "y", "z"), "f2's docstring"))
|
||||||
;
|
;
|
||||||
|
|
||||||
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
|
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
|
||||||
|
|||||||
67
test/args.py
67
test/args.py
@@ -84,24 +84,27 @@
|
|||||||
(2, 4.25, 'wow')
|
(2, 4.25, 'wow')
|
||||||
>>> q.f1()
|
>>> q.f1()
|
||||||
(1, 4.25, 'wow')
|
(1, 4.25, 'wow')
|
||||||
>>> q.f2.__doc__.splitlines()[-4]
|
>>> q.f2.__doc__.splitlines()[1]
|
||||||
|
'f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple :'
|
||||||
|
|
||||||
|
>>> q.f2.__doc__.splitlines()[2]
|
||||||
" f2's docstring"
|
" f2's docstring"
|
||||||
|
|
||||||
>>> X.f.__doc__.splitlines()[:3]
|
>>> X.f.__doc__.splitlines()[1:5]
|
||||||
["This is X.f's docstring", '', 'C++ signature:']
|
['f( (X)self, (int)x, (float)y, (str)z) -> tuple :', " This is X.f's docstring", '', ' C++ signature :']
|
||||||
|
|
||||||
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
|
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
|
||||||
>>> for f in xfuncs:
|
>>> for f in xfuncs:
|
||||||
... print f(q,1).value(),
|
... print f(q,1).value(),
|
||||||
... print f(q, n = 1).value(),
|
... print f(q, n = 1).value(),
|
||||||
... print f(q, n = 0).value(),
|
... print f(q, n = 0).value(),
|
||||||
... print f.__doc__.splitlines()[:3]
|
... print f.__doc__.splitlines()[1:5]
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner0( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner1( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner2( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner3( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner4( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
1 1 0 ['docstring', '', 'C++ signature:']
|
1 1 0 ['inner5( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
|
||||||
|
|
||||||
>>> x = X(a1 = 44, a0 = 22)
|
>>> x = X(a1 = 44, a0 = 22)
|
||||||
>>> x.inner0(0).value()
|
>>> x.inner0(0).value()
|
||||||
@@ -136,49 +139,9 @@ if __name__ == '__main__':
|
|||||||
import sys
|
import sys
|
||||||
status = run()[0]
|
status = run()[0]
|
||||||
if (status == 0): print "Done."
|
if (status == 0): print "Done."
|
||||||
|
import args_ext
|
||||||
|
help(args_ext)
|
||||||
sys.exit(status)
|
sys.exit(status)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,24 @@
|
|||||||
... except TypeError: pass
|
... except TypeError: pass
|
||||||
... else: print 'expected a TypeError exception'
|
... else: print 'expected a TypeError exception'
|
||||||
|
|
||||||
|
>>> print look.__doc__.splitlines()[1]
|
||||||
|
look( (X)arg1) -> int :
|
||||||
|
|
||||||
|
>>> print steal.__doc__.splitlines()[1]
|
||||||
|
steal( (X)arg1) -> int :
|
||||||
|
|
||||||
|
>>> print maybe_steal.__doc__.splitlines()[1]
|
||||||
|
maybe_steal( (X)arg1, (bool)arg2) -> int :
|
||||||
|
|
||||||
|
>>> print make.__doc__.splitlines()[1]
|
||||||
|
make() -> X :
|
||||||
|
|
||||||
|
>>> print callback.__doc__.splitlines()[1]
|
||||||
|
callback( (object)arg1) -> X :
|
||||||
|
|
||||||
|
>>> print extract.__doc__.splitlines()[1]
|
||||||
|
extract( (object)arg1) -> X :
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def run(args = None):
|
def run(args = None):
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
>>> assert y_identity(y) is y
|
>>> assert y_identity(y) is y
|
||||||
>>> y_equality(y, y)
|
>>> y_equality(y, y)
|
||||||
1
|
1
|
||||||
|
|
||||||
|
>>> print y_identity.__doc__.splitlines()[1]
|
||||||
|
y_identity( (Y)arg1) -> object :
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def run(args = None):
|
def run(args = None):
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int Var::static1 = 0;
|
|||||||
Y Var::static2(0);
|
Y Var::static2(0);
|
||||||
|
|
||||||
// Compilability regression tests
|
// Compilability regression tests
|
||||||
namespace
|
namespace boost_python_test
|
||||||
{
|
{
|
||||||
struct trivial
|
struct trivial
|
||||||
{
|
{
|
||||||
@@ -86,6 +86,7 @@ namespace
|
|||||||
|
|
||||||
BOOST_PYTHON_MODULE(data_members_ext)
|
BOOST_PYTHON_MODULE(data_members_ext)
|
||||||
{
|
{
|
||||||
|
using namespace boost_python_test;
|
||||||
class_<X>("X", init<int>())
|
class_<X>("X", init<int>())
|
||||||
.def("value", &X::value)
|
.def("value", &X::value)
|
||||||
.def("set", &X::set)
|
.def("set", &X::set)
|
||||||
|
|||||||
@@ -159,10 +159,10 @@ BOOST_PYTHON_MODULE(defaults_ext)
|
|||||||
.def("get_state", &Y::get_state)
|
.def("get_state", &Y::get_state)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<X>("X")
|
class_<X>("X",no_init)
|
||||||
|
|
||||||
.def(init<int, optional<char, std::string, double> >("doc of init"))
|
.def(init<optional<int, char, std::string, double> >("doc of init", args("self", "a", "b", "c", "d")))
|
||||||
.def(init<std::string, bool>()[default_call_policies()]) // what's a good policy here?
|
.def(init<std::string, bool>(args("self", "s", "b"))[default_call_policies()]) // what's a good policy here?
|
||||||
.def("get_state", &X::get_state)
|
.def("get_state", &X::get_state)
|
||||||
.def("bar", &X::bar, X_bar_stubs())
|
.def("bar", &X::bar, X_bar_stubs())
|
||||||
.def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])
|
.def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])
|
||||||
|
|||||||
@@ -113,26 +113,20 @@
|
|||||||
... doc = obj.__doc__.splitlines()
|
... doc = obj.__doc__.splitlines()
|
||||||
... return "\\n".join(["|"+doc[i] for i in args])
|
... return "\\n".join(["|"+doc[i] for i in args])
|
||||||
|
|
||||||
>>> print selected_doc(X.__init__, 0, 3, 6, 9, 11, 12, 14, 17)
|
>>> print selected_doc(X.__init__, 1, 2, 4, 7, 9)
|
||||||
|C++ signature:
|
|__init__( (object)self [, (int)a [, (str)b [, (str)c [, (float)d]]]]) -> None :
|
||||||
|C++ signature:
|
|
||||||
|C++ signature:
|
|
||||||
|C++ signature:
|
|
||||||
|
|
|
||||||
| doc of init
|
| doc of init
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|__init__( (object)self, (str)s, (bool)b) -> None :
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> print selected_doc(Y.__init__, 0, 2)
|
>>> print selected_doc(Y.__init__, 1, 2, 4)
|
||||||
|
|__init__( (object)arg1) -> None :
|
||||||
| doc of Y init
|
| doc of Y init
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> print selected_doc(X.bar2, 0, 3, 6, 9, 11, 12, 14)
|
>>> print selected_doc(X.bar2, 1, 2, 4)
|
||||||
|C++ signature:
|
|bar2( (X)arg1 [, (int)arg2 [, (str)arg3 [, (str)arg4 [, (float)arg5]]]]) -> Y :
|
||||||
|C++ signature:
|
|
||||||
|C++ signature:
|
|
||||||
|C++ signature:
|
|
||||||
|
|
|
||||||
| doc of X::bar2
|
| doc of X::bar2
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
|
|||||||
@@ -43,54 +43,73 @@ BOOST_PYTHON_MODULE(docstring_ext)
|
|||||||
, init<int>(
|
, init<int>(
|
||||||
"this is the __init__ function\n"
|
"this is the __init__ function\n"
|
||||||
"its documentation has two lines."
|
"its documentation has two lines."
|
||||||
|
, args("self", "value")
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
.def("value", &X::value,
|
.def("value", &X::value,
|
||||||
"gets the value of the object")
|
"gets the value of the object"
|
||||||
|
, args("self"))
|
||||||
.def( "value", &X::value,
|
.def( "value", &X::value,
|
||||||
"also gets the value of the object")
|
"also gets the value of the object"
|
||||||
|
, args("self"))
|
||||||
;
|
;
|
||||||
|
|
||||||
def("create", create, return_value_policy<manage_new_object>(),
|
def("create", create, return_value_policy<manage_new_object>(),
|
||||||
"creates a new X object");
|
"creates a new X object", args("value"));
|
||||||
|
|
||||||
def("fact", fact, "compute the factorial");
|
def("fact", fact, "compute the factorial", args("n"));
|
||||||
|
|
||||||
{
|
{
|
||||||
docstring_options doc_options;
|
docstring_options doc_options;
|
||||||
doc_options.disable_user_defined();
|
doc_options.disable_user_defined();
|
||||||
def("fact_usr_off_1", fact, "usr off 1");
|
def("fact_usr_off_1", fact, "usr off 1", args("n"));
|
||||||
doc_options.enable_user_defined();
|
doc_options.enable_user_defined();
|
||||||
def("fact_usr_on_1", fact, "usr on 1");
|
def("fact_usr_on_1", fact, "usr on 1", args("n"));
|
||||||
doc_options.disable_user_defined();
|
doc_options.disable_user_defined();
|
||||||
def("fact_usr_off_2", fact, "usr off 2");
|
def("fact_usr_off_2", fact, "usr off 2", args("n"));
|
||||||
}
|
}
|
||||||
def("fact_usr_on_2", fact, "usr on 2");
|
def("fact_usr_on_2", fact, "usr on 2", args("n"));
|
||||||
|
|
||||||
{
|
{
|
||||||
docstring_options doc_options(true, false);
|
docstring_options doc_options(true, false);
|
||||||
def("fact_sig_off_1", fact, "sig off 1");
|
def("fact_sig_off_1", fact, "sig off 1", args("n"));
|
||||||
doc_options.enable_signatures();
|
doc_options.enable_signatures();
|
||||||
def("fact_sig_on_1", fact, "sig on 1");
|
def("fact_sig_on_1", fact, "sig on 1", args("n"));
|
||||||
doc_options.disable_signatures();
|
doc_options.disable_signatures();
|
||||||
def("fact_sig_off_2", fact, "sig off 2");
|
def("fact_sig_off_2", fact, "sig off 2", args("n"));
|
||||||
}
|
}
|
||||||
def("fact_sig_on_2", fact, "sig on 2");
|
def("fact_sig_on_2", fact, "sig on 2", args("n"));
|
||||||
|
|
||||||
{
|
{
|
||||||
docstring_options doc_options(false);
|
docstring_options doc_options(false);
|
||||||
def("fact_usr_off_sig_off_1", fact, "usr off sig off 1");
|
def("fact_usr_off_sig_off_1", fact, "usr off sig off 1", args("n"));
|
||||||
{
|
{
|
||||||
docstring_options nested_doc_options;
|
docstring_options nested_doc_options;
|
||||||
def("fact_usr_on_sig_on_1", fact, "usr on sig on 1");
|
def("fact_usr_on_sig_on_1", fact, "usr on sig on 1", args("n"));
|
||||||
nested_doc_options.disable_all();
|
nested_doc_options.disable_all();
|
||||||
nested_doc_options.enable_user_defined();
|
nested_doc_options.enable_user_defined();
|
||||||
def("fact_usr_on_sig_off_1", fact, "usr on sig off 1");
|
def("fact_usr_on_sig_off_1", fact, "usr on sig off 1", args("n"));
|
||||||
nested_doc_options.enable_all();
|
nested_doc_options.enable_all();
|
||||||
def("fact_usr_on_sig_on_2", fact, "usr on sig on 2");
|
def("fact_usr_on_sig_on_2", fact, "usr on sig on 2", args("n"));
|
||||||
}
|
}
|
||||||
def("fact_usr_off_sig_off_2", fact, "usr off sig off 2");
|
def("fact_usr_off_sig_off_2", fact, "usr off sig off 2", args("n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
docstring_options doc_options(true);
|
||||||
|
doc_options.disable_cpp_signatures();
|
||||||
|
def("fact_usr_on_psig_on_csig_off_1", fact, "usr on psig on csig off 1", args("n"));
|
||||||
|
doc_options.enable_cpp_signatures();
|
||||||
|
doc_options.disable_py_signatures();
|
||||||
|
def("fact_usr_on_psig_off_csig_on_1", fact, "usr on psig off csig on 1", args("n"));
|
||||||
|
doc_options.enable_py_signatures();
|
||||||
|
doc_options.disable_user_defined();
|
||||||
|
doc_options.disable_cpp_signatures();
|
||||||
|
def("fact_usr_off_psig_on_csig_off_1", fact, "usr off psig on csig off 1", args("n"));
|
||||||
|
doc_options.enable_cpp_signatures();
|
||||||
|
doc_options.disable_py_signatures();
|
||||||
|
def("fact_usr_off_psig_off_csig_on_1", fact, "usr off psig off csig on 1", args("n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,82 +8,114 @@
|
|||||||
... doc = obj.__doc__.splitlines()
|
... doc = obj.__doc__.splitlines()
|
||||||
... return "\\n".join(["|"+doc[i] for i in args])
|
... return "\\n".join(["|"+doc[i] for i in args])
|
||||||
|
|
||||||
>>> print selected_doc(X.__init__, 0, 1, 3)
|
>>> print selected_doc(X.__init__, 1, 2, 3, 4, 5)
|
||||||
|
|__init__( (object)self, (int)value) -> None :
|
||||||
| this is the __init__ function
|
| this is the __init__ function
|
||||||
| its documentation has two lines.
|
| its documentation has two lines.
|
||||||
|
|
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> print selected_doc(X.value, 0, 2, 4, 5, 7)
|
>>> print selected_doc(X.value, 1, 2, 4, 7, 8, 10)
|
||||||
|
|value( (X)self) -> int :
|
||||||
| gets the value of the object
|
| gets the value of the object
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
|value( (X)self) -> int :
|
||||||
| also gets the value of the object
|
| also gets the value of the object
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> print selected_doc(create, 0, 2)
|
>>> print selected_doc(create, 1, 2, 3, 4)
|
||||||
|
|create( (int)value) -> X :
|
||||||
| creates a new X object
|
| creates a new X object
|
||||||
|
|
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> print selected_doc(fact, 0, 2)
|
>>> print selected_doc(fact, 1, 2, 3, 4)
|
||||||
|
|fact( (int)n) -> int :
|
||||||
| compute the factorial
|
| compute the factorial
|
||||||
|
|
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> len(fact_usr_off_1.__doc__.splitlines())
|
>>> len(fact_usr_off_1.__doc__.splitlines())
|
||||||
2
|
5
|
||||||
>>> print selected_doc(fact_usr_off_1, 0)
|
>>> print selected_doc(fact_usr_off_1, 1, 3)
|
||||||
|
|fact_usr_off_1( (int)n) -> int :
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
>>> len(fact_usr_on_1.__doc__.splitlines())
|
>>> len(fact_usr_on_1.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_usr_on_1, 0, 2)
|
>>> print selected_doc(fact_usr_on_1, 1, 2, 4)
|
||||||
|
|fact_usr_on_1( (int)n) -> int :
|
||||||
| usr on 1
|
| usr on 1
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
>>> len(fact_usr_off_2.__doc__.splitlines())
|
>>> len(fact_usr_off_2.__doc__.splitlines())
|
||||||
2
|
5
|
||||||
>>> print selected_doc(fact_usr_off_2, 0)
|
>>> print selected_doc(fact_usr_off_2, 1, 3)
|
||||||
|
|fact_usr_off_2( (int)n) -> int :
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
>>> len(fact_usr_on_2.__doc__.splitlines())
|
>>> len(fact_usr_on_2.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_usr_on_2, 0, 2)
|
>>> print selected_doc(fact_usr_on_2, 1, 2, 4)
|
||||||
|
|fact_usr_on_2( (int)n) -> int :
|
||||||
| usr on 2
|
| usr on 2
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
|
|
||||||
>>> len(fact_sig_off_1.__doc__.splitlines())
|
>>> len(fact_sig_off_1.__doc__.splitlines())
|
||||||
1
|
2
|
||||||
>>> print selected_doc(fact_sig_off_1, 0)
|
>>> print selected_doc(fact_sig_off_1, 1)
|
||||||
|sig off 1
|
|sig off 1
|
||||||
>>> len(fact_sig_on_1.__doc__.splitlines())
|
>>> len(fact_sig_on_1.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_sig_on_1, 0, 2)
|
>>> print selected_doc(fact_sig_on_1, 1, 2, 4)
|
||||||
|
|fact_sig_on_1( (int)n) -> int :
|
||||||
| sig on 1
|
| sig on 1
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> len(fact_sig_off_2.__doc__.splitlines())
|
>>> len(fact_sig_off_2.__doc__.splitlines())
|
||||||
1
|
2
|
||||||
>>> print selected_doc(fact_sig_off_2, 0)
|
>>> print selected_doc(fact_sig_off_2, 1)
|
||||||
|sig off 2
|
|sig off 2
|
||||||
>>> len(fact_sig_on_2.__doc__.splitlines())
|
>>> len(fact_sig_on_2.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_sig_on_2, 0, 2)
|
>>> print selected_doc(fact_sig_on_2, 1, 2, 4)
|
||||||
|
|fact_sig_on_2( (int)n) -> int :
|
||||||
| sig on 2
|
| sig on 2
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
|
|
||||||
>>> print fact_usr_off_sig_off_1.__doc__
|
>>> print fact_usr_off_sig_off_1.__doc__
|
||||||
None
|
None
|
||||||
>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
|
>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_usr_on_sig_on_1, 0, 2)
|
>>> print selected_doc(fact_usr_on_sig_on_1, 1, 2, 4)
|
||||||
|
|fact_usr_on_sig_on_1( (int)n) -> int :
|
||||||
| usr on sig on 1
|
| usr on sig on 1
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
|
|
||||||
>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
|
>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
|
||||||
1
|
2
|
||||||
>>> print selected_doc(fact_usr_on_sig_off_1, 0)
|
>>> print selected_doc(fact_usr_on_sig_off_1, 1)
|
||||||
|usr on sig off 1
|
|usr on sig off 1
|
||||||
>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
|
>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
|
||||||
4
|
6
|
||||||
>>> print selected_doc(fact_usr_on_sig_on_2, 0, 2)
|
>>> print selected_doc(fact_usr_on_sig_on_2, 1, 2, 4)
|
||||||
|
|fact_usr_on_sig_on_2( (int)n) -> int :
|
||||||
| usr on sig on 2
|
| usr on sig on 2
|
||||||
| C++ signature :
|
| C++ signature :
|
||||||
>>> print fact_usr_off_sig_off_2.__doc__
|
|
||||||
None
|
>>> print selected_doc(fact_usr_on_psig_on_csig_off_1, 1, 2)
|
||||||
|
|fact_usr_on_psig_on_csig_off_1( (int)n) -> int :
|
||||||
|
| usr on psig on csig off 1
|
||||||
|
|
||||||
|
>>> print selected_doc(fact_usr_on_psig_off_csig_on_1, 1, 3)
|
||||||
|
|usr on psig off csig on 1
|
||||||
|
|C++ signature :
|
||||||
|
|
||||||
|
>>> print fact_usr_off_psig_on_csig_off_1.__doc__.splitlines()[1]
|
||||||
|
fact_usr_off_psig_on_csig_off_1( (int)n) -> int
|
||||||
|
|
||||||
|
>>> print selected_doc(fact_usr_off_psig_off_csig_on_1,1)
|
||||||
|
|C++ signature :
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,19 @@
|
|||||||
>>> try: make_x('fool')
|
>>> try: make_x('fool')
|
||||||
... except TypeError: pass
|
... except TypeError: pass
|
||||||
... else: print 'no error'
|
... else: print 'no error'
|
||||||
|
|
||||||
|
>>> print x_value.__doc__.splitlines()[1]
|
||||||
|
x_value( (X)arg1) -> int :
|
||||||
|
|
||||||
|
>>> print make_x.__doc__.splitlines()[1]
|
||||||
|
make_x( (object)arg1) -> X :
|
||||||
|
|
||||||
|
>>> print X.value.__doc__.splitlines()[1]
|
||||||
|
value( (X)arg1) -> int :
|
||||||
|
|
||||||
|
>>> print X.set.__doc__.splitlines()[1]
|
||||||
|
set( (X)arg1, (object)arg2) -> None :
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def run(args = None):
|
def run(args = None):
|
||||||
|
|||||||
@@ -80,7 +80,9 @@
|
|||||||
>>> f.set(1,1.0,"1")
|
>>> f.set(1,1.0,"1")
|
||||||
>>> f.a(), f.b(), f.n()
|
>>> f.a(), f.b(), f.n()
|
||||||
(1, 1.0, '1')
|
(1, 1.0, '1')
|
||||||
>>> f.set2.__doc__.splitlines()[-4]
|
>>> f.set2.__doc__.splitlines()[1]
|
||||||
|
'set2( (Bar)arg1 [, (int)arg2 [, (float)arg3 [, (str)arg4]]]) -> None :'
|
||||||
|
>>> f.set2.__doc__.splitlines()[2]
|
||||||
" set2's docstring"
|
" set2's docstring"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <boost/python/to_python_converter.hpp>
|
#include <boost/python/to_python_converter.hpp>
|
||||||
#include <boost/python/errors.hpp>
|
#include <boost/python/errors.hpp>
|
||||||
#include <boost/python/manage_new_object.hpp>
|
#include <boost/python/manage_new_object.hpp>
|
||||||
|
#include <boost/python/converter/pytype_function.hpp>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "simple_type.hpp"
|
#include "simple_type.hpp"
|
||||||
#include "complicated.hpp"
|
#include "complicated.hpp"
|
||||||
@@ -170,7 +171,8 @@ using boost::python::to_python_converter;
|
|||||||
|
|
||||||
// Wrap a simple by copying it into a Simple
|
// Wrap a simple by copying it into a Simple
|
||||||
struct simple_to_python
|
struct simple_to_python
|
||||||
: to_python_converter<simple, simple_to_python>
|
: to_python_converter<simple, simple_to_python, true>
|
||||||
|
//, boost::python::converter::wrap_pytype<&SimpleType>
|
||||||
{
|
{
|
||||||
static PyObject* convert(simple const& x)
|
static PyObject* convert(simple const& x)
|
||||||
{
|
{
|
||||||
@@ -178,6 +180,7 @@ struct simple_to_python
|
|||||||
p->x = x;
|
p->x = x;
|
||||||
return (PyObject*)p;
|
return (PyObject*)p;
|
||||||
}
|
}
|
||||||
|
static PyTypeObject const *get_pytype(){return &SimpleType; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct int_from_noddy
|
struct int_from_noddy
|
||||||
|
|||||||
@@ -26,61 +26,6 @@ std::string x_value(X const& x)
|
|||||||
return "gotya " + x.s;
|
return "gotya " + x.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
A() : value(0){};
|
|
||||||
A(int v) : value(v) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const A& v1, const A& v2)
|
|
||||||
{
|
|
||||||
return (v1.value == v2.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct B
|
|
||||||
{
|
|
||||||
A a;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Converter from A to python int
|
|
||||||
struct AToPython
|
|
||||||
{
|
|
||||||
static PyObject* convert(const A& s)
|
|
||||||
{
|
|
||||||
return boost::python::incref(boost::python::object((int)s.value).ptr());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Conversion from python int to A
|
|
||||||
struct AFromPython
|
|
||||||
{
|
|
||||||
AFromPython()
|
|
||||||
{
|
|
||||||
boost::python::converter::registry::push_back(
|
|
||||||
&convertible,
|
|
||||||
&construct,
|
|
||||||
boost::python::type_id< A >());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* convertible(PyObject* obj_ptr)
|
|
||||||
{
|
|
||||||
if (!PyInt_Check(obj_ptr)) return 0;
|
|
||||||
return obj_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void construct(
|
|
||||||
PyObject* obj_ptr,
|
|
||||||
boost::python::converter::rvalue_from_python_stage1_data* data)
|
|
||||||
{
|
|
||||||
void* storage = (
|
|
||||||
(boost::python::converter::rvalue_from_python_storage< A >*)
|
|
||||||
data)-> storage.bytes;
|
|
||||||
|
|
||||||
new (storage) A((int)PyInt_AsLong(obj_ptr));
|
|
||||||
data->convertible = storage;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(map_indexing_suite_ext)
|
BOOST_PYTHON_MODULE(map_indexing_suite_ext)
|
||||||
{
|
{
|
||||||
@@ -115,17 +60,9 @@ BOOST_PYTHON_MODULE(map_indexing_suite_ext)
|
|||||||
.def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
|
.def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
|
||||||
;
|
;
|
||||||
|
|
||||||
to_python_converter< A , AToPython >();
|
void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
|
||||||
AFromPython();
|
a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
|
||||||
|
|
||||||
class_< std::map<int, A> >("AMap")
|
|
||||||
.def(map_indexing_suite<std::map<int, A>, true >())
|
|
||||||
;
|
|
||||||
|
|
||||||
class_< B >("B")
|
|
||||||
.add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
|
|
||||||
make_setter(&B::a, return_value_policy<return_by_value>()))
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "module_tail.cpp"
|
#include "module_tail.cpp"
|
||||||
|
|||||||
@@ -183,6 +183,8 @@ are a complicated constructor and member function, respectively.
|
|||||||
>>> dd = take_d(d_as_a)
|
>>> dd = take_d(d_as_a)
|
||||||
>>> dd.name()
|
>>> dd.name()
|
||||||
'D'
|
'D'
|
||||||
|
>>> print g.__doc__.splitlines()[1]
|
||||||
|
g( (Simple)arg1) -> Simple :
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace {
|
namespace boost_python_test {
|
||||||
|
|
||||||
// A friendly class.
|
// A friendly class.
|
||||||
class world
|
class world
|
||||||
@@ -52,6 +52,7 @@ namespace {
|
|||||||
BOOST_PYTHON_MODULE(pickle1_ext)
|
BOOST_PYTHON_MODULE(pickle1_ext)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
using namespace boost_python_test;
|
||||||
class_<world>("world", init<const std::string&>())
|
class_<world>("world", init<const std::string&>())
|
||||||
.def("greet", &world::greet)
|
.def("greet", &world::greet)
|
||||||
.def_pickle(world_pickle_suite())
|
.def_pickle(world_pickle_suite())
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include <boost/python/tuple.hpp>
|
#include <boost/python/tuple.hpp>
|
||||||
#include <boost/python/extract.hpp>
|
#include <boost/python/extract.hpp>
|
||||||
|
|
||||||
namespace { // Avoid cluttering the global namespace.
|
namespace boost_python_test {
|
||||||
|
|
||||||
// A friendly class.
|
// A friendly class.
|
||||||
class world
|
class world
|
||||||
@@ -88,6 +88,7 @@ namespace { // Avoid cluttering the global namespace.
|
|||||||
|
|
||||||
BOOST_PYTHON_MODULE(pickle2_ext)
|
BOOST_PYTHON_MODULE(pickle2_ext)
|
||||||
{
|
{
|
||||||
|
using namespace boost_python_test;
|
||||||
boost::python::class_<world>(
|
boost::python::class_<world>(
|
||||||
"world", boost::python::init<const std::string&>())
|
"world", boost::python::init<const std::string&>())
|
||||||
.def("greet", &world::greet)
|
.def("greet", &world::greet)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
# define make_tuple boost::python::make_tuple
|
# define make_tuple boost::python::make_tuple
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace { // Avoid cluttering the global namespace.
|
namespace boost_python_test {
|
||||||
|
|
||||||
// A friendly class.
|
// A friendly class.
|
||||||
class world
|
class world
|
||||||
@@ -100,6 +100,7 @@ namespace { // Avoid cluttering the global namespace.
|
|||||||
|
|
||||||
BOOST_PYTHON_MODULE(pickle3_ext)
|
BOOST_PYTHON_MODULE(pickle3_ext)
|
||||||
{
|
{
|
||||||
|
using namespace boost_python_test;
|
||||||
boost::python::class_<world>(
|
boost::python::class_<world>(
|
||||||
"world", boost::python::init<const std::string&>())
|
"world", boost::python::init<const std::string&>())
|
||||||
.def("greet", &world::greet)
|
.def("greet", &world::greet)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace {
|
namespace boost_python_test {
|
||||||
|
|
||||||
// A friendly class.
|
// A friendly class.
|
||||||
class world
|
class world
|
||||||
@@ -35,6 +35,7 @@ namespace {
|
|||||||
BOOST_PYTHON_MODULE(pickle4_ext)
|
BOOST_PYTHON_MODULE(pickle4_ext)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
using namespace boost_python_test;
|
||||||
class_<world>("world", init<const std::string&>())
|
class_<world>("world", init<const std::string&>())
|
||||||
.enable_pickling()
|
.enable_pickling()
|
||||||
.def("greet", &world::greet)
|
.def("greet", &world::greet)
|
||||||
|
|||||||
85
test/pytype_function.cpp
Normal file
85
test/pytype_function.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// Copyright Joel de Guzman 2004. 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/module.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/python/extract.hpp>
|
||||||
|
#include <boost/python/to_python_converter.hpp>
|
||||||
|
#include <boost/python/class.hpp>
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B(const A& a_):a(a_){}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Converter from A to python int
|
||||||
|
struct BToPython
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
: converter::to_python_target_type<A> //inherits get_pytype
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
static PyObject* convert(const B& b)
|
||||||
|
{
|
||||||
|
return boost::python::incref(boost::python::object(b.a).ptr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Conversion from python int to A
|
||||||
|
struct BFromPython
|
||||||
|
{
|
||||||
|
BFromPython()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back(
|
||||||
|
&convertible,
|
||||||
|
&construct,
|
||||||
|
boost::python::type_id< B >()
|
||||||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||||
|
, &converter::expected_from_python_type<A>::get_pytype//convertible to A can be converted to B
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
extract<const A&> ex(obj_ptr);
|
||||||
|
if (!ex.check()) return 0;
|
||||||
|
return obj_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
boost::python::converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
void* storage = (
|
||||||
|
(boost::python::converter::rvalue_from_python_storage< B >*)data)-> storage.bytes;
|
||||||
|
|
||||||
|
extract<const A&> ex(obj_ptr);
|
||||||
|
new (storage) B(ex());
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
B func(const B& b) { return b ; }
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(pytype_function_ext)
|
||||||
|
{
|
||||||
|
to_python_converter< B , BToPython,true >(); //has get_pytype
|
||||||
|
BFromPython();
|
||||||
|
|
||||||
|
class_<A>("A") ;
|
||||||
|
|
||||||
|
def("func", &func);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "module_tail.cpp"
|
||||||
27
test/pytype_function.py
Executable file
27
test/pytype_function.py
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright David Abrahams 2004. 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)
|
||||||
|
"""
|
||||||
|
>>> from pytype_function_ext import *
|
||||||
|
|
||||||
|
>>> print func.__doc__.splitlines()[1]
|
||||||
|
func( (A)arg1) -> A :
|
||||||
|
|
||||||
|
"""
|
||||||
|
def run(args = None):
|
||||||
|
import sys
|
||||||
|
import doctest
|
||||||
|
|
||||||
|
if args is not None:
|
||||||
|
sys.argv = args
|
||||||
|
return doctest.testmod(sys.modules.get(__name__))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print "running..."
|
||||||
|
import sys
|
||||||
|
status = run()[0]
|
||||||
|
if (status == 0): print "Done."
|
||||||
|
sys.exit(status)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ struct functions
|
|||||||
}
|
}
|
||||||
|
|
||||||
static shared_ptr<T> get() { return storage; }
|
static shared_ptr<T> get() { return storage; }
|
||||||
|
static shared_ptr<T> &get1() { return storage; }
|
||||||
|
|
||||||
static int look_store()
|
static int look_store()
|
||||||
{
|
{
|
||||||
@@ -71,6 +72,8 @@ struct functions
|
|||||||
.staticmethod("identity")
|
.staticmethod("identity")
|
||||||
.def("null", &null)
|
.def("null", &null)
|
||||||
.staticmethod("null")
|
.staticmethod("null")
|
||||||
|
.def("get1", &get1, return_internal_reference<>())
|
||||||
|
.staticmethod("get1")
|
||||||
.def("get", &get)
|
.def("get", &get)
|
||||||
.staticmethod("get")
|
.staticmethod("get")
|
||||||
.def("count", &T::count)
|
.def("count", &T::count)
|
||||||
@@ -154,6 +157,14 @@ shared_ptr<Y> factory(int n)
|
|||||||
|
|
||||||
// ------
|
// ------
|
||||||
|
|
||||||
|
// from Neal Becker
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
boost::shared_ptr<X> x;
|
||||||
|
};
|
||||||
|
// ------
|
||||||
|
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(shared_ptr_ext)
|
BOOST_PYTHON_MODULE(shared_ptr_ext)
|
||||||
{
|
{
|
||||||
class_<A, boost::shared_ptr<A_Wrapper>, boost::noncopyable>("A")
|
class_<A, boost::shared_ptr<A_Wrapper>, boost::noncopyable>("A")
|
||||||
@@ -193,6 +204,12 @@ BOOST_PYTHON_MODULE(shared_ptr_ext)
|
|||||||
.def("value", &Z::value)
|
.def("value", &Z::value)
|
||||||
.def("v", &Z::v, &ZWrap::default_v)
|
.def("v", &Z::v, &ZWrap::default_v)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// from Neal Becker
|
||||||
|
class_<Test> ("Test")
|
||||||
|
.def_readonly ("x", &Test::x, "x")
|
||||||
|
;
|
||||||
|
// ------
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "module_tail.cpp"
|
#include "module_tail.cpp"
|
||||||
|
|||||||
Reference in New Issue
Block a user