mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
boost/python, libs/python: all changes from trunk merged into branches/release (without any manual modifications)
Commands used: svn merge https://svn.boost.org/svn/boost/branches/release/boost/python https://svn.boost.org/svn/boost/trunk/boost/python /net/chevy/raid1/rwgk/boost_release/merge_attempt/boost/boost/python svn merge https://svn.boost.org/svn/boost/branches/release/libs/python https://svn.boost.org/svn/boost/trunk/libs/python /net/chevy/raid1/rwgk/boost_release/merge_attempt/boost/libs/python svn, version 1.6.4 (r38063) compiled Aug 17 2009, 13:31:03 [SVN r55629]
This commit is contained in:
@@ -10,10 +10,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -31,7 +31,7 @@
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id455921"></a><p>
|
||||
<a name="id457106"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
@@ -94,15 +94,14 @@
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id385276"></a>
|
||||
<a name="id386707"></a>
|
||||
Hello World
|
||||
</h2>
|
||||
<p>
|
||||
Following C/C++ tradition, let's start with the "hello, world". A
|
||||
C++ Function:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="string">"hello, world"</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
@@ -110,8 +109,7 @@
|
||||
<p>
|
||||
can be exposed to Python by writing a Boost.Python wrapper:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -125,8 +123,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
@@ -145,7 +142,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: March 24, 2008 at 23:09:39 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: November 22, 2008 at 03:24:11 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -40,7 +40,7 @@
|
||||
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<a name="embedding.building_embedded_programs"></a><h2>
|
||||
<a name="id471330"></a>
|
||||
<a name="id472330"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
<p>
|
||||
@@ -82,7 +82,7 @@ exe embedded_program # name of the executable
|
||||
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
|
||||
</pre>
|
||||
<a name="embedding.getting_started"></a><h2>
|
||||
<a name="id471435"></a>
|
||||
<a name="id472435"></a>
|
||||
Getting started
|
||||
</h2>
|
||||
<p>
|
||||
@@ -130,23 +130,22 @@ exe embedded_program # name of the executable
|
||||
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
|
||||
<p>
|
||||
As you probably already know, objects in Python are reference-counted. Naturally,
|
||||
the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
|
||||
the <tt class="literal">PyObject</tt>s of the Python C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully automatic
|
||||
in Python, the Python<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
|
||||
by hand]. This is messy and especially hard to get right in the presence
|
||||
in Python, the Python C API requires you to do it <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
|
||||
hand</a>. This is messy and especially hard to get right in the presence
|
||||
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
|
||||
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
|
||||
automate the process.
|
||||
</p>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id471598"></a>
|
||||
<a name="id472601"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
Boost.python provides three related functions to run Python code from C++.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
</pre>
|
||||
@@ -165,8 +164,7 @@ exe embedded_program # name of the executable
|
||||
<p>
|
||||
Boost.python provides a function to import a module:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
import imports a python module (potentially loading it into the running process
|
||||
@@ -176,8 +174,7 @@ exe embedded_program # name of the executable
|
||||
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module and run some Python code in its namespace:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
|
||||
@@ -190,7 +187,7 @@ exe embedded_program # name of the executable
|
||||
a phrase that is well-known in programming circles.
|
||||
</p>
|
||||
<a name="using_the_interpreter.manipulating_python_objects"></a><h2>
|
||||
<a name="id472186"></a>
|
||||
<a name="id473185"></a>
|
||||
Manipulating Python objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -200,8 +197,7 @@ exe embedded_program # name of the executable
|
||||
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
|
||||
The following examples should further illustrate this fact:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
|
||||
@@ -212,20 +208,18 @@ exe embedded_program # name of the executable
|
||||
this variable from the dictionary. Another way to achieve the same result
|
||||
is to use eval instead, which returns the result directly:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</span><span class="special">);</span>
|
||||
</pre>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id472558"></a>
|
||||
<a name="id473554"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
|
||||
is thrown:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">try</span>
|
||||
<pre class="programlisting"><span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
|
||||
<span class="comment">// execution will never get here:
|
||||
@@ -240,14 +234,13 @@ exe embedded_program # name of the executable
|
||||
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
|
||||
information in itself. To find out more about the Python exception that occurred,
|
||||
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
|
||||
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
|
||||
This can be as simple as calling [@http:</em></span>/www.python.org/doc/api/exceptionHandling.html#l2h-70
|
||||
PyErr_Print()] to print the exception's traceback to the console, or comparing
|
||||
the type of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
|
||||
handling functions</a> of the Python C API in your catch-statement. This
|
||||
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
|
||||
to print the exception's traceback to the console, or comparing the type
|
||||
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
|
||||
exceptions</a>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</span>
|
||||
<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
|
||||
<span class="special">{</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -30,14 +30,12 @@
|
||||
is the point where C++ meets Python. Boost.Python provides a default exception
|
||||
handler that translates selected standard exceptions, then gives up:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
<pre class="programlisting"><span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
</pre>
|
||||
<p>
|
||||
Users may provide custom translation. Here's an example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
|
||||
<pre class="programlisting"><span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
|
||||
<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span> <span class="string">"I'm sorry Dave..."</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -40,8 +40,7 @@
|
||||
<p>
|
||||
Consider a C++ class/struct that we want to expose to Python:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -51,8 +50,7 @@
|
||||
<p>
|
||||
We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
|
||||
@@ -71,8 +69,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
@@ -87,8 +84,7 @@
|
||||
exposes the default constructor by default, which is why we were able to
|
||||
write
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
We may wish to wrap a class with a non-default constructor. Let us build
|
||||
@@ -96,8 +92,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor
|
||||
</span> <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -111,8 +106,7 @@
|
||||
We have to tell <tt class="literal">class_<World></tt> about the constructor
|
||||
we want to expose instead.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
|
||||
@@ -133,8 +127,7 @@
|
||||
to the <tt class="literal">def()</tt> member function. Say for example we have
|
||||
another World constructor taking in two doubles:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
|
||||
@@ -144,8 +137,7 @@
|
||||
On the other hand, if we do not wish to expose any constructors at all, we
|
||||
may use <tt class="literal">no_init</tt> instead:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt>
|
||||
@@ -161,8 +153,7 @@
|
||||
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Var</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Var</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">name</span><span class="special">;</span>
|
||||
@@ -173,8 +164,7 @@
|
||||
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
|
||||
to Python:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -184,8 +174,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'is around'</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span>
|
||||
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
|
||||
@@ -194,8 +183,7 @@
|
||||
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
|
||||
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
</span><span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
|
||||
<span class="identifier">File</span> <span class="string">"<stdin>"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> #
|
||||
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
|
||||
@@ -212,8 +200,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Num</span><span class="special">();</span>
|
||||
<span class="keyword">float</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
@@ -227,8 +214,7 @@
|
||||
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
|
||||
class using Boost.Python:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -237,8 +223,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span>
|
||||
<span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">3.14</span><span class="special">)</span>
|
||||
@@ -251,8 +236,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
@@ -268,24 +252,21 @@
|
||||
<p>
|
||||
Consider this trivial inheritance structure:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
|
||||
</pre>
|
||||
<p>
|
||||
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
|
||||
object instances:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
|
||||
<span class="keyword">void</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span>
|
||||
<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -293,8 +274,7 @@
|
||||
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
|
||||
and its base class <tt class="literal">Base</tt>. Thus:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -317,8 +297,7 @@
|
||||
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
|
||||
and <tt class="literal">factory</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -331,8 +310,7 @@
|
||||
is destroyed. We will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
|
||||
policies</a> later.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">// Tell Python to take ownership of factory's result
|
||||
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result
|
||||
</span><span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
|
||||
<span class="identifier">return_value_policy</span><span class="special"><</span><span class="identifier">manage_new_object</span><span class="special">>());</span>
|
||||
</pre>
|
||||
@@ -345,8 +323,7 @@
|
||||
through virtual functions. Continuing our example, let us add a virtual function
|
||||
to our <tt class="literal">Base</tt> class:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
@@ -364,8 +341,7 @@
|
||||
that will unintrusively hook into the virtual functions so that a Python
|
||||
override may be called:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
@@ -397,8 +373,7 @@
|
||||
<p>
|
||||
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -437,8 +412,7 @@
|
||||
section</a>, we wrapped a class with a pure virtual function that we then
|
||||
implemented in C++, or Python classes derived from it. Our base class:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
@@ -447,8 +421,7 @@
|
||||
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
|
||||
function <tt class="literal">f</tt> was not declared as pure virtual:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -457,8 +430,7 @@
|
||||
<p>
|
||||
We wrap it this way:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
@@ -490,8 +462,7 @@
|
||||
<p>
|
||||
Finally, exposing:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="special">&</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -506,8 +477,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
|
||||
<span class="special">...</span> <span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="special">...</span> <span class="keyword">return</span> <span class="number">42</span>
|
||||
@@ -517,15 +487,13 @@
|
||||
<p>
|
||||
Calling <tt class="literal">base.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="number">0</span>
|
||||
</pre>
|
||||
<p>
|
||||
Calling <tt class="literal">derived.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="number">42</span>
|
||||
</pre>
|
||||
</div>
|
||||
@@ -533,7 +501,7 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
|
||||
<a name="class_operators_special_functions.python_operators"></a><h2>
|
||||
<a name="id461482"></a>
|
||||
<a name="id462548"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
<p>
|
||||
@@ -547,8 +515,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
|
||||
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
|
||||
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
|
||||
@@ -562,8 +529,7 @@
|
||||
The class and the various operators can be mapped to Python rather easily
|
||||
and intuitively:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__
|
||||
@@ -582,7 +548,7 @@
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id462239"></a>
|
||||
<a name="id463302"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
<p>
|
||||
@@ -592,8 +558,7 @@
|
||||
wrap C++ functions that correspond to these Python <span class="emphasis"><em>special functions</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">Rational</span>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Rational</span>
|
||||
<span class="special">{</span> <span class="keyword">public</span><span class="special">:</span> <span class="keyword">operator</span> <span class="keyword">double</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">};</span>
|
||||
|
||||
<span class="identifier">Rational</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span> <span class="identifier">Rational</span><span class="special">);</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -87,16 +87,14 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
so Boost.Python must deal with them. To do this, it may need your help. Consider
|
||||
the following C++ function:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
How should the library wrap this function? A naive approach builds a Python
|
||||
X object around result reference. This strategy might or might not work out.
|
||||
Here's an example where it didn't
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
|
||||
<span class="special">>>></span> <span class="identifier">del</span> <span class="identifier">y</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
@@ -106,8 +104,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Well, what if f() was implemented as shown below:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
|
||||
@@ -145,8 +142,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
</span><span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad
|
||||
</span><span class="number">3.14</span>
|
||||
</pre>
|
||||
@@ -160,8 +156,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">z_value</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">z</span><span class="special">-></span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
|
||||
@@ -171,16 +166,14 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Notice that the data member <tt class="literal">z</tt> is held by class Y using
|
||||
a raw pointer. Now we have a potential dangling pointer problem inside Y:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
|
||||
<span class="special">>>></span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
|
||||
<span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
For reference, here's the implementation of <tt class="literal">f</tt> again:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
|
||||
@@ -212,7 +205,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
</ol></div>
|
||||
<a name="call_policies.call_policies"></a><h2>
|
||||
<a name="id464236"></a>
|
||||
<a name="id465291"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
<p>
|
||||
@@ -220,8 +213,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
|
||||
are our friends:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span><span class="special">,</span>
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span> <span class="special">>());</span>
|
||||
</pre>
|
||||
@@ -229,8 +221,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
|
||||
ask?
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&
|
||||
@@ -239,8 +230,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
In short: "return an internal reference <tt class="literal">X&</tt> owned
|
||||
by the 1st argument <tt class="literal">Y& y</tt>".
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the lifetime of the argument indicated by ward
|
||||
@@ -252,8 +242,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
It is also important to note that we have defined two policies above. Two
|
||||
or more policies can be composed by chaining. Here's the general syntax:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">policy1</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<pre class="programlisting"><span class="identifier">policy1</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy2</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy3</span><span class="special"><</span><span class="identifier">args</span><span class="special">...></span> <span class="special">></span> <span class="special">></span>
|
||||
</pre>
|
||||
@@ -317,8 +306,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
We have here our C++ class:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -345,8 +333,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Class X has 4 overloaded functions. We will start by introducing some member
|
||||
function pointer variables:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
@@ -354,8 +341,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
With these in hand, we can proceed to define and wrap this for Python:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
|
||||
@@ -369,30 +355,26 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
with default arguments:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
But the type of a pointer to the function <tt class="literal">f</tt> has no information
|
||||
about its default arguments:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
|
||||
<pre class="programlisting"><span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<p>
|
||||
When we pass this function pointer to the <tt class="literal">def</tt> function,
|
||||
there is no way to retrieve the default arguments:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<p>
|
||||
Because of this, when wrapping C++ code, we had to resort to manual wrapping
|
||||
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
|
||||
or writing thin wrappers:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">// write "thin wrappers"
|
||||
<pre class="programlisting"><span class="comment">// write "thin wrappers"
|
||||
</span><span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
|
||||
|
||||
@@ -415,14 +397,13 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a><h2>
|
||||
<a name="id466276"></a>
|
||||
<a name="id467317"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
Boost.Python now has a way to make it easier. For instance, given a function:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
@@ -430,8 +411,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
will automatically create the thin wrappers for us. This macro will create
|
||||
@@ -441,11 +421,10 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
|
||||
function will automatically add all the foo variants for us:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
|
||||
<a name="id466595"></a>
|
||||
<a name="id467632"></a>
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -460,8 +439,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
may be used to automatically create the thin wrappers for wrapping member
|
||||
functions. Let's have an example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">george</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">george</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span>
|
||||
<span class="identifier">wack_em</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">=</span> <span class="char">'x'</span><span class="special">)</span>
|
||||
@@ -473,8 +451,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
|
||||
@@ -483,15 +460,14 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
in a class named <tt class="literal">george_overloads</tt> that can then be used
|
||||
as an argument to <tt class="literal">def(...)</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<p>
|
||||
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
|
||||
reference</a> for details.
|
||||
</p>
|
||||
<a name="default_arguments.init_and_optional"></a><h2>
|
||||
<a name="id466958"></a>
|
||||
<a name="id467992"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
<p>
|
||||
@@ -499,8 +475,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
arguments or a sequence of overloads. Remember <tt class="literal">init<...></tt>?
|
||||
For example, given a class X with a constructor:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="char">'D'</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">c</span> <span class="special">=</span> <span class="string">"constructor"</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
@@ -509,8 +484,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
You can easily add this constructor to Boost.Python in one shot:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> <span class="special">>())</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice the use of <tt class="literal">init<...></tt> and <tt class="literal">optional<...></tt>
|
||||
@@ -526,8 +500,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
used for overloaded functions and member functions with a common sequence
|
||||
of initial arguments. Here is an example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
@@ -551,21 +524,19 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Like in the previous section, we can generate thin wrappers for these overloaded
|
||||
functions in one-shot:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice though that we have a situation now where we have a minimum of zero
|
||||
(0) arguments and a maximum of 3 arguments.
|
||||
</p>
|
||||
<a name="auto_overloading.manual_wrapping"></a><h2>
|
||||
<a name="id467740"></a>
|
||||
<a name="id468767"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
<p>
|
||||
@@ -584,21 +555,18 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
to automatically wrap the first three of the <tt class="literal">def</tt>s and
|
||||
manually wrap just the last. Here's how we'll do this:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Create a member function pointers as above for both X::f overloads:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
|
||||
<a name="hello.from_start_to_finish"></a><h2>
|
||||
<a name="id386189"></a>
|
||||
<a name="id388718"></a>
|
||||
From Start To Finish
|
||||
</h2>
|
||||
<p>
|
||||
@@ -92,7 +92,7 @@
|
||||
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
|
||||
</p>
|
||||
<a name="hello.let_s_jam_"></a><h2>
|
||||
<a name="id386347"></a>
|
||||
<a name="id387300"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
<p>
|
||||
@@ -108,7 +108,7 @@
|
||||
you going.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id386404"></a>
|
||||
<a name="id387357"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
<p>
|
||||
@@ -156,8 +156,7 @@ using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
|
||||
<p>
|
||||
Finally:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">bjam</span>
|
||||
<pre class="programlisting"><span class="identifier">bjam</span>
|
||||
</pre>
|
||||
<p>
|
||||
It should be building now:
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -64,8 +64,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
</span><span class="keyword">try</span><span class="special">:</span>
|
||||
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
|
||||
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
|
||||
@@ -79,16 +78,14 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
Or for use in class_<>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>range</b></span>
|
||||
@@ -134,8 +131,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
|
||||
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
|
||||
@@ -146,8 +142,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
|
||||
</pre>
|
||||
@@ -163,8 +158,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="comment">// Turn a Python sequence into an STL input range
|
||||
</span> <span class="identifier">stl_input_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
@@ -183,8 +177,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -62,8 +62,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<pre class="programlisting"><span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
|
||||
<span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
|
||||
<span class="keyword">else</span><span class="special">:</span>
|
||||
@@ -78,8 +77,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
|
||||
<span class="keyword">else</span>
|
||||
@@ -126,23 +124,20 @@
|
||||
These derived <tt class="literal">object</tt> types act like real Python types.
|
||||
For instance:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
</pre>
|
||||
<p>
|
||||
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
|
||||
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
|
||||
has a <tt class="literal">keys()</tt> method:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
|
||||
@@ -150,8 +145,7 @@
|
||||
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
|
||||
instances of Python's <tt class="literal">str</tt> type and subtypes.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()
|
||||
</span> <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better
|
||||
@@ -161,15 +155,13 @@
|
||||
<p>
|
||||
In finer detail:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
|
||||
<pre class="programlisting"><span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
Illustrates that we provide versions of the str type's methods as C++ member
|
||||
functions.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
|
||||
@@ -184,19 +176,17 @@
|
||||
<p>
|
||||
Python:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
|
||||
</span><span class="special">>>></span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy
|
||||
</span></pre>
|
||||
<p>
|
||||
C++:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
|
||||
</span></pre>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
|
||||
<a name="id469745"></a>
|
||||
<a name="id470756"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -207,8 +197,7 @@
|
||||
<p>
|
||||
We can use this to create wrapped instances. Example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">>(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span>
|
||||
@@ -225,16 +214,14 @@
|
||||
can be achieved with the <tt class="literal">extract<T></tt> function. Consider
|
||||
the following:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
</span></pre>
|
||||
<p>
|
||||
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
|
||||
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
|
||||
we wanted to do above can be achieved by writing:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&>(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
|
||||
</pre>
|
||||
@@ -251,8 +238,7 @@
|
||||
be extracted, an appropriate exception is thrown. To avoid an exception,
|
||||
we need to test for extractibility:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&></span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&></span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
|
||||
</pre>
|
||||
@@ -260,8 +246,7 @@
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract<T></tt>
|
||||
facility in fact solves the mutable copying problem:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">dict</span><span class="special">>(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">dict</span><span class="special">>(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
|
||||
<span class="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !
|
||||
</span></pre>
|
||||
</div>
|
||||
@@ -276,14 +261,12 @@
|
||||
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
|
||||
to enums). To illustrate, given a C++ enum:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
the construct:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">enum_</span><span class="special"><</span><span class="identifier">choice</span><span class="special">>(</span><span class="string">"choice"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">enum_</span><span class="special"><</span><span class="identifier">choice</span><span class="special">>(</span><span class="string">"choice"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
@@ -315,8 +298,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -325,8 +307,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<pre class="programlisting"><span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -53,8 +53,7 @@
|
||||
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
|
||||
like so:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
|
||||
<pre class="programlisting"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span>
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span>
|
||||
</pre>
|
||||
@@ -62,16 +61,14 @@
|
||||
We would like to present this same hierarchy to the Python user, allowing
|
||||
him to write code like this:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function
|
||||
</span></pre>
|
||||
<p>
|
||||
The first step is to write the wrapping code. We have to export each module
|
||||
separately with Boost.Python, like this:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
|
||||
<pre class="programlisting"><span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
|
||||
@@ -129,8 +126,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">'file.mp3'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">new_sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)</span>
|
||||
@@ -152,8 +148,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file core.cpp */</span>
|
||||
<pre class="programlisting"><span class="comment">/* file core.cpp */</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">...</span>
|
||||
@@ -185,8 +180,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">.</span><span class="identifier">foo</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -196,15 +190,13 @@
|
||||
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
|
||||
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
</pre>
|
||||
<p>
|
||||
We do the same for the other packages. Now the user accesses the functions
|
||||
and classes in the extension modules like before:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -217,8 +209,7 @@
|
||||
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
|
||||
function:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
<span class="keyword">def</span> <span class="identifier">echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span>
|
||||
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
|
||||
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
|
||||
@@ -227,15 +218,13 @@
|
||||
<p>
|
||||
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
</pre>
|
||||
<p>
|
||||
And that's it. The user now accesses this function like any other function
|
||||
from the <tt class="literal">filters</tt> package:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
</div>
|
||||
@@ -246,8 +235,7 @@
|
||||
Thanks to Python's flexibility, you can easily add new methods to a class,
|
||||
even after it was already created:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># a regular function
|
||||
</span><span class="special">>>></span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
|
||||
@@ -270,8 +258,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -284,8 +271,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
|
||||
<span class="comment"># a regular function
|
||||
</span><span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
@@ -317,8 +303,7 @@
|
||||
You can even add a little syntactic sugar with the use of metaclasses. Let's
|
||||
create a special metaclass that "injects" methods in other classes.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
|
||||
</span><span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
|
||||
|
||||
@@ -341,8 +326,7 @@
|
||||
<p>
|
||||
Now let's see how it got:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
|
||||
<span class="identifier">Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="identifier">foo</span><span class="special">!</span>
|
||||
@@ -350,8 +334,7 @@
|
||||
<p>
|
||||
Another useful idea is to replace constructors with factory functions:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
|
||||
<pre class="programlisting"><span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
|
||||
|
||||
<span class="keyword">def</span> <span class="identifier">point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span>
|
||||
<span class="keyword">return</span> <span class="identifier">_point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span>
|
||||
@@ -374,8 +357,7 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file point.cpp */</span>
|
||||
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
@@ -397,8 +379,7 @@
|
||||
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
|
||||
macro, and call the various export functions inside it.
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
|
||||
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">();</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
|
||||
@@ -411,8 +392,7 @@
|
||||
Compiling and linking together all this files produces the same result as
|
||||
the usual approach:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
|
||||
|
||||
@@ -186,10 +186,6 @@ And so on... Finally:
|
||||
Or something similar. If all is well, you should now have built the DLLs and
|
||||
run the Python program.
|
||||
|
||||
[note Starting from Boost 1.35, bjam erases the generated executables
|
||||
(e.g. pyd file) after the test has concluded to conserve disk space.
|
||||
To keep bjam from doing that, pass --preserve-test-targets to bjam.]
|
||||
|
||||
[:[*There you go... Have fun!]]
|
||||
|
||||
[endsect]
|
||||
@@ -1385,10 +1381,10 @@ interpreter. This may be fixed in a future version of boost.python.]
|
||||
[section Using the interpreter]
|
||||
|
||||
As you probably already know, objects in Python are reference-counted.
|
||||
Naturally, the [^PyObject]s of the Python\/C API are also reference-counted.
|
||||
Naturally, the [^PyObject]s of the Python C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully
|
||||
automatic in Python, the Python\/C API requires you to do it
|
||||
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
|
||||
automatic in Python, the Python C API requires you to do it
|
||||
[@http://www.python.org/doc/current/c-api/refcounting.html by hand]. This is
|
||||
messy and especially hard to get right in the presence of C++ exceptions.
|
||||
Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and
|
||||
[@../../../v2/object.html object] class templates to automate the process.
|
||||
@@ -1470,7 +1466,7 @@ If an exception occurs in the evaluation of the python expression,
|
||||
The [^error_already_set] exception class doesn't carry any information in itself.
|
||||
To find out more about the Python exception that occurred, you need to use the
|
||||
[@http://www.python.org/doc/api/exceptionHandling.html exception handling functions]
|
||||
of the Python/C API in your catch-statement. This can be as simple as calling
|
||||
of the Python C API in your catch-statement. This can be as simple as calling
|
||||
[@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to
|
||||
print the exception's traceback to the console, or comparing the type of the
|
||||
exception with those of the [@http://www.python.org/doc/api/standardExceptions.html
|
||||
|
||||
@@ -655,6 +655,11 @@ namespace boost { namespace python { namespace api
|
||||
template <class A0, class A1,...class An>
|
||||
object operator()(A0 const&, A1 const&,...An const&) const;
|
||||
|
||||
detail::args_proxy operator* () const;
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
|
||||
// truth value testing
|
||||
//
|
||||
typedef unspecified bool_type;
|
||||
@@ -704,6 +709,25 @@ object operator()(A0 const& a1, A1 const& a2,...An const& aN) const;
|
||||
call<object>(object(*static_cast<U*>(this)).ptr(), a1,
|
||||
a2,...aN)</dt>
|
||||
</dl>
|
||||
|
||||
<pre>
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
call object with arguments given by the tuple <varname>args</varname></dt>
|
||||
</dl>
|
||||
<pre>
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
call object with arguments given by the tuple <varname>args</varname>, and named
|
||||
arguments given by the dictionary <varname>kwds</varname></dt>
|
||||
</dl>
|
||||
|
||||
|
||||
<pre>
|
||||
operator bool_type() const;
|
||||
</pre>
|
||||
|
||||
9
example/tutorial/Jamroot
Executable file → Normal file
9
example/tutorial/Jamroot
Executable file → Normal file
@@ -2,6 +2,15 @@
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
ECHO "notice: no Python configured in user-config.jam" ;
|
||||
ECHO "notice: will use default configuration" ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
# Specify the path to the Boost project. If you move this project,
|
||||
# adjust this path to refer to the Boost root directory.
|
||||
use-project boost
|
||||
|
||||
@@ -38,7 +38,10 @@ namespace boost { namespace python {
|
||||
|
||||
# endif // CALL_DWA2002411_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, call.hpp)
|
||||
@@ -76,4 +79,5 @@ call(PyObject* callable
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,10 @@ namespace boost { namespace python {
|
||||
|
||||
# endif // CALL_METHOD_DWA2002411_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
|
||||
@@ -76,4 +79,5 @@ call_method(PyObject* self, char const* name
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
|
||||
@@ -117,9 +117,9 @@ struct rvalue_from_python_data : rvalue_from_python_storage<T>
|
||||
// Implementataions
|
||||
//
|
||||
template <class T>
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1)
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& _stage1)
|
||||
{
|
||||
this->stage1 = stage1;
|
||||
this->stage1 = _stage1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -45,10 +45,14 @@ struct shared_ptr_from_python
|
||||
if (data->convertible == source)
|
||||
new (storage) shared_ptr<T>();
|
||||
else
|
||||
{
|
||||
boost::shared_ptr<void> hold_convertible_ref_count(
|
||||
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
|
||||
// use aliasing constructor
|
||||
new (storage) shared_ptr<T>(
|
||||
static_cast<T*>(data->convertible),
|
||||
shared_ptr_deleter(handle<>(borrowed(source)))
|
||||
);
|
||||
hold_convertible_ref_count,
|
||||
static_cast<T*>(data->convertible));
|
||||
}
|
||||
|
||||
data->convertible = storage;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,8 @@ inline object make_getter(D const& d, Policies const& policies)
|
||||
template <class D>
|
||||
inline object make_getter(D& x)
|
||||
{
|
||||
detail::not_specified policy;
|
||||
detail::not_specified policy
|
||||
= detail::not_specified(); // suppress a SunPro warning
|
||||
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
@@ -273,7 +274,8 @@ inline object make_getter(D& x)
|
||||
template <class D>
|
||||
inline object make_getter(D const& d)
|
||||
{
|
||||
detail::not_specified policy;
|
||||
detail::not_specified policy
|
||||
= detail::not_specified(); // Suppress a SunPro warning
|
||||
return detail::make_getter(d, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
# endif
|
||||
|
||||
4
include/boost/python/detail/decorated_type_id.hpp
Executable file → Normal file
4
include/boost/python/detail/decorated_type_id.hpp
Executable file → Normal file
@@ -55,8 +55,8 @@ inline decorated_type_info::decorated_type_info(type_info base_t, decoration dec
|
||||
inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const
|
||||
{
|
||||
return m_decoration < rhs.m_decoration
|
||||
|| m_decoration == rhs.m_decoration
|
||||
&& m_base_type < rhs.m_base_type;
|
||||
|| (m_decoration == rhs.m_decoration
|
||||
&& m_base_type < rhs.m_base_type);
|
||||
}
|
||||
|
||||
inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const
|
||||
|
||||
6
include/boost/python/detail/result.hpp
Executable file → Normal file
6
include/boost/python/detail/result.hpp
Executable file → Normal file
@@ -86,7 +86,10 @@ result(X const&, short = 0) { return 0; }
|
||||
# endif // RESULT_DWA2002521_HPP
|
||||
|
||||
/* --------------- function pointers --------------- */
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers))
|
||||
@@ -128,4 +131,5 @@ boost::type<R>* result(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0)
|
||||
# undef N
|
||||
# undef Q
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,10 @@ T& (* target(R (T::*)) )() { return 0; }
|
||||
# endif // TARGET_DWA2002521_HPP
|
||||
|
||||
/* --------------- function pointers --------------- */
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers))
|
||||
@@ -79,4 +82,5 @@ T& (* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) )()
|
||||
# undef N
|
||||
# undef Q
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
2
include/boost/python/object/class_metadata.hpp
Executable file → Normal file
2
include/boost/python/object/class_metadata.hpp
Executable file → Normal file
@@ -236,7 +236,7 @@ struct class_metadata
|
||||
//
|
||||
// Support for converting smart pointers to python
|
||||
//
|
||||
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
|
||||
inline static void maybe_register_pointer_to_python(...) {}
|
||||
|
||||
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
|
||||
|
||||
@@ -47,7 +47,10 @@ template <int nargs> struct make_holder;
|
||||
|
||||
# endif // MAKE_HOLDER_DWA20011215_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, make_holder.hpp)
|
||||
@@ -102,4 +105,5 @@ struct make_holder<N>
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -127,7 +127,14 @@ void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
|
||||
)
|
||||
return &this->m_p;
|
||||
|
||||
Value* p = get_pointer(this->m_p);
|
||||
Value* p
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
= static_cast<Value*>( get_pointer(this->m_p) )
|
||||
# else
|
||||
= get_pointer(this->m_p)
|
||||
# endif
|
||||
;
|
||||
|
||||
if (p == 0)
|
||||
return 0;
|
||||
|
||||
@@ -163,7 +170,10 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
|
||||
# endif // POINTER_HOLDER_DWA20011215_HPP
|
||||
|
||||
/* --------------- pointer_holder --------------- */
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
|
||||
@@ -205,4 +215,5 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -117,7 +117,10 @@ void* value_holder_back_reference<Value,Held>::holds(
|
||||
|
||||
// --------------- value_holder ---------------
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder))
|
||||
@@ -163,4 +166,5 @@ void* value_holder_back_reference<Value,Held>::holds(
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class kwds_proxy;
|
||||
class args_proxy;
|
||||
}
|
||||
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct arg_to_python;
|
||||
@@ -102,6 +108,11 @@ namespace api
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
detail::args_proxy operator* () const;
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
|
||||
// truth value testing
|
||||
//
|
||||
@@ -219,11 +230,11 @@ namespace api
|
||||
inline object_base(object_base const&);
|
||||
inline object_base(PyObject* ptr);
|
||||
|
||||
object_base& operator=(object_base const& rhs);
|
||||
~object_base();
|
||||
inline object_base& operator=(object_base const& rhs);
|
||||
inline ~object_base();
|
||||
|
||||
// Underlying object access -- returns a borrowed reference
|
||||
PyObject* ptr() const;
|
||||
inline PyObject* ptr() const;
|
||||
|
||||
private:
|
||||
PyObject* m_ptr;
|
||||
@@ -393,7 +404,7 @@ namespace api
|
||||
static PyObject*
|
||||
get(T const& x, U)
|
||||
{
|
||||
return python::incref(get_managed_object(x, tag));
|
||||
return python::incref(get_managed_object(x, boost::python::tag));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -416,6 +427,62 @@ template <class T> struct extract;
|
||||
// implementation
|
||||
//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class call_proxy
|
||||
{
|
||||
public:
|
||||
call_proxy(object target) : m_target(target) {}
|
||||
operator object() const { return m_target;}
|
||||
|
||||
private:
|
||||
object m_target;
|
||||
};
|
||||
|
||||
class kwds_proxy : public call_proxy
|
||||
{
|
||||
public:
|
||||
kwds_proxy(object o = object()) : call_proxy(o) {}
|
||||
};
|
||||
class args_proxy : public call_proxy
|
||||
{
|
||||
public:
|
||||
args_proxy(object o) : call_proxy(o) {}
|
||||
kwds_proxy operator* () const { return kwds_proxy(*this);}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
detail::args_proxy api::object_operators<U>::operator* () const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return boost::python::detail::args_proxy(x);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
object api::object_operators<U>::operator()(detail::args_proxy const &args) const
|
||||
{
|
||||
U const& self = *static_cast<U const*>(this);
|
||||
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
||||
args.operator object().ptr(),
|
||||
0);
|
||||
return object(boost::python::detail::new_reference(result));
|
||||
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
object api::object_operators<U>::operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const
|
||||
{
|
||||
U const& self = *static_cast<U const*>(this);
|
||||
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
||||
args.operator object().ptr(),
|
||||
kwds.operator object().ptr());
|
||||
return object(boost::python::detail::new_reference(result));
|
||||
|
||||
}
|
||||
|
||||
inline object::object()
|
||||
: object_base(python::incref(Py_None))
|
||||
{}
|
||||
|
||||
18
include/boost/python/object_protocol.hpp
Executable file → Normal file
18
include/boost/python/object_protocol.hpp
Executable file → Normal file
@@ -10,9 +10,11 @@
|
||||
# include <boost/python/object_protocol_core.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
// attempt to use SFINAE to prevent functions accepting T const& from
|
||||
// coming up as ambiguous with the one taking a char const* when a
|
||||
// string literal is passed
|
||||
@@ -22,45 +24,45 @@ namespace boost { namespace python { namespace api {
|
||||
# endif
|
||||
|
||||
template <class Target, class Key>
|
||||
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
return getattr(object(target), object(key));
|
||||
}
|
||||
|
||||
template <class Target, class Key, class Default>
|
||||
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
return getattr(object(target), object(key), object(default_));
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value>
|
||||
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
setattr(target, object(key), object(value));
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
delattr(target, object(key));
|
||||
}
|
||||
|
||||
template <class Target, class Key>
|
||||
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
return getitem(object(target), object(key));
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value>
|
||||
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
setitem(target, object(key), object(value));
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
{
|
||||
delitem(target, object(key));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,12 @@ struct slice_policies : const_slice_policies
|
||||
static void del(object const& target, key_type const& key);
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
inline slice_policies::key_type slice_key(T x, U y)
|
||||
{
|
||||
return slice_policies::key_type(handle<>(x), handle<>(y));
|
||||
}
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
@@ -35,7 +41,7 @@ object_slice
|
||||
object_operators<U>::slice(object_cref start, object_cref finish)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
return object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -43,7 +49,7 @@ const_object_slice
|
||||
object_operators<U>::slice(object_cref start, object_cref finish) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -51,7 +57,7 @@ object_slice
|
||||
object_operators<U>::slice(slice_nil, object_cref finish)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
return object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -59,7 +65,7 @@ const_object_slice
|
||||
object_operators<U>::slice(slice_nil, object_cref finish) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -67,7 +73,7 @@ object_slice
|
||||
object_operators<U>::slice(slice_nil, slice_nil)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
return object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -75,7 +81,7 @@ const_object_slice
|
||||
object_operators<U>::slice(slice_nil, slice_nil) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -83,7 +89,7 @@ object_slice
|
||||
object_operators<U>::slice(object_cref start, slice_nil)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
return object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -91,7 +97,7 @@ const_object_slice
|
||||
object_operators<U>::slice(object_cref start, slice_nil) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class U>
|
||||
|
||||
@@ -113,7 +113,10 @@ struct most_derived
|
||||
|
||||
# endif // SIGNATURE_JDG20020813_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
@@ -176,4 +179,5 @@ get_signature(
|
||||
# undef Q
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
@@ -99,8 +99,13 @@ namespace
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||
? &number_methods->nb_int : 0;
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
};
|
||||
@@ -135,7 +140,11 @@ namespace
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
? &py_object_identity : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
@@ -146,10 +155,27 @@ namespace
|
||||
{
|
||||
static T extract(PyObject* intermediate)
|
||||
{
|
||||
return numeric_cast<T>(
|
||||
PyLong_Check(intermediate)
|
||||
? PyLong_AsUnsignedLong(intermediate)
|
||||
: PyInt_AS_LONG(intermediate));
|
||||
if (PyLong_Check(intermediate)) {
|
||||
// PyLong_AsUnsignedLong() checks for negative overflow, so no
|
||||
// need to check it here.
|
||||
unsigned long result = PyLong_AsUnsignedLong(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return numeric_cast<T>(result);
|
||||
} else {
|
||||
// None of PyInt_AsUnsigned*() functions check for negative
|
||||
// overflow, so use PyInt_AS_LONG instead and check if number is
|
||||
// negative, issuing the exception appropriately.
|
||||
long result = PyInt_AS_LONG(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
if (result < 0) {
|
||||
PyErr_SetString(PyExc_OverflowError, "can't convert negative"
|
||||
" value to unsigned");
|
||||
throw_error_already_set();
|
||||
}
|
||||
return numeric_cast<T>(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -226,7 +252,11 @@ namespace
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
|
||||
#else
|
||||
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool extract(PyObject* intermediate)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace
|
||||
detail::new_reference dict_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyDict_Type, "(O)",
|
||||
(PyObject*)&PyDict_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
|
||||
48
src/exec.cpp
48
src/exec.cpp
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <boost/python/exec.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
@@ -15,6 +16,15 @@ namespace python
|
||||
|
||||
object BOOST_PYTHON_DECL eval(str string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (!global)
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (!local) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = python::extract<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
|
||||
@@ -24,6 +34,15 @@ object BOOST_PYTHON_DECL eval(str string, object global, object local)
|
||||
|
||||
object BOOST_PYTHON_DECL exec(str string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (!global)
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (!local) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = python::extract<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
|
||||
@@ -31,15 +50,42 @@ object BOOST_PYTHON_DECL exec(str string, object global, object local)
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (!global)
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (!local) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = python::extract<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
// Execute python source code from file filename.
|
||||
// global and local are the global and local scopes respectively,
|
||||
// used during execution.
|
||||
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (!global)
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (!local) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *f = python::extract<char *>(filename);
|
||||
// Let python open the file to avoid potential binary incompatibilities.
|
||||
PyObject *pyfile = PyFile_FromString(f, "r");
|
||||
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
|
||||
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
|
||||
python::handle<> file(pyfile);
|
||||
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
|
||||
|
||||
@@ -13,7 +13,7 @@ detail::new_non_null_reference list_base::call(object const& arg_)
|
||||
return (detail::new_non_null_reference)
|
||||
(expect_non_null)(
|
||||
PyObject_CallFunction(
|
||||
(PyObject*)&PyList_Type, "(O)",
|
||||
(PyObject*)&PyList_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr()));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,21 +9,21 @@ namespace boost { namespace python { namespace detail {
|
||||
new_non_null_reference long_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, "(O)",
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
new_non_null_reference long_base::call(object const& arg_, object const& base)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, "(OO)",
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(OO)"),
|
||||
arg_.ptr(), base.ptr());
|
||||
}
|
||||
|
||||
long_base::long_base()
|
||||
: object(
|
||||
detail::new_reference(
|
||||
PyObject_CallFunction((PyObject*)&PyLong_Type, "()"))
|
||||
PyObject_CallFunction((PyObject*)&PyLong_Type, const_cast<char*>("()")))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ extern "C"
|
||||
{
|
||||
propertyobject *gs = (propertyobject *)self;
|
||||
|
||||
return PyObject_CallFunction(gs->prop_get, "()");
|
||||
return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -95,9 +95,9 @@ extern "C"
|
||||
return -1;
|
||||
}
|
||||
if (value == NULL)
|
||||
res = PyObject_CallFunction(func, "()");
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("()"));
|
||||
else
|
||||
res = PyObject_CallFunction(func, "(O)", value);
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
@@ -108,7 +108,7 @@ extern "C"
|
||||
static PyTypeObject static_data_object = {
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.StaticProperty",
|
||||
const_cast<char*>("Boost.Python.StaticProperty"),
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
@@ -212,7 +212,7 @@ extern "C"
|
||||
static PyTypeObject class_metatype_object = {
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.class",
|
||||
const_cast<char*>("Boost.Python.class"),
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
@@ -316,7 +316,7 @@ namespace objects
|
||||
{
|
||||
// Attempt to find the __instance_size__ attribute. If not present, no problem.
|
||||
PyObject* d = type_->tp_dict;
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
|
||||
|
||||
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
|
||||
|
||||
@@ -357,20 +357,20 @@ namespace objects
|
||||
|
||||
|
||||
static PyGetSetDef instance_getsets[] = {
|
||||
{"__dict__", instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static PyMemberDef instance_members[] = {
|
||||
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static PyTypeObject class_type_object = {
|
||||
PyObject_HEAD_INIT(0) //&class_metatype_object)
|
||||
0,
|
||||
"Boost.Python.instance",
|
||||
const_cast<char*>("Boost.Python.instance"),
|
||||
offsetof(instance<>,storage), /* tp_basicsize */
|
||||
1, /* tp_itemsize */
|
||||
instance_dealloc, /* tp_dealloc */
|
||||
@@ -506,13 +506,12 @@ namespace objects
|
||||
// Build a tuple of the base Python type objects. If no bases
|
||||
// were declared, we'll use our class_type() as the single base
|
||||
// class.
|
||||
std::size_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
|
||||
assert(num_bases <= ssize_t_max);
|
||||
handle<> bases(PyTuple_New(static_cast<ssize_t>(num_bases)));
|
||||
ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
|
||||
handle<> bases(PyTuple_New(num_bases));
|
||||
|
||||
for (std::size_t i = 1; i <= num_bases; ++i)
|
||||
for (ssize_t i = 1; i <= num_bases; ++i)
|
||||
{
|
||||
type_handle c = (i >= num_types) ? class_type() : get_class(types[i]);
|
||||
type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
|
||||
// PyTuple_SET_ITEM steals this reference
|
||||
PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(c.release()));
|
||||
}
|
||||
@@ -572,7 +571,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -582,7 +581,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -591,7 +590,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), "O", fget.ptr()));
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -600,7 +599,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -615,13 +614,13 @@ namespace objects
|
||||
{
|
||||
extern "C" PyObject* no_init(PyObject*, PyObject*)
|
||||
{
|
||||
::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
|
||||
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
|
||||
return NULL;
|
||||
}
|
||||
static ::PyMethodDef no_init_def = {
|
||||
"__init__", no_init, METH_VARARGS,
|
||||
"Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n"
|
||||
const_cast<char*>("__init__"), no_init, METH_VARARGS,
|
||||
const_cast<char*>("Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n")
|
||||
};
|
||||
}
|
||||
|
||||
@@ -650,7 +649,7 @@ namespace objects
|
||||
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, "staticmethod expects callable object; got an object of type %s, which is not callable"
|
||||
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
|
||||
, callable->ob_type->tp_name
|
||||
);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/python/object_protocol.hpp>
|
||||
#include <structmember.h>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct enum_object
|
||||
{
|
||||
@@ -23,7 +23,7 @@ struct enum_object
|
||||
};
|
||||
|
||||
static PyMemberDef enum_members[] = {
|
||||
{"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ extern "C"
|
||||
{
|
||||
static PyObject* enum_repr(PyObject* self_)
|
||||
{
|
||||
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
|
||||
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
|
||||
enum_object* self = downcast<enum_object>(self_);
|
||||
if (!self->name)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ extern "C"
|
||||
char* name = PyString_AsString(self->name);
|
||||
if (name == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ extern "C"
|
||||
static PyTypeObject enum_type_object = {
|
||||
PyObject_HEAD_INIT(0) // &PyType_Type
|
||||
0,
|
||||
"Boost.Python.enum",
|
||||
const_cast<char*>("Boost.Python.enum"),
|
||||
sizeof(enum_object), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
@@ -139,15 +139,16 @@ namespace
|
||||
dict d;
|
||||
d["__slots__"] = tuple();
|
||||
d["values"] = dict();
|
||||
d["names"] = dict();
|
||||
|
||||
object module_name = module_prefix();
|
||||
if (module_name)
|
||||
d["__module__"] = module_name;
|
||||
if (doc)
|
||||
d["__doc__"] = doc;
|
||||
|
||||
|
||||
object result = (object(metatype))(name, make_tuple(base), d);
|
||||
|
||||
|
||||
scope().attr(name) = result;
|
||||
|
||||
return result;
|
||||
@@ -167,7 +168,7 @@ enum_base::enum_base(
|
||||
converter::registration& converters
|
||||
= const_cast<converter::registration&>(
|
||||
converter::registry::lookup(id));
|
||||
|
||||
|
||||
converters.m_class_object = downcast<PyTypeObject>(this->ptr());
|
||||
converter::registry::insert(to_python, id);
|
||||
converter::registry::insert(convertible, construct, id);
|
||||
@@ -186,23 +187,24 @@ void enum_base::add_value(char const* name_, long value)
|
||||
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
d[value] = x;
|
||||
|
||||
|
||||
// Set the name field in the new enum instanec
|
||||
enum_object* p = downcast<enum_object>(x.ptr());
|
||||
Py_XDECREF(p->name);
|
||||
p->name = incref(name.ptr());
|
||||
|
||||
dict names_dict = extract<dict>(this->attr("names"))();
|
||||
names_dict[x.attr("name")] = x;
|
||||
}
|
||||
|
||||
void enum_base::export_values()
|
||||
{
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
list values = d.values();
|
||||
dict d = extract<dict>(this->attr("names"))();
|
||||
list items = d.items();
|
||||
scope current;
|
||||
|
||||
for (unsigned i = 0, max = len(values); i < max; ++i)
|
||||
{
|
||||
api::setattr(current, object(values[i].attr("name")), values[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0, max = len(items); i < max; ++i)
|
||||
api::setattr(current, items[i][0], items[i][1]);
|
||||
}
|
||||
|
||||
PyObject* enum_base::to_python(PyTypeObject* type_, long x)
|
||||
|
||||
@@ -166,7 +166,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
else
|
||||
{
|
||||
// build a new arg tuple, will adjust its size later
|
||||
assert(max_arity <= ssize_t_max);
|
||||
assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
|
||||
inner_args = handle<>(
|
||||
PyTuple_New(static_cast<ssize_t>(max_arity)));
|
||||
|
||||
@@ -297,7 +297,7 @@ object function::signatures(bool show_return_type) const
|
||||
void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
static handle<> exception(
|
||||
PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0));
|
||||
PyErr_NewException(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
|
||||
|
||||
object message = "Python argument types in\n %s.%s("
|
||||
% make_tuple(this->m_namespace, this->m_name);
|
||||
@@ -440,7 +440,7 @@ void function::add_to_namespace(
|
||||
else if (PyType_Check(ns))
|
||||
dict = ((PyTypeObject*)ns)->tp_dict;
|
||||
else
|
||||
dict = PyObject_GetAttrString(ns, "__dict__");
|
||||
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
|
||||
|
||||
if (dict == 0)
|
||||
throw_error_already_set();
|
||||
@@ -487,7 +487,7 @@ void function::add_to_namespace(
|
||||
new_func->m_name = name;
|
||||
|
||||
handle<> name_space_name(
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__")));
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
|
||||
|
||||
if (name_space_name)
|
||||
new_func->m_namespace = object(name_space_name);
|
||||
@@ -656,18 +656,18 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyGetSetDef function_getsetlist[] = {
|
||||
{"__name__", (getter)function_get_name, 0, 0, 0 },
|
||||
{"func_name", (getter)function_get_name, 0, 0, 0 },
|
||||
{"__class__", (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{"__doc__", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{"func_doc", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{NULL, 0, 0, 0, 0} /* Sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject function_type = {
|
||||
PyObject_HEAD_INIT(0)
|
||||
0,
|
||||
"Boost.Python.function",
|
||||
const_cast<char*>("Boost.Python.function"),
|
||||
sizeof(function),
|
||||
0,
|
||||
(destructor)function_dealloc, /* tp_dealloc */
|
||||
@@ -753,7 +753,8 @@ namespace detail
|
||||
}
|
||||
void BOOST_PYTHON_DECL pure_virtual_called()
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called");
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
6
src/object/function_doc_signature.cpp
Executable file → Normal file
6
src/object/function_doc_signature.cpp
Executable file → Normal file
@@ -52,9 +52,9 @@ namespace boost { namespace python { namespace objects {
|
||||
//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()
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#endif
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/reverse_graph.hpp>
|
||||
#include <boost/property_map.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C"
|
||||
PyTypeObject life_support_type = {
|
||||
PyObject_HEAD_INIT(0)//(&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.life_support",
|
||||
const_cast<char*>("Boost.Python.life_support"),
|
||||
sizeof(life_support),
|
||||
0,
|
||||
life_support_dealloc, /* tp_dealloc */
|
||||
|
||||
6
src/object/stl_iterator.cpp
Executable file → Normal file
6
src/object/stl_iterator.cpp
Executable file → Normal file
@@ -2,6 +2,10 @@
|
||||
// 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)
|
||||
//
|
||||
// Credits:
|
||||
// Andreas Kl\:ockner for fixing increment() to handle
|
||||
// error conditions.
|
||||
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
@@ -27,6 +31,8 @@ void stl_input_iterator_impl::increment()
|
||||
{
|
||||
this->ob_ = boost::python::handle<>(
|
||||
boost::python::allow_null(PyIter_Next(this->it_.ptr())));
|
||||
if (PyErr_Occurred())
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
bool stl_input_iterator_impl::equal(stl_input_iterator_impl const &that) const
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace boost { namespace python { namespace detail {
|
||||
detail::new_reference str_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyString_Type, "(O)",
|
||||
(PyObject*)&PyString_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace {
|
||||
|
||||
ssize_t str_size_as_py_ssize_t(std::size_t n)
|
||||
{
|
||||
if (n > ssize_t_max)
|
||||
if (n > static_cast<std::size_t>(ssize_t_max))
|
||||
{
|
||||
throw std::range_error("str size > ssize_t_max");
|
||||
}
|
||||
@@ -68,8 +68,9 @@ str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const
|
||||
return str(new_reference( \
|
||||
expect_non_null( \
|
||||
PyObject_CallMethod( \
|
||||
this->ptr(), #name, \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \
|
||||
this->ptr(), const_cast<char*>( #name ), \
|
||||
const_cast<char*>( \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
|
||||
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace boost { namespace python { namespace detail {
|
||||
detail::new_reference tuple_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyTuple_Type, "(O)",
|
||||
(PyObject*)&PyTuple_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,25 +19,43 @@ macro(bpl_test TESTNAME)
|
||||
cdr(BPL_TEST_DEFAULT_ARGS ${BPL_TEST_DEFAULT_ARGS})
|
||||
|
||||
get_filename_component(BPL_TEST_PYBASE ${BPL_TEST_PYSOURCE} NAME_WE)
|
||||
|
||||
# Process all the .cpp file and extension module names
|
||||
foreach(SRC ${BPL_TEST_DEFAULT_ARGS})
|
||||
get_filename_component(BPL_SRC_EXT ${SRC} EXT)
|
||||
if (BPL_SRC_EXT STREQUAL ".cpp")
|
||||
|
||||
# Build a Python extension module from this source file
|
||||
get_filename_component(BPL_SRC_NAME ${SRC} NAME_WE)
|
||||
|
||||
if(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
|
||||
boost_python_extension(${BPL_SRC_NAME}_ext ${SRC})
|
||||
set(BPL_EXTENSION_MODULE ${BPL_SRC_NAME}_ext)
|
||||
else(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
|
||||
boost_python_extension(${BPL_SRC_NAME} ${SRC})
|
||||
set(BPL_EXTENSION_MODULE ${BPL_SRC_NAME})
|
||||
endif(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
|
||||
|
||||
boost_python_extension(${BPL_EXTENSION_MODULE} ${SRC})
|
||||
|
||||
else (BPL_SRC_EXT STREQUAL ".cpp")
|
||||
set(BPL_EXTENSION_MODULE ${SRC})
|
||||
|
||||
endif (BPL_SRC_EXT STREQUAL ".cpp")
|
||||
|
||||
add_dependencies(${PROJECT_NAME}-test ${BPL_EXTENSION_MODULE})
|
||||
endforeach(SRC ${BPL_TEST_DEFAULT_ARGS})
|
||||
|
||||
else (BPL_TEST_DEFAULT_ARGS)
|
||||
|
||||
set(BPL_TEST_PYSOURCE "${TESTNAME}.py")
|
||||
|
||||
# Build a Python extension module from this source file
|
||||
boost_python_extension(${TESTNAME}_ext "${TESTNAME}.cpp")
|
||||
add_dependencies(${PROJECT_NAME}-test ${TESTNAME}_ext)
|
||||
|
||||
endif(BPL_TEST_DEFAULT_ARGS)
|
||||
|
||||
add_dependencies(${PROJECT_NAME}-test ${BPL_TEST_PYSOURCE})
|
||||
|
||||
# We'll need the full patch to run the Python test
|
||||
set(BPL_TEST_PYSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${BPL_TEST_PYSOURCE})
|
||||
|
||||
@@ -107,6 +125,13 @@ bpl_test(keywords keywords_test.py keywords.cpp)
|
||||
boost_python_extension(builtin_converters_ext test_builtin_converters.cpp)
|
||||
bpl_test(builtin_converters test_builtin_converters.py builtin_converters_ext)
|
||||
|
||||
#
|
||||
# See the contents of this file for more details on an existing
|
||||
# overload resoluton bug.
|
||||
#
|
||||
# boost_python_extension(overload_resolution test_overload_resolution.cpp)
|
||||
#
|
||||
|
||||
bpl_test(test_pointer_adoption)
|
||||
bpl_test(operators)
|
||||
bpl_test(callbacks)
|
||||
|
||||
@@ -42,7 +42,7 @@ test-suite python
|
||||
:
|
||||
|
||||
[
|
||||
run exec.cpp ../build//boost_python/<link>static $(PY)
|
||||
run exec.cpp /boost/python//boost_python/<link>static $(PY)
|
||||
: # program args
|
||||
: exec.py # input files
|
||||
: # requirements
|
||||
@@ -75,6 +75,7 @@ bpl-test crossmod_exception
|
||||
[ bpl-test return_arg ]
|
||||
[ bpl-test staticmethod ]
|
||||
[ bpl-test shared_ptr ]
|
||||
[ bpl-test enable_shared_from_this ]
|
||||
[ bpl-test andreas_beyer ]
|
||||
[ bpl-test polymorphism ]
|
||||
[ bpl-test polymorphism2 ]
|
||||
@@ -171,7 +172,8 @@ bpl-test crossmod_opaque
|
||||
/boost/python//boost_python ]
|
||||
[ bpl-test
|
||||
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
|
||||
[ py-run import_.cpp : import_.py ]
|
||||
|
||||
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
|
||||
|
||||
# if $(TEST_BIENSTMAN_NON_BUGS)
|
||||
# {
|
||||
|
||||
4
test/andreas_beyer.cpp
Executable file → Normal file
4
test/andreas_beyer.cpp
Executable file → Normal file
@@ -25,8 +25,8 @@ class B {
|
||||
B() {
|
||||
a = A::A_ptr(new A());
|
||||
}
|
||||
void set(A::A_ptr a) {
|
||||
this->a = a;
|
||||
void set(A::A_ptr _a) {
|
||||
this->a = _a;
|
||||
}
|
||||
A::A_ptr get() {
|
||||
return a;
|
||||
|
||||
@@ -27,7 +27,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -34,7 +34,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -19,10 +19,10 @@ struct complicated
|
||||
int n;
|
||||
};
|
||||
|
||||
inline complicated::complicated(simple const&s, int n)
|
||||
: s(s.s), n(n)
|
||||
inline complicated::complicated(simple const&s, int _n)
|
||||
: s(s.s), n(_n)
|
||||
{
|
||||
std::cout << "constructing complicated: " << this->s << ", " << n << std::endl;
|
||||
std::cout << "constructing complicated: " << this->s << ", " << _n << std::endl;
|
||||
}
|
||||
|
||||
inline complicated::~complicated()
|
||||
|
||||
48
test/enable_shared_from_this.cpp
Normal file
48
test/enable_shared_from_this.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
|
||||
class Test;
|
||||
typedef shared_ptr<Test> TestPtr;
|
||||
|
||||
class Test : public boost::enable_shared_from_this<Test> {
|
||||
public:
|
||||
static TestPtr construct() {
|
||||
return TestPtr(new Test);
|
||||
}
|
||||
|
||||
void act() {
|
||||
TestPtr kungFuDeathGrip(shared_from_this());
|
||||
}
|
||||
|
||||
void take(TestPtr t) {
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(enable_shared_from_this_ext)
|
||||
{
|
||||
class_<Test, TestPtr, boost::noncopyable>("Test")
|
||||
.def("construct", &Test::construct).staticmethod("construct")
|
||||
.def("act", &Test::act)
|
||||
.def("take", &Test::take)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
|
||||
26
test/enable_shared_from_this.py
Executable file
26
test/enable_shared_from_this.py
Executable file
@@ -0,0 +1,26 @@
|
||||
# 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 enable_shared_from_this_ext import *
|
||||
|
||||
>>> x = Test.construct()
|
||||
>>> x.take(x)
|
||||
>>> x.act()
|
||||
'''
|
||||
|
||||
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)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
using namespace boost::python;
|
||||
|
||||
enum color { red = 1, green = 2, blue = 4 };
|
||||
enum color { red = 1, green = 2, blue = 4, blood = 1 };
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
namespace boost // Pro7 has a hard time detecting enums
|
||||
@@ -34,6 +34,7 @@ BOOST_PYTHON_MODULE(enum_ext)
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.value("blue", blue)
|
||||
.value("blood", blood)
|
||||
.export_values()
|
||||
;
|
||||
|
||||
|
||||
20
test/enum.py
20
test/enum.py
@@ -4,8 +4,8 @@
|
||||
'''
|
||||
>>> from enum_ext import *
|
||||
|
||||
>>> identity(color.red)
|
||||
enum_ext.color.red
|
||||
>>> identity(color.red) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(color.green)
|
||||
enum_ext.color.green
|
||||
@@ -13,8 +13,8 @@ enum_ext.color.green
|
||||
>>> identity(color.blue)
|
||||
enum_ext.color.blue
|
||||
|
||||
>>> identity(color(1))
|
||||
enum_ext.color.red
|
||||
>>> identity(color(1)) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(color(2))
|
||||
enum_ext.color.green
|
||||
@@ -28,7 +28,7 @@ enum_ext.color.blue
|
||||
--- check export to scope ---
|
||||
|
||||
>>> identity(red)
|
||||
enum_ext.color.red
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(green)
|
||||
enum_ext.color.green
|
||||
@@ -42,10 +42,18 @@ enum_ext.color.blue
|
||||
|
||||
>>> c = colorized()
|
||||
>>> c.x
|
||||
enum_ext.color.red
|
||||
enum_ext.color.blood
|
||||
>>> c.x = green
|
||||
>>> c.x
|
||||
enum_ext.color.green
|
||||
>>> red == blood
|
||||
True
|
||||
>>> red == green
|
||||
False
|
||||
>>> hash(red) == hash(blood)
|
||||
True
|
||||
>>> hash(red) == hash(green)
|
||||
False
|
||||
'''
|
||||
|
||||
# pickling of enums only works with Python 2.3 or higher
|
||||
|
||||
@@ -59,7 +59,7 @@ void eval_test()
|
||||
void exec_test()
|
||||
{
|
||||
// Register the module with the interpreter
|
||||
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
|
||||
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"), initembedded_hello) == -1)
|
||||
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
|
||||
"builtin modules");
|
||||
// Retrieve the main module
|
||||
|
||||
@@ -34,7 +34,7 @@ struct NoddyObject : PyObject
|
||||
PyTypeObject NoddyType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Noddy",
|
||||
const_cast<char*>("Noddy"),
|
||||
sizeof(NoddyObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -106,7 +106,7 @@ struct extract_simple_object
|
||||
PyTypeObject SimpleType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Simple",
|
||||
const_cast<char*>("Simple"),
|
||||
sizeof(SimpleObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -159,7 +159,7 @@ PyTypeObject SimpleType = {
|
||||
PyObject* new_simple()
|
||||
{
|
||||
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
simple->x.s = "hello, world";
|
||||
simple->x.s = const_cast<char*>("hello, world");
|
||||
return (PyObject*)simple;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,11 @@ bool check_string_slice()
|
||||
return s.slice(2,-1).slice(1,-1) == "lo, wor";
|
||||
}
|
||||
|
||||
object test_call(object c, object args, object kwds)
|
||||
{
|
||||
return c(*args, **kwds);
|
||||
}
|
||||
|
||||
bool check_binary_operators()
|
||||
{
|
||||
int y;
|
||||
@@ -377,6 +382,7 @@ BOOST_PYTHON_MODULE(object_ext)
|
||||
def("test_item", test_item);
|
||||
def("test_not_item", test_not_item);
|
||||
|
||||
def("test_call", test_call);
|
||||
def("check_binary_operators", check_binary_operators);
|
||||
def("check_inplace", check_inplace);
|
||||
def("check_string_slice", check_string_slice);
|
||||
|
||||
@@ -134,7 +134,12 @@
|
||||
|
||||
Operators
|
||||
|
||||
|
||||
>>> def print_args(*args, **kwds):
|
||||
... print args, kwds
|
||||
>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
|
||||
(0, 1, 2, 3) {'a': 'A'}
|
||||
|
||||
|
||||
>>> assert check_binary_operators()
|
||||
|
||||
>>> class X: pass
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace boost_python_test {
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& country) {
|
||||
this->country = country;
|
||||
world(const std::string& _country) {
|
||||
this->country = _country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace boost_python_test {
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
world(const std::string& _country) : secret_number(0) {
|
||||
this->country = _country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace boost_python_test {
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
world(const std::string& _country) : secret_number(0) {
|
||||
this->country = _country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace boost_python_test {
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& country) {
|
||||
this->country = country;
|
||||
world(const std::string& _country) {
|
||||
this->country = _country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -100,7 +100,11 @@ bool accept_slice( slice) { return true; }
|
||||
|| BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
|
||||
int check_slice_get_indicies(slice index);
|
||||
#endif
|
||||
int check_slice_get_indicies(const slice index)
|
||||
int check_slice_get_indicies(
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
const
|
||||
#endif
|
||||
slice index)
|
||||
{
|
||||
// A vector of integers from [-5, 5].
|
||||
std::vector<int> coll(11);
|
||||
|
||||
@@ -20,7 +20,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
3
|
||||
4
|
||||
5
|
||||
>>> def generator():
|
||||
... yield 1
|
||||
... yield 2
|
||||
... raise RuntimeError, "oops"
|
||||
>>> try:
|
||||
... x.assign(iter(generator()))
|
||||
... print "NOT OK"
|
||||
... except RuntimeError:
|
||||
... print "OK"
|
||||
OK
|
||||
'''
|
||||
def run(args = None):
|
||||
import sys
|
||||
|
||||
@@ -17,6 +17,10 @@ struct by_value
|
||||
{
|
||||
return x;
|
||||
}
|
||||
static int size(void)
|
||||
{
|
||||
return sizeof(T);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -61,7 +65,17 @@ BOOST_PYTHON_MODULE(builtin_converters_ext)
|
||||
{
|
||||
def("get_type", get_type);
|
||||
def("return_null_handle", return_null_handle);
|
||||
|
||||
|
||||
// These methods are used solely for getting some C++ type sizes
|
||||
def("bool_size", by_value<bool>::size);
|
||||
def("char_size", by_value<char>::size);
|
||||
def("int_size", by_value<int>::size);
|
||||
def("short_size", by_value<short>::size);
|
||||
def("long_size", by_value<long>::size);
|
||||
#ifdef HAVE_LONG_LONG
|
||||
def("long_long_size", by_value<BOOST_PYTHON_LONG_LONG>::size);
|
||||
#endif
|
||||
|
||||
def("rewrap_value_bool", by_value<bool>::rewrap);
|
||||
def("rewrap_value_char", by_value<char>::rewrap);
|
||||
def("rewrap_value_signed_char", by_value<signed char>::rewrap);
|
||||
|
||||
@@ -4,12 +4,33 @@
|
||||
r"""
|
||||
>>> from builtin_converters_ext import *
|
||||
|
||||
# Provide values for integer converter tests
|
||||
>>> def _signed_values(s):
|
||||
... base = 2 ** (8 * s - 1)
|
||||
... return [[-base, -1, 1, base - 1], [-base - 1, base]]
|
||||
>>> def _unsigned_values(s):
|
||||
... base = 2 ** (8 * s)
|
||||
... return [[1, base - 1], [-1L, -1, base]]
|
||||
|
||||
# Wrappers to simplify tests
|
||||
>>> def should_pass(method, values):
|
||||
... result = map(method, values[0])
|
||||
... if result != values[0]:
|
||||
... print "Got %s but expected %s" % (result, values[0])
|
||||
>>> def test_overflow(method, values):
|
||||
... for v in values[1]:
|
||||
... try: method(v)
|
||||
... except OverflowError: pass
|
||||
... else: print "OverflowError expected"
|
||||
|
||||
# Synthesize idendity functions in case long long not supported
|
||||
>>> if not 'rewrap_value_long_long' in dir():
|
||||
... def rewrap_value_long_long(x): return long(x)
|
||||
... def rewrap_value_unsigned_long_long(x): return long(x)
|
||||
... def rewrap_const_reference_long_long(x): return long(x)
|
||||
... def rewrap_const_reference_unsigned_long_long(x): return long(x)
|
||||
>>> if not 'long_long_size' in dir():
|
||||
... def long_long_size(): return long_size()
|
||||
|
||||
>>> try: bool_exists = bool
|
||||
... except: pass
|
||||
@@ -62,15 +83,37 @@ False
|
||||
42L
|
||||
|
||||
show that we have range checking.
|
||||
|
||||
>>> try: rewrap_value_unsigned_short(-42)
|
||||
... except OverflowError: pass
|
||||
... else: print 'expected an OverflowError!'
|
||||
|
||||
>>> try: rewrap_value_int(sys.maxint * 2)
|
||||
... except OverflowError: pass
|
||||
... else: print 'expected an OverflowError!'
|
||||
>>> should_pass(rewrap_value_signed_char, _signed_values(char_size()))
|
||||
>>> should_pass(rewrap_value_short, _signed_values(short_size()))
|
||||
>>> should_pass(rewrap_value_int, _signed_values(int_size()))
|
||||
>>> should_pass(rewrap_value_long, _signed_values(long_size()))
|
||||
>>> should_pass(rewrap_value_long_long, _signed_values(long_long_size()))
|
||||
|
||||
>>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size()))
|
||||
>>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size()))
|
||||
>>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size()))
|
||||
>>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size()))
|
||||
>>> should_pass(rewrap_value_unsigned_long_long,
|
||||
... _unsigned_values(long_long_size()))
|
||||
|
||||
>>> test_overflow(rewrap_value_signed_char, _signed_values(char_size()))
|
||||
>>> test_overflow(rewrap_value_short, _signed_values(short_size()))
|
||||
>>> test_overflow(rewrap_value_int, _signed_values(int_size()))
|
||||
>>> test_overflow(rewrap_value_long, _signed_values(long_size()))
|
||||
>>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size()))
|
||||
|
||||
>>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size()))
|
||||
>>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size()))
|
||||
>>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size()))
|
||||
>>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size()))
|
||||
|
||||
# Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises
|
||||
# TypeError on Python versions prior to 2.7
|
||||
>>> for v in _unsigned_values(long_long_size())[1]:
|
||||
... try: rewrap_value_unsigned_long_long(v)
|
||||
... except (OverflowError, TypeError): pass
|
||||
... else: print "OverflowError or TypeError expected"
|
||||
|
||||
>>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001
|
||||
>>> rewrap_value_double(4.2) - 4.2
|
||||
|
||||
@@ -13,7 +13,7 @@ struct test_class
|
||||
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
|
||||
virtual ~test_class() { BOOST_TEST(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { BOOST_TEST(magic == 7654321 + n); this->x = x; }
|
||||
void set(int _x) { BOOST_TEST(magic == 7654321 + n); this->x = _x; }
|
||||
int value() const { BOOST_TEST(magic == 7654321 + n); return x; }
|
||||
operator int() const { return x; }
|
||||
static int count() { return counter; }
|
||||
|
||||
53
test/test_overload_resolution.cpp
Normal file
53
test/test_overload_resolution.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright Troy D. Straszheim 2009
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// example that shows problems with overloading and automatic conversion.
|
||||
// if you call one of the below functions from python with bool/int/double,
|
||||
// you'll see that the overload called is first match, not best match.
|
||||
// See overload matching in luabind for an example of how to do this better.
|
||||
//
|
||||
// see this mail:
|
||||
// http://mail.python.org/pipermail/cplusplus-sig/2009-March/014362.html
|
||||
//
|
||||
// This test isn't called by the cmake/jamfiles. For future use.
|
||||
//
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <complex>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/cast.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
using boost::python::def;
|
||||
using boost::python::handle;
|
||||
using boost::python::object;
|
||||
using boost::python::borrowed;
|
||||
|
||||
std::string takes_bool(bool b) { return "bool"; }
|
||||
std::string takes_int(int b) { return "int"; }
|
||||
std::string takes_double(double b) { return "double"; }
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(overload_resolution)
|
||||
{
|
||||
def("bid", takes_bool);
|
||||
def("bid", takes_int);
|
||||
def("bid", takes_double);
|
||||
|
||||
def("dib", takes_double);
|
||||
def("dib", takes_int);
|
||||
def("dib", takes_bool);
|
||||
|
||||
def("idb", takes_int);
|
||||
def("idb", takes_double);
|
||||
def("idb", takes_bool);
|
||||
|
||||
def("bdi", takes_bool);
|
||||
def("bdi", takes_double);
|
||||
def("bdi", takes_int);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ struct B
|
||||
B() : x(0) {}
|
||||
B(A* x_) : x(x_) {}
|
||||
|
||||
inner const* adopt(A* x) { this->x = x; return &x->get_inner(); }
|
||||
inner const* adopt(A* _x) { this->x = _x; return &_x->get_inner(); }
|
||||
|
||||
std::string a_content()
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user