mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
1 Commits
boost-1.42
...
boost-1.39
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d3e85a521 |
80
CMakeLists.txt
Normal file
80
CMakeLists.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
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)
|
||||
148
build/Jamfile.v2
148
build/Jamfile.v2
@@ -4,7 +4,6 @@
|
||||
|
||||
import os ;
|
||||
import modules ;
|
||||
import feature ;
|
||||
|
||||
import python ;
|
||||
|
||||
@@ -23,22 +22,6 @@ 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
|
||||
;
|
||||
@@ -46,79 +29,66 @@ project boost/python
|
||||
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
|
||||
rule lib_boost_python ( is-py3 ? )
|
||||
{
|
||||
lib boost_python
|
||||
: # sources
|
||||
numeric.cpp
|
||||
list.cpp
|
||||
long.cpp
|
||||
dict.cpp
|
||||
tuple.cpp
|
||||
str.cpp
|
||||
slice.cpp
|
||||
|
||||
lib [ cond $(is-py3) : boost_python3 : boost_python ]
|
||||
: # sources
|
||||
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
|
||||
: # 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 ]
|
||||
|
||||
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
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
|
||||
<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 ;
|
||||
}
|
||||
|
||||
@@ -32,43 +32,7 @@
|
||||
<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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Chapter 1. python 2.0</title>
|
||||
<title>Chapter 1. python 1.0</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="index.html" title="Chapter 1. python 1.0">
|
||||
@@ -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.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -31,7 +31,7 @@
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id457106"></a><p>
|
||||
<a name="id455921"></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,14 +94,15 @@
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id386707"></a>
|
||||
<a name="id385276"></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>
|
||||
@@ -109,7 +110,8 @@
|
||||
<p>
|
||||
can be exposed to Python by writing a Boost.Python wrapper:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -123,7 +125,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
@@ -142,7 +145,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: November 22, 2008 at 03:24:11 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: March 24, 2008 at 23:09:39 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -40,7 +40,7 @@
|
||||
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<a name="embedding.building_embedded_programs"></a><h2>
|
||||
<a name="id472330"></a>
|
||||
<a name="id471330"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
<p>
|
||||
@@ -82,7 +82,7 @@ exe embedded_program # name of the executable
|
||||
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
|
||||
</pre>
|
||||
<a name="embedding.getting_started"></a><h2>
|
||||
<a name="id472435"></a>
|
||||
<a name="id471435"></a>
|
||||
Getting started
|
||||
</h2>
|
||||
<p>
|
||||
@@ -130,22 +130,23 @@ exe embedded_program # name of the executable
|
||||
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
|
||||
<p>
|
||||
As you probably already know, objects in Python are reference-counted. Naturally,
|
||||
the <tt class="literal">PyObject</tt>s of the Python C API are also reference-counted.
|
||||
the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully automatic
|
||||
in Python, the Python C API requires you to do it <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
|
||||
hand</a>. This is messy and especially hard to get right in the presence
|
||||
in Python, the Python<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
|
||||
by hand]. This is messy and especially hard to get right in the presence
|
||||
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
|
||||
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
|
||||
automate the process.
|
||||
</p>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id472601"></a>
|
||||
<a name="id471598"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
Boost.python provides three related functions to run Python code from C++.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
</pre>
|
||||
@@ -164,7 +165,8 @@ exe embedded_program # name of the executable
|
||||
<p>
|
||||
Boost.python provides a function to import a module:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
import imports a python module (potentially loading it into the running process
|
||||
@@ -174,7 +176,8 @@ exe embedded_program # name of the executable
|
||||
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module and run some Python code in its namespace:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
|
||||
@@ -187,7 +190,7 @@ exe embedded_program # name of the executable
|
||||
a phrase that is well-known in programming circles.
|
||||
</p>
|
||||
<a name="using_the_interpreter.manipulating_python_objects"></a><h2>
|
||||
<a name="id473185"></a>
|
||||
<a name="id472186"></a>
|
||||
Manipulating Python objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -197,7 +200,8 @@ exe embedded_program # name of the executable
|
||||
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
|
||||
The following examples should further illustrate this fact:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
|
||||
@@ -208,18 +212,20 @@ exe embedded_program # name of the executable
|
||||
this variable from the dictionary. Another way to achieve the same result
|
||||
is to use eval instead, which returns the result directly:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</span><span class="special">);</span>
|
||||
</pre>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id473554"></a>
|
||||
<a name="id472558"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
|
||||
is thrown:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">try</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
|
||||
<span class="comment">// execution will never get here:
|
||||
@@ -234,13 +240,14 @@ exe embedded_program # name of the executable
|
||||
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
|
||||
information in itself. To find out more about the Python exception that occurred,
|
||||
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
|
||||
handling functions</a> of the Python C API in your catch-statement. This
|
||||
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
|
||||
to print the exception's traceback to the console, or comparing the type
|
||||
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
|
||||
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
|
||||
This can be as simple as calling [@http:</em></span>/www.python.org/doc/api/exceptionHandling.html#l2h-70
|
||||
PyErr_Print()] to print the exception's traceback to the console, or comparing
|
||||
the type of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
|
||||
exceptions</a>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
|
||||
<span class="special">{</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -30,12 +30,14 @@
|
||||
is the point where C++ meets Python. Boost.Python provides a default exception
|
||||
handler that translates selected standard exceptions, then gives up:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
</pre>
|
||||
<p>
|
||||
Users may provide custom translation. Here's an example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
|
||||
<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span> <span class="string">"I'm sorry Dave..."</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -40,7 +40,8 @@
|
||||
<p>
|
||||
Consider a C++ class/struct that we want to expose to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -50,7 +51,8 @@
|
||||
<p>
|
||||
We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
|
||||
@@ -69,7 +71,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
@@ -84,7 +87,8 @@
|
||||
exposes the default constructor by default, which is why we were able to
|
||||
write
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
We may wish to wrap a class with a non-default constructor. Let us build
|
||||
@@ -92,7 +96,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor
|
||||
</span> <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -106,7 +111,8 @@
|
||||
We have to tell <tt class="literal">class_<World></tt> about the constructor
|
||||
we want to expose instead.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
|
||||
@@ -127,7 +133,8 @@
|
||||
to the <tt class="literal">def()</tt> member function. Say for example we have
|
||||
another World constructor taking in two doubles:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
|
||||
@@ -137,7 +144,8 @@
|
||||
On the other hand, if we do not wish to expose any constructors at all, we
|
||||
may use <tt class="literal">no_init</tt> instead:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt>
|
||||
@@ -153,7 +161,8 @@
|
||||
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Var</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Var</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">name</span><span class="special">;</span>
|
||||
@@ -164,7 +173,8 @@
|
||||
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
|
||||
to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -174,7 +184,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'is around'</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span>
|
||||
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
|
||||
@@ -183,7 +194,8 @@
|
||||
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
|
||||
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
</span><span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
|
||||
<span class="identifier">File</span> <span class="string">"<stdin>"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> #
|
||||
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
|
||||
@@ -200,7 +212,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Num</span><span class="special">();</span>
|
||||
<span class="keyword">float</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
@@ -214,7 +227,8 @@
|
||||
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
|
||||
class using Boost.Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -223,7 +237,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span>
|
||||
<span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">3.14</span><span class="special">)</span>
|
||||
@@ -236,7 +251,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
@@ -252,21 +268,24 @@
|
||||
<p>
|
||||
Consider this trivial inheritance structure:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
|
||||
</pre>
|
||||
<p>
|
||||
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
|
||||
object instances:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
|
||||
<span class="keyword">void</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span>
|
||||
<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -274,7 +293,8 @@
|
||||
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
|
||||
and its base class <tt class="literal">Base</tt>. Thus:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -297,7 +317,8 @@
|
||||
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
|
||||
and <tt class="literal">factory</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
|
||||
</pre>
|
||||
@@ -310,7 +331,8 @@
|
||||
is destroyed. We will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
|
||||
policies</a> later.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result
|
||||
<pre class="programlisting">
|
||||
<span class="comment">// Tell Python to take ownership of factory's result
|
||||
</span><span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
|
||||
<span class="identifier">return_value_policy</span><span class="special"><</span><span class="identifier">manage_new_object</span><span class="special">>());</span>
|
||||
</pre>
|
||||
@@ -323,7 +345,8 @@
|
||||
through virtual functions. Continuing our example, let us add a virtual function
|
||||
to our <tt class="literal">Base</tt> class:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
@@ -341,7 +364,8 @@
|
||||
that will unintrusively hook into the virtual functions so that a Python
|
||||
override may be called:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
@@ -373,7 +397,8 @@
|
||||
<p>
|
||||
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -412,7 +437,8 @@
|
||||
section</a>, we wrapped a class with a pure virtual function that we then
|
||||
implemented in C++, or Python classes derived from it. Our base class:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
@@ -421,7 +447,8 @@
|
||||
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
|
||||
function <tt class="literal">f</tt> was not declared as pure virtual:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span>
|
||||
@@ -430,7 +457,8 @@
|
||||
<p>
|
||||
We wrap it this way:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
@@ -462,7 +490,8 @@
|
||||
<p>
|
||||
Finally, exposing:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="special">&</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
@@ -477,7 +506,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
|
||||
<span class="special">...</span> <span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="special">...</span> <span class="keyword">return</span> <span class="number">42</span>
|
||||
@@ -487,13 +517,15 @@
|
||||
<p>
|
||||
Calling <tt class="literal">base.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="number">0</span>
|
||||
</pre>
|
||||
<p>
|
||||
Calling <tt class="literal">derived.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="number">42</span>
|
||||
</pre>
|
||||
</div>
|
||||
@@ -501,7 +533,7 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
|
||||
<a name="class_operators_special_functions.python_operators"></a><h2>
|
||||
<a name="id462548"></a>
|
||||
<a name="id461482"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
<p>
|
||||
@@ -515,7 +547,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
|
||||
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
|
||||
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
|
||||
@@ -529,7 +562,8 @@
|
||||
The class and the various operators can be mapped to Python rather easily
|
||||
and intuitively:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__
|
||||
@@ -548,7 +582,7 @@
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id463302"></a>
|
||||
<a name="id462239"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
<p>
|
||||
@@ -558,7 +592,8 @@
|
||||
wrap C++ functions that correspond to these Python <span class="emphasis"><em>special functions</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Rational</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">Rational</span>
|
||||
<span class="special">{</span> <span class="keyword">public</span><span class="special">:</span> <span class="keyword">operator</span> <span class="keyword">double</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">};</span>
|
||||
|
||||
<span class="identifier">Rational</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span> <span class="identifier">Rational</span><span class="special">);</span>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -87,14 +87,16 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
so Boost.Python must deal with them. To do this, it may need your help. Consider
|
||||
the following C++ function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
How should the library wrap this function? A naive approach builds a Python
|
||||
X object around result reference. This strategy might or might not work out.
|
||||
Here's an example where it didn't
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
|
||||
<span class="special">>>></span> <span class="identifier">del</span> <span class="identifier">y</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
@@ -104,7 +106,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Well, what if f() was implemented as shown below:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
|
||||
@@ -142,7 +145,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
</span><span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad
|
||||
</span><span class="number">3.14</span>
|
||||
</pre>
|
||||
@@ -156,7 +160,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">z_value</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">z</span><span class="special">-></span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
|
||||
@@ -166,14 +171,16 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Notice that the data member <tt class="literal">z</tt> is held by class Y using
|
||||
a raw pointer. Now we have a potential dangling pointer problem inside Y:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
|
||||
<span class="special">>>></span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
|
||||
<span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
For reference, here's the implementation of <tt class="literal">f</tt> again:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
|
||||
@@ -205,7 +212,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
</ol></div>
|
||||
<a name="call_policies.call_policies"></a><h2>
|
||||
<a name="id465291"></a>
|
||||
<a name="id464236"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
<p>
|
||||
@@ -213,7 +220,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
|
||||
are our friends:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span><span class="special">,</span>
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span> <span class="special">>());</span>
|
||||
</pre>
|
||||
@@ -221,7 +229,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
|
||||
ask?
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&
|
||||
@@ -230,7 +239,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
In short: "return an internal reference <tt class="literal">X&</tt> owned
|
||||
by the 1st argument <tt class="literal">Y& y</tt>".
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the lifetime of the argument indicated by ward
|
||||
@@ -242,7 +252,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
It is also important to note that we have defined two policies above. Two
|
||||
or more policies can be composed by chaining. Here's the general syntax:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">policy1</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">policy1</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy2</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy3</span><span class="special"><</span><span class="identifier">args</span><span class="special">...></span> <span class="special">></span> <span class="special">></span>
|
||||
</pre>
|
||||
@@ -306,7 +317,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
We have here our C++ class:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -333,7 +345,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Class X has 4 overloaded functions. We will start by introducing some member
|
||||
function pointer variables:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
@@ -341,7 +354,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
With these in hand, we can proceed to define and wrap this for Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
|
||||
@@ -355,26 +369,30 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
with default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
But the type of a pointer to the function <tt class="literal">f</tt> has no information
|
||||
about its default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<p>
|
||||
When we pass this function pointer to the <tt class="literal">def</tt> function,
|
||||
there is no way to retrieve the default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<p>
|
||||
Because of this, when wrapping C++ code, we had to resort to manual wrapping
|
||||
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
|
||||
or writing thin wrappers:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// write "thin wrappers"
|
||||
<pre class="programlisting">
|
||||
<span class="comment">// write "thin wrappers"
|
||||
</span><span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
|
||||
|
||||
@@ -397,13 +415,14 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a><h2>
|
||||
<a name="id467317"></a>
|
||||
<a name="id466276"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
Boost.Python now has a way to make it easier. For instance, given a function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
@@ -411,7 +430,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
will automatically create the thin wrappers for us. This macro will create
|
||||
@@ -421,10 +441,11 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
|
||||
function will automatically add all the foo variants for us:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
|
||||
<a name="id467632"></a>
|
||||
<a name="id466595"></a>
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -439,7 +460,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
may be used to automatically create the thin wrappers for wrapping member
|
||||
functions. Let's have an example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">george</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">george</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span>
|
||||
<span class="identifier">wack_em</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">=</span> <span class="char">'x'</span><span class="special">)</span>
|
||||
@@ -451,7 +473,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
|
||||
@@ -460,14 +483,15 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
in a class named <tt class="literal">george_overloads</tt> that can then be used
|
||||
as an argument to <tt class="literal">def(...)</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<p>
|
||||
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
|
||||
reference</a> for details.
|
||||
</p>
|
||||
<a name="default_arguments.init_and_optional"></a><h2>
|
||||
<a name="id467992"></a>
|
||||
<a name="id466958"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
<p>
|
||||
@@ -475,7 +499,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
arguments or a sequence of overloads. Remember <tt class="literal">init<...></tt>?
|
||||
For example, given a class X with a constructor:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="char">'D'</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">c</span> <span class="special">=</span> <span class="string">"constructor"</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
@@ -484,7 +509,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
You can easily add this constructor to Boost.Python in one shot:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> <span class="special">>())</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice the use of <tt class="literal">init<...></tt> and <tt class="literal">optional<...></tt>
|
||||
@@ -500,7 +526,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
used for overloaded functions and member functions with a common sequence
|
||||
of initial arguments. Here is an example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
@@ -524,19 +551,21 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Like in the previous section, we can generate thin wrappers for these overloaded
|
||||
functions in one-shot:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice though that we have a situation now where we have a minimum of zero
|
||||
(0) arguments and a maximum of 3 arguments.
|
||||
</p>
|
||||
<a name="auto_overloading.manual_wrapping"></a><h2>
|
||||
<a name="id468767"></a>
|
||||
<a name="id467740"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
<p>
|
||||
@@ -555,18 +584,21 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
to automatically wrap the first three of the <tt class="literal">def</tt>s and
|
||||
manually wrap just the last. Here's how we'll do this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Create a member function pointers as above for both X::f overloads:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
|
||||
<a name="hello.from_start_to_finish"></a><h2>
|
||||
<a name="id388718"></a>
|
||||
<a name="id386189"></a>
|
||||
From Start To Finish
|
||||
</h2>
|
||||
<p>
|
||||
@@ -92,7 +92,7 @@
|
||||
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
|
||||
</p>
|
||||
<a name="hello.let_s_jam_"></a><h2>
|
||||
<a name="id387300"></a>
|
||||
<a name="id386347"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
<p>
|
||||
@@ -108,7 +108,7 @@
|
||||
you going.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id387357"></a>
|
||||
<a name="id386404"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
<p>
|
||||
@@ -156,7 +156,8 @@ using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
|
||||
<p>
|
||||
Finally:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">bjam</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">bjam</span>
|
||||
</pre>
|
||||
<p>
|
||||
It should be building now:
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -64,7 +64,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
</span><span class="keyword">try</span><span class="special">:</span>
|
||||
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
|
||||
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
|
||||
@@ -78,14 +79,16 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
Or for use in class_<>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>range</b></span>
|
||||
@@ -131,7 +134,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
|
||||
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
|
||||
@@ -142,7 +146,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
|
||||
</pre>
|
||||
@@ -158,7 +163,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="comment">// Turn a Python sequence into an STL input range
|
||||
</span> <span class="identifier">stl_input_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
@@ -177,7 +183,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -62,7 +62,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
|
||||
<span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
|
||||
<span class="keyword">else</span><span class="special">:</span>
|
||||
@@ -77,7 +78,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
|
||||
<span class="keyword">else</span>
|
||||
@@ -124,20 +126,23 @@
|
||||
These derived <tt class="literal">object</tt> types act like real Python types.
|
||||
For instance:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
</pre>
|
||||
<p>
|
||||
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
|
||||
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
|
||||
has a <tt class="literal">keys()</tt> method:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
|
||||
@@ -145,7 +150,8 @@
|
||||
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
|
||||
instances of Python's <tt class="literal">str</tt> type and subtypes.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()
|
||||
</span> <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better
|
||||
@@ -155,13 +161,15 @@
|
||||
<p>
|
||||
In finer detail:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
Illustrates that we provide versions of the str type's methods as C++ member
|
||||
functions.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
|
||||
@@ -176,17 +184,19 @@
|
||||
<p>
|
||||
Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
|
||||
</span><span class="special">>>></span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy
|
||||
</span></pre>
|
||||
<p>
|
||||
C++:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
|
||||
</span></pre>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
|
||||
<a name="id470756"></a>
|
||||
<a name="id469745"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -197,7 +207,8 @@
|
||||
<p>
|
||||
We can use this to create wrapped instances. Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">>(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span>
|
||||
@@ -214,14 +225,16 @@
|
||||
can be achieved with the <tt class="literal">extract<T></tt> function. Consider
|
||||
the following:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
</span></pre>
|
||||
<p>
|
||||
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
|
||||
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
|
||||
we wanted to do above can be achieved by writing:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&>(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
|
||||
</pre>
|
||||
@@ -238,7 +251,8 @@
|
||||
be extracted, an appropriate exception is thrown. To avoid an exception,
|
||||
we need to test for extractibility:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&></span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&></span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
|
||||
</pre>
|
||||
@@ -246,7 +260,8 @@
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract<T></tt>
|
||||
facility in fact solves the mutable copying problem:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">dict</span><span class="special">>(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">dict</span><span class="special">>(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
|
||||
<span class="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !
|
||||
</span></pre>
|
||||
</div>
|
||||
@@ -261,12 +276,14 @@
|
||||
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
|
||||
to enums). To illustrate, given a C++ enum:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
the construct:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">enum_</span><span class="special"><</span><span class="identifier">choice</span><span class="special">>(</span><span class="string">"choice"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">enum_</span><span class="special"><</span><span class="identifier">choice</span><span class="special">>(</span><span class="string">"choice"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
@@ -298,7 +315,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -307,7 +325,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
@@ -53,7 +53,8 @@
|
||||
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
|
||||
like so:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span>
|
||||
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span>
|
||||
</pre>
|
||||
@@ -61,14 +62,16 @@
|
||||
We would like to present this same hierarchy to the Python user, allowing
|
||||
him to write code like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function
|
||||
</span></pre>
|
||||
<p>
|
||||
The first step is to write the wrapping code. We have to export each module
|
||||
separately with Boost.Python, like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
|
||||
@@ -126,7 +129,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">'file.mp3'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">new_sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)</span>
|
||||
@@ -148,7 +152,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">/* file core.cpp */</span>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file core.cpp */</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">...</span>
|
||||
@@ -180,7 +185,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">.</span><span class="identifier">foo</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -190,13 +196,15 @@
|
||||
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
|
||||
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
</pre>
|
||||
<p>
|
||||
We do the same for the other packages. Now the user accesses the functions
|
||||
and classes in the extension modules like before:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -209,7 +217,8 @@
|
||||
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
|
||||
function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
<span class="keyword">def</span> <span class="identifier">echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span>
|
||||
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
|
||||
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
|
||||
@@ -218,13 +227,15 @@
|
||||
<p>
|
||||
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
</pre>
|
||||
<p>
|
||||
And that's it. The user now accesses this function like any other function
|
||||
from the <tt class="literal">filters</tt> package:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
</div>
|
||||
@@ -235,7 +246,8 @@
|
||||
Thanks to Python's flexibility, you can easily add new methods to a class,
|
||||
even after it was already created:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># a regular function
|
||||
</span><span class="special">>>></span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
|
||||
@@ -258,7 +270,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -271,7 +284,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
|
||||
<span class="comment"># a regular function
|
||||
</span><span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
@@ -303,7 +317,8 @@
|
||||
You can even add a little syntactic sugar with the use of metaclasses. Let's
|
||||
create a special metaclass that "injects" methods in other classes.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
<pre class="programlisting">
|
||||
<span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
|
||||
</span><span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
|
||||
|
||||
@@ -326,7 +341,8 @@
|
||||
<p>
|
||||
Now let's see how it got:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
|
||||
<span class="identifier">Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="identifier">foo</span><span class="special">!</span>
|
||||
@@ -334,7 +350,8 @@
|
||||
<p>
|
||||
Another useful idea is to replace constructors with factory functions:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
|
||||
|
||||
<span class="keyword">def</span> <span class="identifier">point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span>
|
||||
<span class="keyword">return</span> <span class="identifier">_point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span>
|
||||
@@ -357,7 +374,8 @@
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file point.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
@@ -379,7 +397,8 @@
|
||||
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
|
||||
macro, and call the various export functions inside it.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
|
||||
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">();</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
|
||||
@@ -392,7 +411,8 @@
|
||||
Compiling and linking together all this files produces the same result as
|
||||
the usual approach:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<pre class="programlisting">
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[library python
|
||||
[version 2.0]
|
||||
[version 1.0]
|
||||
[authors [de Guzman, Joel], [Abrahams, David]]
|
||||
[copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
|
||||
[category inter-language support]
|
||||
@@ -186,6 +186,10 @@ 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]
|
||||
@@ -1381,10 +1385,10 @@ interpreter. This may be fixed in a future version of boost.python.]
|
||||
[section Using the interpreter]
|
||||
|
||||
As you probably already know, objects in Python are reference-counted.
|
||||
Naturally, the [^PyObject]s of the Python C API are also reference-counted.
|
||||
Naturally, the [^PyObject]s of the Python\/C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully
|
||||
automatic in Python, the Python C API requires you to do it
|
||||
[@http://www.python.org/doc/current/c-api/refcounting.html by hand]. This is
|
||||
automatic in Python, the Python\/C API requires you to do it
|
||||
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
|
||||
messy and especially hard to get right in the presence of C++ exceptions.
|
||||
Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and
|
||||
[@../../../v2/object.html object] class templates to automate the process.
|
||||
@@ -1466,7 +1470,7 @@ If an exception occurs in the evaluation of the python expression,
|
||||
The [^error_already_set] exception class doesn't carry any information in itself.
|
||||
To find out more about the Python exception that occurred, you need to use the
|
||||
[@http://www.python.org/doc/api/exceptionHandling.html exception handling functions]
|
||||
of the Python C API in your catch-statement. This can be as simple as calling
|
||||
of the Python/C API in your catch-statement. This can be as simple as calling
|
||||
[@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to
|
||||
print the exception's traceback to the console, or comparing the type of the
|
||||
exception with those of the [@http://www.python.org/doc/api/standardExceptions.html
|
||||
|
||||
@@ -655,11 +655,6 @@ namespace boost { namespace python { namespace api
|
||||
template <class A0, class A1,...class An>
|
||||
object operator()(A0 const&, A1 const&,...An const&) const;
|
||||
|
||||
detail::args_proxy operator* () const;
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
|
||||
// truth value testing
|
||||
//
|
||||
typedef unspecified bool_type;
|
||||
@@ -709,25 +704,6 @@ object operator()(A0 const& a1, A1 const& a2,...An const& aN) const;
|
||||
call<object>(object(*static_cast<U*>(this)).ptr(), a1,
|
||||
a2,...aN)</dt>
|
||||
</dl>
|
||||
|
||||
<pre>
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
call object with arguments given by the tuple <varname>args</varname></dt>
|
||||
</dl>
|
||||
<pre>
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b>
|
||||
call object with arguments given by the tuple <varname>args</varname>, and named
|
||||
arguments given by the dictionary <varname>kwds</varname></dt>
|
||||
</dl>
|
||||
|
||||
|
||||
<pre>
|
||||
operator bool_type() const;
|
||||
</pre>
|
||||
|
||||
@@ -2,15 +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)
|
||||
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
ECHO "notice: no Python configured in user-config.jam" ;
|
||||
ECHO "notice: will use default configuration" ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
# Specify the path to the Boost project. If you move this project,
|
||||
# adjust this path to refer to the Boost root directory.
|
||||
use-project boost
|
||||
|
||||
@@ -38,10 +38,7 @@ namespace boost { namespace python {
|
||||
|
||||
# endif // CALL_DWA2002411_HPP
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, call.hpp)
|
||||
@@ -79,5 +76,4 @@ call(PyObject* callable
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -37,10 +37,7 @@ namespace boost { namespace python {
|
||||
|
||||
# endif // CALL_METHOD_DWA2002411_HPP
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
|
||||
@@ -79,5 +76,4 @@ call_method(PyObject* self, char const* name
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
|
||||
@@ -90,14 +90,6 @@ 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( \
|
||||
@@ -106,7 +98,6 @@ 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
|
||||
@@ -125,24 +116,17 @@ 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), &PyLong_Type)
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
|
||||
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)
|
||||
# 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())), &PyUnicode_Type)
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_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)
|
||||
|
||||
@@ -34,9 +34,7 @@ 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);
|
||||
|
||||
@@ -117,9 +117,9 @@ struct rvalue_from_python_data : rvalue_from_python_storage<T>
|
||||
// Implementataions
|
||||
//
|
||||
template <class T>
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& _stage1)
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1)
|
||||
{
|
||||
this->stage1 = _stage1;
|
||||
this->stage1 = stage1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -45,14 +45,10 @@ struct shared_ptr_from_python
|
||||
if (data->convertible == source)
|
||||
new (storage) shared_ptr<T>();
|
||||
else
|
||||
{
|
||||
boost::shared_ptr<void> hold_convertible_ref_count(
|
||||
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
|
||||
// use aliasing constructor
|
||||
new (storage) shared_ptr<T>(
|
||||
hold_convertible_ref_count,
|
||||
static_cast<T*>(data->convertible));
|
||||
}
|
||||
static_cast<T*>(data->convertible),
|
||||
shared_ptr_deleter(handle<>(borrowed(source)))
|
||||
);
|
||||
|
||||
data->convertible = storage;
|
||||
}
|
||||
|
||||
@@ -265,8 +265,7 @@ inline object make_getter(D const& d, Policies const& policies)
|
||||
template <class D>
|
||||
inline object make_getter(D& x)
|
||||
{
|
||||
detail::not_specified policy
|
||||
= detail::not_specified(); // suppress a SunPro warning
|
||||
detail::not_specified policy;
|
||||
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
@@ -274,8 +273,7 @@ inline object make_getter(D& x)
|
||||
template <class D>
|
||||
inline object make_getter(D const& d)
|
||||
{
|
||||
detail::not_specified policy
|
||||
= detail::not_specified(); // Suppress a SunPro warning
|
||||
detail::not_specified policy;
|
||||
return detail::make_getter(d, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,11 +47,7 @@ enum operator_id
|
||||
op_ixor,
|
||||
op_ior,
|
||||
op_complex,
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
op_bool,
|
||||
#else
|
||||
op_nonzero,
|
||||
#endif
|
||||
op_repr
|
||||
};
|
||||
|
||||
|
||||
@@ -86,10 +86,7 @@ result(X const&, short = 0) { return 0; }
|
||||
# endif // RESULT_DWA2002521_HPP
|
||||
|
||||
/* --------------- function pointers --------------- */
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers))
|
||||
@@ -131,5 +128,4 @@ boost::type<R>* result(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0)
|
||||
# undef N
|
||||
# undef Q
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -37,10 +37,7 @@ T& (* target(R (T::*)) )() { return 0; }
|
||||
# endif // TARGET_DWA2002521_HPP
|
||||
|
||||
/* --------------- function pointers --------------- */
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers))
|
||||
@@ -82,5 +79,4 @@ T& (* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) )()
|
||||
# undef N
|
||||
# undef Q
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
// 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_TDS20091020_HPP
|
||||
# define TRANSLATE_EXCEPTION_TDS20091020_HPP
|
||||
#ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP
|
||||
# define TRANSLATE_EXCEPTION_DWA2002810_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>
|
||||
|
||||
|
||||
@@ -175,19 +175,6 @@ 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
|
||||
|
||||
@@ -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,11 +79,7 @@ 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;
|
||||
|
||||
@@ -20,13 +20,6 @@ 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.
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace detail
|
||||
{
|
||||
void append(object_cref); // append object to end
|
||||
|
||||
ssize_t count(object_cref value) const; // return number of occurrences of value
|
||||
long count(object_cref value) const; // return number of occurrences of value
|
||||
|
||||
void extend(object_cref sequence); // extend list by appending sequence elements
|
||||
|
||||
@@ -37,12 +37,8 @@ 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
|
||||
@@ -117,15 +113,13 @@ 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)
|
||||
|
||||
@@ -63,7 +63,7 @@ struct extract_member
|
||||
{
|
||||
static MemberType& execute(InstanceType& c)
|
||||
{
|
||||
(void)Py_TYPE(&c); // static assertion
|
||||
(void)c.ob_type; // static assertion
|
||||
return c.*member;
|
||||
}
|
||||
};
|
||||
@@ -75,7 +75,7 @@ struct extract_identity
|
||||
{
|
||||
static InstanceType& execute(InstanceType& c)
|
||||
{
|
||||
(void)Py_TYPE(&c); // static assertion
|
||||
(void)c.ob_type; // static assertion
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -11,49 +11,40 @@
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
|
||||
BOOST_PYTHON_DECL void init_module(char const* name, void(*)());
|
||||
|
||||
}}}
|
||||
|
||||
# if PY_VERSION_HEX >= 0x03000000
|
||||
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
|
||||
|
||||
# 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() \
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init_module_##name(); \
|
||||
extern "C" __declspec(dllexport) 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"))) _BOOST_PYTHON_MODULE_INIT(name)
|
||||
extern "C" __attribute__ ((visibility("default"))) void init##name() \
|
||||
{ \
|
||||
boost::python::detail::init_module(#name, &init_module_##name); \
|
||||
} \
|
||||
void init_module_##name()
|
||||
|
||||
# else
|
||||
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init_module_##name(); \
|
||||
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
|
||||
extern "C" void init##name() \
|
||||
{ \
|
||||
boost::python::detail::init_module(#name, &init_module_##name); \
|
||||
} \
|
||||
void init_module_##name()
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ struct class_metadata
|
||||
//
|
||||
// Support for converting smart pointers to python
|
||||
//
|
||||
inline static void maybe_register_pointer_to_python(...) {}
|
||||
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
|
||||
|
||||
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
|
||||
|
||||
@@ -129,11 +129,7 @@ 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
|
||||
|
||||
@@ -47,10 +47,7 @@ template <int nargs> struct make_holder;
|
||||
|
||||
# endif // MAKE_HOLDER_DWA20011215_HPP
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, make_holder.hpp)
|
||||
@@ -105,5 +102,4 @@ struct make_holder<N>
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@ struct make_instance_impl
|
||||
|
||||
// Note the position of the internally-stored Holder,
|
||||
// for the sake of destruction
|
||||
Py_SIZE(instance) = offsetof(instance_t, storage);
|
||||
instance->ob_size = offsetof(instance_t, storage);
|
||||
|
||||
// Release ownership of the python object
|
||||
protect.cancel();
|
||||
|
||||
@@ -127,14 +127,7 @@ void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
|
||||
)
|
||||
return &this->m_p;
|
||||
|
||||
Value* p
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
= static_cast<Value*>( get_pointer(this->m_p) )
|
||||
# else
|
||||
= get_pointer(this->m_p)
|
||||
# endif
|
||||
;
|
||||
|
||||
Value* p = get_pointer(this->m_p);
|
||||
if (p == 0)
|
||||
return 0;
|
||||
|
||||
@@ -170,10 +163,7 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
|
||||
# endif // POINTER_HOLDER_DWA20011215_HPP
|
||||
|
||||
/* --------------- pointer_holder --------------- */
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
|
||||
@@ -215,5 +205,4 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -117,10 +117,7 @@ void* value_holder_back_reference<Value,Held>::holds(
|
||||
|
||||
// --------------- value_holder ---------------
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
|
||||
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder))
|
||||
@@ -166,5 +163,4 @@ void* value_holder_back_reference<Value,Held>::holds(
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
|
||||
@@ -42,12 +42,6 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class kwds_proxy;
|
||||
class args_proxy;
|
||||
}
|
||||
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct arg_to_python;
|
||||
@@ -108,11 +102,6 @@ namespace api
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
detail::args_proxy operator* () const;
|
||||
object operator()(detail::args_proxy const &args) const;
|
||||
object operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const;
|
||||
|
||||
// truth value testing
|
||||
//
|
||||
@@ -126,10 +115,6 @@ 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;
|
||||
@@ -234,11 +219,11 @@ namespace api
|
||||
inline object_base(object_base const&);
|
||||
inline object_base(PyObject* ptr);
|
||||
|
||||
inline object_base& operator=(object_base const& rhs);
|
||||
inline ~object_base();
|
||||
object_base& operator=(object_base const& rhs);
|
||||
~object_base();
|
||||
|
||||
// Underlying object access -- returns a borrowed reference
|
||||
inline PyObject* ptr() const;
|
||||
PyObject* ptr() const;
|
||||
|
||||
private:
|
||||
PyObject* m_ptr;
|
||||
@@ -408,7 +393,7 @@ namespace api
|
||||
static PyObject*
|
||||
get(T const& x, U)
|
||||
{
|
||||
return python::incref(get_managed_object(x, boost::python::tag));
|
||||
return python::incref(get_managed_object(x, tag));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -431,71 +416,6 @@ template <class T> struct extract;
|
||||
// implementation
|
||||
//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class call_proxy
|
||||
{
|
||||
public:
|
||||
call_proxy(object target) : m_target(target) {}
|
||||
operator object() const { return m_target;}
|
||||
|
||||
private:
|
||||
object m_target;
|
||||
};
|
||||
|
||||
class kwds_proxy : public call_proxy
|
||||
{
|
||||
public:
|
||||
kwds_proxy(object o = object()) : call_proxy(o) {}
|
||||
};
|
||||
class args_proxy : public call_proxy
|
||||
{
|
||||
public:
|
||||
args_proxy(object o) : call_proxy(o) {}
|
||||
kwds_proxy operator* () const { return kwds_proxy(*this);}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
detail::args_proxy api::object_operators<U>::operator* () const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return boost::python::detail::args_proxy(x);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
object api::object_operators<U>::operator()(detail::args_proxy const &args) const
|
||||
{
|
||||
U const& self = *static_cast<U const*>(this);
|
||||
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
||||
args.operator object().ptr(),
|
||||
0);
|
||||
return object(boost::python::detail::new_reference(result));
|
||||
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
object api::object_operators<U>::operator()(detail::args_proxy const &args,
|
||||
detail::kwds_proxy const &kwds) const
|
||||
{
|
||||
U const& self = *static_cast<U const*>(this);
|
||||
PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
||||
args.operator object().ptr(),
|
||||
kwds.operator object().ptr());
|
||||
return object(boost::python::detail::new_reference(result));
|
||||
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
{}
|
||||
|
||||
@@ -60,9 +60,7 @@ inline
|
||||
object_operators<U>::operator bool_type() const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
int is_true = PyObject_IsTrue(x.ptr());
|
||||
if (is_true < 0) throw_error_already_set();
|
||||
return is_true ? &object::ptr : 0;
|
||||
return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -70,9 +68,7 @@ inline bool
|
||||
object_operators<U>::operator!() const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
int is_true = PyObject_IsTrue(x.ptr());
|
||||
if (is_true < 0) throw_error_already_set();
|
||||
return !is_true;
|
||||
return !PyObject_IsTrue(x.ptr());
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_COMPARE_OP(op, opid) \
|
||||
|
||||
@@ -10,11 +10,9 @@
|
||||
# include <boost/python/object_protocol_core.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
# if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
|
||||
// attempt to use SFINAE to prevent functions accepting T const& from
|
||||
// coming up as ambiguous with the one taking a char const* when a
|
||||
// string literal is passed
|
||||
@@ -24,45 +22,45 @@ namespace boost { namespace python { namespace api {
|
||||
# endif
|
||||
|
||||
template <class Target, class Key>
|
||||
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
return getattr(object(target), object(key));
|
||||
}
|
||||
|
||||
template <class Target, class Key, class Default>
|
||||
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
return getattr(object(target), object(key), object(default_));
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value>
|
||||
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
setattr(target, object(key), object(value));
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
delattr(target, object(key));
|
||||
}
|
||||
|
||||
template <class Target, class Key>
|
||||
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
return getitem(object(target), object(key));
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value>
|
||||
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
setitem(target, object(key), object(value));
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(Key))
|
||||
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
|
||||
{
|
||||
delitem(target, object(key));
|
||||
}
|
||||
|
||||
@@ -27,12 +27,6 @@ struct slice_policies : const_slice_policies
|
||||
static void del(object const& target, key_type const& key);
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
inline slice_policies::key_type slice_key(T x, U y)
|
||||
{
|
||||
return slice_policies::key_type(handle<>(x), handle<>(y));
|
||||
}
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
@@ -41,7 +35,7 @@ object_slice
|
||||
object_operators<U>::slice(object_cref start, object_cref finish)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -49,7 +43,7 @@ const_object_slice
|
||||
object_operators<U>::slice(object_cref start, object_cref finish) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -57,7 +51,7 @@ object_slice
|
||||
object_operators<U>::slice(slice_nil, object_cref finish)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -65,7 +59,7 @@ const_object_slice
|
||||
object_operators<U>::slice(slice_nil, object_cref finish) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -73,7 +67,7 @@ object_slice
|
||||
object_operators<U>::slice(slice_nil, slice_nil)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
return object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -81,7 +75,7 @@ const_object_slice
|
||||
object_operators<U>::slice(slice_nil, slice_nil) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, api::slice_key(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -89,7 +83,7 @@ object_slice
|
||||
object_operators<U>::slice(object_cref start, slice_nil)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -97,7 +91,7 @@ const_object_slice
|
||||
object_operators<U>::slice(object_cref start, slice_nil) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class U>
|
||||
|
||||
@@ -121,7 +121,8 @@ opaque<Pointee> opaque<Pointee>::instance;
|
||||
template <class Pointee>
|
||||
PyTypeObject opaque<Pointee>::type_object =
|
||||
{
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
PyObject_HEAD_INIT(0)
|
||||
0,
|
||||
0,
|
||||
sizeof( BOOST_DEDUCED_TYPENAME opaque<Pointee>::python_instance ),
|
||||
0,
|
||||
|
||||
@@ -341,11 +341,7 @@ 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_)
|
||||
|
||||
@@ -113,10 +113,7 @@ struct most_derived
|
||||
|
||||
# endif // SIGNATURE_JDG20020813_HPP
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
@@ -179,5 +176,4 @@ get_signature(
|
||||
# undef Q
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
@@ -37,12 +37,10 @@ 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;
|
||||
@@ -187,7 +185,6 @@ 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>
|
||||
@@ -201,7 +198,6 @@ class str : public detail::str_base
|
||||
{
|
||||
return base::decode(object(encoding),object(errors));
|
||||
}
|
||||
#endif
|
||||
|
||||
object encode() const { return base::encode(); }
|
||||
|
||||
@@ -408,11 +404,7 @@ 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
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
3
module.cmake
Normal file
3
module.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
boost_module(python DEPENDS graph numeric)
|
||||
|
||||
# numeric is there because of boost/cast.hpp from libs/python/src/errors.cpp:11
|
||||
64
src/CMakeLists.txt
Normal file
64
src/CMakeLists.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
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}"
|
||||
)
|
||||
@@ -37,20 +37,12 @@ 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
|
||||
@@ -98,52 +90,6 @@ 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
|
||||
{
|
||||
@@ -153,13 +99,8 @@ namespace
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
|
||||
? &number_methods->nb_int : 0;
|
||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
};
|
||||
@@ -175,7 +116,16 @@ 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
|
||||
{
|
||||
@@ -185,11 +135,7 @@ namespace
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
return (PyInt_Check(obj) || PyLong_Check(obj))
|
||||
? &py_object_identity : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
@@ -200,30 +146,12 @@ namespace
|
||||
{
|
||||
static T extract(PyObject* 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);
|
||||
}
|
||||
return numeric_cast<T>(
|
||||
PyLong_Check(intermediate)
|
||||
? PyLong_AsUnsignedLong(intermediate)
|
||||
: PyInt_AS_LONG(intermediate));
|
||||
}
|
||||
};
|
||||
#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
|
||||
@@ -236,9 +164,6 @@ 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;
|
||||
@@ -251,22 +176,19 @@ namespace
|
||||
return &number_methods->nb_long;
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyLong_Type;}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_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);
|
||||
|
||||
@@ -282,13 +204,11 @@ 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);
|
||||
|
||||
@@ -306,13 +226,7 @@ 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)
|
||||
@@ -341,10 +255,8 @@ 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;
|
||||
@@ -352,13 +264,11 @@ 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);
|
||||
}
|
||||
@@ -366,36 +276,22 @@ 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)
|
||||
{
|
||||
#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
|
||||
return (PyString_Check(obj))
|
||||
? &obj->ob_type->tp_str : 0;
|
||||
};
|
||||
|
||||
// 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)
|
||||
@@ -415,11 +311,7 @@ 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;
|
||||
};
|
||||
@@ -462,12 +354,10 @@ 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);
|
||||
@@ -479,20 +369,12 @@ 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)
|
||||
@@ -547,18 +429,13 @@ 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
|
||||
|
||||
@@ -96,12 +96,7 @@ BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
|
||||
if (!data.convertible)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
::PyString_FromFormat(
|
||||
"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
|
||||
@@ -201,12 +196,7 @@ namespace
|
||||
void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
::PyString_FromFormat(
|
||||
"No registered converter was able to extract a C++ %s to type %s"
|
||||
" from this Python object of type %s"
|
||||
, ref_type
|
||||
@@ -228,12 +218,7 @@ namespace
|
||||
if (source->ob_refcnt <= 1)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x3000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
::PyString_FromFormat(
|
||||
"Attempt to return dangling %s to object of type: %s"
|
||||
, ref_type
|
||||
, converters.target_type.name()));
|
||||
|
||||
@@ -70,12 +70,7 @@ BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source)
|
||||
if (this->m_to_python == 0)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x3000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
::PyString_FromFormat(
|
||||
"No to_python (by-value) converter found for C++ type: %s"
|
||||
, this->target_type.name()
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace
|
||||
detail::new_reference dict_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyDict_Type, const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyDict_Type, "(O)",
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
@@ -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->contains(k));
|
||||
return extract<bool>(this->attr("has_key")(k));
|
||||
}
|
||||
|
||||
list dict_base::items() const
|
||||
|
||||
62
src/exec.cpp
62
src/exec.cpp
@@ -5,7 +5,6 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -16,16 +15,6 @@ namespace python
|
||||
|
||||
object BOOST_PYTHON_DECL eval(str string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
object none;
|
||||
if (global.ptr() == none.ptr())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.ptr() == none.ptr()) 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());
|
||||
@@ -35,16 +24,6 @@ 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.
|
||||
object none;
|
||||
if (global.ptr() == none.ptr())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.ptr() == none.ptr()) 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());
|
||||
@@ -52,55 +31,18 @@ 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.
|
||||
object none;
|
||||
if (global.ptr() == none.ptr())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.ptr() == none.ptr()) 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.
|
||||
object none;
|
||||
if (global.ptr() == none.ptr())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.ptr() == none.ptr()) 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, const_cast<char*>("r"));
|
||||
PyObject *pyfile = PyFile_FromString(f, "r");
|
||||
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
|
||||
python::handle<> file(pyfile);
|
||||
FILE *fs = PyFile_AsFile(file.get());
|
||||
#endif
|
||||
PyObject* result = PyRun_File(fs,
|
||||
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
|
||||
f,
|
||||
Py_file_input,
|
||||
global.ptr(), local.ptr());
|
||||
|
||||
24
src/list.cpp
24
src/list.cpp
@@ -13,7 +13,7 @@ detail::new_non_null_reference list_base::call(object const& arg_)
|
||||
return (detail::new_non_null_reference)
|
||||
(expect_non_null)(
|
||||
PyObject_CallFunction(
|
||||
(PyObject*)&PyList_Type, const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyList_Type, "(O)",
|
||||
arg_.ptr()));
|
||||
}
|
||||
|
||||
@@ -48,11 +48,7 @@ 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;
|
||||
@@ -73,11 +69,7 @@ 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);
|
||||
@@ -129,29 +121,17 @@ 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.
|
||||
ssize_t list_base::count(object_cref value) const
|
||||
long 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;
|
||||
|
||||
@@ -9,21 +9,21 @@ namespace boost { namespace python { namespace detail {
|
||||
new_non_null_reference long_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyLong_Type, "(O)",
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
new_non_null_reference long_base::call(object const& arg_, object const& base)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(OO)"),
|
||||
(PyObject*)&PyLong_Type, "(OO)",
|
||||
arg_.ptr(), base.ptr());
|
||||
}
|
||||
|
||||
long_base::long_base()
|
||||
: object(
|
||||
detail::new_reference(
|
||||
PyObject_CallFunction((PyObject*)&PyLong_Type, const_cast<char*>("()")))
|
||||
PyObject_CallFunction((PyObject*)&PyLong_Type, "()"))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
@@ -24,25 +24,11 @@ namespace
|
||||
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
|
||||
BOOST_PYTHON_DECL void 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)
|
||||
{
|
||||
@@ -52,7 +38,6 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)()
|
||||
|
||||
handle_exception(init_function);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -67,50 +67,14 @@ 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, const_cast<char*>("()"));
|
||||
return PyObject_CallFunction(gs->prop_get, "()");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -131,9 +95,9 @@ extern "C"
|
||||
return -1;
|
||||
}
|
||||
if (value == NULL)
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("()"));
|
||||
res = PyObject_CallFunction(func, "()");
|
||||
else
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
|
||||
res = PyObject_CallFunction(func, "(O)", value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
@@ -142,9 +106,10 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyTypeObject static_data_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.StaticProperty"),
|
||||
sizeof(propertyobject),
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.StaticProperty",
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
@@ -178,11 +143,11 @@ static PyTypeObject static_data_object = {
|
||||
static_data_descr_get, /* tp_descr_get */
|
||||
static_data_descr_set, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
property_init, /* tp_init */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, // filled in with type_new /* tp_new */
|
||||
0, // filled in with __PyObject_GC_Del /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
(inquiry)type_is_gc, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
@@ -195,20 +160,17 @@ 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)
|
||||
{
|
||||
Py_TYPE(&static_data_object) = &PyType_Type;
|
||||
static_data_object.ob_type = &PyType_Type;
|
||||
static_data_object.tp_base = &PyProperty_Type;
|
||||
if (PyType_Ready(&static_data_object))
|
||||
return 0;
|
||||
@@ -241,15 +203,16 @@ 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 Py_TYPE(a)->tp_descr_set(a, obj, value);
|
||||
return a->ob_type->tp_descr_set(a, obj, value);
|
||||
else
|
||||
return PyType_Type.tp_setattro(obj, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
static PyTypeObject class_metatype_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.class"),
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.class",
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
@@ -303,7 +266,7 @@ static PyTypeObject class_metatype_object = {
|
||||
// object.
|
||||
void instance_holder::install(PyObject* self) throw()
|
||||
{
|
||||
assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
|
||||
assert(self->ob_type->ob_type == &class_metatype_object);
|
||||
m_next = ((objects::instance<>*)self)->objects;
|
||||
((objects::instance<>*)self)->objects = this;
|
||||
}
|
||||
@@ -316,7 +279,7 @@ namespace objects
|
||||
{
|
||||
if (class_metatype_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&class_metatype_object) = &PyType_Type;
|
||||
class_metatype_object.ob_type = &PyType_Type;
|
||||
class_metatype_object.tp_base = &PyType_Type;
|
||||
if (PyType_Ready(&class_metatype_object))
|
||||
return type_handle();
|
||||
@@ -345,7 +308,7 @@ namespace objects
|
||||
|
||||
Py_XDECREF(kill_me->dict);
|
||||
|
||||
Py_TYPE(inst)->tp_free(inst);
|
||||
inst->ob_type->tp_free(inst);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@@ -353,14 +316,9 @@ namespace objects
|
||||
{
|
||||
// Attempt to find the __instance_size__ attribute. If not present, no problem.
|
||||
PyObject* d = type_->tp_dict;
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");
|
||||
|
||||
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
|
||||
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
|
||||
|
||||
if (instance_size < 0)
|
||||
instance_size = 0;
|
||||
@@ -374,12 +332,7 @@ 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.
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
Py_SIZE(result) =
|
||||
#else
|
||||
result->ob_size =
|
||||
#endif
|
||||
-(static_cast<int>(offsetof(instance<>,storage) + instance_size));
|
||||
result->ob_size = -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
|
||||
}
|
||||
return (PyObject*)result;
|
||||
}
|
||||
@@ -404,19 +357,20 @@ namespace objects
|
||||
|
||||
|
||||
static PyGetSetDef instance_getsets[] = {
|
||||
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{"__dict__", instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static PyMemberDef instance_members[] = {
|
||||
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static PyTypeObject class_type_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.instance"),
|
||||
PyObject_HEAD_INIT(0) //&class_metatype_object)
|
||||
0,
|
||||
"Boost.Python.instance",
|
||||
offsetof(instance<>,storage), /* tp_basicsize */
|
||||
1, /* tp_itemsize */
|
||||
instance_dealloc, /* tp_dealloc */
|
||||
@@ -470,7 +424,7 @@ namespace objects
|
||||
{
|
||||
if (class_type_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&class_type_object) = incref(class_metatype().get());
|
||||
class_type_object.ob_type = incref(class_metatype().get());
|
||||
class_type_object.tp_base = &PyBaseObject_Type;
|
||||
if (PyType_Ready(&class_type_object))
|
||||
return type_handle();
|
||||
@@ -482,7 +436,7 @@ namespace objects
|
||||
BOOST_PYTHON_DECL void*
|
||||
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
|
||||
{
|
||||
if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
|
||||
if (inst->ob_type->ob_type != &class_metatype_object)
|
||||
return 0;
|
||||
|
||||
instance<>* self = reinterpret_cast<instance<>*>(inst);
|
||||
@@ -552,12 +506,13 @@ 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.
|
||||
ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
|
||||
handle<> bases(PyTuple_New(num_bases));
|
||||
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)));
|
||||
|
||||
for (ssize_t i = 1; i <= num_bases; ++i)
|
||||
for (std::size_t i = 1; i <= num_bases; ++i)
|
||||
{
|
||||
type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
|
||||
type_handle c = (i >= num_types) ? class_type() : get_class(types[i]);
|
||||
// PyTuple_SET_ITEM steals this reference
|
||||
PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(c.release()));
|
||||
}
|
||||
@@ -572,7 +527,7 @@ namespace objects
|
||||
d["__doc__"] = doc;
|
||||
|
||||
object result = object(class_metatype())(name, bases, d);
|
||||
assert(PyType_IsSubtype(Py_TYPE(result.ptr()), &PyType_Type));
|
||||
assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
|
||||
|
||||
if (scope().ptr() != Py_None)
|
||||
scope().attr(name) = result;
|
||||
@@ -617,7 +572,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -627,7 +582,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -635,9 +590,8 @@ namespace objects
|
||||
void class_base::add_static_property(char const* name, object const& fget)
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr())
|
||||
);
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), "O", fget.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -646,7 +600,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
|
||||
PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -661,13 +615,13 @@ namespace objects
|
||||
{
|
||||
extern "C" PyObject* no_init(PyObject*, PyObject*)
|
||||
{
|
||||
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
|
||||
::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
|
||||
return NULL;
|
||||
}
|
||||
static ::PyMethodDef no_init_def = {
|
||||
const_cast<char*>("__init__"), no_init, METH_VARARGS,
|
||||
const_cast<char*>("Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n")
|
||||
"__init__", no_init, METH_VARARGS,
|
||||
"Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -696,8 +650,8 @@ namespace objects
|
||||
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
|
||||
, Py_TYPE(callable)->tp_name
|
||||
, "staticmethod expects callable object; got an object of type %s, which is not callable"
|
||||
, callable->ob_type->tp_name
|
||||
);
|
||||
|
||||
throw_error_already_set();
|
||||
@@ -727,18 +681,18 @@ namespace objects
|
||||
|
||||
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
|
||||
{
|
||||
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
|
||||
assert(self_->ob_type->ob_type == &class_metatype_object);
|
||||
objects::instance<>* self = (objects::instance<>*)self_;
|
||||
|
||||
int total_size_needed = holder_offset + holder_size;
|
||||
|
||||
if (-Py_SIZE(self) >= total_size_needed)
|
||||
if (-self->ob_size >= 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
|
||||
Py_SIZE(self) = holder_offset;
|
||||
self->ob_size = holder_offset;
|
||||
return (char*)self + holder_offset;
|
||||
}
|
||||
else
|
||||
@@ -752,9 +706,9 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std:
|
||||
|
||||
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
|
||||
{
|
||||
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
|
||||
assert(self_->ob_type->ob_type == &class_metatype_object);
|
||||
objects::instance<>* self = (objects::instance<>*)self_;
|
||||
if (storage != (char*)self + Py_SIZE(self))
|
||||
if (storage != (char*)self + self->ob_size)
|
||||
{
|
||||
PyMem_Free(storage);
|
||||
}
|
||||
|
||||
@@ -14,20 +14,16 @@
|
||||
#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[] = {
|
||||
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -36,32 +32,19 @@ extern "C"
|
||||
{
|
||||
static PyObject* enum_repr(PyObject* self_)
|
||||
{
|
||||
// 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__");
|
||||
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
|
||||
enum_object* self = downcast<enum_object>(self_);
|
||||
if (!self->name)
|
||||
{
|
||||
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
|
||||
return PyString_FromFormat("%s.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject* name = self->name;
|
||||
char* name = PyString_AsString(self->name);
|
||||
if (name == 0)
|
||||
return 0;
|
||||
|
||||
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
|
||||
|
||||
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +53,7 @@ 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
|
||||
{
|
||||
@@ -84,8 +63,9 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyTypeObject enum_type_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
|
||||
const_cast<char*>("Boost.Python.enum"),
|
||||
PyObject_HEAD_INIT(0) // &PyType_Type
|
||||
0,
|
||||
"Boost.Python.enum",
|
||||
sizeof(enum_object), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
@@ -104,9 +84,7 @@ 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 */
|
||||
@@ -147,12 +125,8 @@ namespace
|
||||
{
|
||||
if (enum_type_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&enum_type_object) = incref(&PyType_Type);
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
enum_type_object.tp_base = &PyLong_Type;
|
||||
#else
|
||||
enum_type_object.ob_type = incref(&PyType_Type);
|
||||
enum_type_object.tp_base = &PyInt_Type;
|
||||
#endif
|
||||
if (PyType_Ready(&enum_type_object))
|
||||
throw_error_already_set();
|
||||
}
|
||||
@@ -165,16 +139,15 @@ 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;
|
||||
@@ -194,7 +167,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);
|
||||
@@ -213,24 +186,23 @@ 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("names"))();
|
||||
list items = d.items();
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
list values = d.values();
|
||||
scope current;
|
||||
|
||||
for (unsigned i = 0, max = len(items); i < max; ++i)
|
||||
api::setattr(current, items[i][0], items[i][1]);
|
||||
|
||||
for (unsigned i = 0, max = len(values); i < max; ++i)
|
||||
{
|
||||
api::setattr(current, object(values[i].attr("name")), values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* enum_base::to_python(PyTypeObject* type_, long x)
|
||||
|
||||
@@ -105,9 +105,9 @@ function::function(
|
||||
}
|
||||
|
||||
PyObject* p = this;
|
||||
if (Py_TYPE(&function_type) == 0)
|
||||
if (function_type.ob_type == 0)
|
||||
{
|
||||
Py_TYPE(&function_type) = &PyType_Type;
|
||||
function_type.ob_type = &PyType_Type;
|
||||
::PyType_Ready(&function_type);
|
||||
}
|
||||
|
||||
@@ -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 <= static_cast<std::size_t>(ssize_t_max));
|
||||
assert(max_arity <= 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(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
|
||||
PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0));
|
||||
|
||||
object message = "Python argument types in\n %s.%s("
|
||||
% make_tuple(this->m_namespace, this->m_name);
|
||||
@@ -435,16 +435,12 @@ 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
|
||||
#endif
|
||||
if (PyType_Check(ns))
|
||||
else if (PyType_Check(ns))
|
||||
dict = ((PyTypeObject*)ns)->tp_dict;
|
||||
else
|
||||
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
|
||||
dict = PyObject_GetAttrString(ns, "__dict__");
|
||||
|
||||
if (dict == 0)
|
||||
throw_error_already_set();
|
||||
@@ -491,7 +487,7 @@ void function::add_to_namespace(
|
||||
new_func->m_name = name;
|
||||
|
||||
handle<> name_space_name(
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__")));
|
||||
|
||||
if (name_space_name)
|
||||
new_func->m_namespace = object(name_space_name);
|
||||
@@ -599,18 +595,9 @@ 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
|
||||
@@ -654,11 +641,7 @@ extern "C"
|
||||
{
|
||||
function* f = downcast<function>(op);
|
||||
if (f->name().ptr() == Py_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());
|
||||
}
|
||||
@@ -673,17 +656,18 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyGetSetDef function_getsetlist[] = {
|
||||
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{"__name__", (getter)function_get_name, 0, 0, 0 },
|
||||
{"func_name", (getter)function_get_name, 0, 0, 0 },
|
||||
{"__class__", (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{"__doc__", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{"func_doc", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{NULL, 0, 0, 0, 0} /* Sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject function_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.function"),
|
||||
PyObject_HEAD_INIT(0)
|
||||
0,
|
||||
"Boost.Python.function",
|
||||
sizeof(function),
|
||||
0,
|
||||
(destructor)function_dealloc, /* tp_dealloc */
|
||||
@@ -769,8 +753,7 @@ namespace detail
|
||||
}
|
||||
void BOOST_PYTHON_DECL pure_virtual_called()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
|
||||
PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// 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>
|
||||
@@ -15,6 +12,7 @@
|
||||
|
||||
#include <boost/python/detail/signature.hpp>
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
@@ -54,9 +52,9 @@ namespace boost { namespace python { namespace objects {
|
||||
//check if the argument default values are the same
|
||||
bool f1_has_names = bool(f1->m_arg_names);
|
||||
bool f2_has_names = bool(f2->m_arg_names);
|
||||
if ( (f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1])
|
||||
|| (f1_has_names && !f2_has_names)
|
||||
|| (!f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object())
|
||||
if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
|
||||
|| f1_has_names && !f2_has_names
|
||||
|| !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
|
||||
)
|
||||
return false;
|
||||
}
|
||||
@@ -230,7 +228,7 @@ namespace boost { namespace python { namespace objects {
|
||||
{
|
||||
return str(
|
||||
"%s %s(%s%s%s%s)"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
% make_tuple
|
||||
( ret_type
|
||||
, f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
@@ -241,7 +239,7 @@ namespace boost { namespace python { namespace objects {
|
||||
}else{
|
||||
return str(
|
||||
"%s(%s%s%s%s) -> %s"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
% make_tuple
|
||||
( f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||
@@ -253,7 +251,7 @@ namespace boost { namespace python { namespace objects {
|
||||
|
||||
return str(
|
||||
"%s %s(%s%s%s%s) %s"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
% make_tuple
|
||||
( cpp_types?ret_type:str("")
|
||||
, f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#endif
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/reverse_graph.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/property_map.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
@@ -36,8 +36,9 @@ extern "C"
|
||||
}
|
||||
|
||||
PyTypeObject life_support_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
|
||||
const_cast<char*>("Boost.Python.life_support"),
|
||||
PyObject_HEAD_INIT(0)//(&PyType_Type)
|
||||
0,
|
||||
"Boost.Python.life_support",
|
||||
sizeof(life_support),
|
||||
0,
|
||||
life_support_dealloc, /* tp_dealloc */
|
||||
@@ -91,9 +92,9 @@ PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
|
||||
if (nurse == Py_None || nurse == patient)
|
||||
return nurse;
|
||||
|
||||
if (Py_TYPE(&life_support_type) == 0)
|
||||
if (life_support_type.ob_type == 0)
|
||||
{
|
||||
Py_TYPE(&life_support_type) = &PyType_Type;
|
||||
life_support_type.ob_type = &PyType_Type;
|
||||
PyType_Ready(&life_support_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Credits:
|
||||
// Andreas Kl\:ockner for fixing increment() to handle
|
||||
// error conditions.
|
||||
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
@@ -31,8 +27,6 @@ void stl_input_iterator_impl::increment()
|
||||
{
|
||||
this->ob_ = boost::python::handle<>(
|
||||
boost::python::allow_null(PyIter_Next(this->it_.ptr())));
|
||||
if (PyErr_Occurred())
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
bool stl_input_iterator_impl::equal(stl_input_iterator_impl const &that) const
|
||||
|
||||
@@ -38,13 +38,7 @@ 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)
|
||||
@@ -64,12 +58,7 @@ 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)
|
||||
|
||||
@@ -103,7 +103,6 @@ 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;
|
||||
|
||||
@@ -115,9 +114,7 @@ namespace // slicing code copied directly out of the Python implementation
|
||||
return NULL;
|
||||
return PySequence_GetSlice(u, ilow, ihigh);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
PyObject *res = PyObject_GetItem(u, slice);
|
||||
@@ -133,7 +130,6 @@ 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;
|
||||
|
||||
@@ -148,9 +144,7 @@ namespace // slicing code copied directly out of the Python implementation
|
||||
else
|
||||
return PySequence_SetSlice(u, ilow, ihigh, x);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
int res;
|
||||
|
||||
112
src/str.cpp
112
src/str.cpp
@@ -10,40 +10,23 @@ namespace boost { namespace python { namespace detail {
|
||||
detail::new_reference str_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
(PyObject*)&PyUnicode_Type,
|
||||
#else
|
||||
(PyObject*)&PyString_Type,
|
||||
#endif
|
||||
const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyString_Type, "(O)",
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
str_base::str_base()
|
||||
: object(detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromString("")
|
||||
#else
|
||||
::PyString_FromString("")
|
||||
#endif
|
||||
))
|
||||
: object(detail::new_reference(::PyString_FromString("")))
|
||||
{}
|
||||
|
||||
str_base::str_base(const char* s)
|
||||
: object(detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromString(s)
|
||||
#else
|
||||
::PyString_FromString(s)
|
||||
#endif
|
||||
))
|
||||
: object(detail::new_reference(::PyString_FromString(s)))
|
||||
{}
|
||||
|
||||
namespace {
|
||||
|
||||
ssize_t str_size_as_py_ssize_t(std::size_t n)
|
||||
{
|
||||
if (n > static_cast<std::size_t>(ssize_t_max))
|
||||
if (n > ssize_t_max)
|
||||
{
|
||||
throw std::range_error("str size > ssize_t_max");
|
||||
}
|
||||
@@ -55,12 +38,9 @@ namespace {
|
||||
str_base::str_base(char const* start, char const* finish)
|
||||
: object(
|
||||
detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
(start, str_size_as_py_ssize_t(finish - start))
|
||||
::PyString_FromStringAndSize(
|
||||
start, str_size_as_py_ssize_t(finish - start)
|
||||
)
|
||||
)
|
||||
)
|
||||
{}
|
||||
@@ -68,12 +48,9 @@ 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(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
( start, str_size_as_py_ssize_t(length) )
|
||||
::PyString_FromStringAndSize(
|
||||
start, str_size_as_py_ssize_t(length)
|
||||
)
|
||||
)
|
||||
)
|
||||
{}
|
||||
@@ -91,9 +68,8 @@ str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const
|
||||
return str(new_reference( \
|
||||
expect_non_null( \
|
||||
PyObject_CallMethod( \
|
||||
this->ptr(), const_cast<char*>( #name ), \
|
||||
const_cast<char*>( \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
|
||||
this->ptr(), #name, \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \
|
||||
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
|
||||
}
|
||||
|
||||
@@ -115,7 +91,6 @@ 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")();
|
||||
@@ -130,7 +105,6 @@ object str_base::decode(object_cref encoding, object_cref errors) const
|
||||
{
|
||||
return this->attr("decode")(encoding,errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
object str_base::encode() const
|
||||
{
|
||||
@@ -147,16 +121,9 @@ 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 = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix).ptr());
|
||||
bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -167,7 +134,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1)
|
||||
|
||||
long str_base::find(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub).ptr());
|
||||
long result = PyInt_AsLong(this->attr("find")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -175,7 +142,7 @@ long str_base::find(object_cref sub) const
|
||||
|
||||
long str_base::find(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start).ptr());
|
||||
long result = PyInt_AsLong(this->attr("find")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -183,7 +150,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 = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start,end).ptr());
|
||||
long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -191,7 +158,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 = _BOOST_PYTHON_ASLONG(this->attr("index")(sub).ptr());
|
||||
long result = PyInt_AsLong(this->attr("index")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -199,7 +166,7 @@ long str_base::index(object_cref sub) const
|
||||
|
||||
long str_base::index(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start).ptr());
|
||||
long result = PyInt_AsLong(this->attr("index")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -207,7 +174,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 = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
|
||||
long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -215,7 +182,7 @@ long str_base::index(object_cref sub, object_cref start, object_cref end) const
|
||||
|
||||
bool str_base::isalnum() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("isalnum")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -223,7 +190,7 @@ bool str_base::isalnum() const
|
||||
|
||||
bool str_base::isalpha() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("isalpha")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -231,7 +198,7 @@ bool str_base::isalpha() const
|
||||
|
||||
bool str_base::isdigit() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("isdigit")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -239,7 +206,7 @@ bool str_base::isdigit() const
|
||||
|
||||
bool str_base::islower() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("islower")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -247,7 +214,7 @@ bool str_base::islower() const
|
||||
|
||||
bool str_base::isspace() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("isspace")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -255,7 +222,7 @@ bool str_base::isspace() const
|
||||
|
||||
bool str_base::istitle() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("istitle")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -263,7 +230,7 @@ bool str_base::istitle() const
|
||||
|
||||
bool str_base::isupper() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isupper")().ptr());
|
||||
bool result = PyInt_AsLong(this->attr("isupper")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -278,7 +245,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3)
|
||||
|
||||
long str_base::rfind(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rfind")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -286,7 +253,7 @@ long str_base::rfind(object_cref sub) const
|
||||
|
||||
long str_base::rfind(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -294,7 +261,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 = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start,end).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -302,7 +269,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 = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rindex")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -310,7 +277,7 @@ long str_base::rindex(object_cref sub) const
|
||||
|
||||
long str_base::rindex(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -318,7 +285,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 = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start,end).ptr());
|
||||
long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -354,7 +321,7 @@ list str_base::splitlines(object_cref keepends) const
|
||||
|
||||
bool str_base::startswith(object_cref prefix) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix).ptr());
|
||||
bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -362,7 +329,7 @@ bool str_base::startswith(object_cref prefix) const
|
||||
|
||||
bool str_base::startswith(object_cref prefix, object_cref start) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start).ptr());
|
||||
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
@@ -370,14 +337,12 @@ 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 = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
|
||||
bool result = PyInt_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)
|
||||
@@ -391,12 +356,7 @@ static struct register_str_pytype_ptr
|
||||
{
|
||||
const_cast<converter::registration &>(
|
||||
converter::registry::lookup(boost::python::type_id<boost::python::str>())
|
||||
)
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
.m_class_object = &PyUnicode_Type;
|
||||
#else
|
||||
.m_class_object = &PyString_Type;
|
||||
#endif
|
||||
).m_class_object = &PyString_Type;
|
||||
}
|
||||
}register_str_pytype_ptr_;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace boost { namespace python { namespace detail {
|
||||
detail::new_reference tuple_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyTuple_Type, const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyTuple_Type, "(O)",
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
|
||||
194
test/CMakeLists.txt
Normal file
194
test/CMakeLists.txt
Normal file
@@ -0,0 +1,194 @@
|
||||
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)
|
||||
@@ -42,7 +42,7 @@ test-suite python
|
||||
:
|
||||
|
||||
[
|
||||
run exec.cpp /boost/python//boost_python/<link>static $(PY)
|
||||
run exec.cpp ../build//boost_python/<link>static $(PY)
|
||||
: # program args
|
||||
: exec.py # input files
|
||||
: # requirements
|
||||
@@ -75,17 +75,13 @@ 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 ]
|
||||
@@ -175,8 +171,7 @@ bpl-test crossmod_opaque
|
||||
/boost/python//boost_python ]
|
||||
[ bpl-test
|
||||
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
|
||||
|
||||
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
|
||||
[ py-run import_.cpp : import_.py ]
|
||||
|
||||
# if $(TEST_BIENSTMAN_NON_BUGS)
|
||||
# {
|
||||
|
||||
@@ -48,11 +48,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -64,11 +60,7 @@ 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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,8 +25,8 @@ class B {
|
||||
B() {
|
||||
a = A::A_ptr(new A());
|
||||
}
|
||||
void set(A::A_ptr _a) {
|
||||
this->a = _a;
|
||||
void set(A::A_ptr a) {
|
||||
this->a = a;
|
||||
}
|
||||
A::A_ptr get() {
|
||||
return a;
|
||||
|
||||
@@ -27,7 +27,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -34,7 +34,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -19,10 +19,10 @@ struct complicated
|
||||
int n;
|
||||
};
|
||||
|
||||
inline complicated::complicated(simple const&s, int _n)
|
||||
: s(s.s), n(_n)
|
||||
inline complicated::complicated(simple const&s, int n)
|
||||
: s(s.s), n(n)
|
||||
{
|
||||
std::cout << "constructing complicated: " << this->s << ", " << _n << std::endl;
|
||||
std::cout << "constructing complicated: " << this->s << ", " << n << std::endl;
|
||||
}
|
||||
|
||||
inline complicated::~complicated()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: latin-1 -*-
|
||||
# -*- coding: iso-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
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
# 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); '
|
||||
|
||||
@@ -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) #doctest: +NORMALIZE_WHITESPACE
|
||||
>>> test_templates(printer)
|
||||
a test string
|
||||
13
|
||||
None
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
|
||||
class Test;
|
||||
typedef shared_ptr<Test> TestPtr;
|
||||
|
||||
class Test : public boost::enable_shared_from_this<Test> {
|
||||
public:
|
||||
static TestPtr construct() {
|
||||
return TestPtr(new Test);
|
||||
}
|
||||
|
||||
void act() {
|
||||
TestPtr kungFuDeathGrip(shared_from_this());
|
||||
}
|
||||
|
||||
void take(TestPtr t) {
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(enable_shared_from_this_ext)
|
||||
{
|
||||
class_<Test, TestPtr, boost::noncopyable>("Test")
|
||||
.def("construct", &Test::construct).staticmethod("construct")
|
||||
.def("act", &Test::act)
|
||||
.def("take", &Test::take)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# Copyright David Abrahams 2004. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
'''
|
||||
>>> from enable_shared_from_this_ext import *
|
||||
|
||||
>>> x = Test.construct()
|
||||
>>> x.take(x)
|
||||
>>> x.act()
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
status = run()[0]
|
||||
if (status == 0): print "Done."
|
||||
sys.exit(status)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
using namespace boost::python;
|
||||
|
||||
enum color { red = 1, green = 2, blue = 4, blood = 1 };
|
||||
enum color { red = 1, green = 2, blue = 4 };
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
namespace boost // Pro7 has a hard time detecting enums
|
||||
@@ -34,7 +34,6 @@ BOOST_PYTHON_MODULE(enum_ext)
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.value("blue", blue)
|
||||
.value("blood", blood)
|
||||
.export_values()
|
||||
;
|
||||
|
||||
|
||||
20
test/enum.py
20
test/enum.py
@@ -4,8 +4,8 @@
|
||||
'''
|
||||
>>> from enum_ext import *
|
||||
|
||||
>>> identity(color.red) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
>>> identity(color.red)
|
||||
enum_ext.color.red
|
||||
|
||||
>>> 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)) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
>>> identity(color(1))
|
||||
enum_ext.color.red
|
||||
|
||||
>>> identity(color(2))
|
||||
enum_ext.color.green
|
||||
@@ -28,7 +28,7 @@ enum_ext.color.blue
|
||||
--- check export to scope ---
|
||||
|
||||
>>> identity(red)
|
||||
enum_ext.color.blood
|
||||
enum_ext.color.red
|
||||
|
||||
>>> identity(green)
|
||||
enum_ext.color.green
|
||||
@@ -42,18 +42,10 @@ enum_ext.color.blue
|
||||
|
||||
>>> c = colorized()
|
||||
>>> c.x
|
||||
enum_ext.color.blood
|
||||
enum_ext.color.red
|
||||
>>> c.x = green
|
||||
>>> c.x
|
||||
enum_ext.color.green
|
||||
>>> red == blood
|
||||
True
|
||||
>>> red == green
|
||||
False
|
||||
>>> hash(red) == hash(blood)
|
||||
True
|
||||
>>> hash(red) == hash(green)
|
||||
False
|
||||
'''
|
||||
|
||||
# pickling of enums only works with Python 2.3 or higher
|
||||
|
||||
@@ -59,13 +59,7 @@ void eval_test()
|
||||
void exec_test()
|
||||
{
|
||||
// Register the module with the interpreter
|
||||
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"),
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyInit_embedded_hello
|
||||
#else
|
||||
initembedded_hello
|
||||
#endif
|
||||
) == -1)
|
||||
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
|
||||
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
|
||||
"builtin modules");
|
||||
// Retrieve the main module
|
||||
@@ -111,76 +105,49 @@ 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);
|
||||
}
|
||||
|
||||
void exercise_embedding_html()
|
||||
{
|
||||
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__");
|
||||
|
||||
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_expected) {
|
||||
BOOST_ERROR("Python Error detected");
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR("A C++ exception was thrown for which "
|
||||
"there was no exception handler registered.");
|
||||
}
|
||||
python::object result = python::exec("print unknown \n", global, global);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
BOOST_TEST(argc == 2 || argc == 3);
|
||||
BOOST_TEST(argc == 2);
|
||||
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(eval_test) ||
|
||||
python::handle_exception(exec_test) ||
|
||||
python::handle_exception(boost::bind(exec_file_test, script)))
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
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))
|
||||
{
|
||||
check_pyerr(/*pyerr_expected*/ true);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
PyErr_Print();
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR("A C++ exception was thrown for which "
|
||||
"there was no exception handler registered.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR("Python exception expected, but not seen.");
|
||||
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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
if 1:
|
||||
number = 42
|
||||
print 'Hello World !'
|
||||
number = 42
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
>>> ll.push_back(x)
|
||||
>>> x.push_back(7)
|
||||
>>> ll.push_back(x)
|
||||
>>> for a in ll: #doctest: +NORMALIZE_WHITESPACE
|
||||
>>> for a in ll:
|
||||
... for b in a:
|
||||
... print b,
|
||||
... print
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#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
|
||||
@@ -111,16 +109,11 @@ 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(¬cmp);
|
||||
#endif
|
||||
print(x);
|
||||
|
||||
list w;
|
||||
|
||||
@@ -73,7 +73,7 @@ X(22)
|
||||
...
|
||||
|
||||
>>> y = X(42)
|
||||
>>> exercise(letters, y, printer) #doctest: +NORMALIZE_WHITESPACE
|
||||
>>> exercise(letters, y, printer)
|
||||
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:
|
||||
['.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
|
||||
[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
|
||||
reverse sorted:
|
||||
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
|
||||
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]]
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
|
||||
12
test/long.py
12
test/long.py
@@ -3,12 +3,12 @@
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
'''
|
||||
>>> from long_ext import *
|
||||
>>> print new_long()
|
||||
0
|
||||
>>> print longify(42)
|
||||
42
|
||||
>>> print longify_string('300')
|
||||
300
|
||||
>>> new_long()
|
||||
0L
|
||||
>>> longify(42)
|
||||
42L
|
||||
>>> longify_string('300')
|
||||
300L
|
||||
>>> is_long(20L)
|
||||
'yes'
|
||||
>>> is_long('20')
|
||||
|
||||
12
test/m1.cpp
12
test/m1.cpp
@@ -32,8 +32,9 @@ struct NoddyObject : PyObject
|
||||
};
|
||||
|
||||
PyTypeObject NoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Noddy"),
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Noddy",
|
||||
sizeof(NoddyObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -103,8 +104,9 @@ struct extract_simple_object
|
||||
};
|
||||
|
||||
PyTypeObject SimpleType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Simple"),
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Simple",
|
||||
sizeof(SimpleObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -157,7 +159,7 @@ PyTypeObject SimpleType = {
|
||||
PyObject* new_simple()
|
||||
{
|
||||
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
simple->x.s = const_cast<char*>("hello, world");
|
||||
simple->x.s = "hello, world";
|
||||
return (PyObject*)simple;
|
||||
}
|
||||
|
||||
|
||||
10
test/m2.cpp
10
test/m2.cpp
@@ -13,11 +13,6 @@
|
||||
#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)
|
||||
@@ -57,11 +52,6 @@ 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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -197,7 +197,7 @@ kiwi
|
||||
>>> tm["kimpo"] = X("bbb")
|
||||
>>> print_xmap(tm)
|
||||
[ (joel, aaa) (kimpo, bbb) ]
|
||||
>>> for el in tm: #doctest: +NORMALIZE_WHITESPACE
|
||||
>>> for el in tm:
|
||||
... print el.key(),
|
||||
... dom = el.data()
|
||||
joel kimpo
|
||||
|
||||
@@ -187,11 +187,6 @@ bool check_string_slice()
|
||||
return s.slice(2,-1).slice(1,-1) == "lo, wor";
|
||||
}
|
||||
|
||||
object test_call(object c, object args, object kwds)
|
||||
{
|
||||
return c(*args, **kwds);
|
||||
}
|
||||
|
||||
bool check_binary_operators()
|
||||
{
|
||||
int y;
|
||||
@@ -382,7 +377,6 @@ BOOST_PYTHON_MODULE(object_ext)
|
||||
def("test_item", test_item);
|
||||
def("test_not_item", test_not_item);
|
||||
|
||||
def("test_call", test_call);
|
||||
def("check_binary_operators", check_binary_operators);
|
||||
def("check_inplace", check_inplace);
|
||||
def("check_string_slice", check_string_slice);
|
||||
|
||||
@@ -134,12 +134,7 @@
|
||||
|
||||
Operators
|
||||
|
||||
>>> def print_args(*args, **kwds):
|
||||
... print args, kwds
|
||||
>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
|
||||
(0, 1, 2, 3) {'a': 'A'}
|
||||
|
||||
|
||||
|
||||
>>> assert check_binary_operators()
|
||||
|
||||
>>> class X: pass
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: latin-1 -*-
|
||||
# -*- coding: iso-latin-1 -*-
|
||||
# Copyright Gottfried Ganßauge 2003..2006. 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)
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace boost_python_test {
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& _country) {
|
||||
this->country = _country;
|
||||
world(const std::string& country) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
@@ -40,7 +40,8 @@ namespace boost_python_test {
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
return boost::python::make_tuple(w.get_country());
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace boost_python_test {
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& _country) : secret_number(0) {
|
||||
this->country = _country;
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
@@ -52,14 +52,16 @@ namespace boost_python_test {
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
return boost::python::make_tuple(w.get_country());
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
|
||||
static
|
||||
boost::python::tuple
|
||||
getstate(const world& w)
|
||||
{
|
||||
return boost::python::make_tuple(w.get_secret_number());
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_secret_number());
|
||||
}
|
||||
|
||||
static
|
||||
@@ -75,7 +77,7 @@ namespace boost_python_test {
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
|
||||
long number = extract<long>(state[0]);
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
|
||||
@@ -29,7 +29,7 @@ r'''>>> import pickle2_ext
|
||||
>>> wd.__dict__
|
||||
{'x': 1}
|
||||
>>> try: pstr = pickle.dumps(wd)
|
||||
... except RuntimeError, err: print err
|
||||
... except RuntimeError, err: print err[0]
|
||||
...
|
||||
Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
'''
|
||||
|
||||
@@ -25,14 +25,18 @@
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/back_reference.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
||||
# define make_tuple boost::python::make_tuple
|
||||
#endif
|
||||
|
||||
namespace boost_python_test {
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& _country) : secret_number(0) {
|
||||
this->country = _country;
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
@@ -49,18 +53,18 @@ namespace boost_python_test {
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
return boost::python::make_tuple(w.get_country());
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
|
||||
static
|
||||
boost::python::tuple
|
||||
getstate(boost::python::object w_obj)
|
||||
{
|
||||
world const& w = boost::python::extract<world const&>(w_obj)();
|
||||
using namespace boost::python;
|
||||
world const& w = extract<world const&>(w_obj)();
|
||||
|
||||
return boost::python::make_tuple(
|
||||
w_obj.attr("__dict__"),
|
||||
w.get_secret_number());
|
||||
return make_tuple(w_obj.attr("__dict__"), w.get_secret_number());
|
||||
}
|
||||
|
||||
static
|
||||
@@ -69,7 +73,7 @@ namespace boost_python_test {
|
||||
{
|
||||
using namespace boost::python;
|
||||
world& w = extract<world&>(w_obj)();
|
||||
|
||||
|
||||
if (len(state) != 2)
|
||||
{
|
||||
PyErr_SetObject(PyExc_ValueError,
|
||||
@@ -78,11 +82,11 @@ namespace boost_python_test {
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
|
||||
// restore the object's __dict__
|
||||
dict d = extract<dict>(w_obj.attr("__dict__"))();
|
||||
d.update(state[0]);
|
||||
|
||||
|
||||
// restore the internal state of the C++ object
|
||||
long number = extract<long>(state[1]);
|
||||
if (number != 42)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user