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

Clean up Boost.Python v1 flotsam, update documentation, prepare for release

[SVN r15829]
This commit is contained in:
Dave Abrahams
2002-10-09 16:58:35 +00:00
parent 9e21275595
commit d5cfa0483a
22 changed files with 1102 additions and 1327 deletions

View File

@@ -1,222 +1,294 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Building an Extension Module</title>
<title>Boost.Python - Building and Testing</title>
</head>
<div>
<h1><img width="277" height="86" align="center" src=
"../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Building an
Extension Module</h1>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<h2>Building Boost.Python</h2>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<p>Every Boost.Python extension module must be linked with the
<code>boost_python</code> shared library. To build
<code>boost_python</code>, use <a
href="../../../tools/build/index.html">Boost.Build</a> in the
usual way from the <code>libs/python/build</code> subdirectory
of your boost installation (if you have already built boost from
the top level this may have no effect, since the work is already
done).
<h2 align="center">Building and Testing</h2>
</td>
</tr>
</table>
<hr>
<h3>Configuration</h3>
You may need to configure the following variables to point Boost.Build at your Python installation:
<h2>Contents</h2>
<dl class="Reference">
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#building">Building Boost.Python</a></dt>
<dd>
<dl class="index">
<dt><a href="#configuration">Configuration</a></dt>
<dt><a href="#results">Results</a></dt>
<dt><a href="#testing">Testing</a></dt>
</dl>
</dd>
<dt><a href="#building_ext">Building your Extension Module</a></dt>
<dt><a href="#variants">Build Variants</a></dt>
</dl>
<hr>
<h2><a name="requirements">Requirements</a></h2>
Boost.Python requires <a href="http://www.python.org">Python</a> 2.2 or
later.
<h2><a name="building">Building Boost.Python</a></h2>
<p>Every Boost.Python extension module must be linked with the
<code>boost_python</code> shared library. To build
<code>boost_python</code>, use <a href=
"../../../tools/build/index.html">Boost.Build</a> in the usual way from
the <code>libs/python/build</code> subdirectory of your boost
installation (if you have already built boost from the top level this may
have no effect, since the work is already done).</p>
<h3><a name="configuration">Configuration</a></h3>
You may need to configure the following variables to point Boost.Build at
your Python installation:
<table border="1" summary="build configuration variables">
<tr>
<th>Variable Name</th>
<th>Semantics</th>
<th>Default</th>
<th>Notes</th>
</tr>
<tr>
<td><code>PYTHON_ROOT</code></td>
<td>The root directory of your Python installation</td>
<table border="1">
<tr><th>Variable Name <th>Semantics <th>Default <th>Notes
<tr>
<td><code>PYTHON_ROOT</code>
<td>The root directory of your Python installation
<td>Windows:&nbsp;<code>c:/tools/python</code>
Unix:&nbsp;<code>/usr/local</code>
<td>On Unix, this is the <code>--with-prefix=</code> directory
used to configure Python
Unix:&nbsp;<code>/usr/local</code></td>
<td>On Unix, this is the <code>--with-prefix=</code> directory used
to configure Python</td>
</tr>
<tr>
<td><code>PYTHON_VERSION</code></td>
<td>The The 2-part python Major.Minor version number</td>
<td><code>2.2</code></td>
<tr>
<td><code>PYTHON_VERSION</code>
<td>The The 2-part python Major.Minor version number
<td>Windows:&nbsp;<code>2.1</code>
Unix:&nbsp;<code>1.5</code>
<td>Be sure not to include a third number, e.g. <b>not</b>
&quot;<code>2.2.1</code>&quot;, even if that's the version you
have.
"<code>2.2.1</code>", even if that's the version you have.</td>
</tr>
<tr>
<td><code>PYTHON_INCLUDES</code>
<td>path to Python <code>#include</code> directories
<td>Autoconfigured from <code>PYTHON_ROOT</code>
<tr>
<td><code>PYTHON_INCLUDES</code></td>
<tr>
<td><code>PYTHON_LIB_PATH</code>
<td>path to Python library object.
<td>Autoconfigured from <code>PYTHON_ROOT</code>
<td>path to Python <code>#include</code> directories</td>
<tr>
<td><code>PYTHON_STDLIB_PATH</code>
<td>path to Python standard library modules
<td>Autoconfigured from <code>PYTHON_ROOT</code>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>PYTHON_LIB_PATH</code></td>
<td>path to Python library object.</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>PYTHON_STDLIB_PATH</code></td>
<td>path to Python standard library modules</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_ROOT</code></td>
<td>path to the user's Cygwin installation</td>
<tr>
<td><code>CYGWIN_ROOT</code>
<td>path to the user's Cygwin installation
<td>
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the following two settings are
useful when building with multiple toolsets on Windows, since
Cygwin requires a different build of Python.
</td>
<tr>
<td><code>GCC_PYTHON_ROOT</code>
<td>path to the user's Cygwin Python installation
<td><code>$(CYGWIN_ROOT)/usr/local</code>
<td><a href="http://www.cygwin.com">Cygwin</a> only
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the
following two settings are useful when building with multiple
toolsets on Windows, since Cygwin requires a different build of
Python.</td>
</tr>
<tr>
<td><code>GCC_DEBUG_PYTHON_ROOT</code>
<td>path to the user's Cygwin <code><a
href="#variants">pydebug</a></code> build
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code>
<td><a href="http://www.cygwin.com">Cygwin</a> only
<tr>
<td><code>GCC_PYTHON_ROOT</code></td>
</table>
<td>path to the user's Cygwin Python installation</td>
<h3>Results</h3>
<p>The build process will create a
<code>libs/python/build/bin-stage</code> subdirectory of the
boost root (or of <code>$(ALL_LOCATE_TARGET)</code>,
if you have set that variable), containing the built
libraries. The libraries are actually built to unique
directories for each toolset and variant elsewhere in the
filesystem, and copied to the
<code>bin-stage</code> directory as a convenience, so if you
build with multiple toolsets at once, the product of later
toolsets will overwrite that of earlier toolsets in
<code>bin-stage</code>.
<td><code>$(CYGWIN_ROOT)/usr/local</code></td>
<h3>Testing</h3>
<p>To build and test Boost.Python from within the
<code>libs/python/build</code> directory, invoke
<blockquote>
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
<tr>
<td><code>GCC_DEBUG_PYTHON_ROOT</code></td>
<td>path to the user's Cygwin <code><a href=
"#variants">pydebug</a></code> build</td>
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code></td>
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
</table>
<h3><a name="results">Results</a></h3>
<p>The build process will create a
<code>libs/python/build/bin-stage</code> subdirectory of the boost root
(or of <code>$(ALL_LOCATE_TARGET)</code>, if you have set that variable),
containing the built libraries. The libraries are actually built to
unique directories for each toolset and variant elsewhere in the
filesystem, and copied to the <code>bin-stage</code> directory as a
convenience, so if you build with multiple toolsets at once, the product
of later toolsets will overwrite that of earlier toolsets in
<code>bin-stage</code>.</p>
<h3><a name="testing">Testing</a></h3>
<p>To build and test Boost.Python, start from the
<code>libs/python/test</code> directory and invoke</p>
<blockquote>
<pre>
bjam -sTOOLS=<i><a href="../../../tools/build/index.html#Tools">toolset</a></i> test
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> test
</pre>
</blockquote>
This will
update all of the Boost.Python v1 test and example targets. The tests
are relatively quiet by default. To get more-verbose output, you might try
<blockquote>
</blockquote>
This will update all of the Boost.Python v1 test and example targets. The
tests are relatively quiet by default. To get more-verbose output, you
might try
<blockquote>
<pre>
bjam -sTOOLS=<i><a href="../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
</pre>
</blockquote>
which will print each test's Python code with the expected output as
it passes.
</blockquote>
which will print each test's Python code with the expected output as it
passes.
<h2>Building your Extension Module</h2>
<h2><a name="building_ext">Building your Extension Module</a></h2>
Though there are other approaches, the easiest way to build an extension
module using Boost.Python is with Boost.Build. Until Boost.Build v2 is
released, cross-project build dependencies are not supported, so it works
most smoothly if you add a new subproject to your boost installation. The
<code>libs/python/example</code> subdirectory of your boost installation
contains a minimal example (along with many extra sources). To copy the
example subproject:
Though there are other approaches, the easiest way to build an
extension module using Boost.Python is with Boost.Build. Until
Boost.Build v2 is released, cross-project build dependencies are
not supported, so it works most smoothly if you add a new
subproject to your boost installation. The
<code>libs/python/example</code> subdirectory of your boost
installation contains a minimal example (along with many extra
sources). To copy the example subproject:
<ol>
<ol>
<li>Create a new subdirectory in, <code>libs/python</code>, say
<code>libs/python/my_project</code>.
<code>libs/python/my_project</code>.</li>
<li>Copy <code><a
href="../example/Jamfile">libs/python/example/Jamfile</a></code>
to your new directory.
<li>Copy <code><a href=
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
directory.</li>
<li>Edit the Jamfile as appropriate for your project. You'll
want to change the &quot;<code>subproject</code>&quot; rule
invocation at the top, and the names of some of the source files
and/or targets.
<li>Edit the Jamfile as appropriate for your project. You'll want to
change the "<code>subproject</code>" rule invocation at the top, and
the names of some of the source files and/or targets.</li>
</ol>
If you can't modify or copy your boost installation, the alternative is
to create your own Boost.Build project. A similar example you can use as
a starting point is available in <code><a href=
"../example/project.zip">this archive</a></code>. You'll need to edit the
Jamfile and Jamrules files, depending on the relative location of your
Boost installation and the new project. Note that automatic testing of
extension modules is not available in this configuration.
</ol>
<h2><a name="variants">Build Variants</a></h2>
Three <a href=
"../../../tools/build/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and can be
selected by setting the <code><a href=
"../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
variable:
If you can't modify or copy your boost installation, the
alternative is to create your own Boost.Build project. A similar
example you can use as a starting point is available in <code><a
href="../example/project.zip">this archive</a></code>. You'll
need to edit the Jamfile and Jamrules files, depending on the
relative location of your Boost installation and the new
project. Note that automatic testing of extension modules is not
available in this configuration.
<ul>
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)</li>
<h2><a name="variants">Build Variants</a></h2>
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)</li>
Three <a
href="../../../tools/build/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and
can be selected by setting the <code><a
href="../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
variable:
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
-DBOOST_DEBUG_PYTHON</tt>)</li>
</ul>
<ul>
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)
<p>The first two variants of the <code>boost_python</code> library are
built by default, and are compatible with the default Python
distribution. The <code>debug-python</code> variant corresponds to a
specially-built debugging version of Python. On Unix platforms, this
python is built by adding <code>--with-pydebug</code> when configuring
the Python build. On Windows, the debugging version of Python is
generated by the "Win32 Debug" target of the <code>PCBuild.dsw</code>
Visual C++ 6.0 project in the <code>PCBuild</code> subdirectory of your
Python distribution. Extension modules built with Python debugging
enabled are <b>not link-compatible</b> with a non-debug build of Python.
Since few people actually have a debug build of Python (it doesn't come
with the standard distribution), the normal <code>debug</code> variant
builds modules which are compatible with ordinary Python.</p>
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)
<p>On many windows compilers, when extension modules are built with
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a special
debugging version of the Python DLL. Since this debug DLL isn't supplied
with the default Python installation for Windows, Boost.Python uses
<tt><a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
<tt>#include</tt>d - unless <code>BOOST_DEBUG_PYTHON</code> is
defined.</p>
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
-DBOOST_DEBUG_PYTHON</tt>)
</ul>
<p>If you want the extra runtime checks available with the debugging
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to re-enable
python debuggin, and link with the <code>debug-python</code> variant of
<tt>boost_python</tt>.</p>
<p>The first two variants of the <code>boost_python</code>
library are built by default, and are compatible with the
default Python distribution. The <code>debug-python</code>
variant corresponds to a specially-built debugging version of
Python. On Unix platforms, this python is built by adding
<code>--with-pydebug</code> when configuring the Python
build. On Windows, the debugging version of Python is generated
by the &quot;Win32 Debug&quot; target of the
<code>PCBuild.dsw</code> Visual C++ 6.0 project in the
<code>PCBuild</code> subdirectory of your Python distribution.
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that any
source files in your extension module <tt>#include&nbsp;&lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</tt>
instead of the usual <tt>Python.h</tt>, or you will have link
incompatibilities.<br>
</p>
<hr>
Extension modules built with Python debugging enabled are <b>not
link-compatible</b> with a non-debug build of Python. Since few
people actually have a debug build of Python (it doesn't come
with the standard distribution), the normal
<code>debug</code> variant builds modules which are compatible
with ordinary Python.
<p>&copy; Copyright David Abrahams 2002. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided ``as is'' without
express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
<p>Updated: O8 October, 2002 (David Abrahams)</p>
</body>
</html>
<p>On many windows compilers, when extension modules are built
with
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a
special debugging version of the Python DLL. Since this debug DLL
isn't supplied with the default Python installation for Windows,
Boost.Python uses <tt><a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
<tt>#include</tt>d - unless <code>BOOST_DEBUG_PYTHON</code> is defined.
<p>If you want the extra runtime checks available with the
debugging version of the library, <tt>#define
BOOST_DEBUG_PYTHON</tt> to re-enable python debuggin, and link
with the <code>debug-python</code> variant of
<tt>boost_python</tt>.
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that
any source files in your extension module <tt>#include &lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</tt>
instead of the usual <tt>Python.h</tt>, or you will have link
incompatibilities.<br>
<hr>
Next: <a href="enums.html">Wrapping Enums</a> Previous: <a href=
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
"index.html">Top</a>
<hr>
<p>&copy; Copyright David Abrahams 2002. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided ``as is'' without
express or implied warranty, and with no claim as to its suitability for
any purpose.
<p>Updated: May 15, 2002 (David Abrahams)
</div>

View File

@@ -1,205 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
The Boost Python Library (Boost.Python)
</title>
<h1>
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277"
align="center" height="86"><br>The Boost Python Library (Boost.Python)
</h1>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<h2>Synopsis</h2>
<p>
Use the Boost Python Library to quickly and easily export a C++ library to <a
href="http://www.python.org">Python</a> such that the Python interface is
very similar to the C++ interface. It is designed to be minimally
intrusive on your C++ design. In most cases, you should not have to alter
your C++ classes in any way in order to use them with Boost.Python. The system
<em>should</em> simply ``reflect'' your C++ classes and functions into
Python.
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<p>
<title>Boost.Python</title>
</head>
<table border="1">
<tr><td> <b>Note:</b> this is the last official release of
Boost.Python v1. Development of this version of the library has
stopped; it will be retired soon in favor of the redesigned and
improved version 2. A summary of the development goals is available on
the Python <a href="http://www.python.org/sigs/c++-sig/">C++-sig</a>
page, which also serves as a mailing list for users of both versions
of the library. A preview of the v2 documentation is available <a
href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/index.html?rev=HEAD&content-type=text/html">here</a>,
and instructions for getting started with a prerelease are available
upon request.
</table>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<h2>Supported Platforms</h2>
<p>Boost.Python is known to have been tested
against <a href="http://www.python/org/2.2.1">Python 2.2.1</a> using
the following compilers:
<td valign="top">
<h1 align="center">Boost.Python</h1>
<ul>
<li><a
href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5</a>.
All tests pass.
<h2 align="center">Index</h2>
</td>
</tr>
</table>
<hr>
<li><a
href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5</a>
with <a href="http://www.stlport.org">STLPort</a>-4.5.3. A compiler bug interferes with
<a
href="../example/simple_vector.cpp">libs/python/example/simple_vector.cpp</a>. All
other tests pass.
<h2>Contents</h2>
<p>
<li><a href="http://msdn.microsoft.com/visualc/">MSVC++7 (Visual
Studio .NET)</a>. All tests pass.
<dl class="index">
<dt><a href="tutorial/index.html">Tutorial Introduction</a></dt>
<p>
<li><a href="http://www.metrowerks.com/products/windows/">Metrowerks
CodeWarrior Pro7.2 and Pro7.0 for Windows</a>. All tests pass.
<dt><a href="building.html">Building and Testing</a></dt>
<p>
<li><a href="http://gcc.gnu.org">GCC 3.0.4</a> under <a
href="http://www.cygwin.com">Cygwin</a> and
<a href="http://www.redhat.com/">RedHat Linux 7.1</a>.
All tests pass.
<dt><a href="v2/reference.html">Reference</a></dt>
<p>
<li>Compaq C++ V6.2-024 for Digital UNIX (an <a
href="http://www.edg.com/">EDG</a>-based compiler).
All tests pass.<br>
Note that the Boost.Compatibility
library must be included (see e.g. tru64_cxx.mak in the build
directory).
<dt><a href="v2/configuration.html">Configuration Information</a></dt>
<p>
<li>Silicon Graphics MIPSpro Version 7.3.1.2m (an <a
href="http://www.edg.com/">EDG</a>-based compiler).
All tests pass.<br>
Note that the Boost.Compatibility
library must be included (see e.g. irix_CC.mak in the build
directory).
<dt><a href="v2/rationale.html">Rationale</a></dt>
<p>
<li><a href="http://gcc.gnu.org">GCC 2.95.2</a> under <a
href="http://www.mingw.org">MinGW</a> and <a
href="http://www.redhat.com/">RedHat Linux 7.1</a>.
Compilation succeeds, but some tests fail at runtime due to
exception handling bugs. It is therefore highly recommended
to use GCC 3.0.4 instead.
<dt><a href="v2/definitions.html">Definitions</a></dt>
<p>
<li><a
href="http://developer.intel.com/software/products/compilers/c50/">Intel
C++ 6.0</a> beta: Comprehensive test fails to link due to a
linker bug. Other tests seem to work.
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<p>
<li><a
href="http://developer.intel.com/software/products/compilers/c50/">Intel
C++ 5.0</a> Comprehensive test fails at runtime due to an
exception-handling bug. Other tests seem to work.
<dt><a href="v2/progress_reports.html">Progress Reports</a></dt>
</ul>
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<p>
Note that pickling doesn't work with Python 2.2
due to a core language bug. This is fixed in
<a href="http://www.python/org/2.2.1">2.2.1</a>.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
08 October, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p>
Boost.Python has also been used with other versions of Python back to
Python 1.5.2. It is expected that the older Python releases still work,
but we are not regularly testing for backward compatibility.
<h2>Credits</h2>
<ul>
<li><a href="../../../people/dave_abrahams.htm">David Abrahams</a> originated
and wrote most of the library, and continues to coordinate development.
<li><a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich Koethe</a>
had independently developed a similar system. When he discovered Boost.Python,
he generously contributed countless hours of coding and much insight into
improving it. He is responsible for an early version of the support for <a
href="overloading.html">function overloading</a> and wrote the support for
<a href="inheritance.html#implicit_conversion">reflecting C++ inheritance
relationships</a>. He has helped to improve error-reporting from both
Python and C++, and has designed an extremely easy-to-use way of
exposing <a href="special.html#numeric">numeric operators</a>, including
a way to avoid explicit coercion by means of overloading.
<li><a href="http://cci.lbl.gov/staff/ralf_grosse-kunstleve.html">Ralf W.
Grosse-Kunstleve</a> contributed <a href="pickle.html">pickle support</a>
and numerous other small improvements. He's working on a way to allow
types exported by multiple modules to interact.
<li>The members of the boost mailing list and the Python community
supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans,
Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott took the
brave step of trying to use Boost.Python while it was still in early
stages of development.
<li>The development of Boost.Python wouldn't have been possible without
the generous support of <a href="http://www.dragonsys.com/">Dragon
Systems/Lernout and Hauspie, Inc</a> who supported its development as an
open-source project.
</ul>
<h2>Table of Contents</h2>
<ol>
<li><a href="extending.html">A Brief Introduction to writing Python
extension modules</a>
<li><a href="comparisons.html">Comparisons between Boost.Python and other
systems for extending Python</a>
<li><a href="example1.html">A Simple Example</a>
<li><a href="exporting_classes.html">Exporting Classes</a>
<li><a href="overriding.html">Overridable Virtual Functions</a>
<li><a href="overloading.html">Function Overloading</a>
<li><a href="inheritance.html">Inheritance</a>
<li><a href="special.html">Special Method and Operator Support</a>
<li><a href="under-the-hood.html">A Peek Under the Hood</a>
<li><a href="building.html">Building an Extension Module</a>
<li><a href="pickle.html">Pickle Support</a>
<li><a href="cross_module.html">Cross-Extension-Module Dependencies</a>
<li><a href="enums.html">Wrapping Enums</a>
<li><a href="pointers.html">Pointers and Smart Pointers</a>
<li><a href="data_structures.txt">Internal Data Structures</a>
</ol>
<p>
Documentation is a major ongoing project; assistance is greatly
appreciated! In the meantime, useful examples of every Boost.Python feature should
be evident in the regression test files <code>test/comprehensive.[<a
href="../test/comprehensive.py">py</a>/<a
href="../test/comprehensive.hpp">hpp</a>/<a
href="../test/comprehensive.cpp">cpp</a>]</code>
<p>
Questions should be directed to the <a href=
"http://www.python.org/sigs/c++-sig/">Python C++ SIG</a>.
<p>
&copy; Copyright David Abrahams 2001. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided ``as is'' without
express or implied warranty, and with no claim as to its suitability for
any purpose.
<p>
Updated: Apr 2002
<p><i>&copy; Copyright <a href="../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -36,26 +36,22 @@ building Boost.Python, check out: <a href="../../building.html">
building.html</a>.
After this brief <i>bjam</i> tutorial, we should have built two DLLs:</p>
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
if you are on Windows, and</p>
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
if you are on Unix.</p>
This assumes of course that we are running on Windows.</p>
<p>
The tutorial example can be found in the directory:
<tt>libs/python/example/tutorial</tt>. There, you can find:</p>
<tt>/libs/python/example/tutorial</tt>. There, you can find:</p>
<ul><li>hello.cpp</li><li>Jamfile</li></ul><p>
The <tt>hello.cpp</tt> file is our C++ hello world example. The <tt>Jamfile</tt> is a
minimalist <i>bjam</i> script that builds the DLLs for us.</p>
<p>
Before anything else, you should have the bjam executable in your boost
directory. Pre-built Boost.Jam executables are available for most
directory. Pre-built Boost.Jam executables are available for some
platforms. For example, a pre-built Microsoft Windows bjam executable can
be downloaded <a href="http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip">
here</a>.
The complete list of bjam pre-built executables can be found <a href="../../../../../tools/build/index.html#Jam">
here</a>.</p>
<a name="lets_jam_"></a><h2>Lets Jam!</h2><p>
<img src="theme/jam.png"></img></p>
<p>
Here is our minimalist Jamfile:</p>
<code><pre>
subproject libs/python/example/tutorial ;
@@ -103,9 +99,8 @@ Python modules. Example:</p>
</span></pre></code>
<p>
The above assumes that the Python installation is in <tt>c:/dev/tools/python</tt>
and that we are using Python version 2.2. You'll have to tweak this path
appropriately. <img src="theme/note.gif"></img> Be sure not to include a third number, e.g. <b>not</b> &quot;2.2.1&quot;,
even if that's the version you have.</p>
and that we are using Python version 2.2. Be sure not to include a third
number, e.g. <b>not</b> &quot;2.2.1&quot;, even if that's the version you have.</p>
<p>
Now we are ready... Be sure to <tt>cd</tt> to <tt>libs/python/example/tutorial</tt>
where the tutorial <tt>&quot;hello.cpp&quot;</tt> and the <tt>&quot;Jamfile&quot;</tt> is situated.</p>
@@ -144,10 +139,6 @@ And so on... Finally:</p>
</pre></code><p>
If all is well, you should now have:</p>
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
if you are on Windows, and</p>
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
if you are on Unix.</p>
<p>
<tt>boost_python.dll</tt> can be found somewhere in <tt>libs\python\build\bin</tt>
while <tt>hello.pyd</tt> can be found somewhere in
<tt>libs\python\example\tutorial\bin</tt>. After a successful build, you can just

View File

@@ -142,7 +142,7 @@ or more policies can be composed by chaining. Here's the general syntax:</p>
</span></pre></code>
<p>
Here is the list of predefined call policies. A complete reference detailing
these can be found <a href="../../v2/reference.html#models_of_call_policies">
these can be found <a href="../../v2/CallPolicies.html">
here</a>.</p>
<ul><li><b>with_custodian_and_ward</b><br> Ties lifetimes of the arguments</li><li><b>with_custodian_and_ward_postcall</b><br> Ties lifetimes of the arguments and results</li><li><b>return_internal_reference</b><br> Ties lifetime of one argument to that of result</li><li><b>return_value_policy&lt;T&gt; with T one of:</b><br></li><li><b>reference_existing_object</b><br>naïve (dangerous) approach</li><li><b>copy_const_reference</b><br>Boost.Python v1 approach</li><li><b>copy_non_const_reference</b><br></li><li><b>manage_new_object</b><br> Adopt a pointer and hold the instance</li></ul><table width="80%" border="0" align="center">
<tr>

View File

@@ -56,11 +56,12 @@ Then, in Python:</p>
Note that <tt>name</tt> is exposed as <b>read-only</b> while <tt>value</tt> is exposed
as <b>read-write</b>.</p>
<code><pre>
&gt;&gt;&gt; x.name = 'e' # can't change name
<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=literal>'e' </span>#<span class=identifier>can</span><span class=literal>'t change name
Traceback (most recent call last):
File &quot;&lt;stdin&gt;&quot;, line 1, in ?
AttributeError: can't set attribute
</pre></code><table border="0">
AttributeError: can'</span><span class=identifier>t </span><span class=identifier>set </span><span class=identifier>attribute
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="constructors.html"><img src="theme/l_arr.gif" border="0"></a></td>

View File

@@ -92,16 +92,15 @@ polymorphically <i>from</i> <b>C++</b>. </td>
<p>
Wrapping <tt>Base</tt> and the free function <tt>call_f</tt>:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>, </span><span class=identifier>no_init</span><span class=special>)
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>, </span><span class=identifier>no_init</span><span class=special>)
</span><span class=special>;
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;call_f&quot;</span><span class=special>, </span><span class=identifier>call_f</span><span class=special>);
</span></pre></code>
<p>
Notice that we parameterized the <tt>class_</tt> template with <tt>BaseWrap</tt> as the
second parameter. What is <tt>noncopyable</tt>? Without it, the library will try
to create code for converting Base return values of wrapped functions to
Python. To do that, it needs Base's copy constructor... which isn't
available, since Base is an abstract class.</p>
to instantiate a copy constructor for returning Base objects from
functions.</p>
<p>
In Python, let us try to instantiate our <tt>Base</tt> class:</p>
<code><pre>

View File

@@ -64,7 +64,7 @@ expose instead.</p>
<p>
<tt>init&lt;std::string&gt;()</tt> exposes the constructor taking in a
<tt>std::string</tt> (in Python, constructors are spelled
&quot;<tt>&quot;__init__&quot;</tt>&quot;).</p>
&quot;<tt>__init__(...)</tt>&quot;).</p>
<p>
We can expose additional constructors by passing more <tt>init&lt;...&gt;</tt>s to
the <tt>def()</tt> member function. Say for example we have another World

View File

@@ -70,21 +70,18 @@ member functions.</p>
<p>
Demonstrates that you can write the C++ equivalent of <tt>&quot;format&quot; % x,y,z</tt>
in Python, which is useful since there's no easy way to do that in std C++.</p>
<p>
<img src="theme/alert.gif"></img> <b>Beware</b> the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.</p>
<p>
Python:</p>
<code><pre>
<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=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<p>
C++:</p>
<code><pre>
<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>&quot;__dict__&quot;</span><span class=special>)); </span>#<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/alert.gif"></img> Beware the common pitfall of
forgetting that the constructors of most of Python's mutable types
make copies, just as in Python.<br><br>
<tt>dict d(x.attr(&quot;__dict__&quot;)); # makes a copy of x's dict<br>
d['whatever'] = 3; # modifies a copy of x.__dict__ (not the original)<br></tt>
</td>
</tr>
</table>
<a name="class__lt_t_gt__as_objects"></a><h2>class_&lt;T&gt; as objects</h2><p>
Due to the dynamic nature of Boost.Python objects, any <tt>class_&lt;T&gt;</tt> may
also be one of these types! The following code snippet wraps the class

View File

@@ -65,15 +65,10 @@ After this brief ['bjam] tutorial, we should have built two DLLs:
* boost_python.dll
* hello.pyd
if you are on Windows, and
* libboost_python.so
* hello.so
if you are on Unix.
This assumes of course that we are running on Windows.
The tutorial example can be found in the directory:
[^libs/python/example/tutorial]. There, you can find:
[^/libs/python/example/tutorial]. There, you can find:
* hello.cpp
* Jamfile
@@ -82,13 +77,12 @@ The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a
minimalist ['bjam] script that builds the DLLs for us.
Before anything else, you should have the bjam executable in your boost
directory. Pre-built Boost.Jam executables are available for most
directory. Pre-built Boost.Jam executables are available for some
platforms. For example, a pre-built Microsoft Windows bjam executable can
be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here].
The complete list of bjam pre-built executables can be found [@../../../../../tools/build/index.html#Jam here].
[h2 Lets Jam!]
[$theme/jam.png]
Here is our minimalist Jamfile:
@@ -147,9 +141,8 @@ Python modules. Example:
set PYTHON_VERSION=2.2
The above assumes that the Python installation is in [^c:/dev/tools/python]
and that we are using Python version 2.2. You'll have to tweak this path
appropriately. __note__ Be sure not to include a third number, e.g. [*not] "2.2.1",
even if that's the version you have.
and that we are using Python version 2.2. Be sure not to include a third
number, e.g. [*not] "2.2.1", even if that's the version you have.
Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial]
where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated.
@@ -193,13 +186,6 @@ If all is well, you should now have:
* boost_python.dll
* hello.pyd
if you are on Windows, and
* libboost_python.so
* hello.so
if you are on Unix.
[^boost_python.dll] can be found somewhere in [^libs\python\build\bin]
while [^hello.pyd] can be found somewhere in
[^libs\python\example\tutorial\bin]. After a successful build, you can just
@@ -290,7 +276,7 @@ expose instead.
[^init<std::string>()] exposes the constructor taking in a
[^std::string] (in Python, constructors are spelled
"[^"__init__"]").
"[^__init__(...)]").
We can expose additional constructors by passing more [^init<...>]s to
the [^def()] member function. Say for example we have another World
@@ -340,12 +326,10 @@ Then, in Python:
Note that [^name] is exposed as [*read-only] while [^value] is exposed
as [*read-write].
[pre
>>> x.name = 'e' # can't change name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: can't set attribute
]
[page:1 Class Properties]
@@ -498,15 +482,14 @@ polymorphically ['from] [*C++].]
Wrapping [^Base] and the free function [^call_f]:
class_<Base, BaseWrap, boost::noncopyable>("Base", no_init)
class_<Base, BaseWrap, noncopyable>("Base", no_init)
;
def("call_f", call_f);
Notice that we parameterized the [^class_] template with [^BaseWrap] as the
second parameter. What is [^noncopyable]? Without it, the library will try
to create code for converting Base return values of wrapped functions to
Python. To do that, it needs Base's copy constructor... which isn't
available, since Base is an abstract class.
to instantiate a copy constructor for returning Base objects from
functions.
In Python, let us try to instantiate our [^Base] class:
@@ -837,7 +820,7 @@ or more policies can be composed by chaining. Here's the general syntax:
policy3<args...> > >
Here is the list of predefined call policies. A complete reference detailing
these can be found [@../../v2/reference.html#models_of_call_policies here].
these can be found [@../../v2/CallPolicies.html here].
* [*with_custodian_and_ward][br] Ties lifetimes of the arguments
* [*with_custodian_and_ward_postcall][br] Ties lifetimes of the arguments and results
@@ -1024,18 +1007,13 @@ member functions.
Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z]
in Python, which is useful since there's no easy way to do that in std C++.
__alert__ [*Beware] the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.
[blurb __alert__ Beware the common pitfall of
forgetting that the constructors of most of Python's mutable types
make copies, just as in Python.[br][br]
Python:
>>> d = dict(x.__dict__) # copies x.__dict__
>>> d['whatever'] # modifies the copy
C++:
dict d(x.attr("__dict__")); # copies x.__dict__
d['whatever'] = 3; # modifies the copy
[^dict d(x.attr("__dict__")); # makes a copy of x's dict[br]
'''d['whatever']''' = 3; # modifies a copy of x.__dict__ (not the original)[br]]
]
[h2 class_<T> as objects]

View File

@@ -1,32 +1,85 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Acknowledgments</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Acknowledgments</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Acknowledgments</h2>
</td>
</tr>
</table>
<hr>
{{text}}
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Acknowledgments</h2>
</td>
</tr>
</table>
<hr>
<p><a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> is
the architect, designer, and implementor of <b>Boost.Python</b>.</p>
<p>Joel de Guzman implemented the <a href="overloads.html">default
argument support</a> and wrote the excellent tutorial documentation.</p>
<p><a href="../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
Grosse-Kunstleve</a> implemented the <a href="pickle.html">pickle
support</a>, and has enthusiastically supported the library since its
birth, contributing to design decisions and providing invaluable
real-world insight into user requirements. Ralf has written some
extensions for converting C++ containers that I hope will be incorporated
into the library soon. He also implemented the cross-module support in
the first version of Boost.Python. More importantly, Ralf makes sure
nobody forgets the near-perfect synergy of C++ and Python for solving the
problems of large-scale software construction.</p>
<p><a href="mailto:achim@procoders.net">Achim Domma</a> contributed some
of the <a href="reference.html#object_wrappers">Object Wrappers</a> and
HTML templates for this documentation. Dave Hawkes contributed
inspiration for the use of the <code><a href=
"scope.html#scope-spec">scope</a></code> class to simplify module
definition syntax. Pearu Pearson wrote some of the test cases that are in
the current test suite.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p>The development of this version of Boost.Python was funded in part by
the <a href="http://www.llnl.gov/">Lawrence Livermore National
Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational
Crystallography Initiative</a> at Lawrence Berkeley National
Laboratories.</p>
<p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
Koethe</a> provided the implementation of inheritance and special
method/operator support in the first version of Boost.Python.</p>
<p>The first version of Boost.Python would not have been possible without
the support of Dragon Systems, which supported its development and
release as a Boost library.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
08 October, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,62 +1,85 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Calling Python Functions and Methods</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Calling Python Functions and Methods</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Calling Python Functions and Methods</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#argument_handling">Argument Handling</a></dt>
<dt><a href="#result_handling">Result Handling</a></dt>
<dt><a href="#result_handling">Rationale</a></dt>
</dl>
<hr>
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<h2><a name="introduction">Introduction</a></h2>
<p>
Boost.Python provides two families of function templates,
<code><a href="call.html#call-spec">call</a></code> and <code><a
href="call_method.html#call_method-spec">call_method</a></code>, for
invoking Python functions and methods respectively. The interface for
calling a Python function object (or any Python callable object) looks
like:
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Calling Python Functions and Methods</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#argument_handling">Argument Handling</a></dt>
<dt><a href="#result_handling">Result Handling</a></dt>
<dt><a href="#result_handling">Rationale</a></dt>
</dl>
<hr>
<h2><a name="introduction">Introduction</a></h2>
The simplest way to call a Python function from C++, given an <code><a
href="object.html#object-spec">object</a></code> instance <code>f</code>
holding the function, is simply to invoke its function call operator.
<pre>
f("tea", 4, 2) // In Python: f('tea', 4, 2)
</pre>
And of course, a method of an <code><a href=
"object.html#object-spec">object</a></code> instance <code>x</code> can
be invoked by using the function-call operator of the corresponding
attribute:
<pre>
x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
</pre>
<p>If you don't have an <code>object</code> instance, Boost.Python
provides two families of function templates, <code><a href=
"call.html#call-spec">call</a></code> and <code><a href=
"call_method.html#call_method-spec">call_method</a></code>, for invoking
Python functions and methods respectively on <code>PyObject*</code>s. The
interface for calling a Python function object (or any Python callable
object) looks like:</p>
<pre>
call&lt;ResultType&gt;(callable_object, a1, a2... a<i>N</i>);
</pre>
Calling a method of a Python object is similarly easy:
Calling a method of a Python object is similarly easy:
<pre>
call_method&lt;ResultType&gt;(self_object, &quot;<i>method-name</i>&quot;, a1, a2... a<i>N</i>);
call_method&lt;ResultType&gt;(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
</pre>
This comparitively low-level interface is the one you'll use when
implementing C++ virtual functions that can be overridden in Python.
<h2><a name="argument_handling">Argument Handling</a></h2>
<h2><a name="argument_handling">Argument Handling</a></h2>
<p>
Arguments are converted to Python according to their type. By default,
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
new Python objects, but this behavior can be overridden by the use of
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a
href="../../../bind/ref.html#reference_wrapper">ref()</a>:
<p>Arguments are converted to Python according to their type. By default,
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
new Python objects, but this behavior can be overridden by the use of
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
"../../../bind/ref.html#reference_wrapper">ref()</a>:</p>
<pre>
class X : boost::noncopyable
{
@@ -69,178 +92,160 @@ void apply(PyObject* callable, X&amp; x)
boost::python::call&lt;void&gt;(callable, boost::ref(x));
}
</pre>
In the table below, <code><b>x</b></code> denotes the actual argument
object and <code><b>cv</b></code> denotes an optional
<i>cv-qualification</i>: &quot;<code>const</code>&quot;,
&quot;<code>volatile</code>&quot;, or &quot;<code>const
volatile</code>&quot;.
In the table below, <code><b>x</b></code> denotes the actual argument
object and <code><b>cv</b></code> denotes an optional
<i>cv-qualification</i>: "<code>const</code>", "<code>volatile</code>",
or "<code>const volatile</code>".
<table border="1" summary="class_ template parameters">
<tr>
<th>Argument Type
<th>Argument Type</th>
<th>Behavior
<th>Behavior</th>
</tr>
<tr>
<td><code>T cv&amp;</code><br>
<code>T cv</code>
<code>T cv</code></td>
<td>The Python argument is created by the same means used
for the return value of a wrapped C++ function returning
<code>T</code>. When
<code>T</code> is a class type, that normally means
<code>*x</code> is copy-constructed into the new Python
object.
<td>The Python argument is created by the same means used for the
return value of a wrapped C++ function returning <code>T</code>. When
<code>T</code> is a class type, that normally means <code>*x</code>
is copy-constructed into the new Python object.</td>
</tr>
<tr>
<td><code>T*</code>
<td><code>T*</code></td>
<td>If <code>x&nbsp;==&nbsp;0</code>, the Python argument will
be <code><a
href="http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>. Otherwise,
the Python argument is created by the same means used for the
return value of a wrapped C++ function returning
<code>T</code>. When
<code>T</code> is a class type, that normally means
<code>*x</code> is copy-constructed into the new Python
object.
<td>If <code>x&nbsp;==&nbsp;0</code>, the Python argument will be
<code><a href=
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
Otherwise, the Python argument is created by the same means used for
the return value of a wrapped C++ function returning <code>T</code>.
When <code>T</code> is a class type, that normally means
<code>*x</code> is copy-constructed into the new Python object.</td>
</tr>
<tr>
<td><code><a
href="../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a>&lt;T&gt; </code>
<td><code><a href=
"../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a>&lt;T&gt;</code></td>
<td>The Python argument contains a pointer to, rather than a
copy of, <code>x.get()</code>. Note: failure to ensure that no
Python code holds a reference to the resulting object beyond
the lifetime of <code>*x.get()</code> <b>may result in a
crash!</b>
<td>The Python argument contains a pointer to, rather than a copy of,
<code>x.get()</code>. Note: failure to ensure that no Python code
holds a reference to the resulting object beyond the lifetime of
<code>*x.get()</code> <b>may result in a crash!</b></td>
</tr>
<tr>
<td><code><a
href="ptr.html#pointer_wrapper-spec">pointer_wrapper</a>&lt;T&gt;</code>
<td>If <code>x.get()&nbsp;==&nbsp;0</code>, the Python
argument will be <code><a
href="http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
Otherwise, the Python argument contains a pointer to, rather
than a copy of, <code>*x.get()</code>. Note: failure to ensure
that no Python code holds a reference to the resulting object
beyond the lifetime of <code>*x.get()</code> <b>may result in
a crash!</b>
<td><code><a href=
"ptr.html#pointer_wrapper-spec">pointer_wrapper</a>&lt;T&gt;</code></td>
<td>If <code>x.get()&nbsp;==&nbsp;0</code>, the Python argument will
be <code><a href=
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
Otherwise, the Python argument contains a pointer to, rather than a
copy of, <code>*x.get()</code>. Note: failure to ensure that no
Python code holds a reference to the resulting object beyond the
lifetime of <code>*x.get()</code> <b>may result in a crash!</b></td>
</tr>
</table>
<h2><a name="result_handling">Result Handling</a></h2>
<h2><a name="result_handling">Result Handling</a></h2>
In general, <code>call&lt;ResultType&gt;()</code> and
<code>call_method&lt;ResultType&gt;()</code> return
<code>ResultType</code> by exploiting all lvalue and rvalue
<code>from_python</code> converters registered for ResultType and
returning a copy of the result. However, when <code>ResultType</code> is
a pointer or reference type, Boost.Python searches only for lvalue
converters. To prevent dangling pointers and references, an exception
will be thrown if the Python result object has only a single reference
count.
In general, <code>call&lt;ResultType&gt;()</code> and
<code>call_method&lt;ResultType&gt;()</code> return
<code>ResultType</code> by exploiting all lvalue and rvalue
<code>from_python</code> converters registered for ResultType and
returning a copy of the result. However, when
<code>ResultType</code> is a pointer or reference type, Boost.Python
searches only for lvalue converters. To prevent dangling pointers and
references, an exception will be thrown if the Python result object
has only a single reference count.
<h2><a name="rationale">Rationale</a></h2>
In general, to get Python arguments corresponding to
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
created for each one; should the C++ object be copied into that Python
object, or should the Python object simply hold a reference/pointer to
the C++ object? In general, the latter approach is unsafe, since the
called function may store a reference to the Python object somewhere. If
the Python object is used after the C++ object is destroyed, we'll crash
Python.
<h2><a name="rationale">Rationale</a></h2>
<p>In keeping with the philosophy that users on the Python side shouldn't
have to worry about crashing the interpreter, the default behavior is to
copy the C++ object, and to allow a non-copying behavior only if the user
writes <code><a href="../../../bind/ref.html">boost::ref</a>(a1)</code>
instead of a1 directly. At least this way, the user doesn't get dangerous
behavior "by accident". It's also worth noting that the non-copying
("by-reference") behavior is in general only available for class types,
and will fail at runtime with a Python exception if used otherwise[<a
href="#1">1</a>].</p>
In general, to get Python arguments corresponding to
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
created for each one; should the C++ object be copied into that Python
object, or should the Python object simply hold a reference/pointer to
the C++ object? In general, the latter approach is unsafe, since the
called function may store a reference to the Python object
somewhere. If the Python object is used after the C++ object is
destroyed, we'll crash Python.
<p>However, pointer types present a problem: one approach is to refuse to
compile if any aN has pointer type: after all, a user can always pass
<code>*aN</code> to pass "by-value" or <code>ref(*aN)</code> to indicate
a pass-by-reference behavior. However, this creates a problem for the
expected null pointer to <code>None</code> conversion: it's illegal to
dereference a null pointer value.</p>
<p>In keeping with the philosophy that users on the Python side
shouldn't have to worry about crashing the interpreter, the default
behavior is to copy the C++ object, and to allow a non-copying
behavior only if the user writes <code><a
href="../../../bind/ref.html">boost::ref</a>(a1)</code> instead of a1
directly. At least this way, the user doesn't get dangerous behavior
&quot;by accident&quot;. It's also worth noting that the non-copying
(&quot;by-reference&quot;) behavior is in general only available for
class types, and will fail at runtime with a Python exception if used
otherwise[<a href="#1">1</a>].
<p>The compromise I've settled on is this:</p>
<p>
However, pointer types present a problem: one approach is to refuse
to compile if any aN has pointer type: after all, a user can always pass
<code>*aN</code> to pass &quot;by-value&quot; or <code>ref(*aN)</code>
to indicate a pass-by-reference behavior. However, this creates a
problem for the expected null pointer to
<code>None</code> conversion: it's illegal to dereference a null
pointer value.
<ol>
<li>The default behavior is pass-by-value. If you pass a non-null
pointer, the pointee is copied into a new Python object; otherwise the
corresponding Python argument will be None.</li>
<p>
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If a
null pointer is passed to <code>ptr(aN)</code>, the corresponding
Python argument will be <code>None</code>.</li>
</ol>
The compromise I've settled on is this:
<p>As for results, we have a similar problem: if <code>ResultType</code>
is allowed to be a pointer or reference type, the lifetime of the object
it refers to is probably being managed by a Python object. When that
Python object is destroyed, our pointer dangles. The problem is
particularly bad when the <code>ResultType</code> is char const* - the
corresponding Python String object is typically uniquely-referenced,
meaning that the pointer dangles as soon as <code>call&lt;char
const*&gt;(...)</code> returns.</p>
<ol>
<li>The default behavior is pass-by-value. If you pass a non-null
pointer, the pointee is copied into a new Python object; otherwise
the corresponding Python argument will be None.
<p>The old Boost.Python v1 deals with this issue by refusing to compile
any uses of <code>call&lt;char const*&gt;()</code>, but this goes both
too far and not far enough. It goes too far because there are cases where
the owning Python string object survives beyond the call (just for
instance, when it's the name of a Python class), and it goes not far
enough because we might just as well have the same problem with a
returned pointer or reference of any other type.</p>
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If
a null pointer is passed to <code>ptr(aN)</code>, the corresponding
Python argument will be <code>None</code>.
</ol>
<p>In Boost.Python v2 this is dealt with by:</p>
<p>
As for results, we have a similar problem: if <code>ResultType</code>
is allowed to be a pointer or reference type, the lifetime of the
object it refers to is probably being managed by a Python object. When
that Python object is destroyed, our pointer dangles. The problem is
particularly bad when the <code>ResultType</code> is char const* - the
corresponding Python String object is typically uniquely-referenced,
meaning that the pointer dangles as soon as <code>call&lt;char
const*&gt;(...)</code> returns.
<ol>
<li>lifting the compile-time restriction on const char* callback
returns</li>
<p>
The old Boost.Python v1 deals with this issue by refusing to compile
any uses of <code>call&lt;char const*&gt;()</code>, but this goes both
too far and not far enough. It goes too far because there are cases
where the owning Python string object survives beyond the call (just
for instance, when it's the name of a Python class), and it goes not
far enough because we might just as well have the same problem with a
returned pointer or reference of any other type.
<li>detecting the case when the reference count on the result Python
object is 1 and throwing an exception inside of
<code>call&lt;U&gt;(...)</code> when <code>U</code> is a pointer or
reference type.</li>
</ol>
This should be acceptably safe because users have to explicitly specify a
pointer/reference for <code>U</code> in <code>call&lt;U&gt;</code>, and
they will be protected against dangles at runtime, at least long enough
to get out of the <code>call&lt;U&gt;(...)</code> invocation.
<hr>
<a name="1">[1]</a> It would be possible to make it fail at compile-time
for non-class types such as int and char, but I'm not sure it's a good
idea to impose this restriction yet.
<p>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 April, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
In Boost.Python v2 this is dealt with by:
<ol>
<li> lifting the compile-time restriction on const
char* callback returns
<li> detecting the case when the reference count on the result
Python object is 1 and throwing an exception inside of
<code>call&lt;U&gt;(...)</code> when <code>U</code> is a pointer
or reference type.
</ol>
This should be acceptably safe because users have to explicitly
specify a pointer/reference for <code>U</code> in
<code>call&lt;U&gt;</code>, and they will be protected against dangles
at runtime, at least long enough to get out of the
<code>call&lt;U&gt;(...)</code> invocation.
<hr>
<a name="1">[1]</a> It would be possible to make it fail at compile-time for non-class
types such as int and char, but I'm not sure it's a good idea to impose
this restriction yet.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 April, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -52,6 +52,7 @@
in the current <code><a href="scope.html">scope</a></code>.</p>
<h2><a name="functions"></a>Functions</h2>
<a name="def-spec"></a>def
<pre>
template &lt;class F&gt;
void def(char const* name, F f);

View File

@@ -32,8 +32,8 @@
<dt><a href="#question1">Is return_internal reference
efficient?</a></dt>
<dt><a href="#question2">How can I which take C++ containers as
arguments?</a></dt>
<dt><a href="#question2">How can I wrap containers which take C++
containers as arguments?</a></dt>
</dl>
<h2><a name="question1"></a>Is return_internal reference efficient?</h2>

View File

@@ -1,43 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Index</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="overview.html">Overview</a></dt>
<dt><a href="reference.html">Reference</a></dt>
<dt><a href="configuration.html">Configuration Information</a></dt>
<dt><a href="rationale.html">Rationale</a></dt>
<dt><a href="definitions.html">Definitions</a></dt>
<dt><a href="faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="progress_reports.html">Progress Reports</a></dt>
<dt><a href="bibliography.html">Bibliography</a></dt>
<dt><a href="acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="refresh" content="0; URL=../index.html">
<title></title>
</head>
<body>
Automatic redirection failed, please go to <a href=
"../index.html">../index.html</a>.
</body>
</html>

View File

@@ -13,7 +13,7 @@
p.c3 {font-style: italic}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
</style>
</head>
<body>
@@ -61,6 +61,8 @@
<dt><a href="#type_conversion">To/From Python Type Conversion</a></dt>
<dt><a href="#utility">Utility and Infrastructure</a></dt>
<dt><a href="#topics">Topics</a></dt>
</dl>
<hr>
<!-- xxxxx -->
@@ -111,6 +113,34 @@
</dl>
</dd>
<dt><a href="def.html">def.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="def.html#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="def.html#def-spec">def</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="enum.html">enum.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="errors.html">errors.hpp</a></dt>
<dd>
@@ -136,7 +166,6 @@
<dt><a href=
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
</dl>
</dd>
</dl>
@@ -207,7 +236,8 @@
<dd>
<dl class="index">
<dt><a href="module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
<dt><a href=
"module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
</dl>
</dd>
</dl>
@@ -238,6 +268,20 @@
</dd>
</dl>
</dd>
<dt><a href="scope.html">scope.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#scope-spec">scope</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="object_wrappers">Object Wrappers</a></h2>
@@ -308,8 +352,8 @@
<dd>
<dl class="index">
<dt><a href="object.html#object-spec">object</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
@@ -326,6 +370,28 @@
</dd>
</dl>
</dd>
<dt><a href="str.html">tuple.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="tuple.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="tuple.html#tuple-spec">tuple</a></dt>
</dl>
</dd>
<dt><a href="tuple.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href="tuple.html#make_tuple-spec">make_tuple</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="invocation">Function Invocation and Creation</a></h2>
@@ -771,6 +837,8 @@
</dl>
</dd>
<dt><a href="python.html">&lt;boost/python.hpp&gt;</a></dt>
<dt><a href="handle.html">handle.hpp</a></dt>
<dd>
@@ -779,18 +847,17 @@
<dd>
<dl class="index">
<dt><a href=
"handle.html#handle-spec">handle</a></dt>
<dt><a href="handle.html#handle-spec">handle</a></dt>
</dl>
</dd>
<dt><a href="handle.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"handle.html#borrowed-spec">borrowed</a></dt>
<dt><a href=
"handle.html#allow_null-spec">allow_null</a></dt>
<dt><a href="handle.html#borrowed-spec">borrowed</a></dt>
<dt><a href="handle.html#allow_null-spec">allow_null</a></dt>
</dl>
</dd>
</dl>
@@ -818,11 +885,20 @@
</dl>
</dd>
</dl>
<h2><a name="topics">Topics</a></h2>
<dl>
<dt><a href="callbacks.html">Calling Python Functions and
Methods</a></dt>
<dt><a href="pickle.html">Pickle Support</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
3 June, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
08 October, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c3">&copy; Copyright <a href=

View File

@@ -6,57 +6,57 @@
#ifndef PYTHON_DWA2002810_HPP
# define PYTHON_DWA2002810_HPP
# include <boost/python/args.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/python/back_reference.hpp>
# include <boost/python/bases.hpp>
# include <boost/python/borrowed.hpp>
# include <boost/python/call.hpp>
# include <boost/python/call_method.hpp>
# include <boost/python/class.hpp>
# include <boost/python/copy_const_reference.hpp>
# include <boost/python/copy_non_const_reference.hpp>
# include <boost/python/data_members.hpp>
# include <boost/python/def.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/dict.hpp>
# include <boost/python/enum.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/exception_translator.hpp>
# include <boost/python/extract.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/has_back_reference.hpp>
# include <boost/python/implicit.hpp>
# include <boost/python/init.hpp>
# include <boost/python/instance_holder.hpp>
# include <boost/python/iterator.hpp>
# include <boost/python/list.hpp>
# include <boost/python/long.hpp>
# include <boost/python/lvalue_from_pytype.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/manage_new_object.hpp>
# include <boost/python/module.hpp>
# include <boost/python/numeric.hpp>
# include <boost/python/object.hpp>
# include <boost/python/object_protocol.hpp>
# include <boost/python/object_protocol_core.hpp>
# include <boost/python/operators.hpp>
# include <boost/python/other.hpp>
# include <boost/python/overloads.hpp>
# include <boost/python/pointee.hpp>
# include <boost/python/ptr.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/scope.hpp>
# include <boost/python/self.hpp>
# include <boost/python/slice_nil.hpp>
# include <boost/python/str.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/python/to_python_value.hpp>
# include <boost/python/tuple.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/with_custodian_and_ward.hpp>
# include <args.hpp>
# include <args_fwd.hpp>
# include <back_reference.hpp>
# include <bases.hpp>
# include <borrowed.hpp>
# include <call.hpp>
# include <call_method.hpp>
# include <class.hpp>
# include <copy_const_reference.hpp>
# include <copy_non_const_reference.hpp>
# include <data_members.hpp>
# include <def.hpp>
# include <default_call_policies.hpp>
# include <dict.hpp>
# include <enum.hpp>
# include <errors.hpp>
# include <exception_translator.hpp>
# include <extract.hpp>
# include <handle.hpp>
# include <has_back_reference.hpp>
# include <implicit.hpp>
# include <init.hpp>
# include <instance_holder.hpp>
# include <iterator.hpp>
# include <list.hpp>
# include <long.hpp>
# include <lvalue_from_pytype.hpp>
# include <make_function.hpp>
# include <manage_new_object.hpp>
# include <module.hpp>
# include <numeric.hpp>
# include <object.hpp>
# include <object_protocol.hpp>
# include <object_protocol_core.hpp>
# include <operators.hpp>
# include <other.hpp>
# include <overloads.hpp>
# include <pointee.hpp>
# include <ptr.hpp>
# include <reference_existing_object.hpp>
# include <return_internal_reference.hpp>
# include <return_value_policy.hpp>
# include <scope.hpp>
# include <self.hpp>
# include <slice_nil.hpp>
# include <str.hpp>
# include <to_python_converter.hpp>
# include <to_python_indirect.hpp>
# include <to_python_value.hpp>
# include <tuple.hpp>
# include <type_id.hpp>
# include <with_custodian_and_ward.hpp>
#endif PYTHON_DWA2002810_HPP

View File

@@ -46,11 +46,9 @@ inline T* expect_non_null(T* x)
return x;
}
# ifdef BOOST_PYTHON_V2
// Return source if it is an instance of pytype; throw an appropriate
// exception otherwise.
BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* pytype, PyObject* source);
# endif
}} // namespace boost::python

View File

@@ -138,16 +138,16 @@ struct init_base
init_base(char const* doc_, detail::keyword_range const& keywords_)
: m_doc(doc_), m_keywords(keywords_)
{}
init_base(char const* doc_)
: m_doc(doc_)
{}
DerivedT const& derived() const
{
return *static_cast<DerivedT const*>(this);
}
char const* doc_string() const
{
return m_doc;
@@ -162,7 +162,7 @@ struct init_base
{
return default_call_policies();
}
private: // data members
char const* m_doc;
detail::keyword_range m_keywords;
@@ -192,7 +192,7 @@ class init_with_call_policies
{
return this->m_policies;
}
private: // data members
CallPoliciesT m_policies;
};
@@ -270,13 +270,13 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
typedef typename mpl::fold<
required_args
, mpl::list0<>
, mpl::push_front<mpl::_,mpl::_>
, mpl::push_front<>
>::type reversed_required;
typedef typename mpl::fold<
optional_args
, reversed_required
, mpl::push_front<mpl::_,mpl::_>
, mpl::push_front<>
>::type reversed_args;
// Count the maximum number of arguments
@@ -310,7 +310,7 @@ namespace detail
typedef typename mpl::fold<
ReversedArgs
, mpl::list0<>
, mpl::push_front<mpl::_,mpl::_>
, mpl::push_front<>
>::type args;
typedef typename ClassT::holder_selector holder_selector_t;
@@ -355,7 +355,7 @@ namespace detail
if (keywords.second > keywords.first)
--keywords.second;
typename mpl::pop_front<ReversedArgs>::type next;
define_class_init_helper<N-1>::apply(cl, policies, next, doc, keywords);
}

View File

@@ -1,555 +1,332 @@
// (C) Copyright Ullrich Koethe and David Abrahams 2000-2001. Permission to
// copy, use, modify, sell and distribute this software is granted provided
// this copyright notice appears in all copies. This software is provided "as
// is" without express or implied warranty, and with no claim as to its
// suitability for any purpose.
//
// The authors gratefully acknowlege the support of Dragon Systems, Inc., in
// producing this work.
//
// Revision History:
// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams)
// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams)
#ifndef OPERATORS_UK112000_H_
# define OPERATORS_UK112000_H_
# ifdef BOOST_PYTHON_V2
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef OPERATORS_DWA2002530_HPP
# define OPERATORS_DWA2002530_HPP
# include <boost/python/operators2.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/arg_to_python.hpp>
# include <boost/python/detail/operator_id.hpp>
# include <boost/python/detail/not_specified.hpp>
# include <boost/python/back_reference.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/self.hpp>
# include <boost/python/other.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/python/refcount.hpp>
# include <string>
# include <complex>
# else
# include <boost/python/reference.hpp>
# include <boost/python/detail/functions.hpp>
// When STLport is used with native streams, _STL::ostringstream().str() is not
// _STL::string, but std::string. This confuses to_python(), so we'll use
// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
# define BOOST_PYTHON_USE_SSTREAM
# endif
# if defined(BOOST_PYTHON_USE_SSTREAM)
# include <sstream>
# else
# include <strstream>
# endif
namespace boost { namespace python {
BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r);
namespace detail {
// helper class for automatic operand type detection
// during operator wrapping.
struct auto_operand {};
}
// Define operator ids that can be or'ed together
// (boost::python::op_add | boost::python::op_sub | boost::python::op_mul).
// This allows to wrap several operators in one line.
enum operator_id
{
op_add = 0x1,
op_sub = 0x2,
op_mul = 0x4,
op_div = 0x8,
op_mod = 0x10,
op_divmod =0x20,
op_pow = 0x40,
op_lshift = 0x80,
op_rshift = 0x100,
op_and = 0x200,
op_xor = 0x400,
op_or = 0x800,
op_neg = 0x1000,
op_pos = 0x2000,
op_abs = 0x4000,
op_invert = 0x8000,
op_int = 0x10000,
op_long = 0x20000,
op_float = 0x40000,
op_str = 0x80000,
op_cmp = 0x100000,
op_gt = 0x200000,
op_ge = 0x400000,
op_lt = 0x800000,
op_le = 0x1000000,
op_eq = 0x2000000,
op_ne = 0x4000000
};
// Wrap the operators given by "which". Usage:
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>());
template <long which, class operand = boost::python::detail::auto_operand>
struct operators {};
// Wrap heterogeneous operators with given left operand type. Usage:
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
// boost::python::left_operand<int>());
template <class T>
struct left_operand {};
// Wrap heterogeneous operators with given right operand type. Usage:
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
// boost::python::right_operand<int>());
template <class T>
struct right_operand {};
namespace boost { namespace python {
namespace detail
{
template <class Specified>
struct operand_select
// This is essentially the old v1 to_python(). It will be eliminated
// once the public interface for to_python is settled on.
template <class T>
PyObject* convert_result(T const& x)
{
template <class wrapped_type>
struct wrapped
{
typedef Specified type;
};
};
template <>
struct operand_select<auto_operand>
{
template <class wrapped_type>
struct wrapped
{
typedef const wrapped_type& type;
};
};
template <long> struct define_operator;
// Base class which grants access to extension_class_base::add_method() to its derived classes
struct add_operator_base
{
protected:
static inline void add_method(extension_class_base* target, function* method, const char* name)
{ target->add_method(method, name); }
};
//
// choose_op, choose_unary_op, and choose_rop
//
// These templates use "poor man's partial specialization" to generate the
// appropriate add_method() call (if any) for a given operator and argument set.
//
// Usage:
// choose_op<(which & op_add)>::template args<left_t,right_t>::add(ext_class);
//
// (see extension_class<>::def_operators() for more examples).
//
template <long op_selector>
struct choose_op
{
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template operator_function<Left, Right>(),
def_op::name());
}
};
};
// specialization for 0 has no effect
template <>
struct choose_op<0>
{
template <class Left, class Right = Left>
struct args
{
static inline void add(extension_class_base*)
{
}
};
};
template <long op_selector>
struct choose_unary_op
{
template <class Operand>
struct args : add_operator_base
{
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template operator_function<Operand>(),
def_op::name());
}
};
};
// specialization for 0 has no effect
template <>
struct choose_unary_op<0>
{
template <class Operand>
struct args
{
static inline void add(extension_class_base*)
{
}
};
};
template <long op_selector>
struct choose_rop
{
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template roperator_function<Right, Left>(),
def_op::rname());
}
};
};
// specialization for 0 has no effect
template <>
struct choose_rop<0>
{
template <class Left, class Right = Left>
struct args
{
static inline void add(extension_class_base*)
{
}
};
};
// Fully specialize define_operator for all operators defined in operator_id above.
// Every specialization defines one function object for normal operator calls and one
// for operator calls with operands reversed ("__r*__" function variants).
// Specializations for most operators follow a standard pattern: execute the expression
// that uses the operator in question. This standard pattern is realized by the following
// macros so that the actual specialization can be done by just calling a macro.
# define PY_DEFINE_BINARY_OPERATORS(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class Left, class Right = Left> \
struct operator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
}; \
\
template <class Right, class Left> \
struct roperator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())); \
} \
\
const char* description() const \
{ return "__r" #id "__"; } \
\
}; \
\
static const char * name() { return "__" #id "__"; } \
static const char * rname() { return "__r" #id "__"; } \
return converter::arg_to_python<T>(x).release();
}
# define PY_DEFINE_UNARY_OPERATORS(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()))); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
}; \
\
static const char * name() { return "__" #id "__"; } \
}
PY_DEFINE_BINARY_OPERATORS(add, +);
PY_DEFINE_BINARY_OPERATORS(sub, -);
PY_DEFINE_BINARY_OPERATORS(mul, *);
PY_DEFINE_BINARY_OPERATORS(div, /);
PY_DEFINE_BINARY_OPERATORS(mod, %);
PY_DEFINE_BINARY_OPERATORS(lshift, <<);
PY_DEFINE_BINARY_OPERATORS(rshift, >>);
PY_DEFINE_BINARY_OPERATORS(and, &);
PY_DEFINE_BINARY_OPERATORS(xor, ^);
PY_DEFINE_BINARY_OPERATORS(or, |);
PY_DEFINE_BINARY_OPERATORS(gt, >);
PY_DEFINE_BINARY_OPERATORS(ge, >=);
PY_DEFINE_BINARY_OPERATORS(lt, <);
PY_DEFINE_BINARY_OPERATORS(le, <=);
PY_DEFINE_BINARY_OPERATORS(eq, ==);
PY_DEFINE_BINARY_OPERATORS(ne, !=);
PY_DEFINE_UNARY_OPERATORS(neg, -);
PY_DEFINE_UNARY_OPERATORS(pos, +);
PY_DEFINE_UNARY_OPERATORS(abs, abs);
PY_DEFINE_UNARY_OPERATORS(invert, ~);
PY_DEFINE_UNARY_OPERATORS(int, long);
PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong);
PY_DEFINE_UNARY_OPERATORS(float, double);
# undef PY_DEFINE_BINARY_OPERATORS
# undef PY_DEFINE_UNARY_OPERATORS
// Some operators need special treatment, e.g. because there is no corresponding
// expression in C++. These are specialized manually.
// pow(): Manual specialization needed because an error message is required if this
// function is called with three arguments. The "power modulo" operator is not
// supported by define_operator, but can be wrapped manually (see special.html).
template <>
struct define_operator<op_pow>
// Operator implementation template declarations. The nested apply
// declaration here keeps MSVC6 happy.
template <operator_id> struct operator_l
{
template <class Left, class Right = Left>
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw_argument_error();
}
return BOOST_PYTHON_CONVERSION::to_python(
pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()),
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
}
const char* description() const
{ return "__pow__"; }
};
template <class Right, class Left>
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
throw_argument_error();
}
return BOOST_PYTHON_CONVERSION::to_python(
pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()),
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
}
const char* description() const
{ return "__rpow__"; }
};
static const char * name() { return "__pow__"; }
static const char * rname() { return "__rpow__"; }
template <class L, class R> struct apply;
};
// divmod(): Manual specialization needed because we must actually call two operators and
// return a tuple containing both results
template <>
struct define_operator<op_divmod>
{
template <class Left, class Right = Left>
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
PyObject * res = PyTuple_New(2);
PyTuple_SET_ITEM(res, 0,
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) /
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
PyTuple_SET_ITEM(res, 1,
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) %
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
return res;
}
const char* description() const
{ return "__divmod__"; }
};
template <class Right, class Left>
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
PyObject * res = PyTuple_New(2);
PyTuple_SET_ITEM(res, 0,
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) /
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
PyTuple_SET_ITEM(res, 1,
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) %
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
return res;
}
const char* description() const
{ return "__rdivmod__"; }
};
static const char * name() { return "__divmod__"; }
static const char * rname() { return "__rdivmod__"; }
};
// cmp(): Manual specialization needed because there is no three-way compare in C++.
// It is implemented by two one-way comparisons with operators reversed in the second.
template <>
struct define_operator<op_cmp>
{
template <class Left, class Right = Left>
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
return BOOST_PYTHON_CONVERSION::to_python(
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) <
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())) ?
- 1 :
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>()) <
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>())) ?
1 :
0) ;
}
const char* description() const
{ return "__cmp__"; }
};
template <class Right, class Left>
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
tuple args(ref(arguments, ref::increment_count));
return BOOST_PYTHON_CONVERSION::to_python(
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) <
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())) ?
- 1 :
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>()) <
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>())) ?
1 :
0) ;
}
const char* description() const
{ return "__rcmp__"; }
};
static const char * name() { return "__cmp__"; }
static const char * rname() { return "__rcmp__"; }
};
# ifndef BOOST_PYTHON_USE_SSTREAM
class unfreezer {
public:
unfreezer(std::ostrstream& s) : m_stream(s) {}
~unfreezer() { m_stream.freeze(false); }
private:
std::ostrstream& m_stream;
};
# endif
// str(): Manual specialization needed because the string conversion does not follow
// the standard pattern relized by the macros.
template <>
struct define_operator<op_str>
template <operator_id> struct operator_r
{
template <class operand>
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject*) const
{
tuple args(ref(arguments, ref::increment_count));
// When STLport is used with native streams, _STL::ostringstream().str() is not
// _STL::string, but std::string.
# ifdef BOOST_PYTHON_USE_SSTREAM
std::ostringstream s;
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
return BOOST_PYTHON_CONVERSION::to_python(s.str());
# else
std::ostrstream s;
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()) << char();
auto unfreezer unfreeze(s);
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
# endif
}
const char* description() const
{ return "__str__"; }
};
static const char * name() { return "__str__"; }
template <class L, class R> struct apply;
};
template <operator_id> struct operator_1
{
template <class T> struct apply;
};
} // namespace detail
// MSVC6 doesn't want us to do this sort of inheritance on a nested
// class template, so we use this layer of indirection to avoid
// ::template<...> on the nested apply functions below
template <operator_id id, class L, class R>
struct operator_l_inner
: operator_l<id>::template apply<L,R>
{};
template <operator_id id, class L, class R>
struct operator_r_inner
: operator_r<id>::template apply<L,R>
{};
template <operator_id id, class T>
struct operator_1_inner
: operator_1<id>::template apply<T>
{};
// Define three different binary_op templates which take care of
// these cases:
// self op self
// self op R
// L op self
//
// The inner apply metafunction is used to adjust the operator to
// the class type being defined. Inheritance of the outer class is
// simply used to provide convenient access to the operation's
// name().
// self op self
template <operator_id id>
struct binary_op : operator_l<id>
{
template <class T>
struct apply : operator_l_inner<id,T,T>
{
};
};
// self op R
template <operator_id id, class R>
struct binary_op_l : operator_l<id>
{
template <class T>
struct apply : operator_l_inner<id,T,R>
{
};
};
// L op self
template <operator_id id, class L>
struct binary_op_r : operator_r<id>
{
template <class T>
struct apply : operator_r_inner<id,L,T>
{
};
};
template <operator_id id>
struct unary_op : operator_1<id>
{
template <class T>
struct apply : operator_1_inner<id,T>
{
};
};
// This type is what actually gets returned from operators used on
// self_t
template <operator_id id, class L = not_specified, class R = not_specified>
struct operator_
: mpl::if_<
is_same<L,self_t>
, typename mpl::if_<
is_same<R,self_t>
, binary_op<id>
, binary_op_l<id,typename unwrap_other<R>::type>
>::type
, typename mpl::if_<
is_same<L,not_specified>
, unary_op<id>
, binary_op_r<id,typename unwrap_other<L>::type>
>::type
>::type
{
};
}
# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
namespace detail \
{ \
template <> \
struct operator_l<op_##id> \
{ \
template <class L, class R> \
struct apply \
{ \
static inline PyObject* execute(L const& l, R const& r) \
{ \
return detail::convert_result(expr); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
\
template <> \
struct operator_r<op_##id> \
{ \
template <class L, class R> \
struct apply \
{ \
static inline PyObject* execute(R const& r, L const& l) \
{ \
return detail::convert_result(expr); \
} \
}; \
static char const* name() { return "__" #rid "__"; } \
}; \
}
# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
namespace self_ns \
{ \
template <class L, class R> \
inline detail::operator_<detail::op_##id,L,R> \
operator##op(L const&, R const&) \
{ \
return detail::operator_<detail::op_##id,L,R>(); \
} \
}
BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
# undef BOOST_PYTHON_BINARY_OPERATOR
// pow isn't an operator in C++; handle it specially.
BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
# undef BOOST_PYTHON_BINARY_OPERATION
namespace self_ns
{
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
template <class L, class R>
inline detail::operator_<detail::op_pow,L,R>
pow(L const&, R const&)
{
return detail::operator_<detail::op_pow,L,R>();
}
# else
// When there's no argument-dependent lookup, we need these
// overloads to handle the case when everything is imported into the
// global namespace. Note that the plain overload below does /not/
// take const& arguments. This is needed by MSVC6 at least, or it
// complains of ambiguities, since there's no partial ordering.
inline detail::operator_<detail::op_pow,self_t,self_t>
pow(self_t, self_t)
{
return detail::operator_<detail::op_pow,self_t,self_t>();
}
template <class R>
inline detail::operator_<detail::op_pow,self_t,R>
pow(self_t const&, R const&)
{
return detail::operator_<detail::op_pow,self_t,R>();
}
template <class L>
inline detail::operator_<detail::op_pow,L,self_t>
pow(L const&, self_t const&)
{
return detail::operator_<detail::op_pow,L,self_t>();
}
# endif
}
# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
namespace detail \
{ \
template <> \
struct operator_l<op_##id> \
{ \
template <class L, class R> \
struct apply \
{ \
static inline PyObject* \
execute(back_reference<L&> l, R const& r) \
{ \
l.get() op r; \
return python::incref(l.source().ptr()); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
} \
namespace self_ns \
{ \
template <class R> \
inline detail::operator_<detail::op_##id,self_t,R> \
operator##op(self_t const&, R const&) \
{ \
return detail::operator_<detail::op_##id,self_t,R>(); \
} \
}
BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
namespace detail \
{ \
template <> \
struct operator_1<op_##id> \
{ \
template <class T> \
struct apply \
{ \
static PyObject* execute(T const& x) \
{ \
return detail::convert_result(op(x)); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
} \
namespace self_ns \
{ \
inline detail::operator_<detail::op_##id> \
func_name(self_t const&) \
{ \
return detail::operator_<detail::op_##id>(); \
} \
}
# undef BOOST_PYTHON_INPLACE_OPERATOR
BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
# undef BOOST_PYTHON_UNARY_OPERATOR
}} // namespace boost::python
# undef BOOST_PYTHON_USE_SSTREAM
# endif
#endif /* OPERATORS_UK112000_H_ */
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::python::self_ns::abs;
using boost::python::self_ns::int_;
using boost::python::self_ns::long_;
using boost::python::self_ns::float_;
using boost::python::self_ns::complex_;
using boost::python::self_ns::str;
using boost::python::self_ns::pow;
# endif
#endif // OPERATORS_DWA2002530_HPP

View File

@@ -25,7 +25,7 @@ namespace // <unnamed>
{
static registry_t registry;
# ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually.
# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
static bool builtin_converters_initialized = false;
if (!builtin_converters_initialized)
{

View File

@@ -10,9 +10,7 @@
#include <boost/python/errors.hpp>
#include <boost/cast.hpp>
#ifdef BOOST_PYTHON_V2
# include <boost/python/detail/exception_handler.hpp>
#endif
#include <boost/python/detail/exception_handler.hpp>
namespace boost { namespace python {
@@ -21,10 +19,8 @@ BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
{
try
{
#ifdef BOOST_PYTHON_V2
if (detail::exception_handler::chain)
return detail::exception_handler::chain->handle(f);
#endif
f();
return false;
}
@@ -75,7 +71,6 @@ namespace detail {
// needed by void_adaptor (see void_adaptor.hpp)
BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 };
#ifdef BOOST_PYTHON_V2
bool exception_handler::operator()(function0<void> const& f) const
{
if (m_next)
@@ -110,7 +105,6 @@ BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f)
// interpreter exits).
new exception_handler(f);
}
#endif
} // namespace boost::python::detail

View File

@@ -120,7 +120,7 @@ if $(TEST_BIENSTMAN_NON_BUGS)
# --- unit tests of library components ---
local UNIT_TEST_PROPERTIES =
local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
[ difference $(PYTHON_PROPERTIES) : <define>BOOST_PYTHON_DYNAMIC_LIB ] <define>BOOST_PYTHON_STATIC_LIB ;
run indirect_traits_test.cpp ;