2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 17:12:22 +00:00

Compare commits

..

14 Commits

Author SHA1 Message Date
Beman Dawes
d095b00dba Release
[SVN r43921]
2008-03-29 11:50:24 +00:00
Beman Dawes
694ae13063 Merge from trunk 43901 at Dave's request
[SVN r43902]
2008-03-28 02:16:12 +00:00
Joel de Guzman
5168895803 Added note about --preserve-test-targets
[SVN r43849]
2008-03-24 23:04:36 +00:00
Joel de Guzman
c8bf94663c Added note about --preserve-test-targets
[SVN r43848]
2008-03-24 23:02:57 +00:00
Daniel James
928a9389ce Rebuild a lot of documentation.
[SVN r43650]
2008-03-16 11:38:32 +00:00
Daniel James
7d22435994 Merged revisions 43211,43214-43219,43222-43225,43227-43238,43242,43244-43245,43249-43250,43257-43259,43261,43263,43265,43267-43268,43270-43271,43273,43275-43279,43284-43289,43291,43295,43297-43298,43304-43305,43307,43313,43315,43324,43326-43327,43331,43333,43339-43343,43345,43348,43350,43352-43353,43355-43356,43358,43360,43366-43367,43369-43370,43372-43376,43378-43389,43394,43396-43398,43400-43401,43403-43404,43406-43408,43413-43415,43417-43418,43420,43422-43423 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43417 | danieljames | 2008-02-26 22:04:55 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Fix a link to Boost.Bimap.
........
  r43418 | danieljames | 2008-02-26 22:07:25 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Change another link that's no longer in the repository to link to the website.
........
  r43422 | danieljames | 2008-02-27 18:51:14 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix broken copyright urls. Fixes #1573.
........
  r43423 | danieljames | 2008-02-27 19:22:01 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix incorrect links to copyright of the form 'http:#www.boost.org
........


[SVN r43425]
2008-02-27 20:00:24 +00:00
Daniel James
96dd880146 Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Jürgen Hunold
63f8e9f3d7 Merged revisions 41544-41546,41549-41551,41558-41561,41564,41567,41570,41573,41576-41579,41581,41583-41586,41589,41591,41594-41612,41614-41620,41622-41624,41628,41630-41635,41637,41640-41641,41643,41649-41650 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r41544 | jhunold | 2007-12-01 20:27:06 +0100 (Sa, 01 Dez 2007) | 2 lines
  
  Silence compiler by adding cosmetic virtual destructors.
........
  r41549 | jhunold | 2007-12-01 21:24:51 +0100 (Sa, 01 Dez 2007) | 2 lines
  
  Silence compiler by adding cosmetic virtual destructors.
........
  r41550 | jhunold | 2007-12-01 21:26:37 +0100 (Sa, 01 Dez 2007) | 3 lines
  
  Remove unused paramters.
  Add -Wextra to gcc flags to enable more warnings.
........
  r41577 | jhunold | 2007-12-02 12:51:08 +0100 (So, 02 Dez 2007) | 3 lines
  
  Revert revisions 41544 and 41549.
  See http://lists.boost.org/Archives/boost/2007/12/131116.php for details.
........
  r41649 | jhunold | 2007-12-03 19:47:17 +0100 (Mo, 03 Dez 2007) | 2 lines
  
  Silence unused paramter warning in release mode.
........
  r41650 | jhunold | 2007-12-03 19:51:26 +0100 (Mo, 03 Dez 2007) | 2 lines
  
  Add cosmetic virtual detructors to silence compile warnings.
........


[SVN r42094]
2007-12-16 10:12:07 +00:00
Beman Dawes
d9b4ada654 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
f5df393360 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Rene Rivera
bf33b54638 Recreate release branch from fixed 1.34.1 tag.
[SVN r40341]
2007-10-23 06:42:50 +00:00
Douglas Gregor
87451007b9 Move Attic files back into their rightful places
[SVN r40311]
2007-10-23 01:47:48 +00:00
Beman Dawes
2392a6a3e2 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
6c1e7decfa This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
90 changed files with 695 additions and 1533 deletions

View File

@@ -1,66 +0,0 @@
if (PYTHON_LIBRARIES)
include_directories(${PYTHON_INCLUDE_PATH})
# Determine extra libraries we need to link against to build Python
# extension modules.
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "DragonFly")
# DragonFly is a variant of FreeBSD
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
# No options necessary for QNX
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# No options necessary for Mac OS X
elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
elseif(UNIX)
# Assume -pthread and -ldl on all other variants
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "util")
endif(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
################################################################################
#-- Macro for building Boost.Python extension modules
macro(boost_python_extension MODULE_NAME)
parse_arguments(BPL_EXT
""
""
${ARGN})
boost_add_single_library(
${MODULE_NAME}
${BPL_EXT_DEFAULT_ARGS}
MODULE
LINK_LIBS ${PYTHON_LIBRARIES}
DEPENDS boost_python
SHARED
)
endmacro(boost_python_extension)
#--
################################################################################
boost_library_project(
Python
SRCDIRS src
TESTDIRS test
HEADERS python.hpp python
MODULARIZED
DESCRIPTION "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."
AUTHORS "David Abrahams <dave -at- boostpro.com>"
)
endif (PYTHON_LIBRARIES)

View File

@@ -9,7 +9,7 @@
</head>
<body>
<div class="document" id="logo-boost-python-build-and-test-howto">
<h1 class="title"><a class="reference external" href="../index.html"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
<h1 class="title"><a class="reference external" href="../index.htm"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->

View File

@@ -11,7 +11,7 @@
:alt: Boost C++ Libraries:
:class: boost-logo
__ ../index.html
__ ../index.htm
.. section-numbering::

View File

@@ -375,27 +375,6 @@
application modules, including GUI and post-processing of results.</p>
</dd>
<dt><b><a href="http://polybori.sourceforge.net/">PolyBoRi</a></b></dt>
<dd>
<p><a href="mailto:brickenstein@mfo.de"
>Michael Brickenstein</a> writes:</p>
<blockquote>
<p>The core of PolyBoRi is a C++ library, which provides
high-level data types for Boolean polynomials and monomials,
exponent vectors, as well as for the underlying polynomial
rings and subsets of the powerset of the Boolean variables. As
a unique approach, binary decision diagrams are used as
internal storage type for polynomial structures. On top of
this C++-library we provide a Python interface. This allows
parsing of complex polynomial systems, as well as sophisticated
and extendable strategies for Gr&ouml;bner basis computation.
Boost.Python has helped us to create this interface in a
very clean way.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
@@ -456,11 +435,11 @@
</dl>
<hr>
<p>Revised
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 May, 2008</p>
15 July, 2003</p>
<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2008.</i></p>
Abrahams</a> 2002-2003.</i></p>
</body>
</html>

View File

@@ -6,8 +6,6 @@ project boost/libs/python/doc/tutorial/doc ;
import boostbook : boostbook ;
using quickbook ;
path-constant images : html ;
boostbook tutorial
:
tutorial.qbk
@@ -15,6 +13,4 @@ boostbook tutorial
<xsl:param>boost.root=../../../../../..
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
<xsl:param>html.stylesheet=../../../../../../doc/html/boostbook.css
<format>pdf:<xsl:param>img.src.path=$(images)/
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html
;

View File

@@ -1,19 +1,19 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter 1. python 2.0</title>
<title>Chapter 1. python 1.0</title>
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
<link rel="start" href="index.html" title="Chapter 1. python 1.0">
<link rel="next" href="python/hello.html" title=" Building Hello World">
<link rel="next" href="python/hello.html" title="Building Hello World">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="http://www.boost.org/people/people.htm">People</a></td>
<td align="center"><a href="http://www.boost.org/more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -31,7 +31,7 @@
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id457106"></a><p>
<a name="id2625929"></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>)
@@ -93,15 +93,16 @@
code takes on the look of a kind of declarative interface definition language
(IDL).
</p>
<a name="quickstart.hello_world"></a><h2>
<a name="id386707"></a>
<a name="quickstart.hello_world"></a><h3>
<a name="id2625972"></a>
Hello World
</h2>
</h3>
<p>
Following C/C++ tradition, let's start with the "hello, world". A
C++ Function:
</p>
<pre class="programlisting"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
<pre class="programlisting">
<span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="string">"hello, world"</span><span class="special">;</span>
<span class="special">}</span>
@@ -109,7 +110,8 @@
<p>
can be exposed to Python by writing a Boost.Python wrapper:
</p>
<pre class="programlisting"><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>
<pre class="programlisting">
<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>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
<span class="special">{</span>
@@ -123,7 +125,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<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="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
</pre>
@@ -133,8 +136,8 @@
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World
module from start to finish...</b></span></em></span>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World
module from start to finish...</strong></span></em></span>
</p>
<p>
</p>
@@ -142,7 +145,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: November 22, 2008 at 03:24:11 GMT</small></p></td>
<td align="left"><p><small>Last revised: March 15, 2008 at 13:46:47 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -40,7 +40,7 @@
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
</p>
<a name="embedding.building_embedded_programs"></a><h2>
<a name="id472330"></a>
<a name="id471329"></a>
Building embedded programs
</h2>
<p>
@@ -82,7 +82,7 @@ exe embedded_program # name of the executable
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
<a name="embedding.getting_started"></a><h2>
<a name="id472435"></a>
<a name="id471434"></a>
Getting started
</h2>
<p>
@@ -130,22 +130,23 @@ exe embedded_program # name of the executable
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
<p>
As you probably already know, objects in Python are reference-counted. Naturally,
the <tt class="literal">PyObject</tt>s of the Python C API are also reference-counted.
the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully automatic
in Python, the Python C API requires you to do it <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
hand</a>. This is messy and especially hard to get right in the presence
in Python, the Python<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
by hand]. This is messy and especially hard to get right in the presence
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
automate the process.
</p>
<a name="using_the_interpreter.running_python_code"></a><h2>
<a name="id472601"></a>
<a name="id471597"></a>
Running Python code
</h2>
<p>
Boost.python provides three related functions to run Python code from C++.
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
</pre>
@@ -164,7 +165,8 @@ exe embedded_program # name of the executable
<p>
Boost.python provides a function to import a module:
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
</pre>
<p>
import imports a python module (potentially loading it into the running process
@@ -174,7 +176,8 @@ exe embedded_program # name of the executable
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
module and run some Python code in its namespace:
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
@@ -187,7 +190,7 @@ exe embedded_program # name of the executable
a phrase that is well-known in programming circles.
</p>
<a name="using_the_interpreter.manipulating_python_objects"></a><h2>
<a name="id473185"></a>
<a name="id472185"></a>
Manipulating Python objects
</h2>
<p>
@@ -197,7 +200,8 @@ exe embedded_program # name of the executable
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
The following examples should further illustrate this fact:
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&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>
@@ -208,18 +212,20 @@ exe embedded_program # name of the executable
this variable from the dictionary. Another way to achieve the same result
is to use eval instead, which returns the result directly:
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&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><h2>
<a name="id473554"></a>
<a name="id472557"></a>
Exception handling
</h2>
<p>
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
is thrown:
</p>
<pre class="programlisting"><span class="keyword">try</span>
<pre class="programlisting">
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
<span class="comment">// execution will never get here:
@@ -234,13 +240,14 @@ exe embedded_program # name of the executable
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
information in itself. To find out more about the Python exception that occurred,
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
handling functions</a> of the Python C API in your catch-statement. This
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
to print the exception's traceback to the console, or comparing the type
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
This can be as simple as calling [@http:</em></span>/www.python.org/doc/api/exceptionHandling.html#l2h-70
PyErr_Print()] to print the exception's traceback to the console, or comparing
the type of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
exceptions</a>:
</p>
<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
<pre class="programlisting">
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
<span class="special">{</span>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -30,12 +30,14 @@
is the point where C++ meets Python. Boost.Python provides a default exception
handler that translates selected standard exceptions, then gives up:
</p>
<pre class="programlisting"><span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
<pre class="programlisting">
<span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
</pre>
<p>
Users may provide custom translation. Here's an example:
</p>
<pre class="programlisting"><span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
<pre class="programlisting">
<span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span> <span class="string">"I'm sorry Dave..."</span><span class="special">);</span>
<span class="special">}</span>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -40,7 +40,8 @@
<p>
Consider a C++ class/struct that we want to expose to Python:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">World</span>
<span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&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>
@@ -50,7 +51,8 @@
<p>
We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&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>
<pre class="programlisting">
<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>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
@@ -69,7 +71,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello</span>
<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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
@@ -84,7 +87,8 @@
exposes the default constructor by default, which is why we were able to
write
</p>
<pre class="programlisting"><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>
<pre class="programlisting">
<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>
</pre>
<p>
We may wish to wrap a class with a non-default constructor. Let us build
@@ -92,7 +96,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">World</span>
<span class="special">{</span>
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor
</span> <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
@@ -106,7 +111,8 @@
We have to tell <tt class="literal">class_&lt;World&gt;</tt> about the constructor
we want to expose instead.
</p>
<pre class="programlisting"><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>
<pre class="programlisting">
<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>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
@@ -127,7 +133,8 @@
to the <tt class="literal">def()</tt> member function. Say for example we have
another World constructor taking in two doubles:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
@@ -137,7 +144,8 @@
On the other hand, if we do not wish to expose any constructors at all, we
may use <tt class="literal">no_init</tt> instead:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&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 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 <tt class="literal"><span class="underline">_init</span>_</tt>
@@ -153,7 +161,8 @@
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Var</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Var</span>
<span class="special">{</span>
<span class="identifier">Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">name</span><span class="special">;</span>
@@ -164,7 +173,8 @@
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
to Python:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Var</span><span class="special">&gt;(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Var</span><span class="special">&gt;(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
</pre>
@@ -174,7 +184,8 @@
</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>
<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>
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
@@ -183,7 +194,8 @@
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
</p>
<pre class="programlisting"><span class="special">&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
<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="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
@@ -200,7 +212,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Num</span>
<span class="special">{</span>
<span class="identifier">Num</span><span class="special">();</span>
<span class="keyword">float</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
@@ -214,7 +227,8 @@
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
class using Boost.Python:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Num</span><span class="special">&gt;(</span><span class="string">"Num"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Num</span><span class="special">&gt;(</span><span class="string">"Num"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
</pre>
@@ -223,7 +237,8 @@
</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>
<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>
@@ -236,7 +251,8 @@
</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 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>
<div class="section" lang="en">
@@ -252,21 +268,24 @@
<p>
Consider this trivial inheritance structure:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
</pre>
<p>
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
object instances:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
<span class="keyword">void</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span>
<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
</pre>
<p>
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<span class="comment">/*...*/</span>
<span class="special">;</span>
</pre>
@@ -274,7 +293,8 @@
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
and its base class <tt class="literal">Base</tt>. Thus:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"Derived"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"Derived"</span><span class="special">)</span>
<span class="comment">/*...*/</span>
<span class="special">;</span>
</pre>
@@ -297,7 +317,8 @@
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
and <tt class="literal">factory</tt>:
</p>
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
</pre>
@@ -310,7 +331,8 @@
is destroyed. We will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
policies</a> later.
</p>
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result
<pre class="programlisting">
<span class="comment">// Tell Python to take ownership of factory's result
</span><span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
<span class="identifier">return_value_policy</span><span class="special">&lt;</span><span class="identifier">manage_new_object</span><span class="special">&gt;());</span>
</pre>
@@ -323,7 +345,8 @@
through virtual functions. Continuing our example, let us add a virtual function
to our <tt class="literal">Base</tt> class:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
@@ -341,7 +364,8 @@
that will unintrusively hook into the virtual functions so that a Python
override may be called:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
@@ -373,7 +397,8 @@
<p>
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
<span class="special">;</span>
</pre>
@@ -412,7 +437,8 @@
section</a>, we wrapped a class with a pure virtual function that we then
implemented in C++, or Python classes derived from it. Our base class:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
@@ -421,7 +447,8 @@
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
function <tt class="literal">f</tt> was not declared as pure virtual:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span>
@@ -430,7 +457,8 @@
<p>
We wrap it this way:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
@@ -462,7 +490,8 @@
<p>
Finally, exposing:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
<span class="special">;</span>
</pre>
@@ -477,7 +506,8 @@
</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>
<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>
<span class="special">...</span> <span class="keyword">return</span> <span class="number">42</span>
@@ -487,13 +517,15 @@
<p>
Calling <tt class="literal">base.f()</tt>:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<span class="number">0</span>
</pre>
<p>
Calling <tt class="literal">derived.f()</tt>:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<span class="number">42</span>
</pre>
</div>
@@ -501,7 +533,7 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
<a name="class_operators_special_functions.python_operators"></a><h2>
<a name="id462548"></a>
<a name="id461481"></a>
Python Operators
</h2>
<p>
@@ -515,7 +547,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
@@ -529,7 +562,8 @@
The class and the various operators can be mapped to Python rather easily
and intuitively:
</p>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">FilePos</span><span class="special">&gt;(</span><span class="string">"FilePos"</span><span class="special">)</span>
<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__
@@ -548,7 +582,7 @@
expressions".
</p>
<a name="class_operators_special_functions.special_methods"></a><h2>
<a name="id463302"></a>
<a name="id462238"></a>
Special Methods
</h2>
<p>
@@ -558,7 +592,8 @@
wrap C++ functions that correspond to these Python <span class="emphasis"><em>special functions</em></span>.
Example:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Rational</span>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">Rational</span>
<span class="special">{</span> <span class="keyword">public</span><span class="special">:</span> <span class="keyword">operator</span> <span class="keyword">double</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">};</span>
<span class="identifier">Rational</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span> <span class="identifier">Rational</span><span class="special">);</span>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -87,14 +87,16 @@ Namespaces are one honking great idea -- let's do more of those!
so Boost.Python must deal with them. To do this, it may need your help. Consider
the following C++ function:
</p>
<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
</pre>
<p>
How should the library wrap this function? A naive approach builds a Python
X object around result reference. This strategy might or might not work out.
Here's an example where it didn't
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">y</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
</pre>
@@ -104,7 +106,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
Well, what if f() was implemented as shown below:
</p>
<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
@@ -142,7 +145,8 @@ Namespaces are one honking great idea -- let's do more of those!
</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
<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>
@@ -156,7 +160,8 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Y</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Y</span>
<span class="special">{</span>
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">z_value</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">z</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
@@ -166,14 +171,16 @@ Namespaces are one honking great idea -- let's do more of those!
Notice that the data member <tt class="literal">z</tt> is held by class Y using
a raw pointer. Now we have a potential dangling pointer problem inside Y:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
</pre>
<p>
For reference, here's the implementation of <tt class="literal">f</tt> again:
</p>
<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
@@ -205,7 +212,7 @@ Namespaces are one honking great idea -- let's do more of those!
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h2>
<a name="id465291"></a>
<a name="id464235"></a>
Call Policies
</h2>
<p>
@@ -213,7 +220,8 @@ Namespaces are one honking great idea -- let's do more of those!
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
are our friends:
</p>
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
<span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span>
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">&gt;());</span>
</pre>
@@ -221,7 +229,8 @@ Namespaces are one honking great idea -- let's do more of those!
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
ask?
</p>
<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span>
<pre class="programlisting">
<span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span>
</pre>
<p>
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&amp;
@@ -230,7 +239,8 @@ Namespaces are one honking great idea -- let's do more of those!
In short: "return an internal reference <tt class="literal">X&amp;</tt> owned
by the 1st argument <tt class="literal">Y&amp; y</tt>".
</p>
<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span>
<pre class="programlisting">
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span>
</pre>
<p>
Informs Boost.Python that the lifetime of the argument indicated by ward
@@ -242,7 +252,8 @@ Namespaces are one honking great idea -- let's do more of those!
It is also important to note that we have defined two policies above. Two
or more policies can be composed by chaining. Here's the general syntax:
</p>
<pre class="programlisting"><span class="identifier">policy1</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
<pre class="programlisting">
<span class="identifier">policy1</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
<span class="identifier">policy2</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
<span class="identifier">policy3</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
</pre>
@@ -306,7 +317,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
We have here our C++ class:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">X</span>
<span class="special">{</span>
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
<span class="special">{</span>
@@ -333,7 +345,8 @@ Namespaces are one honking great idea -- let's do more of those!
Class X has 4 overloaded functions. We will start by introducing some member
function pointer variables:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<pre class="programlisting">
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
@@ -341,7 +354,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
With these in hand, we can proceed to define and wrap this for Python:
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
@@ -355,26 +369,30 @@ Namespaces are one honking great idea -- let's do more of those!
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
with default arguments:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
</pre>
<p>
But the type of a pointer to the function <tt class="literal">f</tt> has no information
about its default arguments:
</p>
<pre class="programlisting"><span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
<pre class="programlisting">
<span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
</span></pre>
<p>
When we pass this function pointer to the <tt class="literal">def</tt> function,
there is no way to retrieve the default arguments:
</p>
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
</span></pre>
<p>
Because of this, when wrapping C++ code, we had to resort to manual wrapping
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
or writing thin wrappers:
</p>
<pre class="programlisting"><span class="comment">// write "thin wrappers"
<pre class="programlisting">
<span class="comment">// write "thin wrappers"
</span><span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
@@ -397,13 +415,14 @@ Namespaces are one honking great idea -- let's do more of those!
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h2>
<a name="id467317"></a>
<a name="id466276"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h2>
<p>
Boost.Python now has a way to make it easier. For instance, given a function:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
@@ -411,7 +430,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
The macro invocation:
</p>
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
</pre>
<p>
will automatically create the thin wrappers for us. This macro will create
@@ -421,10 +441,11 @@ Namespaces are one honking great idea -- let's do more of those!
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
function will automatically add all the foo variants for us:
</p>
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
</pre>
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
<a name="id467632"></a>
<a name="id466594"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h2>
<p>
@@ -439,7 +460,8 @@ Namespaces are one honking great idea -- let's do more of those!
may be used to automatically create the thin wrappers for wrapping member
functions. Let's have an example:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">george</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">george</span>
<span class="special">{</span>
<span class="keyword">void</span>
<span class="identifier">wack_em</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">=</span> <span class="char">'x'</span><span class="special">)</span>
@@ -451,7 +473,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
The macro invocation:
</p>
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
</pre>
<p>
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
@@ -460,14 +483,15 @@ Namespaces are one honking great idea -- let's do more of those!
in a class named <tt class="literal">george_overloads</tt> that can then be used
as an argument to <tt class="literal">def(...)</tt>:
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
</pre>
<p>
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
reference</a> for details.
</p>
<a name="default_arguments.init_and_optional"></a><h2>
<a name="id467992"></a>
<a name="id466958"></a>
init and optional
</h2>
<p>
@@ -475,7 +499,8 @@ Namespaces are one honking great idea -- let's do more of those!
arguments or a sequence of overloads. Remember <tt class="literal">init&lt;...&gt;</tt>?
For example, given a class X with a constructor:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">X</span>
<span class="special">{</span>
<span class="identifier">X</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="char">'D'</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">c</span> <span class="special">=</span> <span class="string">"constructor"</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">);</span>
<span class="comment">/*...*/</span>
@@ -484,7 +509,8 @@ Namespaces are one honking great idea -- let's do more of those!
<p>
You can easily add this constructor to Boost.Python in one shot:
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
Notice the use of <tt class="literal">init&lt;...&gt;</tt> and <tt class="literal">optional&lt;...&gt;</tt>
@@ -500,7 +526,8 @@ Namespaces are one honking great idea -- let's do more of those!
used for overloaded functions and member functions with a common sequence
of initial arguments. Here is an example:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
@@ -524,19 +551,21 @@ Namespaces are one honking great idea -- let's do more of those!
Like in the previous section, we can generate thin wrappers for these overloaded
functions in one-shot:
</p>
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
</pre>
<p>
Then...
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
</pre>
<p>
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
</p>
<a name="auto_overloading.manual_wrapping"></a><h2>
<a name="id468767"></a>
<a name="id467739"></a>
Manual Wrapping
</h2>
<p>
@@ -555,18 +584,21 @@ Namespaces are one honking great idea -- let's do more of those!
to automatically wrap the first three of the <tt class="literal">def</tt>s and
manually wrap just the last. Here's how we'll do this:
</p>
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
</pre>
<p>
Create a member function pointers as above for both X::f overloads:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<pre class="programlisting">
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
</pre>
<p>
Then...
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
</pre>
</div>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -26,7 +26,7 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
<a name="hello.from_start_to_finish"></a><h2>
<a name="id388718"></a>
<a name="id386189"></a>
From Start To Finish
</h2>
<p>
@@ -92,7 +92,7 @@
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
</p>
<a name="hello.let_s_jam_"></a><h2>
<a name="id387300"></a>
<a name="id386347"></a>
Let's Jam!
</h2>
<p>
@@ -108,7 +108,7 @@
you going.
</p>
<a name="hello.running_bjam"></a><h2>
<a name="id387357"></a>
<a name="id386404"></a>
Running bjam
</h2>
<p>
@@ -156,7 +156,8 @@ using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
<p>
Finally:
</p>
<pre class="programlisting"><span class="identifier">bjam</span>
<pre class="programlisting">
<span class="identifier">bjam</span>
</pre>
<p>
It should be building now:
@@ -186,8 +187,7 @@ bjam
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
Starting from Boost 1.35, bjam erases the generated executables (e.g. pyd
file) after the test has concluded to conserve disk space. To keep bjam from
doing that, pass --preserve-test-targets to bjam.
file). To keep bjam from doing that, pass --preserve-test-targets to bjam.
</p></td></tr>
</table></div>
<div class="blockquote"><blockquote class="blockquote">

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -64,7 +64,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
<pre class="programlisting">
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
</span><span class="keyword">try</span><span class="special">:</span>
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
@@ -78,14 +79,16 @@
</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>
<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>
</pre>
<p>
Or for use in class_&lt;&gt;:
</p>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&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>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&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>
</pre>
<p>
<span class="bold"><b>range</b></span>
@@ -131,7 +134,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
<pre class="programlisting">
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
@@ -142,7 +146,8 @@
</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>
<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>
</pre>
@@ -158,7 +163,8 @@
</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>
<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>
@@ -177,7 +183,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
<pre class="programlisting">
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
</pre>
</div>

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -62,7 +62,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
<pre class="programlisting">
<span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
<span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
<span class="keyword">else</span><span class="special">:</span>
@@ -77,7 +78,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
<span class="keyword">else</span>
@@ -124,20 +126,23 @@
These derived <tt class="literal">object</tt> types act like real Python types.
For instance:
</p>
<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==&gt;</span> <span class="string">"1"</span>
<pre class="programlisting">
<span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==&gt;</span> <span class="string">"1"</span>
</pre>
<p>
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
has a <tt class="literal">keys()</tt> method:
</p>
<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
<pre class="programlisting">
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
</pre>
<p>
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
Example:
</p>
<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
</pre>
<p>
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
@@ -145,7 +150,8 @@
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
instances of Python's <tt class="literal">str</tt> type and subtypes.
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()
</span> <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better
@@ -155,13 +161,15 @@
<p>
In finer detail:
</p>
<pre class="programlisting"><span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
<pre class="programlisting">
<span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
</pre>
<p>
Illustrates that we provide versions of the str type's methods as C++ member
functions.
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
</pre>
<p>
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
@@ -176,17 +184,19 @@
<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__
<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__
<pre class="programlisting">
<span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
</span></pre>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
<a name="id470756"></a>
<a name="id469744"></a>
class_&lt;T&gt; as objects
</h2>
<p>
@@ -197,7 +207,8 @@
<p>
We can use this to create wrapped instances. Example:
</p>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&gt;(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span>
@@ -214,14 +225,16 @@
can be achieved with the <tt class="literal">extract&lt;T&gt;</tt> function. Consider
the following:
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
<pre class="programlisting">
<span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
</span></pre>
<p>
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
we wanted to do above can be achieved by writing:
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
<pre class="programlisting">
<span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
<span class="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;(</span><span class="identifier">o</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
</pre>
@@ -238,7 +251,8 @@
be extracted, an appropriate exception is thrown. To avoid an exception,
we need to test for extractibility:
</p>
<pre class="programlisting"><span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
<pre class="programlisting">
<span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
<span class="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
</pre>
@@ -246,7 +260,8 @@
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:
</p>
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&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>
<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>
</div>
@@ -261,12 +276,14 @@
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
to enums). To illustrate, given a C++ enum:
</p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
<pre class="programlisting">
<span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
</pre>
<p>
the construct:
</p>
<pre class="programlisting"><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">choice</span><span class="special">&gt;(</span><span class="string">"choice"</span><span class="special">)</span>
<pre class="programlisting">
<span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">choice</span><span class="special">&gt;(</span><span class="string">"choice"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
<span class="special">;</span>
@@ -298,7 +315,8 @@
</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>
<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>
<p>
@@ -307,7 +325,8 @@
</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>
<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>

View File

@@ -11,10 +11,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -53,7 +53,8 @@
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
like so:
</p>
<pre class="programlisting"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
<pre class="programlisting">
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span>
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span>
</pre>
@@ -61,14 +62,16 @@
We would like to present this same hierarchy to the Python user, allowing
him to write code like this:
</p>
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<pre class="programlisting">
<span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function
</span></pre>
<p>
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:
</p>
<pre class="programlisting"><span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
<pre class="programlisting">
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
@@ -126,7 +129,8 @@
</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>
<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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">new_sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)</span>
@@ -148,7 +152,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">/* file core.cpp */</span>
<pre class="programlisting">
<span class="comment">/* file core.cpp */</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
@@ -180,7 +185,8 @@
</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>
<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>
<p>
@@ -190,13 +196,15 @@
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
</p>
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
</pre>
<p>
We do the same for the other packages. Now the user accesses the functions
and classes in the extension modules like before:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<pre class="programlisting">
<span class="special">&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">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span>
</pre>
<p>
@@ -209,7 +217,8 @@
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
function:
</p>
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
<pre class="programlisting">
<span class="keyword">import</span> <span class="identifier">_filters</span>
<span class="keyword">def</span> <span class="identifier">echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span>
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
@@ -218,13 +227,15 @@
<p>
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
</p>
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
</pre>
<p>
And that's it. The user now accesses this function like any other function
from the <tt class="literal">filters</tt> package:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<pre class="programlisting">
<span class="special">&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">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
</pre>
</div>
@@ -235,7 +246,8 @@
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:
</p>
<pre class="programlisting"><span class="special">&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>
<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>
@@ -258,7 +270,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
<span class="special">{</span>
@@ -271,7 +284,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
<span class="comment"># a regular function
</span><span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
@@ -303,7 +317,8 @@
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
</p>
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.
<pre class="programlisting">
<span class="comment"># The one Boost.Python uses for all wrapped classes.
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
</span><span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
@@ -326,7 +341,8 @@
<p>
Now let's see how it got:
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
<span class="identifier">Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span>
<span class="identifier">foo</span><span class="special">!</span>
@@ -334,7 +350,8 @@
<p>
Another useful idea is to replace constructors with factory functions:
</p>
<pre class="programlisting"><span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
<pre class="programlisting">
<span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
<span class="keyword">def</span> <span class="identifier">point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span>
<span class="keyword">return</span> <span class="identifier">_point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span>
@@ -357,7 +374,8 @@
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
<pre class="programlisting">
<span class="comment">/* file point.cpp */</span>
<span class="preprocessor">#include</span> <span class="special">&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>
@@ -379,7 +397,8 @@
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
macro, and call the various export functions inside it.
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">();</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
@@ -392,7 +411,8 @@
Compiling and linking together all this files produces the same result as
the usual approach:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&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>
<pre class="programlisting">
<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>
<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">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>

View File

@@ -1,5 +1,5 @@
[library python
[version 2.0]
[version 1.0]
[authors [de Guzman, Joel], [Abrahams, David]]
[copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
[category inter-language support]
@@ -186,10 +186,6 @@ And so on... Finally:
Or something similar. If all is well, you should now have built the DLLs and
run the Python program.
[note Starting from Boost 1.35, bjam erases the generated executables
(e.g. pyd file) after the test has concluded to conserve disk space.
To keep bjam from doing that, pass --preserve-test-targets to bjam.]
[:[*There you go... Have fun!]]
[endsect]
@@ -1385,10 +1381,10 @@ interpreter. This may be fixed in a future version of boost.python.]
[section Using the interpreter]
As you probably already know, objects in Python are reference-counted.
Naturally, the [^PyObject]s of the Python C API are also reference-counted.
Naturally, the [^PyObject]s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully
automatic in Python, the Python C API requires you to do it
[@http://www.python.org/doc/current/c-api/refcounting.html by hand]. This is
automatic in Python, the Python/C API requires you to do it
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and
[@../../../v2/object.html object] class templates to automate the process.
@@ -1470,7 +1466,7 @@ If an exception occurs in the evaluation of the python expression,
The [^error_already_set] exception class doesn't carry any information in itself.
To find out more about the Python exception that occurred, you need to use the
[@http://www.python.org/doc/api/exceptionHandling.html exception handling functions]
of the Python C API in your catch-statement. This can be as simple as calling
of the Python/C API in your catch-statement. This can be as simple as calling
[@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to
print the exception's traceback to the console, or comparing the type of the
exception with those of the [@http://www.python.org/doc/api/standardExceptions.html

View File

@@ -11,8 +11,8 @@
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../../../LICENSE_1_0.txt">
accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>
</html>

View File

@@ -137,7 +137,7 @@
<td valign="top"><code>P::extract_return_type</code></td>
<td>A model of <a href=
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a>.</td>
"../../../doc/refmanual/metafunction.html">Metafunction</a>.</td>
<td>An MPL unary <a href=
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>

View File

@@ -4,7 +4,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Dereferenceable Concept</title>
</head>
<body link="#0000ff" vlink="#800080">

View File

@@ -4,7 +4,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Extractor Concept</title>
</head>
<body link="#0000ff" vlink="#800080">

View File

@@ -4,7 +4,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Holder Concept</title>
</head>
<body link="#0000ff" vlink="#800080">

View File

@@ -74,32 +74,6 @@
</dl>
</dd>
<dt><a href="#const_objattribute_policies-spec">Class
<code>const_objattribute_policies</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#const_objattribute_policies-spec-synopsis">Class
<code>const_objattribute_policies</code> synopsis</a></dt>
<dt><a href="#const_objattribute_policies-spec-statics">Class
<code>const_objattribute_policies</code> static functions</a></dt>
</dl>
</dd>
<dt><a href="#objattribute_policies-spec">Class
<code>objattribute_policies</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#objattribute_policies-spec-synopsis">Class
<code>objattribute_policies</code> synopsis</a></dt>
<dt><a href="#objattribute_policies-spec-statics">Class
<code>objattribute_policies</code> static functions</a></dt>
</dl>
</dd>
<dt><a href="#const_item_policies-spec">Class
<code>const_item_policies</code></a></dt>
@@ -354,102 +328,6 @@ static void del(object const&amp;target, char const* key);
<!-- end -->
<!-- begin -->
<h3><a name="const_objattribute_policies-spec"></a>Class
<code>const_objattribute_policies</code></h3>
<p>The policies which are used for proxies representing an attribute
access to a <code>const&nbsp;object</code> when the attribute name is
given as a <code>const&nbsp;object</code>.</p>
<h4><a name="const_objattribute_policies-spec-synopsis"></a>Class
<code>const_objattribute_policies</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace api
{
struct const_objattribute_policies
{
typedef object const& key_type;
static object get(object const&amp; target, object const& key);
};
}}}
</pre>
<h4><a name="const_objattribute_policies-spec-statics"></a>Class
<code>const_objattribute_policies</code> static functions</h4>
<pre>
static object get(object const&amp; target, object const& key);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
holding a string.</dt>
<dt><b>Effects:</b> accesses the attribute of <code>target</code> named
by <code>key</code>.</dt>
<dt><b>Returns:</b> An <code>object</code> managing the result of the
attribute access.</dt>
<dt><b>Throws:</b> <code><a href=
"errors.html#error_already_set-spec">error_already_set</a></code> if a
Python exception is raised.</dt>
</dl>
<h3><a name="objattribute_policies-spec"></a>Class
<code>objattribute_policies</code></h3>
<p>The policies which are used for proxies representing an attribute
access to a mutable <code>object</code> when the attribute name is
given as a <code>const&nbsp;object</code>.</p>
<h4><a name="objattribute_policies-spec-synopsis"></a>Class
<code>objattribute_policies</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace api
{
struct objattribute_policies : const_objattribute_policies
{
static object const&amp; set(object const&amp; target, object const& key, object const&amp; value);
static void del(object const&amp;target, object const& key);
};
}}}
</pre>
<h4><a name="objattribute_policies-spec-statics"></a>Class
<code>objattribute_policies</code> static functions</h4>
<pre>
static object const&amp; set(object const&amp; target, object const& key, object const&amp; value);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
holding a string.</dt>
<dt><b>Effects:</b> sets the attribute of <code>target</code> named by
<code>key</code> to <code>value</code>.</dt>
<dt><b>Throws:</b> <code><a href=
"errors.html#error_already_set-spec">error_already_set</a></code> if a
Python exception is raised.</dt>
</dl>
<pre>
static void del(object const&amp;target, object const& key);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
holding a string.</dt>
<dt><b>Effects:</b> deletes the attribute of <code>target</code> named
by <code>key</code>.</dt>
<dt><b>Throws:</b> <code><a href=
"errors.html#error_already_set-spec">error_already_set</a></code> if a
Python exception is raised.</dt>
</dl>
<!-- end -->
<!-- begin -->
<h3><a name="const_item_policies-spec"></a>Class
<code>const_item_policies</code></h3>
@@ -655,11 +533,6 @@ namespace boost { namespace python { namespace api
template &lt;class A0, class A1,...class An&gt;
object operator()(A0 const&amp;, A1 const&amp;,...An const&amp;) const;
detail::args_proxy operator* () const;
object operator()(detail::args_proxy const &amp;args) const;
object operator()(detail::args_proxy const &amp;args,
detail::kwds_proxy const &amp;kwds) const;
// truth value testing
//
typedef unspecified bool_type;
@@ -669,8 +542,6 @@ namespace boost { namespace python { namespace api
//
proxy&lt;const_object_attribute&gt; attr(char const*) const;
proxy&lt;object_attribute&gt; attr(char const*);
proxy&lt;const_object_objattribute&gt; attr(object const&) const;
proxy&lt;object_objattribute&gt; attr(object const&);
// item access
//
@@ -709,25 +580,6 @@ object operator()(A0 const&amp; a1, A1 const&amp; a2,...An const&amp; aN) const;
call&lt;object&gt;(object(*static_cast&lt;U*&gt;(this)).ptr(), a1,
a2,...aN)</dt>
</dl>
<pre>
object operator()(detail::args_proxy const &amp;args) const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
call object with arguments given by the tuple <varname>args</varname></dt>
</dl>
<pre>
object operator()(detail::args_proxy const &amp;args,
detail::kwds_proxy const &amp;kwds) const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
call object with arguments given by the tuple <varname>args</varname>, and named
arguments given by the dictionary <varname>kwds</varname></dt>
</dl>
<pre>
operator bool_type() const;
</pre>
@@ -756,21 +608,6 @@ proxy&lt;object_attribute&gt; attr(char const* name);
<code>name</code> as its key.</dt>
</dl>
<pre>
proxy&lt;const_object_objattribute&gt; attr(const object& name) const;
proxy&lt;object_objattribute&gt; attr(const object& name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> name is a <code>object</code> holding a string.</dt>
<dt><b>Effects:</b> accesses the named attribute of
<code>*this</code>.</dt>
<dt><b>Returns:</b> a proxy object which binds
<code>object(*static_cast&lt;U*&gt;(this))</code> as its target, and
<code>name</code> as its key.</dt>
</dl>
<pre>
template &lt;class T&gt;
proxy&lt;const_object_item&gt; operator[](T const&amp; key) const;
template &lt;class T&gt;
@@ -1101,11 +938,11 @@ object sum_items(object seq)
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
27 May, 2008
13 January, 2006
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2008.</i></p>
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2006.</i></p>
</body>
</html>

View File

@@ -1,93 +1,112 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Boost.Python Pickle Support</title>
</head>
<title>Boost.Python Pickle Support</title>
<body>
<div>
<img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"center" width="277" height="86" />
<hr />
<div>
<h1>Boost.Python Pickle Support</h1>Pickle is a Python module for object
serialization, also known as persistence, marshalling, or flattening.
<img src="../../../../boost.png"
alt="boost.png (6897 bytes)"
align="center"
width="277" height="86">
<p>It is often necessary to save and restore the contents of an object to
a file. One approach to this problem is to write a pair of functions that
read and write data from a file in a special format. A powerful
alternative approach is to use Python's pickle module. Exploiting
Python's ability for introspection, the pickle module recursively
converts nearly arbitrary Python objects into a stream of bytes that can
be written to a file.</p>
<hr>
<h1>Boost.Python Pickle Support</h1>
<p>The Boost Python Library supports the pickle module through the
interface as described in detail in the <a href=
"http://www.python.org/doc/current/lib/module-pickle.html">Python Library
Reference for pickle.</a> This interface involves the special methods
<tt>__getinitargs__</tt>, <tt>__getstate__</tt> and <tt>__setstate__</tt>
as described in the following. Note that Boost.Python is also fully
compatible with Python's cPickle module.</p>
<hr />
Pickle is a Python module for object serialization, also known
as persistence, marshalling, or flattening.
<h2>The Boost.Python Pickle Interface</h2>At the user level, the
Boost.Python pickle interface involves three special methods:
<p>
It is often necessary to save and restore the contents of an object to
a file. One approach to this problem is to write a pair of functions
that read and write data from a file in a special format. A powerful
alternative approach is to use Python's pickle module. Exploiting
Python's ability for introspection, the pickle module recursively
converts nearly arbitrary Python objects into a stream of bytes that
can be written to a file.
<dl>
<dt><strong><tt>__getinitargs__</tt></strong></dt>
<p>
The Boost Python Library supports the pickle module
through the interface as described in detail in the
<a href="http://www.python.org/doc/current/lib/module-pickle.html"
>Python Library Reference for pickle.</a> This interface
involves the special methods <tt>__getinitargs__</tt>,
<tt>__getstate__</tt> and <tt>__setstate__</tt> as described
in the following. Note that Boost.Python is also fully compatible
with Python's cPickle module.
<dd>
When an instance of a Boost.Python extension class is pickled, the
pickler tests if the instance has a <tt>__getinitargs__</tt> method.
This method must return a Python tuple (it is most convenient to use
a boost::python::tuple). When the instance is restored by the
unpickler, the contents of this tuple are used as the arguments for
the class constructor.
<hr>
<h2>The Boost.Python Pickle Interface</h2>
<p>If <tt>__getinitargs__</tt> is not defined, <tt>pickle.load</tt>
will call the constructor (<tt>__init__</tt>) without arguments;
i.e., the object must be default-constructible.</p>
</dd>
At the user level, the Boost.Python pickle interface involves three special
methods:
<dt><strong><tt>__getstate__</tt></strong></dt>
<dl>
<dt>
<strong><tt>__getinitargs__</tt></strong>
<dd>
When an instance of a Boost.Python extension class is pickled, the
pickler tests if the instance has a <tt>__getinitargs__</tt> method.
This method must return a Python tuple (it is most convenient to use
a boost::python::tuple). When the instance is restored by the
unpickler, the contents of this tuple are used as the arguments for
the class constructor.
<dd>When an instance of a Boost.Python extension class is pickled, the
pickler tests if the instance has a <tt>__getstate__</tt> method. This
method should return a Python object representing the state of the
instance.</dd>
<p>
If <tt>__getinitargs__</tt> is not defined, <tt>pickle.load</tt>
will call the constructor (<tt>__init__</tt>) without arguments;
i.e., the object must be default-constructible.
<dt><strong><tt>__setstate__</tt></strong></dt>
<p>
<dt>
<strong><tt>__getstate__</tt></strong>
<dd>When an instance of a Boost.Python extension class is restored by
the unpickler (<tt>pickle.load</tt>), it is first constructed using the
result of <tt>__getinitargs__</tt> as arguments (see above).
Subsequently the unpickler tests if the new instance has a
<tt>__setstate__</tt> method. If so, this method is called with the
result of <tt>__getstate__</tt> (a Python object) as the argument.</dd>
</dl>The three special methods described above may be <tt>.def()</tt>'ed
individually by the user. However, Boost.Python provides an easy to use
high-level interface via the
<strong><tt>boost::python::pickle_suite</tt></strong> class that also
enforces consistency: <tt>__getstate__</tt> and <tt>__setstate__</tt>
must be defined as pairs. Use of this interface is demonstrated by the
following examples.
<hr />
<dd>
When an instance of a Boost.Python extension class is pickled, the
pickler tests if the instance has a <tt>__getstate__</tt> method.
This method should return a Python object representing the state of
the instance.
<h2>Examples</h2>There are three files in <tt>boost/libs/python/test</tt>
that show how to provide pickle support.
<hr />
<p>
<dt>
<strong><tt>__setstate__</tt></strong>
<h3><a href="../../test/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>The C++
class in this example can be fully restored by passing the appropriate
argument to the constructor. Therefore it is sufficient to define the
pickle interface method <tt>__getinitargs__</tt>. This is done in the
following way:
<dd>
When an instance of a Boost.Python extension class is restored by the
unpickler (<tt>pickle.load</tt>), it is first constructed using the
result of <tt>__getinitargs__</tt> as arguments (see above). Subsequently
the unpickler tests if the new instance has a <tt>__setstate__</tt>
method. If so, this method is called with the result of
<tt>__getstate__</tt> (a Python object) as the argument.
<ul>
<li>1. Definition of the C++ pickle function:
<pre>
</dl>
The three special methods described above may be <tt>.def()</tt>'ed
individually by the user. However, Boost.Python provides an easy to use
high-level interface via the
<strong><tt>boost::python::pickle_suite</tt></strong> class that also
enforces consistency: <tt>__getstate__</tt> and <tt>__setstate__</tt>
must be defined as pairs. Use of this interface is demonstrated by the
following examples.
<hr>
<h2>Examples</h2>
There are three files in
<tt>boost/libs/python/test</tt> that show how to
provide pickle support.
<hr>
<h3><a href="../../test/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>
The C++ class in this example can be fully restored by passing the
appropriate argument to the constructor. Therefore it is sufficient
to define the pickle interface method <tt>__getinitargs__</tt>.
This is done in the following way:
<ul>
<li>1. Definition of the C++ pickle function:
<pre>
struct world_pickle_suite : boost::python::pickle_suite
{
static
@@ -98,28 +117,26 @@
}
};
</pre>
</li>
<li>2. Establishing the Python binding:
<pre>
<li>2. Establishing the Python binding:
<pre>
class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
// ...
.def_pickle(world_pickle_suite())
// ...
</pre>
</li>
</ul>
<hr />
</ul>
<h3><a href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>The C++
class in this example contains member data that cannot be restored by any
of the constructors. Therefore it is necessary to provide the
<tt>__getstate__</tt>/<tt>__setstate__</tt> pair of pickle interface
methods:
<hr>
<h3><a href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>
<ul>
<li>1. Definition of the C++ pickle functions:
<pre>
The C++ class in this example contains member data that cannot be
restored by any of the constructors. Therefore it is necessary to
provide the <tt>__getstate__</tt>/<tt>__setstate__</tt> pair of
pickle interface methods:
<ul>
<li>1. Definition of the C++ pickle functions:
<pre>
struct world_pickle_suite : boost::python::pickle_suite
{
static
@@ -144,76 +161,92 @@
}
};
</pre>
</li>
<li>2. Establishing the Python bindings for the entire suite:
<pre>
<li>2. Establishing the Python bindings for the entire suite:
<pre>
class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
// ...
.def_pickle(world_pickle_suite())
// ...
</pre>
</li>
</ul>
</ul>
<p>For simplicity, the <tt>__dict__</tt> is not included in the result of
<tt>__getstate__</tt>. This is not generally recommended, but a valid
approach if it is anticipated that the object's <tt>__dict__</tt> will
always be empty. Note that the safety guard described below will catch
the cases where this assumption is violated.</p>
<hr />
<p>
For simplicity, the <tt>__dict__</tt> is not included in the result
of <tt>__getstate__</tt>. This is not generally recommended, but a
valid approach if it is anticipated that the object's
<tt>__dict__</tt> will always be empty. Note that the safety guard
described below will catch the cases where this assumption is violated.
<h3><a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>This
example is similar to <a href=
"../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the object's
<tt>__dict__</tt> is included in the result of <tt>__getstate__</tt>.
This requires a little more code but is unavoidable if the object's
<tt>__dict__</tt> is not always empty.
<hr />
<hr>
<h3><a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>
<h2>Pitfall and Safety Guard</h2>The pickle protocol described above has
an important pitfall that the end user of a Boost.Python extension module
might not be aware of:
This example is similar to <a
href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the
object's <tt>__dict__</tt> is included in the result of
<tt>__getstate__</tt>. This requires a little more code but is
unavoidable if the object's <tt>__dict__</tt> is not always empty.
<p><strong><tt>__getstate__</tt> is defined and the instance's
<tt>__dict__</tt> is not empty.</strong></p>
<hr>
<h2>Pitfall and Safety Guard</h2>
<p>The author of a Boost.Python extension class might provide a
<tt>__getstate__</tt> method without considering the possibilities
that:</p>
The pickle protocol described above has an important pitfall that the
end user of a Boost.Python extension module might not be aware of:
<p>
<strong>
<tt>__getstate__</tt> is defined and the instance's <tt>__dict__</tt>
is not empty.
</strong>
<p>
<ul>
<li>his class is used in Python as a base class. Most likely the
<tt>__dict__</tt> of instances of the derived class needs to be pickled
in order to restore the instances correctly.</li>
The author of a Boost.Python extension class might provide a
<tt>__getstate__</tt> method without considering the possibilities
that:
<li>the user adds items to the instance's <tt>__dict__</tt> directly.
Again, the <tt>__dict__</tt> of the instance then needs to be
pickled.</li>
</ul>
<p>
<ul>
<li>
his class is used in Python as a base class. Most likely the
<tt>__dict__</tt> of instances of the derived class needs to be
pickled in order to restore the instances correctly.
<p>To alert the user to this highly unobvious problem, a safety guard is
provided. If <tt>__getstate__</tt> is defined and the instance's
<tt>__dict__</tt> is not empty, Boost.Python tests if the class has an
attribute <tt>__getstate_manages_dict__</tt>. An exception is raised if
this attribute is not defined:</p>
<pre>
<p>
<li>
the user adds items to the instance's <tt>__dict__</tt> directly.
Again, the <tt>__dict__</tt> of the instance then needs to be
pickled.
</ul>
<p>
To alert the user to this highly unobvious problem, a safety guard is
provided. If <tt>__getstate__</tt> is defined and the instance's
<tt>__dict__</tt> is not empty, Boost.Python tests if the class has
an attribute <tt>__getstate_manages_dict__</tt>. An exception is
raised if this attribute is not defined:
<pre>
RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
</pre>To resolve this problem, it should first be established that the <tt>
__getstate__</tt> and <tt>__setstate__</tt> methods manage the
instances's <tt>__dict__</tt> correctly. Note that this can be done
either at the C++ or the Python level. Finally, the safety guard should
intentionally be overridden. E.g. in C++ (from <a href=
"../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a>):
<pre>
</pre>
To resolve this problem, it should first be established that the
<tt>__getstate__</tt> and <tt>__setstate__</tt> methods manage the
instances's <tt>__dict__</tt> correctly. Note that this can be done
either at the C++ or the Python level. Finally, the safety guard
should intentionally be overridden. E.g. in C++ (from
<a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a>):
<pre>
struct world_pickle_suite : boost::python::pickle_suite
{
// ...
static bool getstate_manages_dict() { return true; }
};
</pre>Alternatively in Python:
<pre>
</pre>
Alternatively in Python:
<pre>
import your_bpl_module
class your_class(your_bpl_module.your_class):
__getstate_manages_dict__ = 1
@@ -222,41 +255,54 @@
def __setstate__(self, state):
# your code here
</pre>
<hr />
<h2>Practical Advice</h2>
<hr>
<h2>Practical Advice</h2>
<ul>
<li>In Boost.Python extension modules with many extension classes,
providing complete pickle support for all classes would be a
significant overhead. In general complete pickle support should only be
implemented for extension classes that will eventually be pickled.</li>
<ul>
<li>
In Boost.Python extension modules with many extension classes,
providing complete pickle support for all classes would be a
significant overhead. In general complete pickle support should
only be implemented for extension classes that will eventually
be pickled.
<li>Avoid using <tt>__getstate__</tt> if the instance can also be
reconstructed by way of <tt>__getinitargs__</tt>. This automatically
avoids the pitfall described above.</li>
<p>
<li>
Avoid using <tt>__getstate__</tt> if the instance can also be
reconstructed by way of <tt>__getinitargs__</tt>. This automatically
avoids the pitfall described above.
<li>If <tt>__getstate__</tt> is required, include the instance's
<tt>__dict__</tt> in the Python object that is returned.</li>
</ul>
<hr />
<p>
<li>
If <tt>__getstate__</tt> is required, include the instance's
<tt>__dict__</tt> in the Python object that is returned.
<h2>Light-weight alternative: pickle support implemented in Python</h2>
</ul>
<h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>The
<tt>pickle4.cpp</tt> example demonstrates an alternative technique for
implementing pickle support. First we direct Boost.Python via the
<tt>class_::enable_pickling()</tt> member function to define only the
basic attributes required for pickling:
<pre>
<hr>
<h2>Light-weight alternative: pickle support implemented in Python</h2>
<h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>
The <tt>pickle4.cpp</tt> example demonstrates an alternative technique
for implementing pickle support. First we direct Boost.Python via
the <tt>class_::enable_pickling()</tt> member function to define only
the basic attributes required for pickling:
<pre>
class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
// ...
.enable_pickling()
// ...
</pre>This enables the standard Python pickle interface as described in the
Python documentation. By "injecting" a <tt>__getinitargs__</tt> method into
the definition of the wrapped class we make all instances pickleable:
<pre>
</pre>
This enables the standard Python pickle interface as described
in the Python documentation. By &quot;injecting&quot; a
<tt>__getinitargs__</tt> method into the definition of the wrapped
class we make all instances pickleable:
<pre>
# import the wrapped world class
from pickle4_ext import world
@@ -266,15 +312,18 @@ the definition of the wrapped class we make all instances pickleable:
# now inject __getinitargs__ (Python is a dynamic language!)
world.__getinitargs__ = world_getinitargs
</pre>See also the <a href=
"../tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python">
tutorial section</a> on injecting additional methods from Python.
<hr />
© Copyright Ralf W. Grosse-Kunstleve 2001-2004. Distributed under the
Boost Software License, Version 1.0. (See accompanying file
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</pre>
<p>Updated: Feb 2004.</p>
</div>
</body>
</html>
See also the
<a href="../tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python"
>tutorial section</a> on injecting additional methods from Python.
<hr>
&copy; Copyright Ralf W. Grosse-Kunstleve 2001-2004. Distributed under
the Boost Software License, Version 1.0. (See accompanying file
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<p>
Updated: Feb 2004.
</div>

View File

@@ -38,10 +38,7 @@ namespace boost { namespace python {
# endif // CALL_DWA2002411_HPP
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call.hpp)
@@ -79,5 +76,4 @@ call(PyObject* callable
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -37,10 +37,7 @@ namespace boost { namespace python {
# endif // CALL_METHOD_DWA2002411_HPP
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
@@ -79,5 +76,4 @@ call_method(PyObject* self, char const* name
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif // BOOST_PP_IS_ITERATING

View File

@@ -117,9 +117,9 @@ struct rvalue_from_python_data : rvalue_from_python_storage<T>
// Implementataions
//
template <class T>
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& _stage1)
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1)
{
this->stage1 = _stage1;
this->stage1 = stage1;
}
template <class T>

View File

@@ -45,14 +45,10 @@ struct shared_ptr_from_python
if (data->convertible == source)
new (storage) shared_ptr<T>();
else
{
boost::shared_ptr<void> hold_convertible_ref_count(
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
// use aliasing constructor
new (storage) shared_ptr<T>(
hold_convertible_ref_count,
static_cast<T*>(data->convertible));
}
static_cast<T*>(data->convertible),
shared_ptr_deleter(handle<>(borrowed(source)))
);
data->convertible = storage;
}

View File

@@ -265,8 +265,7 @@ inline object make_getter(D const& d, Policies const& policies)
template <class D>
inline object make_getter(D& x)
{
detail::not_specified policy
= detail::not_specified(); // suppress a SunPro warning
detail::not_specified policy;
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
}
@@ -274,8 +273,7 @@ inline object make_getter(D& x)
template <class D>
inline object make_getter(D const& d)
{
detail::not_specified policy
= detail::not_specified(); // Suppress a SunPro warning
detail::not_specified policy;
return detail::make_getter(d, policy, is_member_pointer<D>(), 0L);
}
# endif

View File

@@ -86,10 +86,7 @@ result(X const&, short = 0) { return 0; }
# endif // RESULT_DWA2002521_HPP
/* --------------- function pointers --------------- */
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers))
@@ -131,5 +128,4 @@ boost::type<R>* result(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0)
# undef N
# undef Q
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -37,10 +37,7 @@ T& (* target(R (T::*)) )() { return 0; }
# endif // TARGET_DWA2002521_HPP
/* --------------- function pointers --------------- */
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers))
@@ -82,5 +79,4 @@ T& (* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) )()
# undef N
# undef Q
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -41,7 +41,7 @@ inline enum_<T>::enum_(char const* name, char const* doc )
, &enum_<T>::convertible_from_python
, &enum_<T>::construct
, type_id<T>()
, doc
, doc
)
{
}

View File

@@ -14,16 +14,6 @@
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# if defined(BOOST_MSVC) && (BOOST_MSVC == 1400) /*
> warning C4180: qualifier applied to function type has no meaning; ignored
Peter Dimov wrote:
This warning is caused by an overload resolution bug in VC8 that cannot be
worked around and will probably not be fixed by MS in the VC8 line. The
problematic overload is only instantiated and never called, and the code
works correctly. */
# pragma warning(disable: 4180)
# endif
# include <boost/bind.hpp>
# include <boost/bind/protect.hpp>

View File

@@ -105,12 +105,12 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
#if defined _MSC_VER && _MSC_VER < 1300
typedef is_same<
typedef is_same<
typename BasePolicy_::result_converter
, default_result_converter
> same_result_converter;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
#else
BOOST_MPL_ASSERT_MSG(
(is_same<

View File

@@ -236,7 +236,7 @@ struct class_metadata
//
// Support for converting smart pointers to python
//
inline static void maybe_register_pointer_to_python(...) {}
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)

View File

@@ -47,10 +47,7 @@ template <int nargs> struct make_holder;
# endif // MAKE_HOLDER_DWA20011215_HPP
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, make_holder.hpp)
@@ -105,5 +102,4 @@ struct make_holder<N>
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -127,14 +127,7 @@ void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
)
return &this->m_p;
Value* p
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
= static_cast<Value*>( get_pointer(this->m_p) )
# else
= get_pointer(this->m_p)
# endif
;
Value* p = get_pointer(this->m_p);
if (p == 0)
return 0;
@@ -170,10 +163,7 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
# endif // POINTER_HOLDER_DWA20011215_HPP
/* --------------- pointer_holder --------------- */
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
@@ -215,5 +205,4 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -117,10 +117,7 @@ void* value_holder_back_reference<Value,Held>::holds(
// --------------- value_holder ---------------
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder))
@@ -166,5 +163,4 @@ void* value_holder_back_reference<Value,Held>::holds(
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

@@ -17,7 +17,6 @@ struct const_attribute_policies
{
typedef char const* key_type;
static object get(object const& target, char const* key);
static object get(object const& target, object const& key);
};
struct attribute_policies : const_attribute_policies
@@ -26,18 +25,6 @@ struct attribute_policies : const_attribute_policies
static void del(object const&target, char const* key);
};
struct const_objattribute_policies
{
typedef object const key_type;
static object get(object const& target, object const& key);
};
struct objattribute_policies : const_objattribute_policies
{
static object const& set(object const& target, object const& key, object const& value);
static void del(object const&target, object const& key);
};
//
// implementation
//
@@ -55,30 +42,11 @@ inline const_object_attribute object_operators<U>::attr(char const* name) const
return const_object_attribute(x, name);
}
template <class U>
inline object_objattribute object_operators<U>::attr(object const& name)
{
object_cref2 x = *static_cast<U*>(this);
return object_objattribute(x, name);
}
template <class U>
inline const_object_objattribute object_operators<U>::attr(object const& name) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_objattribute(x, name);
}
inline object const_attribute_policies::get(object const& target, char const* key)
{
return python::getattr(target, key);
}
inline object const_objattribute_policies::get(object const& target, object const& key)
{
return python::getattr(target, key);
}
inline object const& attribute_policies::set(
object const& target
, char const* key
@@ -88,15 +56,6 @@ inline object const& attribute_policies::set(
return value;
}
inline object const& objattribute_policies::set(
object const& target
, object const& key
, object const& value)
{
python::setattr(target, key, value);
return value;
}
inline void attribute_policies::del(
object const& target
, char const* key)
@@ -104,13 +63,6 @@ inline void attribute_policies::del(
python::delattr(target, key);
}
inline void objattribute_policies::del(
object const& target
, object const& key)
{
python::delattr(target, key);
}
}}} // namespace boost::python::api
#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP

View File

@@ -42,12 +42,6 @@
namespace boost { namespace python {
namespace detail
{
class kwds_proxy;
class args_proxy;
}
namespace converter
{
template <class T> struct arg_to_python;
@@ -65,8 +59,6 @@ namespace api
struct const_attribute_policies;
struct attribute_policies;
struct const_objattribute_policies;
struct objattribute_policies;
struct const_item_policies;
struct item_policies;
struct const_slice_policies;
@@ -75,8 +67,6 @@ namespace api
typedef proxy<const_attribute_policies> const_object_attribute;
typedef proxy<attribute_policies> object_attribute;
typedef proxy<const_objattribute_policies> const_object_objattribute;
typedef proxy<objattribute_policies> object_objattribute;
typedef proxy<const_item_policies> const_object_item;
typedef proxy<item_policies> object_item;
typedef proxy<const_slice_policies> const_object_slice;
@@ -108,11 +98,6 @@ namespace api
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
# include BOOST_PP_ITERATE()
detail::args_proxy operator* () const;
object operator()(detail::args_proxy const &args) const;
object operator()(detail::args_proxy const &args,
detail::kwds_proxy const &kwds) const;
// truth value testing
//
@@ -123,8 +108,6 @@ namespace api
//
const_object_attribute attr(char const*) const;
object_attribute attr(char const*);
const_object_objattribute attr(object const&) const;
object_objattribute attr(object const&);
// item access
//
@@ -230,11 +213,11 @@ namespace api
inline object_base(object_base const&);
inline object_base(PyObject* ptr);
inline object_base& operator=(object_base const& rhs);
inline ~object_base();
object_base& operator=(object_base const& rhs);
~object_base();
// Underlying object access -- returns a borrowed reference
inline PyObject* ptr() const;
PyObject* ptr() const;
private:
PyObject* m_ptr;
@@ -404,7 +387,7 @@ namespace api
static PyObject*
get(T const& x, U)
{
return python::incref(get_managed_object(x, boost::python::tag));
return python::incref(get_managed_object(x, tag));
}
};
@@ -427,62 +410,6 @@ template <class T> struct extract;
// implementation
//
namespace detail
{
class call_proxy
{
public:
call_proxy(object target) : m_target(target) {}
operator object() const { return m_target;}
private:
object m_target;
};
class kwds_proxy : public call_proxy
{
public:
kwds_proxy(object o = object()) : call_proxy(o) {}
};
class args_proxy : public call_proxy
{
public:
args_proxy(object o) : call_proxy(o) {}
kwds_proxy operator* () const { return kwds_proxy(*this);}
};
}
template <typename U>
detail::args_proxy api::object_operators<U>::operator* () const
{
object_cref2 x = *static_cast<U const*>(this);
return boost::python::detail::args_proxy(x);
}
template <typename U>
object api::object_operators<U>::operator()(detail::args_proxy const &args) const
{
U const& self = *static_cast<U const*>(this);
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
args.operator object().ptr(),
0);
return object(boost::python::detail::new_reference(result));
}
template <typename U>
object api::object_operators<U>::operator()(detail::args_proxy const &args,
detail::kwds_proxy const &kwds) const
{
U const& self = *static_cast<U const*>(this);
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
args.operator object().ptr(),
kwds.operator object().ptr());
return object(boost::python::detail::new_reference(result));
}
inline object::object()
: object_base(python::incref(Py_None))
{}

View File

@@ -10,11 +10,9 @@
# include <boost/python/object_protocol_core.hpp>
# include <boost/python/object_core.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace api {
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
# if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
// attempt to use SFINAE to prevent functions accepting T const& from
// coming up as ambiguous with the one taking a char const* when a
// string literal is passed
@@ -24,45 +22,45 @@ namespace boost { namespace python { namespace api {
# endif
template <class Target, class Key>
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getattr(object(target), object(key));
}
template <class Target, class Key, class Default>
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(Key))
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getattr(object(target), object(key), object(default_));
}
template <class Key, class Value>
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
{
setattr(target, object(key), object(value));
}
template <class Key>
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
delattr(target, object(key));
}
template <class Target, class Key>
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getitem(object(target), object(key));
}
template <class Key, class Value>
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
{
setitem(target, object(key), object(value));
}
template <class Key>
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
delitem(target, object(key));
}

View File

@@ -27,12 +27,6 @@ struct slice_policies : const_slice_policies
static void del(object const& target, key_type const& key);
};
template <class T, class U>
inline slice_policies::key_type slice_key(T x, U y)
{
return slice_policies::key_type(handle<>(x), handle<>(y));
}
//
// implementation
//
@@ -41,7 +35,7 @@ object_slice
object_operators<U>::slice(object_cref start, object_cref finish)
{
object_cref2 x = *static_cast<U*>(this);
return object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
}
template <class U>
@@ -49,7 +43,7 @@ const_object_slice
object_operators<U>::slice(object_cref start, object_cref finish) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
}
template <class U>
@@ -57,7 +51,7 @@ object_slice
object_operators<U>::slice(slice_nil, object_cref finish)
{
object_cref2 x = *static_cast<U*>(this);
return object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
}
template <class U>
@@ -65,7 +59,7 @@ const_object_slice
object_operators<U>::slice(slice_nil, object_cref finish) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
}
template <class U>
@@ -73,7 +67,7 @@ object_slice
object_operators<U>::slice(slice_nil, slice_nil)
{
object_cref2 x = *static_cast<U*>(this);
return object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
return object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
}
template <class U>
@@ -81,7 +75,7 @@ const_object_slice
object_operators<U>::slice(slice_nil, slice_nil) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
}
template <class U>
@@ -89,7 +83,7 @@ object_slice
object_operators<U>::slice(object_cref start, slice_nil)
{
object_cref2 x = *static_cast<U*>(this);
return object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
}
template <class U>
@@ -97,7 +91,7 @@ const_object_slice
object_operators<U>::slice(object_cref start, slice_nil) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
}
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
template <class U>

View File

@@ -8,7 +8,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
// Based on boost/ref.hpp, thus:
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001 Peter Dimov
# if _MSC_VER+0 >= 1020

View File

@@ -113,10 +113,7 @@ struct most_derived
# endif // SIGNATURE_JDG20020813_HPP
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
# define N BOOST_PP_ITERATION()
@@ -179,5 +176,4 @@ get_signature(
# undef Q
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif // !defined(BOOST_PP_IS_ITERATING)

View File

@@ -7,12 +7,9 @@
#ifndef PY_CONTAINER_UTILS_JDG20038_HPP
# define PY_CONTAINER_UTILS_JDG20038_HPP
# include <utility>
# include <boost/foreach.hpp>
# include <boost/python/object.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/extract.hpp>
# include <boost/python/stl_iterator.hpp>
namespace boost { namespace python { namespace container_utils {
@@ -22,13 +19,11 @@ namespace boost { namespace python { namespace container_utils {
{
typedef typename Container::value_type data_type;
// l must be iterable
BOOST_FOREACH(object elem,
std::make_pair(
boost::python::stl_input_iterator<object>(l),
boost::python::stl_input_iterator<object>()
))
// l must be a list or some container
for (int i = 0; i < l.attr("__len__")(); i++)
{
object elem(l[i]);
extract<data_type const&> x(elem);
// try if elem is an exact data_type type
if (x.check())

View File

@@ -11,7 +11,6 @@
# include <boost/operators.hpp>
# include <typeinfo>
# include <cstring>
# include <ostream>
# include <boost/static_assert.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/same_traits.hpp>

View File

@@ -68,9 +68,8 @@ struct with_custodian_and_ward : BasePolicy_
bool result = BasePolicy_::precall(args_);
if (!result) {
if (!result)
Py_DECREF(life_support);
}
return result;
}

View File

@@ -1,3 +0,0 @@
boost_module(python DEPENDS graph numeric)
# numeric is there because of boost/cast.hpp from libs/python/src/errors.cpp:11

View File

@@ -1,64 +0,0 @@
if (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON)
# We have detected that there might be Python debug libraries
# available, but check for ourselves whether this is true by trying
# to compile/link a program against them.
set(CMAKE_REQUIRED_DEFINITIONS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG")
get_directory_property(CMAKE_REQUIRED_INCLUDES INCLUDE_DIRECTORIES)
set(CMAKE_REQUIRED_LIBRARIES ${PYTHON_DEBUG_LIBRARIES})
set(CHECK_PYDEBUG_SOURCE
"#include <boost/python/object.hpp>")
check_cxx_source_compiles(
"#include <boost/python/object.hpp>
void check(PyObject *obj) { Py_INCREF(obj); } int main() { }"
PYDEBUG_CAN_BUILD)
# Setup an option to enable/disable building variants with Python
# debugging. If we were able to link against the debug libraries,
# default to ON; otherwise, default to OFF.
option(BUILD_PYTHON_DEBUG
"Build an additional Boost.Python library with Python debugging enabled"
${PYDEBUG_CAN_BUILD})
endif (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON)
# Always build the non-debug variants of the boost_python library
set(BUILD_PYTHON_NODEBUG ON)
boost_add_library(boost_python
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
STATIC_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE -DBOOST_PYTHON_STATIC_LIB"
SHARED_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE"
PYTHON_NODEBUG_LINK_LIBS "${PYTHON_LIBRARIES}"
# Support for Python debugging
EXTRA_VARIANTS PYTHON_NODEBUG:PYTHON_DEBUG
PYTHON_DEBUG_COMPILE_FLAGS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG"
PYTHON_DEBUG_LINK_LIBS "${PYTHON_DEBUG_LIBRARIES}"
)

View File

@@ -99,13 +99,8 @@ namespace
if (number_methods == 0)
return 0;
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
? &number_methods->nb_int : 0;
return (PyInt_Check(obj) || PyLong_Check(obj))
? &number_methods->nb_int : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
@@ -140,11 +135,7 @@ namespace
if (number_methods == 0)
return 0;
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
return (PyInt_Check(obj) || PyLong_Check(obj))
? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
@@ -235,11 +226,7 @@ namespace
{
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
#else
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
#endif
}
static bool extract(PyObject* intermediate)

View File

@@ -29,7 +29,7 @@ namespace
detail::new_reference dict_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyDict_Type, const_cast<char*>("(O)"),
(PyObject*)&PyDict_Type, "(O)",
arg_.ptr());
}

View File

@@ -41,10 +41,6 @@ BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
{
PyErr_SetString(PyExc_IndexError, x.what());
}
catch(const std::invalid_argument& x)
{
PyErr_SetString(PyExc_ValueError, x.what());
}
catch(const std::exception& x)
{
PyErr_SetString(PyExc_RuntimeError, x.what());

View File

@@ -39,7 +39,7 @@ object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
// Let python open the file to avoid potential binary incompatibilities.
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
PyObject *pyfile = PyFile_FromString(f, "r");
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
python::handle<> file(pyfile);
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),

View File

@@ -13,7 +13,7 @@ detail::new_non_null_reference list_base::call(object const& arg_)
return (detail::new_non_null_reference)
(expect_non_null)(
PyObject_CallFunction(
(PyObject*)&PyList_Type, const_cast<char*>("(O)"),
(PyObject*)&PyList_Type, "(O)",
arg_.ptr()));
}

View File

@@ -9,21 +9,21 @@ namespace boost { namespace python { namespace detail {
new_non_null_reference long_base::call(object const& arg_)
{
return (detail::new_non_null_reference)PyObject_CallFunction(
(PyObject*)&PyLong_Type, const_cast<char*>("(O)"),
(PyObject*)&PyLong_Type, "(O)",
arg_.ptr());
}
new_non_null_reference long_base::call(object const& arg_, object const& base)
{
return (detail::new_non_null_reference)PyObject_CallFunction(
(PyObject*)&PyLong_Type, const_cast<char*>("(OO)"),
(PyObject*)&PyLong_Type, "(OO)",
arg_.ptr(), base.ptr());
}
long_base::long_base()
: object(
detail::new_reference(
PyObject_CallFunction((PyObject*)&PyLong_Type, const_cast<char*>("()")))
PyObject_CallFunction((PyObject*)&PyLong_Type, "()"))
)
{}

View File

@@ -74,7 +74,7 @@ extern "C"
{
propertyobject *gs = (propertyobject *)self;
return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
return PyObject_CallFunction(gs->prop_get, "()");
}
static int
@@ -95,9 +95,9 @@ extern "C"
return -1;
}
if (value == NULL)
res = PyObject_CallFunction(func, const_cast<char*>("()"));
res = PyObject_CallFunction(func, "()");
else
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
res = PyObject_CallFunction(func, "(O)", value);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -108,7 +108,7 @@ extern "C"
static PyTypeObject static_data_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
const_cast<char*>("Boost.Python.StaticProperty"),
"Boost.Python.StaticProperty",
PyType_Type.tp_basicsize,
0,
0, /* tp_dealloc */
@@ -212,7 +212,7 @@ extern "C"
static PyTypeObject class_metatype_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
const_cast<char*>("Boost.Python.class"),
"Boost.Python.class",
PyType_Type.tp_basicsize,
0,
0, /* tp_dealloc */
@@ -316,7 +316,7 @@ namespace objects
{
// Attempt to find the __instance_size__ attribute. If not present, no problem.
PyObject* d = type_->tp_dict;
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
@@ -357,20 +357,20 @@ namespace objects
static PyGetSetDef instance_getsets[] = {
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
{"__dict__", instance_get_dict, instance_set_dict, NULL, 0},
{0, 0, 0, 0, 0}
};
static PyMemberDef instance_members[] = {
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
{0, 0, 0, 0, 0}
};
static PyTypeObject class_type_object = {
PyObject_HEAD_INIT(0) //&class_metatype_object)
0,
const_cast<char*>("Boost.Python.instance"),
"Boost.Python.instance",
offsetof(instance<>,storage), /* tp_basicsize */
1, /* tp_itemsize */
instance_dealloc, /* tp_dealloc */
@@ -572,7 +572,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
this->setattr(name, property);
}
@@ -582,7 +582,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
this->setattr(name, property);
}
@@ -591,7 +591,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr()));
PyObject_CallFunction(static_data(), "O", fget.ptr()));
this->setattr(name, property);
}
@@ -600,7 +600,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
this->setattr(name, property);
}
@@ -615,13 +615,13 @@ namespace objects
{
extern "C" PyObject* no_init(PyObject*, PyObject*)
{
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
return NULL;
}
static ::PyMethodDef no_init_def = {
const_cast<char*>("__init__"), no_init, METH_VARARGS,
const_cast<char*>("Raises an exception\n"
"This class cannot be instantiated from Python\n")
"__init__", no_init, METH_VARARGS,
"Raises an exception\n"
"This class cannot be instantiated from Python\n"
};
}
@@ -650,7 +650,7 @@ namespace objects
::PyErr_Format(
PyExc_TypeError
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
, "staticmethod expects callable object; got an object of type %s, which is not callable"
, callable->ob_type->tp_name
);

View File

@@ -23,7 +23,7 @@ struct enum_object
};
static PyMemberDef enum_members[] = {
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
{"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
{0, 0, 0, 0, 0}
};
@@ -32,7 +32,7 @@ extern "C"
{
static PyObject* enum_repr(PyObject* self_)
{
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
@@ -65,7 +65,7 @@ extern "C"
static PyTypeObject enum_type_object = {
PyObject_HEAD_INIT(0) // &PyType_Type
0,
const_cast<char*>("Boost.Python.enum"),
"Boost.Python.enum",
sizeof(enum_object), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */

View File

@@ -297,7 +297,7 @@ object function::signatures(bool show_return_type) const
void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
{
static handle<> exception(
PyErr_NewException(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0));
object message = "Python argument types in\n %s.%s("
% make_tuple(this->m_namespace, this->m_name);
@@ -440,7 +440,7 @@ void function::add_to_namespace(
else if (PyType_Check(ns))
dict = ((PyTypeObject*)ns)->tp_dict;
else
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
dict = PyObject_GetAttrString(ns, "__dict__");
if (dict == 0)
throw_error_already_set();
@@ -487,7 +487,7 @@ void function::add_to_namespace(
new_func->m_name = name;
handle<> name_space_name(
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__")));
if (name_space_name)
new_func->m_namespace = object(name_space_name);
@@ -656,18 +656,18 @@ extern "C"
}
static PyGetSetDef function_getsetlist[] = {
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{"__name__", (getter)function_get_name, 0, 0, 0 },
{"func_name", (getter)function_get_name, 0, 0, 0 },
{"__class__", (getter)function_get_class, 0, 0, 0 }, // see note above
{"__doc__", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{"func_doc", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{NULL, 0, 0, 0, 0} /* Sentinel */
};
PyTypeObject function_type = {
PyObject_HEAD_INIT(0)
0,
const_cast<char*>("Boost.Python.function"),
"Boost.Python.function",
sizeof(function),
0,
(destructor)function_dealloc, /* tp_dealloc */
@@ -753,8 +753,7 @@ namespace detail
}
void BOOST_PYTHON_DECL pure_virtual_called()
{
PyErr_SetString(
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called");
throw_error_already_set();
}
}

View File

@@ -10,7 +10,7 @@
#endif
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map.hpp>
#include <boost/bind.hpp>
#include <boost/integer_traits.hpp>
#include <boost/tuple/tuple.hpp>

View File

@@ -38,7 +38,7 @@ extern "C"
PyTypeObject life_support_type = {
PyObject_HEAD_INIT(0)//(&PyType_Type)
0,
const_cast<char*>("Boost.Python.life_support"),
"Boost.Python.life_support",
sizeof(life_support),
0,
life_support_dealloc, /* tp_dealloc */

View File

@@ -2,10 +2,6 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Credits:
// Andreas Kl\:ockner for fixing increment() to handle
// error conditions.
#include <boost/python/object.hpp>
#include <boost/python/handle.hpp>
@@ -31,8 +27,6 @@ void stl_input_iterator_impl::increment()
{
this->ob_ = boost::python::handle<>(
boost::python::allow_null(PyIter_Next(this->it_.ptr())));
if (PyErr_Occurred())
throw boost::python::error_already_set();
}
bool stl_input_iterator_impl::equal(stl_input_iterator_impl const &that) const

View File

@@ -10,7 +10,7 @@ namespace boost { namespace python { namespace detail {
detail::new_reference str_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyString_Type, const_cast<char*>("(O)"),
(PyObject*)&PyString_Type, "(O)",
arg_.ptr());
}
@@ -68,9 +68,8 @@ str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const
return str(new_reference( \
expect_non_null( \
PyObject_CallMethod( \
this->ptr(), const_cast<char*>( #name ), \
const_cast<char*>( \
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
this->ptr(), #name, \
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
}

View File

@@ -9,7 +9,7 @@ namespace boost { namespace python { namespace detail {
detail::new_reference tuple_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyTuple_Type, const_cast<char*>("(O)"),
(PyObject*)&PyTuple_Type, "(O)",
arg_.ptr());
}

View File

@@ -1,207 +0,0 @@
macro(bpl_test TESTNAME)
parse_arguments(BPL_TEST
"ARGS"
""
${ARGN})
# Determine the Python and C++ source files for this test
if (BPL_TEST_DEFAULT_ARGS)
# First argument is the Python source we will run, the rest are
# either extra Python sources we're dependent on or C++ files from
# which we will build extension modules.
car(BPL_TEST_PYSOURCE ${BPL_TEST_DEFAULT_ARGS})
cdr(BPL_TEST_DEFAULT_ARGS ${BPL_TEST_DEFAULT_ARGS})
get_filename_component(BPL_TEST_PYBASE ${BPL_TEST_PYSOURCE} NAME_WE)
foreach(SRC ${BPL_TEST_DEFAULT_ARGS})
get_filename_component(BPL_SRC_EXT ${SRC} EXT)
if (BPL_SRC_EXT STREQUAL ".cpp")
# Build a Python extension module from this source file
get_filename_component(BPL_SRC_NAME ${SRC} NAME_WE)
if(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
boost_python_extension(${BPL_SRC_NAME}_ext ${SRC})
else(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
boost_python_extension(${BPL_SRC_NAME} ${SRC})
endif(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
endif (BPL_SRC_EXT STREQUAL ".cpp")
endforeach(SRC ${BPL_TEST_DEFAULT_ARGS})
else (BPL_TEST_DEFAULT_ARGS)
set(BPL_TEST_PYSOURCE "${TESTNAME}.py")
# Build a Python extension module from this source file
boost_python_extension(${TESTNAME}_ext "${TESTNAME}.cpp")
endif(BPL_TEST_DEFAULT_ARGS)
# We'll need the full patch to run the Python test
set(BPL_TEST_PYSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${BPL_TEST_PYSOURCE})
# Run the test itself
file(TO_NATIVE_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" PYTHONPATH)
if(WIN32 AND NOT UNIX)
string(REPLACE "\\" "\\\\" PYTHONPATH "${PYTHONPATH}")
endif(WIN32 AND NOT UNIX)
set(FULL_TESTNAME ${PROJECT_NAME}-${TESTNAME})
add_test(${FULL_TESTNAME}
${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/pyrun.py"
"${PYTHONPATH}"
${BPL_TEST_PYSOURCE} ${BPL_TEST_ARGS})
set_tests_properties(${FULL_TESTNAME}
PROPERTIES
LABELS "${PROJECT_NAME}"
)
endmacro(bpl_test)
macro(py_run TESTNAME)
boost_test_run(${TESTNAME}
${TESTNAME}.cpp
DEPENDS boost_python STATIC
LINK_LIBS ${PYTHON_LIBRARIES})
endmacro(py_run)
boost_test_run(exec
DEPENDS boost_python STATIC
ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py"
LINK_LIBS ${PYTHON_LIBRARIES})
boost_test_run(exec-dynamic
exec.cpp
ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py"
DEPENDS boost_python SHARED
LINK_LIBS ${PYTHON_LIBRARIES})
bpl_test(crossmod_exception
crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp)
bpl_test(injected)
bpl_test(properties)
bpl_test(return_arg)
bpl_test(staticmethod)
bpl_test(shared_ptr)
bpl_test(andreas_beyer)
bpl_test(polymorphism)
bpl_test(polymorphism2)
bpl_test(wrapper_held_type)
bpl_test(polymorphism2_auto_ptr)
bpl_test(auto_ptr)
bpl_test(minimal)
bpl_test(args)
bpl_test(raw_ctor)
bpl_test(numpy numpy.py printer.py numeric_tests.py numarray_tests.py numpy.cpp)
bpl_test(enum)
bpl_test(exception_translator)
bpl_test(pearu1 test_cltree.py cltree.cpp)
bpl_test(try newtest.py m1.cpp m2.cpp)
bpl_test(const_argument)
bpl_test(keywords keywords_test.py keywords.cpp)
boost_python_extension(builtin_converters_ext test_builtin_converters.cpp)
bpl_test(builtin_converters test_builtin_converters.py builtin_converters_ext)
#
# See the contents of this file for more details on an existing
# overload resoluton bug.
#
# boost_python_extension(overload_resolution test_overload_resolution.cpp)
#
bpl_test(test_pointer_adoption)
bpl_test(operators)
bpl_test(callbacks)
bpl_test(defaults)
bpl_test(object)
bpl_test(list)
bpl_test(long)
bpl_test(dict)
bpl_test(tuple)
bpl_test(str)
bpl_test(slice)
bpl_test(virtual_functions)
bpl_test(back_reference)
bpl_test(implicit)
bpl_test(data_members)
bpl_test(ben_scott1)
bpl_test(bienstman1)
bpl_test(bienstman2)
bpl_test(bienstman3)
bpl_test(multi_arg_constructor)
# TODO: A bug in the Win32 intel compilers causes compilation of one
# of our tests to take forever when debug symbols are
# enabled. This rule turns them off when added to the requirements
# section
# <toolset>intel-win:<debug-symbols>off
bpl_test(iterator iterator.py iterator.cpp input_iterator.cpp)
bpl_test(stl_iterator stl_iterator.py stl_iterator.cpp)
bpl_test(extract)
bpl_test (crossmod_opaque
crossmod_opaque.py crossmod_opaque_a.cpp crossmod_opaque_b.cpp)
bpl_test(opaque)
bpl_test(voidptr)
bpl_test(pickle1)
bpl_test(pickle2)
bpl_test(pickle3)
bpl_test(pickle4)
bpl_test(nested)
bpl_test(docstring)
bpl_test(vector_indexing_suite)
bpl_test(pointer_vector)
# TODO: Turn off this test on HP CXX, as the test hangs when executing.
# Whenever the cause for the failure of the polymorphism test is found
# and fixed, this should be retested.
# <toolset>hp_cxx:<build>no
boost_python_extension(map_indexing_suite_ext
map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp)
bpl_test(map_indexing_suite
map_indexing_suite.py map_indexing_suite_ext)
# --- unit tests of library components ---
boost_test_compile(indirect_traits_test)
boost_test_run(destroy_test)
py_run(pointer_type_id_test)
py_run(bases)
boost_test_run(if_else)
py_run(pointee)
boost_test_run(result)
boost_test_compile(string_literal)
boost_test_compile(borrowed)
boost_test_compile(object_manager)
boost_test_compile(copy_ctor_mutates_rhs)
py_run(upcast)
boost_test_compile(select_holder)
boost_test_run(select_from_python_test
select_from_python_test.cpp ../src/converter/type_id.cpp
COMPILE_FLAGS "-DBOOST_PYTHON_STATIC_LIB"
LINK_LIBS ${PYTHON_LIBRARIES})
boost_test_compile(select_arg_to_python_test)
boost_test_compile_fail(raw_pyobject_fail1)
boost_test_compile_fail(raw_pyobject_fail2)
boost_test_compile_fail(as_to_python_function)
boost_test_compile_fail(object_fail1)

View File

@@ -42,7 +42,7 @@ test-suite python
:
[
run exec.cpp /boost/python//boost_python/<link>static $(PY)
run exec.cpp ../build//boost_python/<link>static $(PY)
: # program args
: exec.py # input files
: # requirements
@@ -75,7 +75,6 @@ bpl-test crossmod_exception
[ bpl-test return_arg ]
[ bpl-test staticmethod ]
[ bpl-test shared_ptr ]
[ bpl-test enable_shared_from_this ]
[ bpl-test andreas_beyer ]
[ bpl-test polymorphism ]
[ bpl-test polymorphism2 ]
@@ -172,8 +171,7 @@ bpl-test crossmod_opaque
/boost/python//boost_python ]
[ bpl-test
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
[ py-run import_.cpp : import_.py ]
# if $(TEST_BIENSTMAN_NON_BUGS)
# {

View File

@@ -25,8 +25,8 @@ class B {
B() {
a = A::A_ptr(new A());
}
void set(A::A_ptr _a) {
this->a = _a;
void set(A::A_ptr a) {
this->a = a;
}
A::A_ptr get() {
return a;

View File

@@ -14,7 +14,7 @@
using namespace boost::python;
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
# define make_tuple boost::python::make_tuple
#endif

View File

@@ -27,7 +27,7 @@ struct X
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private:

View File

@@ -34,7 +34,7 @@ struct X
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private:

View File

@@ -19,10 +19,10 @@ struct complicated
int n;
};
inline complicated::complicated(simple const&s, int _n)
: s(s.s), n(_n)
inline complicated::complicated(simple const&s, int n)
: s(s.s), n(n)
{
std::cout << "constructing complicated: " << this->s << ", " << _n << std::endl;
std::cout << "constructing complicated: " << this->s << ", " << n << std::endl;
}
inline complicated::~complicated()

View File

@@ -1,48 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/def.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include "test_class.hpp"
#include <memory>
using namespace boost::python;
using boost::shared_ptr;
class Test;
typedef shared_ptr<Test> TestPtr;
class Test : public boost::enable_shared_from_this<Test> {
public:
static TestPtr construct() {
return TestPtr(new Test);
}
void act() {
TestPtr kungFuDeathGrip(shared_from_this());
}
void take(TestPtr t) {
}
};
BOOST_PYTHON_MODULE(enable_shared_from_this_ext)
{
class_<Test, TestPtr, boost::noncopyable>("Test")
.def("construct", &Test::construct).staticmethod("construct")
.def("act", &Test::act)
.def("take", &Test::take)
;
}
#include "module_tail.cpp"

View File

@@ -1,26 +0,0 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from enable_shared_from_this_ext import *
>>> x = Test.construct()
>>> x.take(x)
>>> x.act()
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
status = run()[0]
if (status == 0): print "Done."
sys.exit(status)

View File

@@ -59,7 +59,7 @@ void eval_test()
void exec_test()
{
// Register the module with the interpreter
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"), initembedded_hello) == -1)
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
"builtin modules");
// Retrieve the main module

View File

@@ -34,7 +34,7 @@ struct NoddyObject : PyObject
PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0,
const_cast<char*>("Noddy"),
"Noddy",
sizeof(NoddyObject),
0,
dealloc, /* tp_dealloc */
@@ -106,7 +106,7 @@ struct extract_simple_object
PyTypeObject SimpleType = {
PyObject_HEAD_INIT(NULL)
0,
const_cast<char*>("Simple"),
"Simple",
sizeof(SimpleObject),
0,
dealloc, /* tp_dealloc */
@@ -159,7 +159,7 @@ PyTypeObject SimpleType = {
PyObject* new_simple()
{
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
simple->x.s = const_cast<char*>("hello, world");
simple->x.s = "hello, world";
return (PyObject*)simple;
}

View File

@@ -62,7 +62,7 @@ BOOST_PYTHON_MODULE(map_indexing_suite_ext)
void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
}
#include "module_tail.cpp"

View File

@@ -13,7 +13,6 @@
# endif
# ifdef _MSC_VER
# include <eh.h> // for _set_se_translator()
# pragma warning(push)
# pragma warning(disable:4297)
# pragma warning(disable:4535)

View File

@@ -10,16 +10,19 @@
#include <boost/python/str.hpp>
using namespace boost::python;
namespace py = boost::python;
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
# define make_tuple boost::python::make_tuple
#endif
// See if we can invoke array() from C++
numeric::array new_array()
{
return numeric::array(
py::make_tuple(
py::make_tuple(1,2,3)
, py::make_tuple(4,5,6)
, py::make_tuple(7,8,9)
make_tuple(
make_tuple(1,2,3)
, make_tuple(4,5,6)
, make_tuple(7,8,9)
)
);
}
@@ -48,7 +51,7 @@ namespace
str format("exception type: %sn");
format += "exception value: %sn";
format += "traceback:n%s" ;
object ret = format % py::make_tuple(ty, v, tr);
object ret = format % boost::python::make_tuple(ty, v, tr);
return ret;
}
}
@@ -68,7 +71,7 @@ namespace
// inherits that behavior from object.
void exercise(numeric::array& y, object check)
{
y[py::make_tuple(2,1)] = 3;
y[make_tuple(2,1)] = 3;
CHECK(y);
CHECK(y.astype('D'));
CHECK(y.copy());
@@ -113,12 +116,12 @@ void exercise_numarray(numeric::array& y, object check)
CHECK(y);
CHECK(y.type());
CHECK(y.factory(py::make_tuple(1.2, 3.4)));
CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8"));
CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true));
CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true, false));
CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true, false, object()));
CHECK (y.factory(py::make_tuple(1.2, 3.4), "f8", true, false, object(), py::make_tuple(1,2,1)));
CHECK(y.factory(make_tuple(1.2, 3.4)));
CHECK(y.factory(make_tuple(1.2, 3.4), "f8"));
CHECK(y.factory(make_tuple(1.2, 3.4), "f8", true));
CHECK(y.factory(make_tuple(1.2, 3.4), "f8", true, false));
CHECK(y.factory(make_tuple(1.2, 3.4), "f8", true, false, object()));
CHECK (y.factory(make_tuple(1.2, 3.4), "f8", true, false, object(), make_tuple(1,2,1)));
}

View File

@@ -38,61 +38,26 @@ object obj_getattr(object x, char const* name)
return x.attr(name);
}
object obj_objgetattr(object x, object const& name)
{
return x.attr(name);
}
object obj_const_getattr(object const& x, char const* name)
{
return x.attr(name);
}
object obj_const_objgetattr(object const& x, object const& name)
{
return x.attr(name);
}
void obj_setattr(object x, char const* name, object value)
{
x.attr(name) = value;
}
void obj_objsetattr(object x, object const& name, object value)
{
x.attr(name) = value;
}
void obj_setattr42(object x, char const* name)
{
x.attr(name) = 42;
}
void obj_objsetattr42(object x, object const& name)
{
x.attr(name) = 42;
}
void obj_moveattr(object& x, char const* src, char const* dst)
{
x.attr(dst) = x.attr(src);
}
void obj_objmoveattr(object& x, object const& src, object const& dst)
{
x.attr(dst) = x.attr(src);
}
void obj_delattr(object x, char const* name)
{
x.attr(name).del();
}
void obj_objdelattr(object x, object const& name)
{
x.attr(name).del();
}
object obj_getitem(object x, object key)
{
return x[key];
@@ -143,21 +108,11 @@ bool test_attr(object y, char* name)
return y.attr(name);
}
bool test_objattr(object y, object& name)
{
return y.attr(name);
}
bool test_not_attr(object y, char* name)
{
return !y.attr(name);
}
bool test_not_objattr(object y, object& name)
{
return !y.attr(name);
}
bool test_item(object y, object key)
{
return y[key];
@@ -187,11 +142,6 @@ bool check_string_slice()
return s.slice(2,-1).slice(1,-1) == "lo, wor";
}
object test_call(object c, object args, object kwds)
{
return c(*args, **kwds);
}
bool check_binary_operators()
{
int y;
@@ -351,17 +301,11 @@ BOOST_PYTHON_MODULE(object_ext)
def("number", number);
def("obj_getattr", obj_getattr);
def("obj_objgetattr", obj_objgetattr);
def("obj_const_getattr", obj_const_getattr);
def("obj_const_objgetattr", obj_const_objgetattr);
def("obj_setattr", obj_setattr);
def("obj_objsetattr", obj_objsetattr);
def("obj_setattr42", obj_setattr42);
def("obj_objsetattr42", obj_objsetattr42);
def("obj_moveattr", obj_moveattr);
def("obj_objmoveattr", obj_objmoveattr);
def("obj_delattr", obj_delattr);
def("obj_objdelattr", obj_objdelattr);
def("obj_getitem", obj_getitem);
def("obj_getitem3", obj_getitem);
@@ -375,14 +319,11 @@ BOOST_PYTHON_MODULE(object_ext)
def("test_not", test_not);
def("test_attr", test_attr);
def("test_objattr", test_objattr);
def("test_not_attr", test_not_attr);
def("test_not_objattr", test_not_objattr);
def("test_item", test_item);
def("test_not_item", test_not_item);
def("test_call", test_call);
def("check_binary_operators", check_binary_operators);
def("check_inplace", check_inplace);
def("check_string_slice", check_string_slice);

View File

@@ -34,68 +34,29 @@
>>> try: obj_getattr(x, 'foo')
... except AttributeError: pass
... else: print 'expected an exception'
>>> try: obj_objgetattr(x, 'objfoo')
... except AttributeError: pass
... else: print 'expected an exception'
>>> obj_setattr(x, 'foo', 1)
>>> x.foo
1
>>> obj_objsetattr(x, 'objfoo', 1)
>>> try:obj_objsetattr(x, 1)
... except TypeError: pass
... else: print 'expected an exception'
>>> x.objfoo
1
>>> obj_getattr(x, 'foo')
1
>>> obj_objgetattr(x, 'objfoo')
1
>>> try:obj_objgetattr(x, 1)
... except TypeError: pass
... else: print 'expected an exception'
>>> obj_const_getattr(x, 'foo')
1
>>> obj_const_objgetattr(x, 'objfoo')
1
>>> obj_setattr42(x, 'foo')
>>> x.foo
42
>>> obj_objsetattr42(x, 'objfoo')
>>> x.objfoo
42
>>> obj_moveattr(x, 'foo', 'bar')
>>> x.bar
42
>>> obj_objmoveattr(x, 'objfoo', 'objbar')
>>> x.objbar
42
>>> test_attr(x, 'foo')
1
>>> test_objattr(x, 'objfoo')
1
>>> test_not_attr(x, 'foo')
0
>>> test_not_objattr(x, 'objfoo')
0
>>> x.foo = None
>>> test_attr(x, 'foo')
0
>>> x.objfoo = None
>>> test_objattr(x, 'objfoo')
0
>>> test_not_attr(x, 'foo')
1
>>> test_not_objattr(x, 'objfoo')
1
>>> obj_delattr(x, 'foo')
>>> obj_objdelattr(x, 'objfoo')
>>> try:obj_delattr(x, 'foo')
... except AttributeError: pass
... else: print 'expected an exception'
>>> try:obj_objdelattr(x, 'objfoo')
... except AttributeError: pass
... else: print 'expected an exception'
Items
@@ -134,12 +95,7 @@
Operators
>>> def print_args(*args, **kwds):
... print args, kwds
>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
(0, 1, 2, 3) {'a': 'A'}
>>> assert check_binary_operators()
>>> class X: pass

View File

@@ -27,8 +27,8 @@ namespace boost_python_test {
private:
std::string country;
public:
world(const std::string& _country) {
this->country = _country;
world(const std::string& country) {
this->country = country;
}
std::string greet() const { return "Hello from " + country + "!"; }
std::string get_country() const { return country; }

View File

@@ -34,8 +34,8 @@ namespace boost_python_test {
class world
{
public:
world(const std::string& _country) : secret_number(0) {
this->country = _country;
world(const std::string& country) : secret_number(0) {
this->country = country;
}
std::string greet() const { return "Hello from " + country + "!"; }
std::string get_country() const { return country; }

View File

@@ -25,7 +25,7 @@
#include <boost/python/extract.hpp>
#include <boost/python/back_reference.hpp>
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
# define make_tuple boost::python::make_tuple
#endif
@@ -35,8 +35,8 @@ namespace boost_python_test {
class world
{
public:
world(const std::string& _country) : secret_number(0) {
this->country = _country;
world(const std::string& country) : secret_number(0) {
this->country = country;
}
std::string greet() const { return "Hello from " + country + "!"; }
std::string get_country() const { return country; }

View File

@@ -23,8 +23,8 @@ namespace boost_python_test {
private:
std::string country;
public:
world(const std::string& _country) {
this->country = _country;
world(const std::string& country) {
this->country = country;
}
std::string greet() const { return "Hello from " + country + "!"; }
std::string get_country() const { return country; }

View File

@@ -1,7 +0,0 @@
import sys
pythonpath = sys.argv[1]
scriptfile = sys.argv[2]
sys.argv = sys.argv[2:]
sys.path.append(pythonpath)
execfile(scriptfile)

View File

@@ -10,7 +10,7 @@
using namespace boost::python;
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
# define make_tuple boost::python::make_tuple
#endif
@@ -100,11 +100,7 @@ bool accept_slice( slice) { return true; }
|| BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
int check_slice_get_indicies(slice index);
#endif
int check_slice_get_indicies(
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
const
#endif
slice index)
int check_slice_get_indicies(const slice index)
{
// A vector of integers from [-5, 5].
std::vector<int> coll(11);

View File

@@ -20,7 +20,7 @@ struct X
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private:

View File

@@ -12,16 +12,6 @@
3
4
5
>>> def generator():
... yield 1
... yield 2
... raise RuntimeError, "oops"
>>> try:
... x.assign(iter(generator()))
... print "NOT OK"
... except RuntimeError:
... print "OK"
OK
'''
def run(args = None):
import sys

View File

@@ -13,7 +13,7 @@ struct test_class
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
virtual ~test_class() { BOOST_TEST(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_TEST(magic == 7654321 + n); this->x = _x; }
void set(int x) { BOOST_TEST(magic == 7654321 + n); this->x = x; }
int value() const { BOOST_TEST(magic == 7654321 + n); return x; }
operator int() const { return x; }
static int count() { return counter; }

View File

@@ -1,53 +0,0 @@
// Copyright Troy D. Straszheim 2009
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// example that shows problems with overloading and automatic conversion.
// if you call one of the below functions from python with bool/int/double,
// you'll see that the overload called is first match, not best match.
// See overload matching in luabind for an example of how to do this better.
//
// see this mail:
// http://mail.python.org/pipermail/cplusplus-sig/2009-March/014362.html
//
// This test isn't called by the cmake/jamfiles. For future use.
//
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <complex>
#include <boost/python/handle.hpp>
#include <boost/python/cast.hpp>
#include <boost/python/object.hpp>
#include <boost/python/detail/wrap_python.hpp>
using boost::python::def;
using boost::python::handle;
using boost::python::object;
using boost::python::borrowed;
std::string takes_bool(bool b) { return "bool"; }
std::string takes_int(int b) { return "int"; }
std::string takes_double(double b) { return "double"; }
BOOST_PYTHON_MODULE(overload_resolution)
{
def("bid", takes_bool);
def("bid", takes_int);
def("bid", takes_double);
def("dib", takes_double);
def("dib", takes_int);
def("dib", takes_bool);
def("idb", takes_int);
def("idb", takes_double);
def("idb", takes_bool);
def("bdi", takes_bool);
def("bdi", takes_double);
def("bdi", takes_int);
}

View File

@@ -65,7 +65,7 @@ struct B
B() : x(0) {}
B(A* x_) : x(x_) {}
inner const* adopt(A* _x) { this->x = _x; return &_x->get_inner(); }
inner const* adopt(A* x) { this->x = x; return &x->get_inner(); }
std::string a_content()
{

View File

@@ -321,19 +321,6 @@ e
>>> print_xvec(v)
[ a b c d e f g h i j ]
#####################################################################
# extend using a generator expression
#####################################################################
>>> v[:] = ['a','b','c','d','e'] # reset again
>>> def generator():
... addlist = ['f','g','h','i','j']
... for i in addlist:
... if i != 'g':
... yield i
>>> v.extend(generator())
>>> print_xvec(v)
[ a b c d e f h i j ]
#####################################################################
# vector of strings
#####################################################################

View File

@@ -22,7 +22,7 @@ struct X
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private: