2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 16:32:16 +00:00

Compare commits

...

25 Commits

Author SHA1 Message Date
Stefan Seefeld
e1e9eb303a Merge pull request #13 from ax3l/fix-missingPlaceholderInclude
Fix Trac #10932 Missing Include: Bind Placeholders
2015-03-26 09:16:15 -04:00
Stefan Seefeld
9eee9ef461 Merge pull request #15 from mmatrosov/master
Fix #11100 and #8058: binary compatibility and leaked file handle in exec_file()
2015-03-26 08:23:15 -04:00
Mikhail Matrosov
fe24ab9dd5 [#8058] Close file handle before exec_file() routine returns. 2015-03-11 01:11:54 +03:00
Mikhail Matrosov
a911c17fd6 [#11100] Fix binary incompatibilities with fopen() in exec_file() routine. 2015-03-11 01:11:54 +03:00
Daniel James
8d5d777ebb Add metadata file. 2015-01-25 21:25:23 +02:00
Axel Huebl
17a7655c74 Fix Missing Include: Bind Placeholders
boost/python/exception_translator.hpp(22): error: identifier "_1" is undefined
boost/python/exception_translator.hpp(22): error: identifier "_2" is undefined
2015-01-14 16:02:23 +01:00
Beman Dawes
832a1edd79 Merge 86392 from trunk. The spirit change was not applied because the file is not present in branches/release.
[SVN r86489]
2013-10-27 21:10:04 +00:00
Ralf W. Grosse-Kunstleve
ca18dc9daa merging current boost/python and libs/python from trunk into release branch
[SVN r82295]
2012-12-31 04:14:35 +00:00
Ralf W. Grosse-Kunstleve
8cc149f4f4 merging current boost/python and libs/python from trunk into release branch
[SVN r81965]
2012-12-15 01:25:41 +00:00
Ralf W. Grosse-Kunstleve
a3f478e9af boost.python: merging trunk to release
[SVN r81773]
2012-12-07 19:51:06 +00:00
Ralf W. Grosse-Kunstleve
46796f3413 merging current boost/python and libs/python from trunk into release branch
[SVN r79096]
2012-06-25 22:09:52 +00:00
Ralf W. Grosse-Kunstleve
0b8b88abc7 merging current boost/python and libs/python from trunk into release branch
[SVN r79011]
2012-06-19 20:01:25 +00:00
Ralf W. Grosse-Kunstleve
76db3311ed merging current boost/python and libs/python from trunk into release branch
[SVN r77125]
2012-02-27 02:49:42 +00:00
Ralf W. Grosse-Kunstleve
7acb544b47 merging current boost/python and libs/python from trunk into release branch
[SVN r76422]
2012-01-11 23:48:18 +00:00
Daniel James
f054b64315 Merge python doc rebuild to release.
[SVN r76359]
2012-01-08 10:07:09 +00:00
Ralf W. Grosse-Kunstleve
9064a063b2 merging current boost/python and libs/python from trunk into release branch
[SVN r75919]
2011-12-12 17:46:33 +00:00
Ralf W. Grosse-Kunstleve
fa24dbb88f merging current boost/python and libs/python from trunk into release branch
[SVN r75414]
2011-11-08 21:27:05 +00:00
Ralf W. Grosse-Kunstleve
49e8699b9f merging current boost/python and libs/python from trunk into release branch
[SVN r74931]
2011-10-12 21:38:53 +00:00
Ralf W. Grosse-Kunstleve
cfa2baf8c9 merging current boost/python and libs/python from trunk into release branch
[SVN r72464]
2011-06-07 04:15:33 +00:00
Ralf W. Grosse-Kunstleve
faf3cd0b78 merging current boost/python and libs/python from trunk into release branch
[SVN r72277]
2011-05-30 05:51:49 +00:00
Ralf W. Grosse-Kunstleve
a5e564be83 merging current boost/python and libs/python from trunk into release branch
[SVN r71226]
2011-04-13 17:34:35 +00:00
Dave Abrahams
dcc3590907 verifying commit privs
[SVN r71150]
2011-04-09 16:55:43 +00:00
Ralf W. Grosse-Kunstleve
74daea3d88 boost/libs/python/doc/PyConDC_2003: removing $Date$ and $Revision$ so they do not create noise on each merge to the release branch
[SVN r71004]
2011-04-05 16:49:31 +00:00
Ralf W. Grosse-Kunstleve
e28f0509d8 merging current boost/python and libs/python from trunk into release branch
[SVN r71002]
2011-04-05 16:31:51 +00:00
Ralf W. Grosse-Kunstleve
0a211a746d merging current boost/python and libs/python from trunk into release branch
[SVN r70448]
2011-03-23 00:14:55 +00:00
47 changed files with 478 additions and 348 deletions

28
class.cpp Normal file
View File

@@ -0,0 +1,28 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct X
{
int x;
X(int n) : x(n) { }
};
int x_function(X& x)
{ return x.x;
}
BOOST_PYTHON_MODULE(class_ext)
{
class_<X>("X", init<int>());
def("x_function", x_function);
}
#include "module_tail.cpp"

View File

@@ -27,7 +27,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Somerville, MA 02143
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:status: This is a "work in progress"
:version: 1
:copyright: Copyright David Abrahams 2002. All rights reserved

View File

@@ -1,8 +1,6 @@
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
boostinspect:nolicense

View File

@@ -396,27 +396,33 @@
</blockquote>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
<dt><b><a href="http://pyrap.googlecode.com/">Pyrap</a></b></dt>
<dd>
<p><a href="diepen@astron.nl"
>Ger van Diepen</a> writes:</p>
<blockquote>
<p>Pyrap is the python interface to the Radio-Astronomical Package
casacore (<a href="http://casacore.googlecode.com/"
>casacore.googlecode.com</a>). Astronomers love pyrap because
it makes it easily possible to get their data (observed with
radio-astronomical telescopes like LOFAR, ASKAP, and eVLA) in numpy
arrays and do basic data inspection and manipulation using the many
python packages that are available.</p>
<p>Boost.Python made it quite easily possible to create converters for
the various data types, also for numpy arrays and individual elements
of a numpy array. It's nice they work fully recursively. Mapping C++
functions to Python was straightforward.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.rdkit.org/"
>RDKit: Cheminformatics and Machine Learning Software</a></b></dt>
<dd>
Rational Discovery provides computational modeling, combinatorial
library design and custom software development services to the
pharmaceutical, biotech and chemical industries. We do a substantial
amount of internal research to develop new approaches for applying
machine-learning techniques to solve chemical problems. Because we're a
small organization and chemistry is a large and complex field, it is
essential that we be able to quickly and easily prototype and test new
algorithms.
<p>For our internal software, we implement core data structures in C
and expose them to Python using Boost.Python. Algorithm development is
done in Python and then translated to C if required (often it's not).
This hybrid development approach not only greatly increases our
productivity, but it also allows "non-developers" (people without C
experience) to take part in method development. Learning C is a
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel for
the quote.)</p>
A collection of cheminformatics and machine-learning software
written in C++ and Python.
</dd>
</dl>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Chapter&#160;1.&#160;python 2.0</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="next" href="python/hello.html" title="Building Hello World">
</head>
@@ -31,7 +31,7 @@
<div><p class="copyright">Copyright &#169; 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id759709"></a><p>
<a name="python.legal"></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>)
@@ -42,8 +42,8 @@
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="index.html#python.quickstart">QuickStart</a></span></dt>
<dt><span class="section"><a href="python/hello.html"> Building Hello World</a></span></dt>
<dt><span class="section"><a href="python/exposing.html"> Exposing Classes</a></span></dt>
<dt><span class="section"><a href="python/hello.html">Building Hello World</a></span></dt>
<dt><span class="section"><a href="python/exposing.html">Exposing Classes</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="python/exposing.html#python.constructors">Constructors</a></span></dt>
<dt><span class="section"><a href="python/exposing.html#python.class_data_members">Class Data Members</a></span></dt>
@@ -60,18 +60,19 @@
<dt><span class="section"><a href="python/functions.html#python.default_arguments">Default Arguments</a></span></dt>
<dt><span class="section"><a href="python/functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="python/object.html"> Object Interface</a></span></dt>
<dt><span class="section"><a href="python/object.html">Object Interface</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="python/object.html#python.basic_interface">Basic Interface</a></span></dt>
<dt><span class="section"><a href="python/object.html#python.derived_object_types">Derived Object types</a></span></dt>
<dt><span class="section"><a href="python/object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
<dt><span class="section"><a href="python/object.html#python.enums">Enums</a></span></dt>
<dt><span class="section"><a href="python/object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
</dl></dd>
<dt><span class="section"><a href="python/embedding.html">Embedding</a></span></dt>
<dd><dl><dt><span class="section"><a href="python/embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></dd>
<dt><span class="section"><a href="python/iterators.html">Iterators</a></span></dt>
<dt><span class="section"><a href="python/exception.html"> Exception Translation</a></span></dt>
<dt><span class="section"><a href="python/techniques.html"> General Techniques</a></span></dt>
<dt><span class="section"><a href="python/exception.html">Exception Translation</a></span></dt>
<dt><span class="section"><a href="python/techniques.html">General Techniques</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="python/techniques.html#python.creating_packages">Creating Packages</a></span></dt>
<dt><span class="section"><a href="python/techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
@@ -93,8 +94,8 @@
code takes on the look of a kind of declarative interface definition language
(IDL).
</p>
<a name="quickstart.hello_world"></a><h3>
<a name="id759740"></a>
<h3>
<a name="quickstart.hello_world"></a>
Hello World
</h3>
<p>
@@ -121,14 +122,10 @@
That's it. We're done. We can now build this as a shared library. The resulting
DLL is now visible to Python. Here's a sample Python session:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<span class="special">&gt;&gt;&gt;</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="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">hello_ext</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>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World module
from start to finish...</strong></span></em></span>
@@ -136,7 +133,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: July 01, 2010 at 21:56:58 GMT</small></p></td>
<td align="left"><p><small>Last revised: December 26, 2011 at 21:58:39 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Embedding</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="object.html" title="Object Interface">
@@ -39,8 +39,8 @@
a lot easier and, in a future version, it may become unnecessary to touch the
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><h3>
<a name="id773307"></a>
<h3>
<a name="embedding.building_embedded_programs"></a>
Building embedded programs
</h3>
<p>
@@ -81,8 +81,8 @@ exe embedded_program # name of the executable
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
<a name="embedding.getting_started"></a><h3>
<a name="id773391"></a>
<h3>
<a name="embedding.getting_started"></a>
Getting started
</h3>
<p>
@@ -95,8 +95,7 @@ exe embedded_program # name of the executable
</li>
<li class="listitem">
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
to start the interpreter and create the <code class="literal"><span class="underline">_main</span>_</code>
module.
to start the interpreter and create the <code class="literal">__main__</code> module.
</li>
<li class="listitem">
Call other Python C API routines to use the interpreter.
@@ -132,8 +131,8 @@ exe embedded_program # name of the executable
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><h3>
<a name="id773549"></a>
<h3>
<a name="using_the_interpreter.running_python_code"></a>
Running Python code
</h3>
<p>
@@ -152,8 +151,7 @@ exe embedded_program # name of the executable
The <code class="literal">globals</code> and <code class="literal">locals</code> parameters are
Python dictionaries containing the globals and locals of the context in which
to run the code. For most intents and purposes you can use the namespace
dictionary of the <code class="literal"><span class="underline">_main</span>_</code>
module for both parameters.
dictionary of the <code class="literal">__main__</code> module for both parameters.
</p>
<p>
Boost.python provides a function to import a module:
@@ -165,8 +163,8 @@ exe embedded_program # name of the executable
first), and returns it.
</p>
<p>
Let's import the <code class="literal"><span class="underline">_main</span>_</code>
module and run some Python code in its namespace:
Let's import the <code class="literal">__main__</code> 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>
<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>
@@ -180,8 +178,8 @@ exe embedded_program # name of the executable
This should create a file called 'hello.txt' in the current directory containing
a phrase that is well-known in programming circles.
</p>
<a name="using_the_interpreter.manipulating_python_objects"></a><h3>
<a name="id774064"></a>
<h3>
<a name="using_the_interpreter.manipulating_python_objects"></a>
Manipulating Python objects
</h3>
<p>
@@ -197,16 +195,16 @@ exe embedded_program # name of the executable
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
</pre>
<p>
Here we create a dictionary object for the <code class="literal"><span class="underline">_main</span>_</code>
module's namespace. Then we assign 5 squared to the result variable and read
this variable from the dictionary. Another way to achieve the same result
is to use eval instead, which returns the result directly:
Here we create a dictionary object for the <code class="literal">__main__</code> module's
namespace. Then we assign 5 squared to the result variable and read 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>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
</pre>
<a name="using_the_interpreter.exception_handling"></a><h3>
<a name="id774390"></a>
<h3>
<a name="using_the_interpreter.exception_handling"></a>
Exception handling
</h3>
<p>
@@ -216,13 +214,13 @@ exe embedded_program # name of the executable
<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:
</span> <span class="keyword">int</span> <span class="identifier">five_divided_by_zero</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
<span class="comment">// execution will never get here:</span>
<span class="keyword">int</span> <span class="identifier">five_divided_by_zero</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
<span class="special">{</span>
<span class="comment">// handle the exception in some way
</span><span class="special">}</span>
<span class="comment">// handle the exception in some way</span>
<span class="special">}</span>
</pre>
<p>
The <code class="literal">error_already_set</code> exception class doesn't carry any
@@ -238,12 +236,12 @@ exe embedded_program # name of the executable
<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>
<span class="comment">// handle ZeroDivisionError specially
</span> <span class="special">}</span>
<span class="comment">// handle ZeroDivisionError specially</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="comment">// print all other errors to stderr
</span> <span class="identifier">PyErr_Print</span><span class="special">();</span>
<span class="comment">// print all other errors to stderr</span>
<span class="identifier">PyErr_Print</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Exception Translation</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="iterators.html" title="Iterators">
@@ -24,7 +24,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.exception"></a> Exception Translation</h2></div></div></div>
<a name="python.exception"></a>Exception Translation</h2></div></div></div>
<p>
All C++ exceptions must be caught at the boundary with Python code. This boundary
is the point where C++ meets Python. Boost.Python provides a default exception

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Exposing Classes</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="hello.html" title="Building Hello World">
@@ -24,7 +24,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.exposing"></a> Exposing Classes</h2></div></div></div>
<a name="python.exposing"></a>Exposing Classes</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="exposing.html#python.constructors">Constructors</a></span></dt>
<dt><span class="section"><a href="exposing.html#python.class_data_members">Class Data Members</a></span></dt>
@@ -67,8 +67,6 @@
we may use our class <code class="literal">World</code> in Python. Here's a sample Python
session:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello</span>
<span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
@@ -90,12 +88,10 @@
We may wish to wrap a class with a non-default constructor. Let us build
on our previous example:
</p>
<p>
</p>
<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">-&gt;</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">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">-&gt;</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>
<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>
@@ -120,7 +116,7 @@
<p>
<code class="literal">init&lt;std::string&gt;()</code> exposes the constructor taking
in a <code class="literal">std::string</code> (in Python, constructors are spelled
"<code class="literal">"<span class="underline">_init</span>_"</code>").
"<code class="literal">"__init__"</code>").
</p>
<p>
We can expose additional constructors by passing more <code class="literal">init&lt;...&gt;</code>s
@@ -140,8 +136,8 @@
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Abstract</span><span class="special">&gt;(</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 <code class="literal"><span class="underline">_init</span>_</code>
method which always raises a Python RuntimeError exception.
This actually adds an <code class="literal">__init__</code> method which always raises
a Python RuntimeError exception.
</p>
</div>
<div class="section">
@@ -172,8 +168,6 @@
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
@@ -183,8 +177,8 @@
Note that <code class="literal">name</code> is exposed as <span class="bold"><strong>read-only</strong></span>
while <code class="literal">value</code> is exposed as <span class="bold"><strong>read-write</strong></span>.
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">"&lt;stdin&gt;"</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="error">?</span>
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span><span class="error">'</span><span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
</pre>
@@ -198,8 +192,6 @@
The only way to access the class' data is through access (getter/setter)
functions. Access functions expose class properties. Here's an example:
</p>
<p>
</p>
<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>
@@ -221,21 +213,17 @@
<p>
And at last, in Python:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!
</span></pre>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!</span>
</pre>
<p>
Take note that the class property <code class="literal">rovalue</code> is exposed as
<span class="bold"><strong>read-only</strong></span> since the <code class="literal">rovalue</code>
setter member function is not passed in:
</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">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
</pre>
</div>
@@ -310,8 +298,8 @@
is destroyed. We will see more of Boost.Python <a class="link" 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
</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 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">&lt;</span><span class="identifier">manage_new_object</span><span class="special">&gt;());</span>
</pre>
</div>
@@ -356,7 +344,7 @@
the job of wrapping classes that are meant to overridden in Python, easier.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="titlepage"></div>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
</p>
@@ -436,8 +424,8 @@
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">override</span> <span class="identifier">f</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">))</span>
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*
</span> <span class="keyword">return</span> <span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span>
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*</span>
<span class="keyword">return</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="keyword">int</span> <span class="identifier">default_f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span> <span class="special">}</span>
@@ -449,7 +437,7 @@
If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="titlepage"></div>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
</p>
@@ -477,8 +465,6 @@
<p>
In Python, the results would be as expected:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</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>
@@ -502,8 +488,8 @@
<div class="section">
<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><h3>
<a name="id764956"></a>
<h3>
<a name="class_operators_special_functions.python_operators"></a>
Python Operators
</h3>
<p>
@@ -515,8 +501,6 @@
Consider a file position class <code class="literal">FilePos</code> and a set of operators
that take on FilePos instances:
</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>
<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>
@@ -532,14 +516,14 @@
and intuitively:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">FilePos</span><span class="special">&gt;(</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__
</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">// __sub__
</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">// __iadd__
</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">other</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">&lt;</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__
</span></pre>
<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__</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">// __sub__</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">// __iadd__</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">other</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">&lt;</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__</span>
</pre>
<p>
The code snippet above is very clear and needs almost no explanation at all.
It is virtually the same as the operators' signatures. Just take note that
@@ -549,8 +533,8 @@
in place of an actual <code class="literal">T</code> instance when writing "self
expressions".
</p>
<a name="class_operators_special_functions.special_methods"></a><h3>
<a name="id765570"></a>
<h3>
<a name="class_operators_special_functions.special_methods"></a>
Special Methods
</h3>
<p>
@@ -568,11 +552,11 @@
<span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">ostream</span><span class="special">&amp;,</span><span class="identifier">Rational</span><span class="special">);</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;(</span><span class="string">"Rational"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;))</span> <span class="comment">// __pow__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __str__
</span> <span class="special">;</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;))</span> <span class="comment">// __pow__</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __str__</span>
<span class="special">;</span>
</pre>
<p>
Need we say more?

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Functions</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="exposing.html" title="Exposing Classes">
@@ -136,11 +136,9 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
We could copy result into a new object:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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 class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
<p>
This is not really our intent of our C++ interface. We've broken our promise
@@ -150,8 +148,6 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
Our problems do not end there. Suppose Y is implemented as follows:
</p>
<p>
</p>
<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>
@@ -203,8 +199,8 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="bold"><strong>BOOM!</strong></span>
</li>
</ol></div>
<a name="call_policies.call_policies"></a><h3>
<a name="id767074"></a>
<h3>
<a name="call_policies.call_policies"></a>
Call Policies
</h3>
<p>
@@ -284,7 +280,7 @@ Namespaces are one honking great idea -- let's do more of those!
</li>
</ul></div>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="titlepage"></div>
<p>
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span>
</p>
@@ -362,30 +358,30 @@ Namespaces are one honking great idea -- let's do more of those!
But the type of a pointer to the function <code class="literal">f</code> 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!
</span></pre>
<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 <code class="literal">def</code> 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!
</span></pre>
<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 class="link" href="functions.html#python.overloading" title="Overloading">previous section</a>,
or writing thin wrappers:
</p>
<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>
<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="keyword">return</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="keyword">return</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>
<span class="comment">/*...*/</span>
<span class="comment">// in module init
</span> <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">// all arguments
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument
</span></pre>
<span class="comment">// in module init</span>
<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">// all arguments</span>
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments</span>
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument</span>
</pre>
<p>
When you want to wrap functions (or member functions) that either:
</p>
@@ -397,8 +393,8 @@ Namespaces are one honking great idea -- let's do more of those!
are overloaded with a common sequence of initial arguments
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h3>
<a name="id769042"></a>
<h3>
<a name="default_arguments.boost_python_function_overloads"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h3>
<p>
@@ -424,8 +420,8 @@ Namespaces are one honking great idea -- let's do more of those!
</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>
<a name="default_arguments.boost_python_member_function_overloads"></a><h3>
<a name="id769301"></a>
<h3>
<a name="default_arguments.boost_python_member_function_overloads"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h3>
<p>
@@ -467,8 +463,8 @@ Namespaces are one honking great idea -- let's do more of those!
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><h3>
<a name="id769596"></a>
<h3>
<a name="default_arguments.init_and_optional"></a>
init and optional
</h3>
<p>
@@ -536,8 +532,8 @@ Namespaces are one honking great idea -- let's do more of those!
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><h3>
<a name="id770226"></a>
<h3>
<a name="auto_overloading.manual_wrapping"></a>
Manual Wrapping
</h3>
<p>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Building Hello World</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
@@ -24,9 +24,9 @@
</div>
<div class="section">
<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><h3>
<a name="id760024"></a>
<a name="python.hello"></a>Building Hello World</h2></div></div></div>
<h3>
<a name="hello.from_start_to_finish"></a>
From Start To Finish
</h3>
<p>
@@ -91,8 +91,8 @@
in the command line. Pre-built Boost.Jam executables are available for most
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><h3>
<a name="id760177"></a>
<h3>
<a name="hello.let_s_jam_"></a>
Let's Jam!
</h3>
<p>
@@ -107,8 +107,8 @@
The comments contained in the Jamrules file above should be sufficient to get
you going.
</p>
<a name="hello.running_bjam"></a><h3>
<a name="id760225"></a>
<h3>
<a name="hello.running_bjam"></a>
Running bjam
</h3>
<p>
@@ -133,12 +133,12 @@
using msvc : 8.0 ;
# Python configuration
using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
using python : 2.4 : C:<span class="emphasis"><em>dev/tools/Python</em></span> ;
</pre>
<p>
The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools.
The second rule provides information on Python, its version and where it is
located. The above assumes that the Python installation is in <code class="literal">C:/dev/tools/Python/</code>.
located. The above assumes that the Python installation is in <code class="literal">C:<span class="emphasis"><em>dev/tools\/Python</em></span></code>.
If you have one fairly "standard" python installation for your platform,
you might not need to do this.
</p>
@@ -165,7 +165,7 @@ bjam
And so on... Finally:
</p>
<pre class="programlisting">Creating library <span class="emphasis"><em>path-to-boost_python.dll</em></span>
Creating library <span class="emphasis"><em>path-to-'''hello_ext'''.exp</em></span>
Creating library /path-to-hello_ext.exp/
**passed** ... hello.test
...updated 35 targets...
</pre>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Iterators</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="embedding.html" title="Embedding">
@@ -62,22 +62,18 @@
The typical Python iteration protocol: <code class="literal"><span class="bold"><strong>for y
in x...</strong></span></code> is as follows:
</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
</span><span class="keyword">try</span><span class="special">:</span>
<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
</span> <span class="special">...</span> <span class="comment"># process y
</span><span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted
</span></pre>
<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</span>
<span class="special">...</span> <span class="comment"># process y</span>
<span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted</span>
</pre>
<p>
Boost.Python provides some mechanisms to make C++ iterators play along nicely
as Python iterators. What we need to do is to produce appropriate <code class="computeroutput"><span class="identifier">__iter__</span></code> function from C++ iterators that
is compatible with the Python iteration protocol. For example:
</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">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;();</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>
@@ -129,8 +125,6 @@
Let's put this into action... Here's an example from some hypothetical bogon
Particle accelerator code:
</p>
<p>
</p>
<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>
@@ -140,8 +134,6 @@
<p>
Now, our C++ Wrapper:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</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">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&amp;</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">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
@@ -156,27 +148,23 @@
a Python iterator look like an STL iterator. For that, we use <code class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special">&lt;&gt;</span></code>.
Consider how we might implement a function that exposes <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></code> to Python:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>
<span class="comment">// Turn a Python sequence into an STL input range</span>
<span class="identifier">stl_input_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>
<span class="identifier">l</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
<span class="special">}</span>
<span class="comment">// Part of the wrapper for list&lt;int&gt;
</span><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"list_int"</span><span class="special">)</span>
<span class="comment">// Part of the wrapper for list&lt;int&gt;</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"list_int"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"assign"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">list_assign</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span>
<span class="comment">// ...
</span> <span class="special">;</span>
<span class="comment">// ...</span>
<span class="special">;</span>
</pre>
<p>
Now in Python, we can assign any integer sequence to <code class="computeroutput"><span class="identifier">list_int</span></code>
objects:
</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>
<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>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Object Interface</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="functions.html" title="Functions">
@@ -24,12 +24,13 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.object"></a> Object Interface</h2></div></div></div>
<a name="python.object"></a>Object Interface</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="object.html#python.basic_interface">Basic Interface</a></span></dt>
<dt><span class="section"><a href="object.html#python.derived_object_types">Derived Object types</a></span></dt>
<dt><span class="section"><a href="object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
<dt><span class="section"><a href="object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
</dl></div>
<p>
Python is dynamically typed, unlike C++ which is statically typed. Python variables
@@ -60,8 +61,6 @@
<p>
To illustrate, this Python code snippet:
</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>
<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>
@@ -75,8 +74,6 @@
<p>
Can be rewritten in C++ using Boost.Python facilities this way:
</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>
<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>
@@ -147,9 +144,9 @@
</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>
<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
</span> <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>
<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</span>
<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>
<span class="special">}</span>
</pre>
<p>
@@ -169,7 +166,7 @@
do that in std C++.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="titlepage"></div>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
of forgetting that the constructors of most of Python's mutable types make
@@ -179,17 +176,17 @@
<p>
Python:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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__
</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><h3>
<a name="id771905"></a>
<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>
<h3>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a>
class_&lt;T&gt; as objects
</h3>
<p>
@@ -217,8 +214,8 @@
can be achieved with the <code class="literal">extract&lt;T&gt;</code> 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
</span></pre>
<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 <code class="literal">object</code>
can't be implicitly converted to <code class="literal">double</code>s. Instead, what
@@ -250,8 +247,8 @@
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">&lt;</span><span class="identifier">dict</span><span class="special">&gt;(</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>
<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>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
@@ -299,8 +296,6 @@
<p>
You can access those values in Python as
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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>
@@ -308,20 +303,44 @@
where my_module is the module where the enum is declared. You can also create
a new scope around a class:
</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;(</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>
<span class="comment">// Expose X::nested as X.nested
</span><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">&gt;(</span><span class="string">"nested"</span><span class="special">)</span>
<span class="comment">// Expose X::nested as X.nested</span>
<span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">&gt;(</span><span class="string">"nested"</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>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.creating_python_object"></a>Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
</h3></div></div></div>
<p>
When you want a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> to manage a pointer to <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
pyobj one does:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</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">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">pyobj</span><span class="special">));</span>
</pre>
<p>
In this case, the <code class="computeroutput"><span class="identifier">o</span></code> object,
manages the <code class="computeroutput"><span class="identifier">pyobj</span></code>, it won&#8217;t
increase the reference count on construction.
</p>
<p>
Otherwise, to use a borrowed reference:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</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">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">borrowed</span><span class="special">(</span><span class="identifier">pyobj</span><span class="special">)));</span>
</pre>
<p>
In this case, <code class="computeroutput"><span class="identifier">Py_INCREF</span></code> is
called, so <code class="computeroutput"><span class="identifier">pyobj</span></code> is not destructed
when object o goes out of scope.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>

View File

@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>General Techniques</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
<link rel="prev" href="exception.html" title="Exception Translation">
@@ -23,7 +23,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.techniques"></a> General Techniques</h2></div></div></div>
<a name="python.techniques"></a>General Techniques</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="techniques.html#python.creating_packages">Creating Packages</a></span></dt>
<dt><span class="section"><a href="techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
@@ -62,8 +62,8 @@
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>
<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>
<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:
@@ -124,8 +124,6 @@
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
and fire up the interpreter:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<span class="special">&gt;&gt;&gt;</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>
@@ -146,8 +144,6 @@
If we want this flexibility, we will have to complicate our package hierarchy
a little. First, we will have to change the name of the extension modules:
</p>
<p>
</p>
<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>
@@ -178,8 +174,6 @@
to each one. But if we leave it that way, the user will have to access the
functions in the core module with this syntax:
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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>
@@ -188,7 +182,7 @@
magic: everything that is brought to the <code class="literal">__init__.py</code> namespace
can be accessed directly by the user. So, all we have to do is bring the
entire namespace from <code class="literal">_core.pyd</code> to <code class="literal">core/__init__.py</code>.
So add this line of code to <code class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</code>:
So add this line of code to <code class="literal">sounds/core/__init__.py</code>:
</p>
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
</pre>
@@ -216,7 +210,7 @@
<span class="keyword">return</span> <span class="identifier">s</span>
</pre>
<p>
Next, we add this line to <code class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</code>:
Next, we add this line to <code class="literal">sounds/filters/__init__.py</code>:
</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>
@@ -237,11 +231,11 @@
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</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">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># a regular function
</span><span class="special">&gt;&gt;&gt;</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>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># a regular function</span>
<span class="special">&gt;&gt;&gt;</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>
<span class="special">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># now we turn it in a member function
</span><span class="special">&gt;&gt;&gt;</span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># now we turn it in a member function</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
<span class="special">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">C</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">c</span>
@@ -256,8 +250,6 @@
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <code class="literal">point</code> in C++:
</p>
<p>
</p>
<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>
@@ -269,16 +261,14 @@
If we are using the technique from the previous session, <a class="link" href="techniques.html#python.creating_packages" title="Creating Packages">Creating
Packages</a>, we can code directly into <code class="literal">geom/__init__.py</code>:
</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>
<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>
<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>
<span class="keyword">return</span> <span class="identifier">str</span><span class="special">((</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">))</span>
<span class="comment"># now we turn it into a member function
</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
<span class="comment"># now we turn it into a member function</span>
<span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
</pre>
<p>
<span class="bold"><strong>All</strong></span> point instances created from C++ will
@@ -303,9 +293,9 @@
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.
</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>
<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>
<span class="keyword">class</span> <span class="identifier">injector</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span>
<span class="keyword">class</span> <span class="identifier">__metaclass__</span><span class="special">(</span><span class="identifier">BoostPythonMetaclass</span><span class="special">):</span>
@@ -316,8 +306,8 @@
<span class="identifier">setattr</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span><span class="special">)</span>
<span class="keyword">return</span> <span class="identifier">type</span><span class="special">.</span><span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">)</span>
<span class="comment"># inject some methods in the point foo
</span><span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
<span class="comment"># inject some methods in the point foo</span>
<span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
<span class="keyword">def</span> <span class="identifier">__repr__</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
<span class="keyword">return</span> <span class="string">'Point(x=%s, y=%s)'</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">)</span>
<span class="keyword">def</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
@@ -355,8 +345,6 @@
can easily become too high. If this is causing you problems, you can split
the class_ definitions in multiple files:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>

View File

@@ -62,7 +62,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:
[python]
>>> import hello_ext
>>> print hello.greet()
>>> print hello_ext.greet()
hello, world
[c++]
@@ -901,8 +901,8 @@ wrapping as outlined in the [link python.overloading previous section], or
writing thin wrappers:
// write "thin wrappers"
int f1(int x) { f(x); }
int f2(int x, double y) { f(x,y); }
int f1(int x) { return f(x); }
int f2(int x, double y) { return f(x,y); }
/*...*/
@@ -1302,6 +1302,23 @@ create a new scope around a class:
[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]]
[endsect]
[section:creating_python_object Creating `boost::python::object` from `PyObject*`]
When you want a `boost::python::object` to manage a pointer to `PyObject*` pyobj one does:
boost::python::object o(boost::python::handle<>(pyobj));
In this case, the `o` object, manages the `pyobj`, it wont increase the reference count on construction.
Otherwise, to use a borrowed reference:
boost::python::object o(boost::python::handle<>(boost::python::borrowed(pyobj)));
In this case, `Py_INCREF` is called, so `pyobj` is not destructed when object o goes out of scope.
[endsect] [/ creating_python_object ]
[endsect] [/ Object Interface]
[section Embedding]

View File

@@ -96,10 +96,10 @@ template &lt;class F, class Policies, class Keywords, class Signature&gt;
to <code>f</code>. <ul>
<li> If <code>policies</code> are supplied, it
will be applied to the function as described <a href=
"CallPolicies.html">here</a>.
"CallPolicies.html">here</a>.
<li>If <code>keywords</code> are
supplied, the keywords will be applied in order to the final
arguments of the resulting function.
arguments of the resulting function.
<li>If <code>Signature</code>
is supplied, it should be an instance of an <a
href="../../../mpl/doc/refmanual/front-extensible-sequence.html">MPL front-extensible
@@ -125,36 +125,33 @@ template &lt;class F, class Policies, class Keywords, class Signature&gt;
</dl>
<pre>
<a name=
"make_constructor-spec"></a>template &lt;class T, class ArgList, class Generator&gt;
<a href="object.html#object-spec">object</a> make_constructor();
template &lt;class ArgList, class Generator, class Policies&gt;
<a name="make_constructor-spec">template &lt;class F&gt;</a>
<a href="object.html#object-spec">object</a> make_constructor(F f)
template &lt;class F, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_constructor(Policies const&amp; policies)
"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies)
template &lt;class F, class Policies, class KeywordsOrSignature&gt;
<a href=
"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
template &lt;class F, class Policies, class Keywords, class Signature&gt;
<a href=
"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>T</code> is a class type.
<code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>. <code>ArgList</code> is an <a
href="../../../mpl/doc/refmanual/forward-sequence.html">MPL sequence</a> of C++ argument
types (<i>A1,&nbsp;A2,...&nbsp;AN</i>) such that if
<code>a1,&nbsp;a2</code>...&nbsp;<code>aN</code> are objects of type
<i>A1,&nbsp;A2,...&nbsp;AN</i> respectively, the expression <code>new
Generator::apply&lt;T&gt;::type(a1,&nbsp;a2</code>...&nbsp;<code>aN</code>)
is valid. Generator is a model of <a href=
"HolderGenerator.html">HolderGenerator</a>.</dt>
<dt><b>Requires:</b> <code>F</code> is a
function pointer type. If <code>policies</code> are supplied, it must
be a model of <a href="CallPolicies.html">CallPolicies</a>. If
<code>kewords</code> are supplied, it must be the result of a <a href=
"args.html#keyword-expression"><em>keyword-expression</em></a>
specifying no more arguments than the <a href=
"definitions.html#arity">arity</a> of <code>f</code>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which, when called
from Python, expects its first argument to be a Boost.Python extension
class object. It converts its remaining its arguments to C++ and passes
them to the constructor of a dynamically-allocated
<code>Generator::apply&lt;T&gt;::type</code> object, which is then
installed in the extension class object. In the second form, the
<code>policies</code> are applied to the arguments and result (<a href=
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a>)
of the Python callable object</dt>
from Python, converts its arguments to C++ and calls <code>f</code>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
@@ -186,7 +183,7 @@ BOOST_PYTHON_MODULE(make_function_test)
def("choose_function", choose_function);
}
</pre>
It can be used this way in Python:
It can be used this way in Python:
<pre>
&gt;&gt;&gt; from make_function_test import *
&gt;&gt;&gt; f = choose_function(1)

View File

@@ -85,7 +85,7 @@ namespace boost { namespace python
object stop();
object step();
// The return type of slice::get_indicies()
// The return type of slice::get_indices()
template &lt;typename RandomAccessIterator&gt;
struct range
{
@@ -96,7 +96,7 @@ namespace boost { namespace python
template &lt;typename RandomAccessIterator&gt;
range&lt;RandomAccessIterator&gt;
get_indicies(
get_indices(
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end);
};
@@ -164,7 +164,7 @@ slice object, but in practice they are usually integers.</dt>
<pre>
template &lt;typename RandomAccessIterator&gt;
slice::range&lt;RandomAccessIterator&gt;
slice::get_indicies(
slice::get_indices(
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end) const;
</pre>
@@ -173,8 +173,8 @@ slice::get_indicies(
Iterators that form a half-open range.</dt>
<dt><b>Effects:</b> Create a RandomAccessIterator pair that defines a
fully-closed range within the [begin,end) range of its arguments.&nbsp;
This function translates this slice's indicies while accounting for the
effects of any PyNone or negative indicies, and non-singular step sizes.</dt>
This function translates this slice's indices while accounting for the
effects of any PyNone or negative indices, and non-singular step sizes.</dt>
<dt><b>Returns:</b> a slice::range
that has been initialized with a non-zero value of step and a pair of
RandomAccessIterators that point within the range of this functions
@@ -182,7 +182,7 @@ arguments and define a closed interval.</dt>
<dt><b>Throws:</b> <a href="definitions.html#raise">Raises</a> a Python <code>TypeError</code> exception if any of this slice's arguments
are neither references to <code>PyNone</code> nor convertible to <code>int</code>.&nbsp; Throws
<code>std::invalid_argument</code> if the resulting range would be empty.&nbsp; You
should always wrap calls to <code>slice::get_indicies()</code>
should always wrap calls to <code>slice::get_indices()</code>
within <code>try { ...; } catch (std::invalid_argument) {}</code> to
handle this case and take appropriate action.</dt>
<dt><b>Rationale</b>: closed-interval: If
@@ -221,7 +221,7 @@ double partial_sum(std::vector&lt;double&gt; const&amp; Foo, const slice index)
{
slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
try {
bounds = index.get_indicies&lt;&gt;(Foo.begin(), Foo.end());
bounds = index.get_indices&lt;&gt;(Foo.begin(), Foo.end());
}
catch (std::invalid_argument) {
return 0.0;

View File

@@ -91,7 +91,7 @@
<hr>
<h2>
<a name="introduction">Introduction</a>
</h2>This header provides faciliites for establishing a lifetime
</h2>This header provides facilities for establishing a lifetime
dependency between two of a function's Python argument or result objects.
The <i>ward</i> object will not be destroyed until after the custodian as
long as the <i>custodian</i> object supports <a href=

5
example/Jamroot Executable file → Normal file
View File

@@ -11,7 +11,10 @@ use-project boost
# boost_python library from the project whose global ID is
# /boost/python.
project
: requirements <library>/boost/python//boost_python ;
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.

2
example/quickstart/Jamroot Executable file → Normal file
View File

@@ -12,6 +12,8 @@ use-project boost
# /boost/python.
project boost-python-quickstart
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Make the definition of the python-extension rule available

View File

@@ -20,7 +20,10 @@ use-project boost
# boost_python library from the project whose global ID is
# /boost/python.
project
: requirements <library>/boost/python//boost_python ;
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.

View File

@@ -138,7 +138,8 @@ namespace detail
static void
must_be_derived_class_member(Default const&)
{
typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
// https://svn.boost.org/trac/boost/ticket/5803
//typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
typedef typename assertion<is_polymorphic<T> >::failed test1;
# endif

View File

@@ -76,13 +76,13 @@
# if BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __attribute__ ((visibility("default")))
# define BOOST_PYTHON_DECL __attribute__ ((__visibility__("default")))
# define BOOST_PYTHON_BUILD_DLL
# else
# define BOOST_PYTHON_DECL
# endif
# define BOOST_PYTHON_DECL_FORWARD
# define BOOST_PYTHON_DECL_EXCEPTION __attribute__ ((visibility("default")))
# define BOOST_PYTHON_DECL_EXCEPTION __attribute__ ((__visibility__("default")))
# elif (defined(_WIN32) || defined(__CYGWIN__))
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __declspec(dllexport)

View File

@@ -57,7 +57,7 @@ object make_keyword_range_constructor(
, Holder* = 0
, ArgList* = 0, Arity* = 0)
{
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
#endif
return detail::make_keyword_range_function(

View File

@@ -8,6 +8,7 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/bind.hpp>
# include <boost/bind/placeholders.hpp>
# include <boost/type.hpp>
# include <boost/python/detail/translate_exception.hpp>
# include <boost/python/detail/exception_handler.hpp>

View File

@@ -19,7 +19,6 @@
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/utility.hpp>
# include <boost/call_traits.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)

2
include/boost/python/instance_holder.hpp Executable file → Normal file
View File

@@ -7,7 +7,7 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/utility.hpp>
# include <boost/noncopyable.hpp>
# include <boost/python/type_id.hpp>
# include <cstddef>

View File

@@ -76,7 +76,7 @@ extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" __attribute__ ((visibility("default"))) _BOOST_PYTHON_MODULE_INIT(name)
extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name)
# else

View File

@@ -6,7 +6,6 @@
# define CLASS_DWA20011214_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/utility.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/type_id.hpp>
# include <cstddef>

View File

@@ -238,7 +238,7 @@ struct class_metadata
//
inline static void maybe_register_pointer_to_python(...) {}
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
{
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
@@ -255,7 +255,7 @@ struct class_metadata
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
>()
);
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
@@ -270,7 +270,7 @@ struct class_metadata
inline static void maybe_register_class_to_python(T2*, mpl::false_)
{
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif

View File

@@ -12,7 +12,7 @@
# include <boost/python/object/instance.hpp>
# include <boost/python/converter/registry.hpp>
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
# include <boost/python/detail/python_type.hpp>
#endif
@@ -81,7 +81,7 @@ struct make_holder<N>
# endif
static void execute(
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
#else
PyObject *p

View File

@@ -348,12 +348,12 @@ namespace api
// Macros for forwarding constructors in classes derived from
// object. Derived classes will usually want these as an
// implementation detail
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
inline explicit derived(python::detail::borrowed_reference p) \
: base(p) {} \
inline explicit derived(python::detail::new_reference p) \
: base(p) {} \
inline explicit derived(python::detail::new_non_null_reference p) \
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
inline explicit derived(::boost::python::detail::borrowed_reference p) \
: base(p) {} \
inline explicit derived(::boost::python::detail::new_reference p) \
: base(p) {} \
inline explicit derived(::boost::python::detail::new_non_null_reference p) \
: base(p) {}
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300

2
include/boost/python/override.hpp Executable file → Normal file
View File

@@ -77,7 +77,7 @@ namespace detail
template <class T>
T unchecked(type<T>* = 0)
{
return extract<T>(m_obj)();
return extract<T>(m_obj.get())();
}
private:
mutable handle<> m_obj;

View File

@@ -8,7 +8,6 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/object.hpp>
# include <boost/python/refcount.hpp>
# include <boost/utility.hpp>
namespace boost { namespace python {

View File

@@ -30,7 +30,7 @@ namespace detail
// that created this slice, than that parameter is None here, and compares
// equal to a default-constructed boost::python::object.
// If a user-defined type wishes to support slicing, then support for the
// special meaning associated with negative indicies is up to the user.
// special meaning associated with negative indices is up to the user.
object start() const;
object stop() const;
object step() const;
@@ -63,7 +63,7 @@ class slice : public detail::slice_base
// The following algorithm is intended to automate the process of
// determining a slice range when you want to fully support negative
// indicies and non-singular step sizes. Its functionallity is simmilar to
// indices and non-singular step sizes. Its functionallity is simmilar to
// PySlice_GetIndicesEx() in the Python/C API, but tailored for C++ users.
// This template returns a slice::range struct that, when used in the
// following iterative loop, will traverse a slice of the function's
@@ -110,7 +110,7 @@ class slice : public detail::slice_base
template<typename RandomAccessIterator>
slice::range<RandomAccessIterator>
get_indicies( const RandomAccessIterator& begin,
get_indices( const RandomAccessIterator& begin,
const RandomAccessIterator& end) const
{
// This is based loosely on PySlice_GetIndicesEx(), but it has been
@@ -240,6 +240,16 @@ class slice : public detail::slice_base
return ret;
}
// Incorrect spelling. DO NOT USE. Only here for backward compatibility.
// Corrected 2011-06-14.
template<typename RandomAccessIterator>
slice::range<RandomAccessIterator>
get_indicies( const RandomAccessIterator& begin,
const RandomAccessIterator& end) const
{
return get_indices(begin, end);
}
public:
// This declaration, in conjunction with the specialization of

15
meta/libraries.json Normal file
View File

@@ -0,0 +1,15 @@
{
"key": "python",
"name": "Python",
"authors": [
"Dave Abrahams"
],
"description": "The Boost Python Library is a framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler.",
"category": [
"Inter-language"
],
"maintainers": [
"Ralf Grosse-Kunstleve <rwgrosse-kunstleve -at- lbl.gov>",
"Ravi Rajagopal <lists_ravi -at- lavabit.com>"
]
}

View File

@@ -4,12 +4,16 @@
# http://www.boost.org/LICENSE_1_0.txt)
from declarations import *
# try to use cElementTree if avaiable
try:
from cElementTree import ElementTree
# try to use internal elementtree
from xml.etree.cElementTree import ElementTree
except ImportError:
# fall back to the normal elementtree
from elementtree.ElementTree import ElementTree
# try to use cElementTree if avaiable
try:
from cElementTree import ElementTree
except ImportError:
# fall back to the normal elementtree
from elementtree.ElementTree import ElementTree
from xml.parsers.expat import ExpatError
from copy import deepcopy
from utils import enumerate

View File

@@ -366,7 +366,9 @@ namespace
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
};
#if PY_VERSION_HEX >= 0x03000000
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
#endif
// A SlotPolicy for extracting C++ strings from Python objects.
struct string_rvalue_from_python
@@ -375,7 +377,8 @@ namespace
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x03000000
return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc : 0;
return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc :
PyBytes_Check(obj) ? &py_object_identity : 0;
#else
return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
@@ -431,7 +434,10 @@ namespace
if (!result.empty())
{
int err = PyUnicode_AsWideChar(
(PyUnicodeObject *)intermediate
#if PY_VERSION_HEX < 0x03020000
(PyUnicodeObject *)
#endif
intermediate
, &result[0]
, result.size());

View File

@@ -44,11 +44,8 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
// First check to see if it's embedded in an extension class
// instance, as a special case.
data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
if (data.convertible)
{
data.construct = 0;
}
else
if (!data.convertible)
{
for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
chain != 0;

View File

@@ -84,22 +84,24 @@ object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
#if PY_VERSION_HEX >= 0x03000000
// TODO(bhy) temporary workaround for Python 3.
// should figure out a way to avoid binary incompatibilities as the Python 2
// version did.
FILE *fs = fopen(f, "r");
#else
// Let python open the file to avoid potential binary incompatibilities.
#if PY_VERSION_HEX >= 0x03000000
// See http://www.codeproject.com/Articles/820116/Embedding-Python-program-in-a-C-Cplusplus-code
FILE *fs = _Py_fopen(f, "r");
#else
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);
FILE *fs = PyFile_AsFile(file.get());
#endif
PyObject* result = PyRun_File(fs,
int closeit = 1; // Close file before PyRun returns
PyObject* result = PyRun_FileEx(fs,
f,
Py_file_input,
global.ptr(), local.ptr());
global.ptr(), local.ptr(),
closeit);
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
}

View File

@@ -38,7 +38,7 @@ BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char
#if PY_VERSION_HEX >= 0x03000000
PyObject* init_module(PyModuleDef& moduledef, void(*init_function)())
BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef& moduledef, void(*init_function)())
{
return init_module_in_scope(
PyModule_Create(&moduledef),

View File

@@ -76,11 +76,11 @@ extern "C"
static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
static const char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
propertyobject *prop = (propertyobject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
kwlist, &get, &set, &del, &doc))
const_cast<char **>(kwlist), &get, &set, &del, &doc))
return -1;
if (get == Py_None)
@@ -303,7 +303,7 @@ static PyTypeObject class_metatype_object = {
// object.
void instance_holder::install(PyObject* self) throw()
{
assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self)), &class_metatype_object));
m_next = ((objects::instance<>*)self)->objects;
((objects::instance<>*)self)->objects = this;
}
@@ -482,7 +482,8 @@ namespace objects
BOOST_PYTHON_DECL void*
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
{
if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
if (!Py_TYPE(Py_TYPE(inst)) ||
!PyType_IsSubtype(Py_TYPE(Py_TYPE(inst)), &class_metatype_object))
return 0;
instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -727,7 +728,7 @@ namespace objects
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
{
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
objects::instance<>* self = (objects::instance<>*)self_;
int total_size_needed = holder_offset + holder_size;
@@ -752,7 +753,7 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std:
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
{
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
objects::instance<>* self = (objects::instance<>*)self_;
if (storage != (char*)self + Py_SIZE(self))
{

View File

@@ -433,23 +433,23 @@ void function::add_to_namespace(
if (attribute.ptr()->ob_type == &function_type)
{
function* new_func = downcast<function>(attribute.ptr());
PyObject* dict = 0;
handle<> dict;
#if PY_VERSION_HEX < 0x03000000
// Old-style class gone in Python 3
if (PyClass_Check(ns))
dict = ((PyClassObject*)ns)->cl_dict;
dict = handle<>(borrowed(((PyClassObject*)ns)->cl_dict));
else
#endif
if (PyType_Check(ns))
dict = ((PyTypeObject*)ns)->tp_dict;
dict = handle<>(borrowed(((PyTypeObject*)ns)->tp_dict));
else
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
dict = handle<>(PyObject_GetAttrString(ns, const_cast<char*>("__dict__")));
if (dict == 0)
throw_error_already_set();
handle<> existing(allow_null(::PyObject_GetItem(dict, name.ptr())));
handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
if (existing)
{

View File

@@ -3,11 +3,15 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
import os ;
lib socket ;
use-project /boost/python : ../build ;
project /boost/python/test
: requirements
<toolset>gcc:<cxxflags>-Wextra
<target-os>qnxnto:<library>socket
;
local PY = ;
@@ -117,6 +121,7 @@ bpl-test crossmod_exception
[ bpl-test defaults ]
[ bpl-test object ]
[ bpl-test class ]
[ bpl-test list ]
[ bpl-test long ]
[ bpl-test dict ]

28
test/class.cpp Normal file
View File

@@ -0,0 +1,28 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct X
{
int x;
X(int n) : x(n) { }
};
int x_function(X& x)
{ return x.x;
}
BOOST_PYTHON_MODULE(class_ext)
{
class_<X>("X", init<int>());
def("x_function", x_function);
}
#include "module_tail.cpp"

40
test/class.py Executable file
View File

@@ -0,0 +1,40 @@
# 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 class_ext import *
Ensure sanity:
>>> x = X(42)
>>> x_function(x)
42
Demonstrate extraction in the presence of metaclass changes:
>>> class MetaX(X.__class__):
... def __new__(cls, *args):
... return super(MetaX, cls).__new__(cls, *args)
>>> class XPlusMetatype(X):
... __metaclass__ = MetaX
>>> x = XPlusMetatype(42)
>>> x_function(x)
42
'''
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)

View File

@@ -98,9 +98,9 @@ bool accept_slice( slice) { return true; }
#if BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
int check_slice_get_indicies(slice index);
int check_slice_get_indices(slice index);
#endif
int check_slice_get_indicies(
int check_slice_get_indices(
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
const
#endif
@@ -116,7 +116,7 @@ int check_slice_get_indicies(
slice::range<std::vector<int>::iterator> bounds;
try {
bounds = index.get_indicies(coll.begin(), coll.end());
bounds = index.get_indices(coll.begin(), coll.end());
}
catch (std::invalid_argument) {
return 0;
@@ -136,5 +136,5 @@ BOOST_PYTHON_MODULE(slice_ext)
def( "accept_slice", accept_slice);
def( "check_numeric_array_rich_slice", check_numeric_array_rich_slice);
def( "check_string_rich_slice", check_string_rich_slice);
def( "check_slice_get_indicies", check_slice_get_indicies);
def( "check_slice_get_indices", check_slice_get_indices);
}

View File

@@ -37,17 +37,17 @@ test passed
... print 1
...
1
>>> check_slice_get_indicies( slice(None))
>>> check_slice_get_indices( slice(None))
0
>>> check_slice_get_indicies( slice(2,-2))
>>> check_slice_get_indices( slice(2,-2))
0
>>> check_slice_get_indicies( slice(2, None, 2))
>>> check_slice_get_indices( slice(2, None, 2))
5
>>> check_slice_get_indicies( slice(2, None, -1))
>>> check_slice_get_indices( slice(2, None, -1))
-12
>>> check_slice_get_indicies( slice( 20, None))
>>> check_slice_get_indices( slice( 20, None))
0
>>> check_slice_get_indicies( slice( -2, -5, -2))
>>> check_slice_get_indices( slice( -2, -5, -2))
6
"""