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

Compare commits

..

15 Commits

Author SHA1 Message Date
Beman Dawes
e376cbbd95 Release 1.43.0
[SVN r61817]
2010-05-06 13:21:09 +00:00
Ralf W. Grosse-Kunstleve
86db60255a libs/python/test/Jamfile.v2: disabling calling_conventions tests
[SVN r61034]
2010-04-04 05:23:15 +00:00
Ralf W. Grosse-Kunstleve
37b45d2baf merging current boost/python and libs/python from trunk into release branch
[SVN r61033]
2010-04-04 05:19:57 +00:00
Ralf W. Grosse-Kunstleve
471be524f4 boost.python: merging from trunk to release (gcc 4.4 -std=c++0x compatibility)
[SVN r57837]
2009-11-21 14:41:51 +00:00
Ralf W. Grosse-Kunstleve
e485244886 boost.python: merging from trunk to release (Troy Straszheim's fix for a long-standing bug)
[SVN r57621]
2009-11-13 00:40:01 +00:00
Troy D. Straszheim
b9cd3ff109 merge from trunk very minor fixes for ticket #2582
[SVN r57017]
2009-10-20 15:18:26 +00:00
Troy D. Straszheim
d804f1250e rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Ralf W. Grosse-Kunstleve
89100353db boost/python, libs/python: all changes from trunk merged into branches/release
[SVN r56806]
2009-10-13 22:37:59 +00:00
Ralf W. Grosse-Kunstleve
46be73387c boost/python/object_operators.hpp: merging trunk rev. 55708 into release branch
[SVN r55742]
2009-08-23 21:22:52 +00:00
Ralf W. Grosse-Kunstleve
d685a5e8c5 python library: sync with trunk to adopt recent exec.cpp fixes
[SVN r55642]
2009-08-18 01:08:46 +00:00
Ralf W. Grosse-Kunstleve
e80224b1ad boost/python, libs/python: all changes from trunk merged into branches/release (without any manual modifications)
Commands used:
  svn merge https://svn.boost.org/svn/boost/branches/release/boost/python https://svn.boost.org/svn/boost/trunk/boost/python /net/chevy/raid1/rwgk/boost_release/merge_attempt/boost/boost/python

  svn merge https://svn.boost.org/svn/boost/branches/release/libs/python https://svn.boost.org/svn/boost/trunk/libs/python /net/chevy/raid1/rwgk/boost_release/merge_attempt/boost/libs/python

  svn, version 1.6.4 (r38063)
     compiled Aug 17 2009, 13:31:03


[SVN r55629]
2009-08-17 21:01:18 +00:00
Troy D. Straszheim
03fdf5b992 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Jeremiah Willcock
73b4cd3325 Fixed almost all tab and min/max issues found by inspect tool
[SVN r53142]
2009-05-20 19:41:20 +00:00
Douglas Gregor
f7d31f6ead Fix Boost.Python tests
[SVN r52856]
2009-05-08 20:42:11 +00:00
Douglas Gregor
47bb3f55a7 Add the pyrun.py script used to run Boost.Python tests via CMake
[SVN r52818]
2009-05-07 04:44:23 +00:00
123 changed files with 2257 additions and 1128 deletions

View File

@@ -1,80 +0,0 @@
if (PYTHON_LIBRARIES)
include_directories(${PYTHON_INCLUDE_PATH})
# Determine extra libraries we need to link against to build Python
# extension modules.
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "DragonFly")
# DragonFly is a variant of FreeBSD
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
# No options necessary for QNX
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# No options necessary for Mac OS X
elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
elseif(UNIX)
# Assume -pthread and -ldl on all other variants
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "util")
endif(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
################################################################################
#-- Macro for building Boost.Python extension modules
macro(boost_python_extension MODULE_NAME)
parse_arguments(BPL_EXT
""
""
${ARGN})
#TODO: The target properties are NOT being set correctly for the test libraries
if (FALSE)
# Create the library target itself
add_library(${MODULE_NAME} MODULE ${BPL_EXT_DEFAULT_ARGS} )
# Miscellaneous target properties
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
# Link against Boost.Python library
target_link_libraries(${MODULE_NAME} boost_python-static)
# Link against Python libraries
target_link_libraries(${MODULE_NAME} ${PYTHON_LIBRARIES})
endif(FALSE)
boost_add_library(
${MODULE_NAME}
${BPL_EXT_DEFAULT_ARGS}
MODULE
LINK_LIBS ${PYTHON_LIBRARIES}
DEPENDS boost_python
)
endmacro(boost_python_extension)
#--
################################################################################
boost_library_project(
Python
SRCDIRS src
TESTDIRS test
HEADERS python.hpp python
MODULARIZED
DESCRIPTION "A framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler."
AUTHORS "David Abrahams <dave -at- boostpro.com>"
)
endif (PYTHON_LIBRARIES)

View File

@@ -3,7 +3,9 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ;
import indirect ;
import modules ;
import feature ;
import python ;
@@ -22,73 +24,121 @@ if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
}
}
rule find-py3-version
{
local versions = [ feature.values python ] ;
local py3ver ;
for local v in $(versions)
{
if $(v) >= 3.0
{
py3ver = $(v) ;
}
}
return $(py3ver) ;
}
py3-version = [ find-py3-version ] ;
project boost/python
: source-location ../src
: requirements
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
if $(name) = boost_python && $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
}
# forward to the boost tagging rule
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
$(result) : $(type) : $(property-set) ] ;
}
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
lib boost_python
: # sources
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
rule lib_boost_python ( is-py3 ? )
{
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
lib [ cond $(is-py3) : boost_python3 : boost_python ]
: # sources
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
[ cond $(is-py3) : <python>$(py3-version) ]
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
lib_boost_python ;
boost-install boost_python ;
if $(py3-version)
{
lib_boost_python yes ;
boost-install boost_python3 ;
}

View File

@@ -32,7 +32,43 @@
<hr>
<dl class="page-index">
<dt>Current SVN</dt>
<dd>
<ul>
<li>Python 3 support:</li>
<ul>
<li>All the current Boost.Python test cases passed. Extension modules using
Boost.Python expected to support Python 3 smoothly.</li>
<li>Introduced <code>object.contains</code> where <code>x.contains(y)</code>
is equivalent to Python code <code>y in x</code>.
Now <code>dict.has_key</code> is just a wrapper of <code>object.contains</code>.
</li>
<li>When building against Python 3, <code>str.decode</code> will be removed.</li>
<li>When building against Python 3, the original signature of <code>list.sort</code>, which is:
<pre>void sort(object_cref cmpfunc);</pre>
will change to:
<pre>void sort(args_proxy const &args, kwds_proxy const &kwds);</pre>
This is because in Python 3 <code>list.sort</code> requires all its arguments be keyword arguments.
So you should call it like this:
<pre>x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));</pre>
</li>
<li>According to <a href="http://www.python.org/dev/peps/pep-3123/">PEP 3123</a>,
when building Boost.Python against Python older than 2.6, the following macros will
be defined in Boost.Python header:
<pre>
# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)</pre>
So extension writers can use these macro directly, to make code clean and compatible with Python 3.
</li>
</ul>
</ul>
</dd>
<dt>1.39.0 Release</dt>
<dd>
<ul>

View File

@@ -10,10 +10,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -31,7 +31,7 @@
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id455921"></a><p>
<a name="id457106"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
http://www.boost.org/LICENSE_1_0.txt </a>)
@@ -94,15 +94,14 @@
(IDL).
</p>
<a name="quickstart.hello_world"></a><h2>
<a name="id385276"></a>
<a name="id386707"></a>
Hello World
</h2>
<p>
Following C/C++ tradition, let's start with the "hello, world". A
C++ Function:
</p>
<pre class="programlisting">
<span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
<pre class="programlisting"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="string">"hello, world"</span><span class="special">;</span>
<span class="special">}</span>
@@ -110,8 +109,7 @@
<p>
can be exposed to Python by writing a Boost.Python wrapper:
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
<span class="special">{</span>
@@ -125,8 +123,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
</pre>
@@ -145,7 +142,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: March 24, 2008 at 23:09:39 GMT</small></p></td>
<td align="left"><p><small>Last revised: November 22, 2008 at 03:24:11 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,10 +12,10 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
@@ -64,8 +64,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
</span><span class="keyword">try</span><span class="special">:</span>
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
@@ -79,16 +78,14 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;();</span>
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;();</span>
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
</pre>
<p>
Or for use in class_&lt;&gt;:
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
<span class="bold"><b>range</b></span>
@@ -134,8 +131,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
@@ -146,8 +142,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="string">"Field"</span><span class="special">)</span>
<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="string">"Field"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
</pre>
@@ -163,8 +158,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
<span class="comment">// Turn a Python sequence into an STL input range
</span> <span class="identifier">stl_input_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
@@ -183,8 +177,7 @@
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
</pre>
</div>

View File

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

View File

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

View File

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

View File

@@ -106,6 +106,33 @@
function from being treated as an exported symbol on platforms which
support that distinction in-code</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_CDECL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__cdecl
</code> calling convention to be wrapped.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_STDCALL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__stdcall
</code> calling convention to be wrapped.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_FASTCALL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__fastcall
</code> calling convention to be wrapped.</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation

View File

@@ -655,6 +655,11 @@ namespace boost { namespace python { namespace api
template &lt;class A0, class A1,...class An&gt;
object operator()(A0 const&amp;, A1 const&amp;,...An const&amp;) const;
detail::args_proxy operator* () const;
object operator()(detail::args_proxy const &amp;args) const;
object operator()(detail::args_proxy const &amp;args,
detail::kwds_proxy const &amp;kwds) const;
// truth value testing
//
typedef unspecified bool_type;
@@ -704,6 +709,25 @@ object operator()(A0 const&amp; a1, A1 const&amp; a2,...An const&amp; aN) const;
call&lt;object&gt;(object(*static_cast&lt;U*&gt;(this)).ptr(), a1,
a2,...aN)</dt>
</dl>
<pre>
object operator()(detail::args_proxy const &amp;args) const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
call object with arguments given by the tuple <varname>args</varname></dt>
</dl>
<pre>
object operator()(detail::args_proxy const &amp;args,
detail::kwds_proxy const &amp;kwds) const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
call object with arguments given by the tuple <varname>args</varname>, and named
arguments given by the dictionary <varname>kwds</varname></dt>
</dl>
<pre>
operator bool_type() const;
</pre>
@@ -811,6 +835,8 @@ namespace boost { namespace python { namespace api
object&amp; operator=(object const&amp;);
PyObject* ptr() const;
bool is_none() const;
};
}}}
</pre>
@@ -871,6 +897,14 @@ PyObject* ptr() const;
<dt><b>Returns:</b> a pointer to the internally-held Python
object.</dt>
</dl>
<pre>
bool is_none() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> result of (ptr() == Py_None)</dt>
</dl>
<!-- -->
<h3><a name="proxy-spec"></a>Class template <code>proxy</code></h3>
@@ -1077,7 +1111,7 @@ object sum_items(object seq)
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
27 May, 2008
15 March, 2010
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -2,6 +2,15 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
if ! [ python.configured ]
{
ECHO "notice: no Python configured in user-config.jam" ;
ECHO "notice: will use default configuration" ;
using python ;
}
# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost

View File

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

View File

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

View File

@@ -90,6 +90,14 @@ namespace detail
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
// Specialize converters for signed and unsigned T to Python Int
#if PY_VERSION_HEX >= 0x03000000
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyLong_FromLong(x), &PyLong_Type) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, ::PyLong_FromUnsignedLong(x), &PyLong_Type)
#else
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
@@ -98,6 +106,7 @@ namespace detail
(std::numeric_limits<long>::max)()) \
? ::PyLong_FromUnsignedLong(x) \
: ::PyInt_FromLong(x), &PyInt_Type)
#endif
// Bool is not signed.
#if PY_VERSION_HEX >= 0x02030000
@@ -116,17 +125,24 @@ BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyLong_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
# endif
# undef BOOST_TO_PYTHON_INT
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyUnicode_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyUnicode_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyUnicode_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
#else
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
#endif
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)

View File

@@ -34,7 +34,9 @@ struct pyobject_traits<PyObject>
// This is not an exhaustive list; should be expanded.
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
#if PY_VERSION_HEX < 0x03000000
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
#endif
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);

View File

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

View File

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

View File

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

View File

@@ -55,8 +55,8 @@ inline decorated_type_info::decorated_type_info(type_info base_t, decoration dec
inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const
{
return m_decoration < rhs.m_decoration
|| m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type;
|| (m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type);
}
inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const

View File

@@ -30,7 +30,7 @@ struct value_destroyer<
template <class T>
static void execute(T const volatile* p)
{
p->T::~T();
p->~T();
}
};

View File

@@ -47,7 +47,11 @@ enum operator_id
op_ixor,
op_ior,
op_complex,
#if PY_VERSION_HEX >= 0x03000000
op_bool,
#else
op_nonzero,
#endif
op_repr
};

View File

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

View File

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

View File

@@ -2,13 +2,15 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP
# define TRANSLATE_EXCEPTION_DWA2002810_HPP
#ifndef TRANSLATE_EXCEPTION_TDS20091020_HPP
# define TRANSLATE_EXCEPTION_TDS20091020_HPP
# include <boost/python/detail/exception_handler.hpp>
# include <boost/call_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/function/function0.hpp>

View File

@@ -175,6 +175,19 @@ typedef int pid_t;
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
#endif
// Define Python 3 macros for Python 2.x
#if PY_VERSION_HEX < 0x02060000
# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)
# define PyVarObject_HEAD_INIT(type, size) \
PyObject_HEAD_INIT(type) size,
#endif
#ifdef __MWERKS__
# pragma warn_possunwant off
#elif _MSC_VER

View File

@@ -41,7 +41,7 @@ inline enum_<T>::enum_(char const* name, char const* doc )
, &enum_<T>::convertible_from_python
, &enum_<T>::construct
, type_id<T>()
, doc
, doc
)
{
}
@@ -79,7 +79,11 @@ void* enum_<T>::convertible_from_python(PyObject* obj)
template <class T>
void enum_<T>::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data)
{
#if PY_VERSION_HEX >= 0x03000000
T x = static_cast<T>(PyLong_AS_LONG(obj));
#else
T x = static_cast<T>(PyInt_AS_LONG(obj));
#endif
void* const storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
new (storage) T(x);
data->convertible = storage;

View File

@@ -20,6 +20,13 @@ object
BOOST_PYTHON_DECL
eval(str string, object global = object(), object local = object());
// Execute an individual python statement from str.
// global and local are the global and local scopes respectively,
// used during execution.
object
BOOST_PYTHON_DECL
exec_statement(str string, object global = object(), object local = object());
// Execute python source code from str.
// global and local are the global and local scopes respectively,
// used during execution.

View File

@@ -19,7 +19,7 @@ namespace detail
{
void append(object_cref); // append object to end
long count(object_cref value) const; // return number of occurrences of value
ssize_t count(object_cref value) const; // return number of occurrences of value
void extend(object_cref sequence); // extend list by appending sequence elements
@@ -37,8 +37,12 @@ namespace detail
void reverse(); // reverse *IN PLACE*
void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
#if PY_VERSION_HEX >= 0x03000000
void sort(args_proxy const &args,
kwds_proxy const &kwds);
#else
void sort(object_cref cmpfunc);
#endif
protected:
list_base(); // new list
@@ -113,13 +117,15 @@ class list : public detail::list_base
base::remove(object(value));
}
#if PY_VERSION_HEX <= 0x03000000
void sort() { base::sort(); }
template <class T>
void sort(T const& value)
{
base::sort(object(value));
}
#endif
public: // implementation detail -- for internal use only
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base)

View File

@@ -63,7 +63,7 @@ struct extract_member
{
static MemberType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
(void)Py_TYPE(&c); // static assertion
return c.*member;
}
};
@@ -75,7 +75,7 @@ struct extract_identity
{
static InstanceType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
(void)Py_TYPE(&c); // static assertion
return c;
}
};

View File

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

View File

@@ -11,40 +11,49 @@
namespace boost { namespace python { namespace detail {
BOOST_PYTHON_DECL void init_module(char const* name, void(*)());
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
}}}
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# if PY_VERSION_HEX >= 0x03000000
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __declspec(dllexport) void init##name() \
# define _BOOST_PYTHON_MODULE_INIT(name) \
PyObject* PyInit_##name() \
{ \
return boost::python::detail::init_module( \
#name,&init_module_##name); \
} \
void init_module_##name()
# else
# define _BOOST_PYTHON_MODULE_INIT(name) \
void init##name() \
{ \
boost::python::detail::init_module( \
#name,&init_module_##name); \
} \
void init_module_##name()
# endif
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __attribute__ ((visibility("default"))) void init##name() \
{ \
boost::python::detail::init_module(#name, &init_module_##name); \
} \
void init_module_##name()
extern "C" __attribute__ ((visibility("default"))) _BOOST_PYTHON_MODULE_INIT(name)
# else
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" void init##name() \
{ \
boost::python::detail::init_module(#name, &init_module_##name); \
} \
void init_module_##name()
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
# endif

View File

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

View File

@@ -129,7 +129,11 @@ namespace detail
return class_<range_>(name, no_init)
.def("__iter__", identity_function())
.def(
#if PY_VERSION_HEX >= 0x03000000
"__next__"
#else
"next"
#endif
, make_function(
next_fn()
, policies

View File

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

View File

@@ -10,6 +10,7 @@
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/decref_guard.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/type_traits/is_union.hpp>
namespace boost { namespace python { namespace objects {
@@ -21,7 +22,7 @@ struct make_instance_impl
template <class Arg>
static inline PyObject* execute(Arg& x)
{
BOOST_STATIC_ASSERT(is_class<T>::value);
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));
PyTypeObject* type = Derived::get_class_object(x);
@@ -43,7 +44,7 @@ struct make_instance_impl
// Note the position of the internally-stored Holder,
// for the sake of destruction
instance->ob_size = offsetof(instance_t, storage);
Py_SIZE(instance) = offsetof(instance_t, storage);
// Release ownership of the python object
protect.cancel();

View File

@@ -35,6 +35,8 @@
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/remove_const.hpp>
namespace boost { namespace python {
template <class T> class wrapper;
@@ -122,19 +124,29 @@ inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_referen
template <class Pointer, class Value>
void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
{
typedef typename boost::remove_const< Value >::type non_const_value;
if (dst_t == python::type_id<Pointer>()
&& !(null_ptr_only && get_pointer(this->m_p))
)
return &this->m_p;
Value* p = get_pointer(this->m_p);
Value* p0
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
= static_cast<Value*>( get_pointer(this->m_p) )
# else
= get_pointer(this->m_p)
# endif
;
non_const_value* p = const_cast<non_const_value*>( p0 );
if (p == 0)
return 0;
if (void* wrapped = holds_wrapped(dst_t, p, p))
return wrapped;
type_info src_t = python::type_id<Value>();
type_info src_t = python::type_id<non_const_value>();
return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}
@@ -163,7 +175,10 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
# endif // POINTER_HOLDER_DWA20011215_HPP
/* --------------- pointer_holder --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
@@ -205,4 +220,5 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif

View File

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

View File

@@ -5,6 +5,8 @@
#ifndef OBJECT_CORE_DWA2002615_HPP
# define OBJECT_CORE_DWA2002615_HPP
# define BOOST_PYTHON_OBJECT_HAS_IS_NONE // added 2010-03-15 by rwgk
# include <boost/python/detail/prefix.hpp>
# include <boost/type.hpp>
@@ -42,6 +44,12 @@
namespace boost { namespace python {
namespace detail
{
class kwds_proxy;
class args_proxy;
}
namespace converter
{
template <class T> struct arg_to_python;
@@ -102,6 +110,11 @@ namespace api
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
# include BOOST_PP_ITERATE()
detail::args_proxy operator* () const;
object operator()(detail::args_proxy const &args) const;
object operator()(detail::args_proxy const &args,
detail::kwds_proxy const &kwds) const;
// truth value testing
//
@@ -115,6 +128,10 @@ namespace api
const_object_objattribute attr(object const&) const;
object_objattribute attr(object const&);
// Wrap 'in' operator (aka. __contains__)
template <class T>
object contains(T const& key) const;
// item access
//
const_object_item operator[](object_cref) const;
@@ -219,12 +236,14 @@ namespace api
inline object_base(object_base const&);
inline object_base(PyObject* ptr);
object_base& operator=(object_base const& rhs);
~object_base();
inline object_base& operator=(object_base const& rhs);
inline ~object_base();
// Underlying object access -- returns a borrowed reference
PyObject* ptr() const;
inline PyObject* ptr() const;
inline bool is_none() const;
private:
PyObject* m_ptr;
};
@@ -393,7 +412,7 @@ namespace api
static PyObject*
get(T const& x, U)
{
return python::incref(get_managed_object(x, tag));
return python::incref(get_managed_object(x, boost::python::tag));
}
};
@@ -416,6 +435,71 @@ template <class T> struct extract;
// implementation
//
namespace detail
{
class call_proxy
{
public:
call_proxy(object target) : m_target(target) {}
operator object() const { return m_target;}
private:
object m_target;
};
class kwds_proxy : public call_proxy
{
public:
kwds_proxy(object o = object()) : call_proxy(o) {}
};
class args_proxy : public call_proxy
{
public:
args_proxy(object o) : call_proxy(o) {}
kwds_proxy operator* () const { return kwds_proxy(*this);}
};
}
template <typename U>
detail::args_proxy api::object_operators<U>::operator* () const
{
object_cref2 x = *static_cast<U const*>(this);
return boost::python::detail::args_proxy(x);
}
template <typename U>
object api::object_operators<U>::operator()(detail::args_proxy const &args) const
{
U const& self = *static_cast<U const*>(this);
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
args.operator object().ptr(),
0);
return object(boost::python::detail::new_reference(result));
}
template <typename U>
object api::object_operators<U>::operator()(detail::args_proxy const &args,
detail::kwds_proxy const &kwds) const
{
U const& self = *static_cast<U const*>(this);
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
args.operator object().ptr(),
kwds.operator object().ptr());
return object(boost::python::detail::new_reference(result));
}
template <typename U>
template <class T>
object api::object_operators<U>::contains(T const& key) const
{
return this->attr("__contains__")(object(key));
}
inline object::object()
: object_base(python::incref(Py_None))
{}
@@ -459,6 +543,11 @@ inline PyObject* api::object_base::ptr() const
return m_ptr;
}
inline bool api::object_base::is_none() const
{
return (m_ptr == Py_None);
}
//
// Converter specialization implementations
//

View File

@@ -60,7 +60,9 @@ inline
object_operators<U>::operator bool_type() const
{
object_cref2 x = *static_cast<U const*>(this);
return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0;
int is_true = PyObject_IsTrue(x.ptr());
if (is_true < 0) throw_error_already_set();
return is_true ? &object::ptr : 0;
}
template <class U>
@@ -68,7 +70,9 @@ inline bool
object_operators<U>::operator!() const
{
object_cref2 x = *static_cast<U const*>(this);
return !PyObject_IsTrue(x.ptr());
int is_true = PyObject_IsTrue(x.ptr());
if (is_true < 0) throw_error_already_set();
return !is_true;
}
# define BOOST_PYTHON_COMPARE_OP(op, opid) \

View File

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

View File

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

View File

@@ -121,8 +121,7 @@ opaque<Pointee> opaque<Pointee>::instance;
template <class Pointee>
PyTypeObject opaque<Pointee>::type_object =
{
PyObject_HEAD_INIT(0)
0,
PyVarObject_HEAD_INIT(NULL, 0)
0,
sizeof( BOOST_DEDUCED_TYPENAME opaque<Pointee>::python_instance ),
0,

View File

@@ -341,7 +341,11 @@ 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~)
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_UNARY_OPERATOR(bool, !!, operator!)
#else
BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
#endif
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)

View File

@@ -52,16 +52,23 @@ struct most_derived
//
// template <class RT, class T0... class TN>
// inline mpl::vector<RT, T0...TN>
// get_signature(RT(*)(T0...TN), void* = 0)
// get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0)
// {
// return mpl::list<RT, T0...TN>();
// }
//
// where BOOST_PYTHON_FN_CC is a calling convention keyword, can be
//
// empty, for default calling convention
// __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined)
// __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined)
// __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined)
//
// And, for an appropriate assortment of cv-qualifications::
//
// template <class RT, class ClassT, class T0... class TN>
// inline mpl::vector<RT, ClassT&, T0...TN>
// get_signature(RT(ClassT::*)(T0...TN) cv))
// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv))
// {
// return mpl::list<RT, ClassT&, T0...TN>();
// }
@@ -72,7 +79,7 @@ struct most_derived
// , typename most_derived<Target, ClassT>::type&
// , T0...TN
// >
// get_signature(RT(ClassT::*)(T0...TN) cv), Target*)
// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*)
// {
// return mpl::list<RT, ClassT&, T0...TN>();
// }
@@ -87,7 +94,8 @@ struct most_derived
//
// These functions extract the return type, class (for member
// functions) and arguments of the input signature and stuff them in
// an mpl type sequence. Note that cv-qualification is dropped from
// an mpl type sequence (the calling convention is dropped).
// Note that cv-qualification is dropped from
// the "hidden this" argument of member functions; that is a
// necessary sacrifice to ensure that an lvalue from_python converter
// is used. A pointer is not used so that None will be rejected for
@@ -100,10 +108,64 @@ struct most_derived
//
// @group {
// 'default' calling convention
# define BOOST_PYTHON_FN_CC
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
// __cdecl calling convention
# if defined(BOOST_PYTHON_ENABLE_CDECL)
# define BOOST_PYTHON_FN_CC __cdecl
# define BOOST_PYTHON_FN_CC_IS_CDECL
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# undef BOOST_PYTHON_FN_CC_IS_CDECL
# endif // defined(BOOST_PYTHON_ENABLE_CDECL)
// __stdcall calling convention
# if defined(BOOST_PYTHON_ENABLE_STDCALL)
# define BOOST_PYTHON_FN_CC __stdcall
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# endif // defined(BOOST_PYTHON_ENABLE_STDCALL)
// __fastcall calling convention
# if defined(BOOST_PYTHON_ENABLE_FASTCALL)
# define BOOST_PYTHON_FN_CC __fastcall
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# endif // defined(BOOST_PYTHON_ENABLE_FASTCALL)
# undef BOOST_PYTHON_LIST_INC
// }
@@ -113,21 +175,31 @@ struct most_derived
# endif // SIGNATURE_JDG20020813_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
# define N BOOST_PP_ITERATION()
// as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same
// function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)',
// we don't define it twice
# if !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
template <
class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
inline BOOST_PYTHON_LIST_INC(N)<
RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
{
return BOOST_PYTHON_LIST_INC(N)<
RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
>();
}
# endif // !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
# undef N
# define BOOST_PP_ITERATION_PARAMS_2 \
@@ -143,7 +215,7 @@ template <
class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
{
return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
@@ -162,7 +234,7 @@ inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
>
get_signature(
RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
, Target*
)
{
@@ -176,4 +248,5 @@ get_signature(
# undef Q
# undef N
#endif // BOOST_PP_ITERATION_DEPTH()
#endif // !defined(BOOST_PP_IS_ITERATING)

View File

@@ -37,10 +37,12 @@ namespace detail
long count(object_cref sub, object_cref start, object_cref end) const;
#if PY_VERSION_HEX < 0x03000000
object decode() const;
object decode(object_cref encoding) const;
object decode(object_cref encoding, object_cref errors) const;
#endif
object encode() const;
object encode(object_cref encoding) const;
@@ -185,6 +187,7 @@ class str : public detail::str_base
return base::count(object(sub), object(start));
}
#if PY_VERSION_HEX < 0x03000000
object decode() const { return base::decode(); }
template<class T>
@@ -198,6 +201,7 @@ class str : public detail::str_base
{
return base::decode(object(encoding),object(errors));
}
#endif
object encode() const { return base::encode(); }
@@ -404,7 +408,11 @@ namespace converter
{
template <>
struct object_manager_traits<str>
#if PY_VERSION_HEX >= 0x03000000
: pytype_object_manager_traits<&PyUnicode_Type,str>
#else
: pytype_object_manager_traits<&PyString_Type,str>
#endif
{
};
}

View File

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

View File

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

View File

@@ -37,12 +37,20 @@ void shared_ptr_deleter::operator()(void const*)
namespace
{
// An lvalue conversion function which extracts a char const* from a
// Python String.
#if PY_VERSION_HEX < 0x03000000
void* convert_to_cstring(PyObject* obj)
{
return PyString_Check(obj) ? PyString_AsString(obj) : 0;
}
#else
void* convert_to_cstring(PyObject* obj)
{
return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
}
#endif
// Given a target type and a SlotPolicy describing how to perform a
// given conversion, registers from_python converters which use the
@@ -90,6 +98,52 @@ namespace
}
};
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
// "slot" which just returns its argument.
extern "C" PyObject* identity_unaryfunc(PyObject* x)
{
Py_INCREF(x);
return x;
}
unaryfunc py_object_identity = identity_unaryfunc;
#if PY_VERSION_HEX >= 0x03000000
// As in Python 3 there is only one integer type, we can have much
// simplified logic.
// XXX(bhy) maybe the code will work with 2.6 or even 2.5?
struct int_rvalue_from_python_base
{
static unaryfunc* get_slot(PyObject* obj)
{
return PyLong_Check(obj) ? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() {return &PyLong_Type;}
};
template <class T>
struct signed_int_rvalue_from_python : int_rvalue_from_python_base
{
static T extract(PyObject* intermediate)
{
long x = PyLong_AsLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(x);
}
};
template <class T>
struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
{
static T extract(PyObject* intermediate)
{
unsigned long x = PyLong_AsUnsignedLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(x);
}
};
#else // PY_VERSION_HEX >= 0x03000000
// A SlotPolicy for extracting signed integer types from Python objects
struct signed_int_rvalue_from_python_base
{
@@ -99,8 +153,13 @@ namespace
if (number_methods == 0)
return 0;
return (PyInt_Check(obj) || PyLong_Check(obj))
? &number_methods->nb_int : 0;
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
? &number_methods->nb_int : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
@@ -116,16 +175,7 @@ namespace
return numeric_cast<T>(x);
}
};
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
// "slot" which just returns its argument.
extern "C" PyObject* identity_unaryfunc(PyObject* x)
{
Py_INCREF(x);
return x;
}
unaryfunc py_object_identity = identity_unaryfunc;
// A SlotPolicy for extracting unsigned integer types from Python objects
struct unsigned_int_rvalue_from_python_base
{
@@ -135,7 +185,11 @@ namespace
if (number_methods == 0)
return 0;
return (PyInt_Check(obj) || PyLong_Check(obj))
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
@@ -146,12 +200,30 @@ namespace
{
static T extract(PyObject* intermediate)
{
return numeric_cast<T>(
PyLong_Check(intermediate)
? PyLong_AsUnsignedLong(intermediate)
: PyInt_AS_LONG(intermediate));
if (PyLong_Check(intermediate)) {
// PyLong_AsUnsignedLong() checks for negative overflow, so no
// need to check it here.
unsigned long result = PyLong_AsUnsignedLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(result);
} else {
// None of PyInt_AsUnsigned*() functions check for negative
// overflow, so use PyInt_AS_LONG instead and check if number is
// negative, issuing the exception appropriately.
long result = PyInt_AS_LONG(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
if (result < 0) {
PyErr_SetString(PyExc_OverflowError, "can't convert negative"
" value to unsigned");
throw_error_already_set();
}
return numeric_cast<T>(result);
}
}
};
#endif // PY_VERSION_HEX >= 0x03000000
// Checking Python's macro instead of Boost's - we don't seem to get
// the config right all the time. Furthermore, Python's is defined
@@ -164,6 +236,9 @@ namespace
{
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x03000000
return PyLong_Check(obj) ? &py_object_identity : 0;
#else
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
@@ -176,19 +251,22 @@ namespace
return &number_methods->nb_long;
else
return 0;
#endif
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
static PyTypeObject const* get_pytype() { return &PyLong_Type;}
};
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
{
static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
else
#endif
{
BOOST_PYTHON_LONG_LONG result = PyLong_AsLongLong(intermediate);
@@ -204,11 +282,13 @@ namespace
{
static unsigned BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
}
else
#endif
{
unsigned BOOST_PYTHON_LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate);
@@ -226,7 +306,13 @@ namespace
{
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x03000000
return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
#elif PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
#else
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
#endif
}
static bool extract(PyObject* intermediate)
@@ -255,8 +341,10 @@ namespace
// For integer types, return the tp_int conversion slot to avoid
// creating a new object. We'll handle that below
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(obj))
return &number_methods->nb_int;
#endif
return (PyLong_Check(obj) || PyFloat_Check(obj))
? &number_methods->nb_float : 0;
@@ -264,11 +352,13 @@ namespace
static double extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
else
#endif
{
return PyFloat_AS_DOUBLE(intermediate);
}
@@ -276,22 +366,36 @@ namespace
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
};
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
// A SlotPolicy for extracting C++ strings from Python objects.
struct string_rvalue_from_python
{
// If the underlying object is "string-able" this will succeed
static unaryfunc* get_slot(PyObject* obj)
{
return (PyString_Check(obj))
? &obj->ob_type->tp_str : 0;
#if PY_VERSION_HEX >= 0x03000000
return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc : 0;
#else
return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
#endif
};
// Remember that this will be used to construct the result object
#if PY_VERSION_HEX >= 0x03000000
static std::string extract(PyObject* intermediate)
{
return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
}
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
#else
static std::string extract(PyObject* intermediate)
{
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
}
static PyTypeObject const* get_pytype() { return &PyString_Type;}
#endif
};
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
@@ -311,7 +415,11 @@ namespace
{
return PyUnicode_Check(obj)
? &py_object_identity
#if PY_VERSION_HEX >= 0x03000000
: PyBytes_Check(obj)
#else
: PyString_Check(obj)
#endif
? &py_encode_string
: 0;
};
@@ -354,10 +462,12 @@ namespace
PyComplex_RealAsDouble(intermediate)
, PyComplex_ImagAsDouble(intermediate));
}
#if PY_VERSION_HEX < 0x03000000
else if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
#endif
else
{
return PyFloat_AS_DOUBLE(intermediate);
@@ -369,12 +479,20 @@ namespace
BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
{
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_FromStringAndSize(&x, 1);
#else
return PyString_FromStringAndSize(&x, 1);
#endif
}
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
{
#if PY_VERSION_HEX >= 0x03000000
return x ? PyUnicode_FromString(x) : boost::python::detail::none();
#else
return x ? PyString_FromString(x) : boost::python::detail::none();
#endif
}
BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x)
@@ -429,13 +547,18 @@ void initialize_builtin_converters()
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
// Add an lvalue converter for char which gets us char const*
#if PY_VERSION_HEX < 0x03000000
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
#else
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyUnicode_Type>::get_pytype);
#endif
// Register by-value converters to std::string, std::wstring
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
# endif
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
}
}}} // namespace boost::python::converter

View File

@@ -96,7 +96,12 @@ BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
if (!data.convertible)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, source->ob_type->tp_name
@@ -196,7 +201,12 @@ namespace
void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No registered converter was able to extract a C++ %s to type %s"
" from this Python object of type %s"
, ref_type
@@ -218,7 +228,12 @@ namespace
if (source->ob_refcnt <= 1)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x3000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"Attempt to return dangling %s to object of type: %s"
, ref_type
, converters.target_type.name()));

View File

@@ -70,7 +70,12 @@ BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source)
if (this->m_to_python == 0)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x3000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No to_python (by-value) converter found for C++ type: %s"
, this->target_type.name()
)

View File

@@ -29,7 +29,7 @@ namespace
detail::new_reference dict_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyDict_Type, "(O)",
(PyObject*)&PyDict_Type, const_cast<char*>("(O)"),
arg_.ptr());
}
@@ -84,7 +84,7 @@ object dict_base::get(object_cref k, object_cref d) const
bool dict_base::has_key(object_cref k) const
{
return extract<bool>(this->attr("has_key")(k));
return extract<bool>(this->contains(k));
}
list dict_base::items() const

View File

@@ -5,6 +5,7 @@
#include <boost/python/exec.hpp>
#include <boost/python/borrowed.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/handle.hpp>
@@ -15,6 +16,15 @@ namespace python
object BOOST_PYTHON_DECL eval(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
@@ -24,6 +34,15 @@ object BOOST_PYTHON_DECL eval(str string, object global, object local)
object BOOST_PYTHON_DECL exec(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
@@ -31,18 +50,53 @@ object BOOST_PYTHON_DECL exec(str string, object global, object local)
return object(detail::new_reference(result));
}
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
}
// Execute python source code from file filename.
// global and local are the global and local scopes respectively,
// used during execution.
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
#if PY_VERSION_HEX >= 0x03000000
// TODO(bhy) temporary workaround for Python 3.
// should figure out a way to avoid binary incompatibilities as the Python 2
// version did.
FILE *fs = fopen(f, "r");
#else
// Let python open the file to avoid potential binary incompatibilities.
PyObject *pyfile = PyFile_FromString(f, "r");
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
python::handle<> file(pyfile);
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
FILE *fs = PyFile_AsFile(file.get());
#endif
PyObject* result = PyRun_File(fs,
f,
Py_file_input,
global.ptr(), local.ptr());

View File

@@ -13,7 +13,7 @@ detail::new_non_null_reference list_base::call(object const& arg_)
return (detail::new_non_null_reference)
(expect_non_null)(
PyObject_CallFunction(
(PyObject*)&PyList_Type, "(O)",
(PyObject*)&PyList_Type, const_cast<char*>("(O)"),
arg_.ptr()));
}
@@ -48,7 +48,11 @@ void list_base::extend(object_cref sequence)
long list_base::index(object_cref value) const
{
object result_obj(this->attr("index")(value));
#if PY_VERSION_HEX >= 0x03000000
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
#else
long result = PyInt_AsLong(result_obj.ptr());
#endif
if (result == -1)
throw_error_already_set();
return result;
@@ -69,7 +73,11 @@ void list_base::insert(ssize_t index, object_cref item)
void list_base::insert(object const& index, object_cref x)
{
#if PY_VERSION_HEX >= 0x03000000
ssize_t index_ = PyLong_AsSsize_t(index.ptr());
#else
long index_ = PyInt_AsLong(index.ptr());
#endif
if (index_ == -1 && PyErr_Occurred())
throw_error_already_set();
this->insert(index_, x);
@@ -121,17 +129,29 @@ void list_base::sort()
}
}
#if PY_VERSION_HEX >= 0x03000000
void list_base::sort(args_proxy const &args,
kwds_proxy const &kwds)
{
this->attr("sort")(args, kwds);
}
#else
void list_base::sort(object_cref cmpfunc)
{
this->attr("sort")(cmpfunc);
}
#endif
// For some reason, moving this to the end of the TU suppresses an ICE
// with vc6.
long list_base::count(object_cref value) const
ssize_t list_base::count(object_cref value) const
{
object result_obj(this->attr("count")(value));
#if PY_VERSION_HEX >= 0x03000000
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
#else
long result = PyInt_AsLong(result_obj.ptr());
#endif
if (result == -1)
throw_error_already_set();
return result;

View File

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

View File

@@ -24,11 +24,25 @@ namespace
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
}
BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)())
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
{
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
name,
0, /* m_doc */
-1, /* m_size */
initial_methods,
0, /* m_reload */
0, /* m_traverse */
0, /* m_clear */
0, /* m_free */
};
PyObject* m = PyModule_Create(&moduledef);
#else
PyObject* m
= Py_InitModule(const_cast<char*>(name), initial_methods);
#endif
if (m != 0)
{
@@ -38,6 +52,7 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)())
handle_exception(init_function);
}
return m;
}
}}} // namespace boost::python::detail

View File

@@ -67,14 +67,50 @@ extern "C"
PyObject *prop_set;
PyObject *prop_del;
PyObject *prop_doc;
int getter_doc;
} propertyobject;
// Copied from Python source and removed the part for setting docstring,
// since we don't have a setter for __doc__ and trying to set it will
// cause the init fail.
static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
propertyobject *prop = (propertyobject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
kwlist, &get, &set, &del, &doc))
return -1;
if (get == Py_None)
get = NULL;
if (set == Py_None)
set = NULL;
if (del == Py_None)
del = NULL;
Py_XINCREF(get);
Py_XINCREF(set);
Py_XINCREF(del);
Py_XINCREF(doc);
prop->prop_get = get;
prop->prop_set = set;
prop->prop_del = del;
prop->prop_doc = doc;
prop->getter_doc = 0;
return 0;
}
static PyObject *
static_data_descr_get(PyObject *self, PyObject * /*obj*/, PyObject * /*type*/)
{
propertyobject *gs = (propertyobject *)self;
return PyObject_CallFunction(gs->prop_get, "()");
return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
}
static int
@@ -95,9 +131,9 @@ extern "C"
return -1;
}
if (value == NULL)
res = PyObject_CallFunction(func, "()");
res = PyObject_CallFunction(func, const_cast<char*>("()"));
else
res = PyObject_CallFunction(func, "(O)", value);
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -106,10 +142,9 @@ extern "C"
}
static PyTypeObject static_data_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
"Boost.Python.StaticProperty",
PyType_Type.tp_basicsize,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.StaticProperty"),
sizeof(propertyobject),
0,
0, /* tp_dealloc */
0, /* tp_print */
@@ -143,11 +178,11 @@ static PyTypeObject static_data_object = {
static_data_descr_get, /* tp_descr_get */
static_data_descr_set, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
property_init, /* tp_init */
0, /* tp_alloc */
0, // filled in with type_new /* tp_new */
0, // filled in with __PyObject_GC_Del /* tp_free */
(inquiry)type_is_gc, /* tp_is_gc */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
@@ -160,17 +195,20 @@ static PyTypeObject static_data_object = {
namespace objects
{
#if PY_VERSION_HEX < 0x03000000
// XXX Not sure why this run into compiling error in Python 3
extern "C"
{
// This declaration needed due to broken Python 2.2 headers
extern DL_IMPORT(PyTypeObject) PyProperty_Type;
}
#endif
BOOST_PYTHON_DECL PyObject* static_data()
{
if (static_data_object.tp_dict == 0)
{
static_data_object.ob_type = &PyType_Type;
Py_TYPE(&static_data_object) = &PyType_Type;
static_data_object.tp_base = &PyProperty_Type;
if (PyType_Ready(&static_data_object))
return 0;
@@ -203,16 +241,15 @@ extern "C"
// If we found a static data descriptor, call it directly to
// force it to set the static data member
if (a != 0 && PyObject_IsInstance(a, objects::static_data()))
return a->ob_type->tp_descr_set(a, obj, value);
return Py_TYPE(a)->tp_descr_set(a, obj, value);
else
return PyType_Type.tp_setattro(obj, name, value);
}
}
static PyTypeObject class_metatype_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
"Boost.Python.class",
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.class"),
PyType_Type.tp_basicsize,
0,
0, /* tp_dealloc */
@@ -266,7 +303,7 @@ static PyTypeObject class_metatype_object = {
// object.
void instance_holder::install(PyObject* self) throw()
{
assert(self->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
m_next = ((objects::instance<>*)self)->objects;
((objects::instance<>*)self)->objects = this;
}
@@ -279,7 +316,7 @@ namespace objects
{
if (class_metatype_object.tp_dict == 0)
{
class_metatype_object.ob_type = &PyType_Type;
Py_TYPE(&class_metatype_object) = &PyType_Type;
class_metatype_object.tp_base = &PyType_Type;
if (PyType_Ready(&class_metatype_object))
return type_handle();
@@ -308,7 +345,7 @@ namespace objects
Py_XDECREF(kill_me->dict);
inst->ob_type->tp_free(inst);
Py_TYPE(inst)->tp_free(inst);
}
static PyObject *
@@ -316,9 +353,14 @@ namespace objects
{
// Attempt to find the __instance_size__ attribute. If not present, no problem.
PyObject* d = type_->tp_dict;
PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
ssize_t instance_size = instance_size_obj ?
#if PY_VERSION_HEX >= 0x03000000
PyLong_AsSsize_t(instance_size_obj) : 0;
#else
PyInt_AsLong(instance_size_obj) : 0;
#endif
if (instance_size < 0)
instance_size = 0;
@@ -332,7 +374,12 @@ namespace objects
// like, so we'll store the total size of the object
// there. A negative number indicates that the extra
// instance memory is not yet allocated to any holders.
result->ob_size = -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
#if PY_VERSION_HEX >= 0x02060000
Py_SIZE(result) =
#else
result->ob_size =
#endif
-(static_cast<int>(offsetof(instance<>,storage) + instance_size));
}
return (PyObject*)result;
}
@@ -357,20 +404,19 @@ namespace objects
static PyGetSetDef instance_getsets[] = {
{"__dict__", instance_get_dict, instance_set_dict, NULL, 0},
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
{0, 0, 0, 0, 0}
};
static PyMemberDef instance_members[] = {
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
{0, 0, 0, 0, 0}
};
static PyTypeObject class_type_object = {
PyObject_HEAD_INIT(0) //&class_metatype_object)
0,
"Boost.Python.instance",
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.instance"),
offsetof(instance<>,storage), /* tp_basicsize */
1, /* tp_itemsize */
instance_dealloc, /* tp_dealloc */
@@ -424,7 +470,7 @@ namespace objects
{
if (class_type_object.tp_dict == 0)
{
class_type_object.ob_type = incref(class_metatype().get());
Py_TYPE(&class_type_object) = incref(class_metatype().get());
class_type_object.tp_base = &PyBaseObject_Type;
if (PyType_Ready(&class_type_object))
return type_handle();
@@ -436,7 +482,7 @@ namespace objects
BOOST_PYTHON_DECL void*
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
{
if (inst->ob_type->ob_type != &class_metatype_object)
if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
return 0;
instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -506,13 +552,12 @@ namespace objects
// Build a tuple of the base Python type objects. If no bases
// were declared, we'll use our class_type() as the single base
// class.
std::size_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
assert(num_bases <= ssize_t_max);
handle<> bases(PyTuple_New(static_cast<ssize_t>(num_bases)));
ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
handle<> bases(PyTuple_New(num_bases));
for (std::size_t i = 1; i <= num_bases; ++i)
for (ssize_t i = 1; i <= num_bases; ++i)
{
type_handle c = (i >= num_types) ? class_type() : get_class(types[i]);
type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
// PyTuple_SET_ITEM steals this reference
PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(c.release()));
}
@@ -527,7 +572,7 @@ namespace objects
d["__doc__"] = doc;
object result = object(class_metatype())(name, bases, d);
assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
assert(PyType_IsSubtype(Py_TYPE(result.ptr()), &PyType_Type));
if (scope().ptr() != Py_None)
scope().attr(name) = result;
@@ -572,7 +617,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
this->setattr(name, property);
}
@@ -582,7 +627,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
this->setattr(name, property);
}
@@ -590,8 +635,9 @@ namespace objects
void class_base::add_static_property(char const* name, object const& fget)
{
object property(
(python::detail::new_reference)
PyObject_CallFunction(static_data(), "O", fget.ptr()));
(python::detail::new_reference)
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr())
);
this->setattr(name, property);
}
@@ -600,7 +646,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
this->setattr(name, property);
}
@@ -615,13 +661,13 @@ namespace objects
{
extern "C" PyObject* no_init(PyObject*, PyObject*)
{
::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
return NULL;
}
static ::PyMethodDef no_init_def = {
"__init__", no_init, METH_VARARGS,
"Raises an exception\n"
"This class cannot be instantiated from Python\n"
const_cast<char*>("__init__"), no_init, METH_VARARGS,
const_cast<char*>("Raises an exception\n"
"This class cannot be instantiated from Python\n")
};
}
@@ -650,8 +696,8 @@ namespace objects
::PyErr_Format(
PyExc_TypeError
, "staticmethod expects callable object; got an object of type %s, which is not callable"
, callable->ob_type->tp_name
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
, Py_TYPE(callable)->tp_name
);
throw_error_already_set();
@@ -681,18 +727,18 @@ namespace objects
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
{
assert(self_->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
objects::instance<>* self = (objects::instance<>*)self_;
int total_size_needed = holder_offset + holder_size;
if (-self->ob_size >= total_size_needed)
if (-Py_SIZE(self) >= total_size_needed)
{
// holder_offset should at least point into the variable-sized part
assert(holder_offset >= offsetof(objects::instance<>,storage));
// Record the fact that the storage is occupied, noting where it starts
self->ob_size = holder_offset;
Py_SIZE(self) = holder_offset;
return (char*)self + holder_offset;
}
else
@@ -706,9 +752,9 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std:
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
{
assert(self_->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
objects::instance<>* self = (objects::instance<>*)self_;
if (storage != (char*)self + self->ob_size)
if (storage != (char*)self + Py_SIZE(self))
{
PyMem_Free(storage);
}

View File

@@ -14,16 +14,20 @@
#include <boost/python/object_protocol.hpp>
#include <structmember.h>
namespace boost { namespace python { namespace objects {
namespace boost { namespace python { namespace objects {
struct enum_object
{
#if PY_VERSION_HEX >= 0x03000000
PyLongObject base_object;
#else
PyIntObject base_object;
#endif
PyObject* name;
};
static PyMemberDef enum_members[] = {
{"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
{0, 0, 0, 0, 0}
};
@@ -32,19 +36,32 @@ extern "C"
{
static PyObject* enum_repr(PyObject* self_)
{
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
// XXX(bhy) Potentional memory leak here since PyObject_GetAttrString returns a new reference
// const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
PyObject *mod = PyObject_GetAttrString( self_, "__module__");
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
return PyString_FromFormat("%s.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
return
#if PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyLong_AsLong(self_));
#else
PyString_FromFormat("%s.%s(%ld)", PyString_AsString(mod), self_->ob_type->tp_name, PyInt_AS_LONG(self_));
#endif
}
else
{
char* name = PyString_AsString(self->name);
PyObject* name = self->name;
if (name == 0)
return 0;
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
return
#if PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat("%S.%s.%S", mod, self_->ob_type->tp_name, name);
#else
PyString_FromFormat("%s.%s.%s",
PyString_AsString(mod), self_->ob_type->tp_name, PyString_AsString(name));
#endif
}
}
@@ -53,7 +70,11 @@ extern "C"
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
#if PY_VERSION_HEX >= 0x03000000
return PyLong_Type.tp_str(self_);
#else
return PyInt_Type.tp_str(self_);
#endif
}
else
{
@@ -63,9 +84,8 @@ extern "C"
}
static PyTypeObject enum_type_object = {
PyObject_HEAD_INIT(0) // &PyType_Type
0,
"Boost.Python.enum",
PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
const_cast<char*>("Boost.Python.enum"),
sizeof(enum_object), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
@@ -84,7 +104,9 @@ static PyTypeObject enum_type_object = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT
#if PY_VERSION_HEX < 0x03000000
| Py_TPFLAGS_CHECKTYPES
#endif
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
@@ -125,8 +147,12 @@ namespace
{
if (enum_type_object.tp_dict == 0)
{
enum_type_object.ob_type = incref(&PyType_Type);
Py_TYPE(&enum_type_object) = incref(&PyType_Type);
#if PY_VERSION_HEX >= 0x03000000
enum_type_object.tp_base = &PyLong_Type;
#else
enum_type_object.tp_base = &PyInt_Type;
#endif
if (PyType_Ready(&enum_type_object))
throw_error_already_set();
}
@@ -139,15 +165,16 @@ namespace
dict d;
d["__slots__"] = tuple();
d["values"] = dict();
d["names"] = dict();
object module_name = module_prefix();
if (module_name)
d["__module__"] = module_name;
if (doc)
d["__doc__"] = doc;
object result = (object(metatype))(name, make_tuple(base), d);
scope().attr(name) = result;
return result;
@@ -167,7 +194,7 @@ enum_base::enum_base(
converter::registration& converters
= const_cast<converter::registration&>(
converter::registry::lookup(id));
converters.m_class_object = downcast<PyTypeObject>(this->ptr());
converter::registry::insert(to_python, id);
converter::registry::insert(convertible, construct, id);
@@ -186,23 +213,24 @@ void enum_base::add_value(char const* name_, long value)
dict d = extract<dict>(this->attr("values"))();
d[value] = x;
// Set the name field in the new enum instanec
enum_object* p = downcast<enum_object>(x.ptr());
Py_XDECREF(p->name);
p->name = incref(name.ptr());
dict names_dict = extract<dict>(this->attr("names"))();
names_dict[x.attr("name")] = x;
}
void enum_base::export_values()
{
dict d = extract<dict>(this->attr("values"))();
list values = d.values();
dict d = extract<dict>(this->attr("names"))();
list items = d.items();
scope current;
for (unsigned i = 0, max = len(values); i < max; ++i)
{
api::setattr(current, object(values[i].attr("name")), values[i]);
}
for (unsigned i = 0, max = len(items); i < max; ++i)
api::setattr(current, items[i][0], items[i][1]);
}
PyObject* enum_base::to_python(PyTypeObject* type_, long x)

View File

@@ -105,9 +105,9 @@ function::function(
}
PyObject* p = this;
if (function_type.ob_type == 0)
if (Py_TYPE(&function_type) == 0)
{
function_type.ob_type = &PyType_Type;
Py_TYPE(&function_type) = &PyType_Type;
::PyType_Ready(&function_type);
}
@@ -144,7 +144,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
if (n_keyword_actual > 0 // Keyword arguments were supplied
|| n_actual < min_arity) // or default keyword values are needed
{
if (f->m_arg_names.ptr() == Py_None)
if (f->m_arg_names.is_none())
{
// this overload doesn't accept keywords
inner_args = handle<>();
@@ -166,7 +166,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
else
{
// build a new arg tuple, will adjust its size later
assert(max_arity <= ssize_t_max);
assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
inner_args = handle<>(
PyTuple_New(static_cast<ssize_t>(max_arity)));
@@ -297,7 +297,7 @@ object function::signatures(bool show_return_type) const
void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
{
static handle<> exception(
PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0));
PyErr_NewException(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
object message = "Python argument types in\n %s.%s("
% make_tuple(this->m_namespace, this->m_name);
@@ -435,12 +435,16 @@ void function::add_to_namespace(
function* new_func = downcast<function>(attribute.ptr());
PyObject* dict = 0;
#if PY_VERSION_HEX < 0x03000000
// Old-style class gone in Python 3
if (PyClass_Check(ns))
dict = ((PyClassObject*)ns)->cl_dict;
else if (PyType_Check(ns))
else
#endif
if (PyType_Check(ns))
dict = ((PyTypeObject*)ns)->tp_dict;
else
dict = PyObject_GetAttrString(ns, "__dict__");
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
if (dict == 0)
throw_error_already_set();
@@ -483,11 +487,11 @@ void function::add_to_namespace(
}
// A function is named the first time it is added to a namespace.
if (new_func->name().ptr() == Py_None)
if (new_func->name().is_none())
new_func->m_name = name;
handle<> name_space_name(
allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__")));
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
if (name_space_name)
new_func->m_namespace = object(name_space_name);
@@ -595,9 +599,18 @@ extern "C"
static PyObject *
function_descr_get(PyObject *func, PyObject *obj, PyObject *type_)
{
#if PY_VERSION_HEX >= 0x03000000
// The implement is different in Python 3 because of the removal of unbound method
if (obj == Py_None || obj == NULL) {
Py_INCREF(func);
return func;
}
return PyMethod_New(func, obj);
#else
if (obj == Py_None)
obj = NULL;
return PyMethod_New(func, obj, type_);
#endif
}
static void
@@ -640,8 +653,12 @@ extern "C"
static PyObject* function_get_name(PyObject* op, void*)
{
function* f = downcast<function>(op);
if (f->name().ptr() == Py_None)
if (f->name().is_none())
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_InternFromString("<unnamed Boost.Python function>");
#else
return PyString_InternFromString("<unnamed Boost.Python function>");
#endif
else
return python::incref(f->name().ptr());
}
@@ -656,18 +673,17 @@ extern "C"
}
static PyGetSetDef function_getsetlist[] = {
{"__name__", (getter)function_get_name, 0, 0, 0 },
{"func_name", (getter)function_get_name, 0, 0, 0 },
{"__class__", (getter)function_get_class, 0, 0, 0 }, // see note above
{"__doc__", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{"func_doc", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{NULL, 0, 0, 0, 0} /* Sentinel */
};
PyTypeObject function_type = {
PyObject_HEAD_INIT(0)
0,
"Boost.Python.function",
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.function"),
sizeof(function),
0,
(destructor)function_dealloc, /* tp_dealloc */
@@ -753,7 +769,8 @@ namespace detail
}
void BOOST_PYTHON_DECL pure_virtual_called()
{
PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called");
PyErr_SetString(
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
throw_error_already_set();
}
}

View File

@@ -3,6 +3,9 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// boost::python::make_tuple below are for gcc 4.4 -std=c++0x compatibility
// (Intel C++ 10 and 11 with -std=c++0x don't need the full qualification).
#include <boost/python/converter/registrations.hpp>
#include <boost/python/object/function_doc_signature.hpp>
#include <boost/python/errors.hpp>
@@ -12,7 +15,6 @@
#include <boost/python/detail/signature.hpp>
#include <vector>
namespace boost { namespace python { namespace objects {
@@ -52,9 +54,9 @@ namespace boost { namespace python { namespace objects {
//check if the argument default values are the same
bool f1_has_names = bool(f1->m_arg_names);
bool f2_has_names = bool(f2->m_arg_names);
if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
|| f1_has_names && !f2_has_names
|| !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
if ( (f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1])
|| (f1_has_names && !f2_has_names)
|| (!f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object())
)
return false;
}
@@ -228,7 +230,7 @@ namespace boost { namespace python { namespace objects {
{
return str(
"%s %s(%s%s%s%s)"
% make_tuple
% boost::python::make_tuple // workaround, see top
( ret_type
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
@@ -239,7 +241,7 @@ namespace boost { namespace python { namespace objects {
}else{
return str(
"%s(%s%s%s%s) -> %s"
% make_tuple
% boost::python::make_tuple // workaround, see top
( f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
@@ -251,7 +253,7 @@ namespace boost { namespace python { namespace objects {
return str(
"%s %s(%s%s%s%s) %s"
% make_tuple
% boost::python::make_tuple // workaround, see top
( cpp_types?ret_type:str("")
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))

View File

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

View File

@@ -36,9 +36,8 @@ extern "C"
}
PyTypeObject life_support_type = {
PyObject_HEAD_INIT(0)//(&PyType_Type)
0,
"Boost.Python.life_support",
PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
const_cast<char*>("Boost.Python.life_support"),
sizeof(life_support),
0,
life_support_dealloc, /* tp_dealloc */
@@ -92,9 +91,9 @@ PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
if (nurse == Py_None || nurse == patient)
return nurse;
if (life_support_type.ob_type == 0)
if (Py_TYPE(&life_support_type) == 0)
{
life_support_type.ob_type = &PyType_Type;
Py_TYPE(&life_support_type) = &PyType_Type;
PyType_Ready(&life_support_type);
}

View File

@@ -38,21 +38,21 @@ namespace {
}
object getinitargs = getattr(instance_obj, "__getinitargs__", none);
tuple initargs;
if (getinitargs.ptr() != none.ptr()) {
if (!getinitargs.is_none()) {
initargs = tuple(getinitargs());
}
result.append(initargs);
object getstate = getattr(instance_obj, "__getstate__", none);
object instance_dict = getattr(instance_obj, "__dict__", none);
long len_instance_dict = 0;
if (instance_dict.ptr() != none.ptr()) {
if (!instance_dict.is_none()) {
len_instance_dict = len(instance_dict);
}
if (getstate.ptr() != none.ptr()) {
if (!getstate.is_none()) {
if (len_instance_dict > 0) {
object getstate_manages_dict = getattr(
instance_obj, "__getstate_manages_dict__", none);
if (getstate_manages_dict.ptr() == none.ptr()) {
if (getstate_manages_dict.is_none()) {
PyErr_SetString(PyExc_RuntimeError,
"Incomplete pickle support"
" (__getstate_manages_dict__ not set)");

View File

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

View File

@@ -38,7 +38,13 @@ BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
BOOST_PYTHON_BINARY_OPERATOR(+, Add)
BOOST_PYTHON_BINARY_OPERATOR(-, Subtract)
BOOST_PYTHON_BINARY_OPERATOR(*, Multiply)
#if PY_VERSION_HEX >= 0x03000000
// We choose FloorDivide instead of TrueDivide to keep the semantic
// conform with C/C++'s '/' operator
BOOST_PYTHON_BINARY_OPERATOR(/, FloorDivide)
#else
BOOST_PYTHON_BINARY_OPERATOR(/, Divide)
#endif
BOOST_PYTHON_BINARY_OPERATOR(%, Remainder)
BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift)
BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift)
@@ -58,7 +64,12 @@ BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \
BOOST_PYTHON_INPLACE_OPERATOR(+, Add)
BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract)
BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply)
#if PY_VERSION_HEX >= 0x03000000
// Same reason as above for choosing FloorDivide instead of TrueDivide
BOOST_PYTHON_INPLACE_OPERATOR(/, FloorDivide)
#else
BOOST_PYTHON_INPLACE_OPERATOR(/, Divide)
#endif
BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder)
BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift)
BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift)

View File

@@ -103,6 +103,7 @@ namespace // slicing code copied directly out of the Python implementation
static PyObject *
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
{
#if PY_VERSION_HEX < 0x03000000
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
@@ -114,7 +115,9 @@ namespace // slicing code copied directly out of the Python implementation
return NULL;
return PySequence_GetSlice(u, ilow, ihigh);
}
else {
else
#endif
{
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL) {
PyObject *res = PyObject_GetItem(u, slice);
@@ -130,6 +133,7 @@ namespace // slicing code copied directly out of the Python implementation
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
/* u[v:w] = x */
{
#if PY_VERSION_HEX < 0x03000000
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
@@ -144,7 +148,9 @@ namespace // slicing code copied directly out of the Python implementation
else
return PySequence_SetSlice(u, ilow, ihigh, x);
}
else {
else
#endif
{
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL) {
int res;

View File

@@ -10,23 +10,40 @@ namespace boost { namespace python { namespace detail {
detail::new_reference str_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyString_Type, "(O)",
#if PY_VERSION_HEX >= 0x03000000
(PyObject*)&PyUnicode_Type,
#else
(PyObject*)&PyString_Type,
#endif
const_cast<char*>("(O)"),
arg_.ptr());
}
str_base::str_base()
: object(detail::new_reference(::PyString_FromString("")))
: object(detail::new_reference(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromString("")
#else
::PyString_FromString("")
#endif
))
{}
str_base::str_base(const char* s)
: object(detail::new_reference(::PyString_FromString(s)))
: object(detail::new_reference(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromString(s)
#else
::PyString_FromString(s)
#endif
))
{}
namespace {
ssize_t str_size_as_py_ssize_t(std::size_t n)
{
if (n > ssize_t_max)
if (n > static_cast<std::size_t>(ssize_t_max))
{
throw std::range_error("str size > ssize_t_max");
}
@@ -38,9 +55,12 @@ namespace {
str_base::str_base(char const* start, char const* finish)
: object(
detail::new_reference(
::PyString_FromStringAndSize(
start, str_size_as_py_ssize_t(finish - start)
)
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromStringAndSize
#else
::PyString_FromStringAndSize
#endif
(start, str_size_as_py_ssize_t(finish - start))
)
)
{}
@@ -48,9 +68,12 @@ str_base::str_base(char const* start, char const* finish)
str_base::str_base(char const* start, std::size_t length) // new str
: object(
detail::new_reference(
::PyString_FromStringAndSize(
start, str_size_as_py_ssize_t(length)
)
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromStringAndSize
#else
::PyString_FromStringAndSize
#endif
( start, str_size_as_py_ssize_t(length) )
)
)
{}
@@ -68,8 +91,9 @@ str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const
return str(new_reference( \
expect_non_null( \
PyObject_CallMethod( \
this->ptr(), #name, \
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \
this->ptr(), const_cast<char*>( #name ), \
const_cast<char*>( \
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
}
@@ -91,6 +115,7 @@ long str_base::count(object_cref sub, object_cref start, object_cref end) const
return extract<long>(this->attr("count")(sub,start,end));
}
#if PY_VERSION_HEX < 0x03000000
object str_base::decode() const
{
return this->attr("decode")();
@@ -105,6 +130,7 @@ object str_base::decode(object_cref encoding, object_cref errors) const
{
return this->attr("decode")(encoding,errors);
}
#endif
object str_base::encode() const
{
@@ -121,9 +147,16 @@ object str_base::encode(object_cref encoding, object_cref errors) const
return this->attr("encode")(encoding,errors);
}
#if PY_VERSION_HEX >= 0x03000000
#define _BOOST_PYTHON_ASLONG PyLong_AsLong
#else
#define _BOOST_PYTHON_ASLONG PyInt_AsLong
#endif
bool str_base::endswith(object_cref suffix) const
{
bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -134,7 +167,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1)
long str_base::find(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("find")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -142,7 +175,7 @@ long str_base::find(object_cref sub) const
long str_base::find(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -150,7 +183,7 @@ long str_base::find(object_cref sub, object_cref start) const
long str_base::find(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -158,7 +191,7 @@ long str_base::find(object_cref sub, object_cref start, object_cref end) const
long str_base::index(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("index")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -166,7 +199,7 @@ long str_base::index(object_cref sub) const
long str_base::index(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -174,7 +207,7 @@ long str_base::index(object_cref sub, object_cref start) const
long str_base::index(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -182,7 +215,7 @@ long str_base::index(object_cref sub, object_cref start, object_cref end) const
bool str_base::isalnum() const
{
bool result = PyInt_AsLong(this->attr("isalnum")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -190,7 +223,7 @@ bool str_base::isalnum() const
bool str_base::isalpha() const
{
bool result = PyInt_AsLong(this->attr("isalpha")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -198,7 +231,7 @@ bool str_base::isalpha() const
bool str_base::isdigit() const
{
bool result = PyInt_AsLong(this->attr("isdigit")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -206,7 +239,7 @@ bool str_base::isdigit() const
bool str_base::islower() const
{
bool result = PyInt_AsLong(this->attr("islower")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -214,7 +247,7 @@ bool str_base::islower() const
bool str_base::isspace() const
{
bool result = PyInt_AsLong(this->attr("isspace")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -222,7 +255,7 @@ bool str_base::isspace() const
bool str_base::istitle() const
{
bool result = PyInt_AsLong(this->attr("istitle")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -230,7 +263,7 @@ bool str_base::istitle() const
bool str_base::isupper() const
{
bool result = PyInt_AsLong(this->attr("isupper")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isupper")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -245,7 +278,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3)
long str_base::rfind(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -253,7 +286,7 @@ long str_base::rfind(object_cref sub) const
long str_base::rfind(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -261,7 +294,7 @@ long str_base::rfind(object_cref sub, object_cref start) const
long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -269,7 +302,7 @@ long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
long str_base::rindex(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -277,7 +310,7 @@ long str_base::rindex(object_cref sub) const
long str_base::rindex(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -285,7 +318,7 @@ long str_base::rindex(object_cref sub, object_cref start) const
long str_base::rindex(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -321,7 +354,7 @@ list str_base::splitlines(object_cref keepends) const
bool str_base::startswith(object_cref prefix) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -329,7 +362,7 @@ bool str_base::startswith(object_cref prefix) const
bool str_base::startswith(object_cref prefix, object_cref start) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -337,12 +370,14 @@ bool str_base::startswith(object_cref prefix, object_cref start) const
bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
#undef _BOOST_PYTHON_ASLONG
BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0)
BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0)
BOOST_PYTHON_DEFINE_STR_METHOD(title, 0)
@@ -356,7 +391,12 @@ static struct register_str_pytype_ptr
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::str>())
).m_class_object = &PyString_Type;
)
#if PY_VERSION_HEX >= 0x03000000
.m_class_object = &PyUnicode_Type;
#else
.m_class_object = &PyString_Type;
#endif
}
}register_str_pytype_ptr_;

View File

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

View File

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

View File

@@ -42,7 +42,7 @@ test-suite python
:
[
run exec.cpp ../build//boost_python/<link>static $(PY)
run exec.cpp /boost/python//boost_python/<link>static $(PY)
: # program args
: exec.py # input files
: # requirements
@@ -75,13 +75,17 @@ bpl-test crossmod_exception
[ bpl-test return_arg ]
[ bpl-test staticmethod ]
[ bpl-test shared_ptr ]
[ bpl-test enable_shared_from_this ]
[ bpl-test andreas_beyer ]
[ bpl-test wrapper_held_type ]
[ bpl-test polymorphism2_auto_ptr
: polymorphism2_auto_ptr.py polymorphism2.py polymorphism2_auto_ptr.cpp
]
[ bpl-test polymorphism ]
[ bpl-test polymorphism2 ]
[ bpl-test wrapper_held_type ]
[ bpl-test polymorphism2_auto_ptr ]
[ bpl-test auto_ptr ]
[ bpl-test minimal ]
@@ -171,7 +175,8 @@ bpl-test crossmod_opaque
/boost/python//boost_python ]
[ bpl-test
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
[ py-run import_.cpp : import_.py ]
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
# if $(TEST_BIENSTMAN_NON_BUGS)
# {
@@ -179,6 +184,11 @@ bpl-test crossmod_opaque
# bpl-test bienstman5 ;
# }
# XXX disabled on release branch only,
# XXX to avoid failures on platforms other than Windows
# [ bpl-test calling_conventions ]
# [ bpl-test calling_conventions_mf ]
# --- unit tests of library components ---
[ compile indirect_traits_test.cpp ]

View File

@@ -48,7 +48,11 @@ struct AFromPython
static void* convertible(PyObject* obj_ptr)
{
#if PY_VERSION_HEX >= 0x03000000
if (!PyLong_Check(obj_ptr)) return 0;
#else
if (!PyInt_Check(obj_ptr)) return 0;
#endif
return obj_ptr;
}
@@ -60,7 +64,11 @@ struct AFromPython
(boost::python::converter::rvalue_from_python_storage< A >*)
data)-> storage.bytes;
#if PY_VERSION_HEX >= 0x03000000
new (storage) A((int)PyLong_AsLong(obj_ptr));
#else
new (storage) A((int)PyInt_AsLong(obj_ptr));
#endif
data->convertible = storage;
}
};

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,158 @@
//
// adapted from bind_stdcall_test.cpp - test for bind.hpp + __stdcall (free functions)
// The purpose of this simple test is to determine if a function can be
// called from Python with the various existing calling conventions
//
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if !defined(TEST_INCLUDE_RECURSION)
#define TEST_INCLUDE_RECURSION
//------------------------------------------------------------------------------
// this section is the main body of the test extension module
#define BOOST_PYTHON_ENABLE_CDECL
#define BOOST_PYTHON_ENABLE_STDCALL
#define BOOST_PYTHON_ENABLE_FASTCALL
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/python.hpp>
using namespace boost::python;
// first define test functions for every calling convention
#define TEST_DECLARE_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_DECLARE_FUNCTIONS
// then create a module wrapping the defined functions for every calling convention
BOOST_PYTHON_MODULE( calling_conventions_ext )
{
#define TEST_WRAP_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_WRAP_FUNCTIONS
}
#else // !defined(TEST_INCLUDE_RECURSION)
//------------------------------------------------------------------------------
// this section defines the functions to be wrapped
# if defined(TEST_DECLARE_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
long TESTED_CALLING_CONVENTION f_0()
{
return 17041L;
}
long TESTED_CALLING_CONVENTION f_1(long a)
{
return a;
}
long TESTED_CALLING_CONVENTION f_2(long a, long b)
{
return a + 10 * b;
}
long TESTED_CALLING_CONVENTION f_3(long a, long b, long c)
{
return a + 10 * b + 100 * c;
}
long TESTED_CALLING_CONVENTION f_4(long a, long b, long c, long d)
{
return a + 10 * b + 100 * c + 1000 * d;
}
long TESTED_CALLING_CONVENTION f_5(long a, long b, long c, long d, long e)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
}
long TESTED_CALLING_CONVENTION f_6(long a, long b, long c, long d, long e, long f)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
}
long TESTED_CALLING_CONVENTION f_7(long a, long b, long c, long d, long e, long f, long g)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
}
long TESTED_CALLING_CONVENTION f_8(long a, long b, long c, long d, long e, long f, long g, long h)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
}
long TESTED_CALLING_CONVENTION f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
}
} // namespace test##TESTED_CALLING_CONVENTION
# endif // defined(TEST_DECLARE_FUNCTIONS)
//------------------------------------------------------------------------------
// this section wraps the functions
# if defined(TEST_WRAP_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
def("f_0" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_0);
def("f_1" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_1);
def("f_2" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_2);
def("f_3" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_3);
def("f_4" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_4);
def("f_5" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_5);
def("f_6" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_6);
def("f_7" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_7);
def("f_8" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_8);
def("f_9" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_9);
# endif // defined(TEST_WRAP_FUNCTIONS)
#endif // !defined(TEST_INCLUDE_RECURSION)

View File

@@ -0,0 +1,81 @@
# Copyright Nicolas Lelong, 2010. Distributed under the Boost
# Software License, Version 1.0 (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from calling_conventions_ext import *
>>> f_0__cdecl()
17041
>>> f_1__cdecl(1)
1
>>> f_2__cdecl(1, 2)
21
>>> f_3__cdecl(1, 2, 3)
321
>>> f_4__cdecl(1, 2, 3, 4)
4321
>>> f_5__cdecl(1, 2, 3, 4, 5)
54321
>>> f_6__cdecl(1, 2, 3, 4, 5, 6)
654321
>>> f_7__cdecl(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__cdecl(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__cdecl(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
>>> f_0__stdcall()
17041
>>> f_1__stdcall(1)
1
>>> f_2__stdcall(1, 2)
21
>>> f_3__stdcall(1, 2, 3)
321
>>> f_4__stdcall(1, 2, 3, 4)
4321
>>> f_5__stdcall(1, 2, 3, 4, 5)
54321
>>> f_6__stdcall(1, 2, 3, 4, 5, 6)
654321
>>> f_7__stdcall(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__stdcall(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__stdcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
>>> f_0__fastcall()
17041
>>> f_1__fastcall(1)
1
>>> f_2__fastcall(1, 2)
21
>>> f_3__fastcall(1, 2, 3)
321
>>> f_4__fastcall(1, 2, 3, 4)
4321
>>> f_5__fastcall(1, 2, 3, 4, 5)
54321
>>> f_6__fastcall(1, 2, 3, 4, 5, 6)
654321
>>> f_7__fastcall(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__fastcall(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__fastcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
status = run()[0]
if (status == 0): print "Done."
sys.exit(status)

View File

@@ -0,0 +1,159 @@
//
// adapted from bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (free functions)
// The purpose of this simple test is to determine if a function can be
// called from Python with the various existing calling conventions
//
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if !defined(TEST_INCLUDE_RECURSION)
#define TEST_INCLUDE_RECURSION
//------------------------------------------------------------------------------
// this section is the main body of the test extension module
#define BOOST_PYTHON_ENABLE_CDECL
#define BOOST_PYTHON_ENABLE_STDCALL
#define BOOST_PYTHON_ENABLE_FASTCALL
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/python.hpp>
using namespace boost::python;
// first define test functions for every calling convention
#define TEST_DECLARE_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_DECLARE_FUNCTIONS
// then create a module wrapping the defined functions for every calling convention
BOOST_PYTHON_MODULE( calling_conventions_mf_ext )
{
#define TEST_WRAP_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_WRAP_FUNCTIONS
}
#else // !defined(TEST_INCLUDE_RECURSION)
//------------------------------------------------------------------------------
// this section defines the functions to be wrapped
# if defined(TEST_DECLARE_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
struct X
{
mutable unsigned int hash;
X(): hash(0) {}
void TESTED_CALLING_CONVENTION f0() { f1(17); }
void TESTED_CALLING_CONVENTION g0() const { g1(17); }
void TESTED_CALLING_CONVENTION f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
void TESTED_CALLING_CONVENTION g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
void TESTED_CALLING_CONVENTION f2(int a1, int a2) { f1(a1); f1(a2); }
void TESTED_CALLING_CONVENTION g2(int a1, int a2) const { g1(a1); g1(a2); }
void TESTED_CALLING_CONVENTION f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
void TESTED_CALLING_CONVENTION g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
void TESTED_CALLING_CONVENTION f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
void TESTED_CALLING_CONVENTION g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
void TESTED_CALLING_CONVENTION f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
void TESTED_CALLING_CONVENTION g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
void TESTED_CALLING_CONVENTION f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
void TESTED_CALLING_CONVENTION g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
void TESTED_CALLING_CONVENTION f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
void TESTED_CALLING_CONVENTION g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
void TESTED_CALLING_CONVENTION f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
void TESTED_CALLING_CONVENTION g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
};
} // namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)
# endif // defined(TEST_DECLARE_FUNCTIONS)
//------------------------------------------------------------------------------
// this section wraps the functions
# if defined(TEST_WRAP_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
{
typedef BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::X X;
class_<X>("X" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION))
.def("f0", &X::f0)
.def("g0", &X::g0)
.def("f1", &X::f1)
.def("g1", &X::g1)
.def("f2", &X::f2)
.def("g2", &X::g2)
.def("f3", &X::f3)
.def("g3", &X::g3)
.def("f4", &X::f4)
.def("g4", &X::g4)
.def("f5", &X::f5)
.def("g5", &X::g5)
.def("f6", &X::f6)
.def("g6", &X::g6)
.def("f7", &X::f7)
.def("g7", &X::g7)
.def("f8", &X::f8)
.def("g8", &X::g8)
.def_readonly("hash", &X::hash)
;
}
# endif // defined(TEST_WRAP_FUNCTIONS)
#endif // !defined(TEST_INCLUDE_RECURSION)

View File

@@ -0,0 +1,84 @@
# Copyright Nicolas Lelong, 2010. Distributed under the Boost
# Software License, Version 1.0 (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from calling_conventions_mf_ext import *
>>> x = X__cdecl()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
>>> x = X__stdcall()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
>>> x = X__fastcall()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
status = run()[0]
if (status == 0): print "Done."
sys.exit(status)

View File

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

View File

@@ -1,4 +1,4 @@
# -*- coding: iso-latin-1 -*-
# -*- coding: latin-1 -*-
# Copyright Gottfried Ganßauge 2006.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at

View File

@@ -2,13 +2,6 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
# Use builtin True/False when available:
>>> try:
... assert(True == 1)
... except:
... True = 1
... False = 0
>>> from defaults_ext import *
>>> bar(1)
'int(1); char(D); string(default); double(0.0); '

View File

@@ -22,6 +22,10 @@ struct foo
*kills++ = n;
}
int n;
// This used to cause compiler errors with MSVC 9.0.
foo& operator~();
foo& T();
};
void assert_destructions(int n)

View File

@@ -20,7 +20,7 @@
[(1, {'key2': 'value2'}), ('key1', 'value1')]
>>> print dict_from_sequence([(1,1),(2,2),(3,3)])
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer)
>>> test_templates(printer) #doctest: +NORMALIZE_WHITESPACE
a test string
13
None

View File

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

26
test/enable_shared_from_this.py Executable file
View File

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

View File

@@ -12,7 +12,7 @@
#endif
using namespace boost::python;
enum color { red = 1, green = 2, blue = 4 };
enum color { red = 1, green = 2, blue = 4, blood = 1 };
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
namespace boost // Pro7 has a hard time detecting enums
@@ -34,6 +34,7 @@ BOOST_PYTHON_MODULE(enum_ext)
.value("red", red)
.value("green", green)
.value("blue", blue)
.value("blood", blood)
.export_values()
;

View File

@@ -4,8 +4,8 @@
'''
>>> from enum_ext import *
>>> identity(color.red)
enum_ext.color.red
>>> identity(color.red) # in case of duplicated enums it always take the last enum
enum_ext.color.blood
>>> identity(color.green)
enum_ext.color.green
@@ -13,8 +13,8 @@ enum_ext.color.green
>>> identity(color.blue)
enum_ext.color.blue
>>> identity(color(1))
enum_ext.color.red
>>> identity(color(1)) # in case of duplicated enums it always take the last enum
enum_ext.color.blood
>>> identity(color(2))
enum_ext.color.green
@@ -28,7 +28,7 @@ enum_ext.color.blue
--- check export to scope ---
>>> identity(red)
enum_ext.color.red
enum_ext.color.blood
>>> identity(green)
enum_ext.color.green
@@ -42,10 +42,18 @@ enum_ext.color.blue
>>> c = colorized()
>>> c.x
enum_ext.color.red
enum_ext.color.blood
>>> c.x = green
>>> c.x
enum_ext.color.green
>>> red == blood
True
>>> red == green
False
>>> hash(red) == hash(blood)
True
>>> hash(red) == hash(green)
False
'''
# pickling of enums only works with Python 2.3 or higher

View File

@@ -59,7 +59,13 @@ void eval_test()
void exec_test()
{
// Register the module with the interpreter
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"),
#if PY_VERSION_HEX >= 0x03000000
PyInit_embedded_hello
#else
initembedded_hello
#endif
) == -1)
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
"builtin modules");
// Retrieve the main module
@@ -105,49 +111,76 @@ void exec_test_error()
{
// Execute a statement that raises a python exception.
python::dict global;
python::object result = python::exec("print unknown \n", global, global);
python::object result = python::exec("print(unknown) \n", global, global);
}
int main(int argc, char **argv)
void exercise_embedding_html()
{
BOOST_TEST(argc == 2);
std::string script = argv[1];
// Initialize the interpreter
Py_Initialize();
using namespace boost::python;
/* code from: libs/python/doc/tutorial/doc/tutorial.qbk
(generates libs/python/doc/tutorial/doc/html/python/embedding.html)
*/
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
if (python::handle_exception(eval_test) ||
python::handle_exception(exec_test) ||
python::handle_exception(boost::bind(exec_file_test, script)))
object ignored = exec("hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()",
main_namespace);
}
void check_pyerr(bool pyerr_expected=false)
{
if (PyErr_Occurred())
{
if (PyErr_Occurred())
{
if (!pyerr_expected) {
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
if (python::handle_exception(exec_test_error))
{
if (PyErr_Occurred())
{
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
else {
PyErr_Clear();
}
}
else
{
BOOST_ERROR("Python exception expected, but not seen.");
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
int main(int argc, char **argv)
{
BOOST_TEST(argc == 2 || argc == 3);
std::string script = argv[1];
// Initialize the interpreter
Py_Initialize();
if (python::handle_exception(eval_test)) {
check_pyerr();
}
else if(python::handle_exception(exec_test)) {
check_pyerr();
}
else if (python::handle_exception(boost::bind(exec_file_test, script))) {
check_pyerr();
}
if (python::handle_exception(exec_test_error))
{
check_pyerr(/*pyerr_expected*/ true);
}
else
{
BOOST_ERROR("Python exception expected, but not seen.");
}
if (argc > 2) {
// The main purpose is to test compilation. Since this test generates
// a file and I (rwgk) am uncertain about the side-effects, run it only
// if explicitly requested.
exercise_embedding_html();
}
// Boost.Python doesn't support Py_Finalize yet.
// Py_Finalize();
return boost::report_errors();

View File

@@ -2,5 +2,5 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
print 'Hello World !'
number = 42
if 1:
number = 42

View File

@@ -53,7 +53,7 @@
>>> ll.push_back(x)
>>> x.push_back(7)
>>> ll.push_back(x)
>>> for a in ll:
>>> for a in ll: #doctest: +NORMALIZE_WHITESPACE
... for b in a:
... print b,
... print

View File

@@ -7,6 +7,8 @@
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/list.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/make_function.hpp>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
@@ -109,11 +111,16 @@ void exercise(list x, object y, object print)
print("sorted:");
x.pop(2); // make sorting predictable
x.pop(2); // remove [1,2] so the list is sortable in py3k
x.sort();
print(x);
print("reverse sorted:");
#if PY_VERSION_HEX >= 0x03000000
x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));
#else
x.sort(&notcmp);
#endif
print(x);
list w;

View File

@@ -73,7 +73,7 @@ X(22)
...
>>> y = X(42)
>>> exercise(letters, y, printer)
>>> exercise(letters, y, printer) #doctest: +NORMALIZE_WHITESPACE
after append:
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)]
number of X(42) instances: 1
@@ -97,9 +97,9 @@ removing 666
reversing...
['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h']
sorted:
[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
['.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
reverse sorted:
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]]
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
'''
def run(args = None):

View File

@@ -3,12 +3,12 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from long_ext import *
>>> new_long()
0L
>>> longify(42)
42L
>>> longify_string('300')
300L
>>> print new_long()
0
>>> print longify(42)
42
>>> print longify_string('300')
300
>>> is_long(20L)
'yes'
>>> is_long('20')

View File

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

View File

@@ -13,6 +13,11 @@
#include <boost/python/return_value_policy.hpp>
#include "simple_type.hpp"
#if PY_VERSION_HEX >= 0x03000000
# define PyString_FromString PyUnicode_FromString
# define PyInt_FromLong PyLong_FromLong
#endif
// Get a simple (by value) from the argument, and return the
// string it holds.
PyObject* unwrap_simple(simple x)
@@ -52,6 +57,11 @@ PyObject* unwrap_int_const_ref(int const& x)
return PyInt_FromLong(x);
}
#if PY_VERSION_HEX >= 0x03000000
# undef PyString_FromString
# undef PyInt_FromLong
#endif
// rewrap<T> extracts a T from the argument, then converts the T back
// to a PyObject* and returns it.
template <class T>

View File

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

Some files were not shown because too many files have changed in this diff Show More