mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
23 Commits
svn-branch
...
boost-1.39
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aebc49b341 | ||
|
|
6296bd5bc4 | ||
|
|
217250f078 | ||
|
|
29152af56c | ||
|
|
19846f5d79 | ||
|
|
a1924a2a72 | ||
|
|
c205cd86c6 | ||
|
|
8d86dc199c | ||
|
|
55e9ff14a1 | ||
|
|
4fea58f634 | ||
|
|
694ae13063 | ||
|
|
5168895803 | ||
|
|
c8bf94663c | ||
|
|
928a9389ce | ||
|
|
7d22435994 | ||
|
|
96dd880146 | ||
|
|
63f8e9f3d7 | ||
|
|
d9b4ada654 | ||
|
|
f5df393360 | ||
|
|
bf33b54638 | ||
|
|
87451007b9 | ||
|
|
2392a6a3e2 | ||
|
|
6c1e7decfa |
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)
|
||||
@@ -9,7 +9,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="logo-boost-python-build-and-test-howto">
|
||||
<h1 class="title"><a class="reference external" href="../index.htm"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
|
||||
<h1 class="title"><a class="reference external" href="../index.html"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
@@ -158,8 +158,8 @@ all the parts of your Python installation. If it isn't, consider
|
||||
<p>If you're still having trouble, Someone on one of the following
|
||||
mailing lists may be able to help:</p>
|
||||
<ul class="simple">
|
||||
<li>The <a class="reference external" href="http://www.boost.org/community/groups.html#jamboost">Boost.Build mailing list</a> for issues related to Boost.Build</li>
|
||||
<li>The Python <a class="reference external" href="http://www.boost.org/community/groups.html#cplussig">C++ Sig</a> for issues specifically related to Boost.Python</li>
|
||||
<li>The <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#jamboost">Boost.Build mailing list</a> for issues related to Boost.Build</li>
|
||||
<li>The Python <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#cplussig">C++ Sig</a> for issues specifically related to Boost.Python</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="in-case-everything-seemed-to-work">
|
||||
|
||||
@@ -177,8 +177,8 @@ mailing lists may be able to help:
|
||||
* The `Boost.Build mailing list`__ for issues related to Boost.Build
|
||||
* The Python `C++ Sig`__ for issues specifically related to Boost.Python
|
||||
|
||||
__ http://www.boost.org/community/groups.html#jamboost
|
||||
__ http://www.boost.org/community/groups.html#cplussig
|
||||
__ http://www.boost.org/more/mailing_lists.htm#jamboost
|
||||
__ http://www.boost.org/more/mailing_lists.htm#cplussig
|
||||
|
||||
In Case Everything Seemed to Work
|
||||
---------------------------------
|
||||
|
||||
@@ -375,6 +375,27 @@
|
||||
application modules, including GUI and post-processing of results.</p>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://polybori.sourceforge.net/">PolyBoRi</a></b></dt>
|
||||
|
||||
<dd>
|
||||
<p><a href="mailto:brickenstein@mfo.de"
|
||||
>Michael Brickenstein</a> writes:</p>
|
||||
|
||||
<blockquote>
|
||||
<p>The core of PolyBoRi is a C++ library, which provides
|
||||
high-level data types for Boolean polynomials and monomials,
|
||||
exponent vectors, as well as for the underlying polynomial
|
||||
rings and subsets of the powerset of the Boolean variables. As
|
||||
a unique approach, binary decision diagrams are used as
|
||||
internal storage type for polynomial structures. On top of
|
||||
this C++-library we provide a Python interface. This allows
|
||||
parsing of complex polynomial systems, as well as sophisticated
|
||||
and extendable strategies for Gröbner basis computation.
|
||||
Boost.Python has helped us to create this interface in a
|
||||
very clean way.</p>
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
|
||||
LLC</a></b></dt>
|
||||
|
||||
@@ -435,11 +456,11 @@
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
15 July, 2003</p>
|
||||
29 May, 2008</p>
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
Abrahams</a> 2002-2008.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</dt>
|
||||
|
||||
<dt><b><a href=
|
||||
"http://www.boost.org/community/groups.html#cplussig">The Python
|
||||
"http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
|
||||
C++-sig</a></b> mailing list is a forum for discussing Python/C++
|
||||
interoperability, and Boost.Python in particular. Post your
|
||||
Boost.Python questions here.<br>
|
||||
|
||||
@@ -6,6 +6,8 @@ project boost/libs/python/doc/tutorial/doc ;
|
||||
import boostbook : boostbook ;
|
||||
using quickbook ;
|
||||
|
||||
path-constant images : html ;
|
||||
|
||||
boostbook tutorial
|
||||
:
|
||||
tutorial.qbk
|
||||
@@ -13,4 +15,6 @@ boostbook tutorial
|
||||
<xsl:param>boost.root=../../../../../..
|
||||
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
|
||||
<xsl:param>html.stylesheet=../../../../../../doc/html/boostbook.css
|
||||
<format>pdf:<xsl:param>img.src.path=$(images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html
|
||||
;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Chapter 1. python 1.0</title>
|
||||
<title>Chapter 1. python 2.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">
|
||||
@@ -31,7 +31,7 @@
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id455917"></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,7 +94,7 @@
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id385257"></a>
|
||||
<a name="id385276"></a>
|
||||
Hello World
|
||||
</h2>
|
||||
<p>
|
||||
@@ -145,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 07, 2007 at 03:34:24 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>
|
||||
|
||||
@@ -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="id471171"></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="id471276"></a>
|
||||
<a name="id471435"></a>
|
||||
Getting started
|
||||
</h2>
|
||||
<p>
|
||||
@@ -139,7 +139,7 @@ exe embedded_program # name of the executable
|
||||
automate the process.
|
||||
</p>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id471439"></a>
|
||||
<a name="id471598"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
@@ -190,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="id472027"></a>
|
||||
<a name="id472186"></a>
|
||||
Manipulating Python objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -217,7 +217,7 @@ exe embedded_program # name of the executable
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</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="id472399"></a>
|
||||
<a name="id472558"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -533,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="id461460"></a>
|
||||
<a name="id461482"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
<p>
|
||||
@@ -582,7 +582,7 @@
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id462216"></a>
|
||||
<a name="id462239"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -212,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="id464076"></a>
|
||||
<a name="id464236"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
<p>
|
||||
@@ -415,7 +415,7 @@ 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="id466117"></a>
|
||||
<a name="id466276"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -445,7 +445,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<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="id466436"></a>
|
||||
<a name="id466595"></a>
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -491,7 +491,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
reference</a> for details.
|
||||
</p>
|
||||
<a name="default_arguments.init_and_optional"></a><h2>
|
||||
<a name="id466799"></a>
|
||||
<a name="id466958"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
<p>
|
||||
@@ -565,7 +565,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
(0) arguments and a maximum of 3 arguments.
|
||||
</p>
|
||||
<a name="auto_overloading.manual_wrapping"></a><h2>
|
||||
<a name="id467581"></a>
|
||||
<a name="id467740"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -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="id387672"></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="id386265"></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="id386322"></a>
|
||||
<a name="id386404"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
<p>
|
||||
@@ -180,6 +180,17 @@ bjam
|
||||
Or something similar. If all is well, you should now have built the DLLs and
|
||||
run the Python program.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
Starting from Boost 1.35, bjam erases the generated executables (e.g. pyd
|
||||
file) after the test has concluded to conserve disk space. To keep bjam from
|
||||
doing that, pass --preserve-test-targets to bjam.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
</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="id469586"></a>
|
||||
<a name="id469745"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[library python
|
||||
[version 1.0]
|
||||
[version 2.0]
|
||||
[authors [de Guzman, Joel], [Abrahams, David]]
|
||||
[copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
|
||||
[category inter-language support]
|
||||
@@ -93,7 +93,7 @@ who had to use a different tool.
|
||||
|
||||
We will skip over the details. Our objective will be to simply create
|
||||
the hello world module and run it in Python. For a complete reference to
|
||||
building Boost.Python, check out: [@/libs/python/doc/building.html
|
||||
building Boost.Python, check out: [@../../../building.html
|
||||
building.html]. After this brief ['bjam] tutorial, we should have built
|
||||
the DLLs and run a python program using the extension.
|
||||
|
||||
@@ -118,7 +118,7 @@ platforms. The complete list of Bjam executables can be found
|
||||
[h2 Let's Jam!]
|
||||
__jam__
|
||||
|
||||
[@/libs/python/example/tutorial/Jamroot Here] is our minimalist Jamroot
|
||||
[@../../../../example/tutorial/Jamroot Here] is our minimalist Jamroot
|
||||
file. Simply copy the file and tweak [^use-project boost] to where your
|
||||
boost root directory is and your OK.
|
||||
|
||||
@@ -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]
|
||||
@@ -463,7 +467,7 @@ functions so that a Python override may be called:
|
||||
};
|
||||
|
||||
Notice too that in addition to inheriting from `Base`, we also multiply-
|
||||
inherited `wrapper<Base>` (See [@/libs/python/doc/v2/wrapper.html Wrapper]). The
|
||||
inherited `wrapper<Base>` (See [@../../../v2/wrapper.html Wrapper]). The
|
||||
`wrapper` template makes the job of wrapping classes that are meant to
|
||||
overridden in Python, easier.
|
||||
|
||||
@@ -495,7 +499,7 @@ Methods correspond roughly to C++'s [*member functions]]
|
||||
[section Virtual Functions with Default Implementations]
|
||||
|
||||
We've seen in the previous section how classes with pure virtual functions are
|
||||
wrapped using Boost.Python's [@/libs/python/doc/v2/wrapper.html class wrapper]
|
||||
wrapped using Boost.Python's [@../../../v2/wrapper.html class wrapper]
|
||||
facilities. If we wish to wrap [*non]-pure-virtual functions instead, the
|
||||
mechanism is a bit different.
|
||||
|
||||
@@ -812,7 +816,7 @@ or more policies can be composed by chaining. Here's the general syntax:
|
||||
policy3<args...> > >
|
||||
|
||||
Here is the list of predefined call policies. A complete reference detailing
|
||||
these can be found [@/libs/python/doc/v2/reference.html#models_of_call_policies here].
|
||||
these can be found [@../../../v2/reference.html#models_of_call_policies here].
|
||||
|
||||
* [*with_custodian_and_ward]: Ties lifetimes of the arguments
|
||||
* [*with_custodian_and_ward_postcall]: Ties lifetimes of the arguments and results
|
||||
@@ -970,7 +974,7 @@ fourth macro argument). The thin wrappers are all enclosed in a class named
|
||||
|
||||
.def("wack_em", &george::wack_em, george_overloads());
|
||||
|
||||
See the [@/libs/python/doc/v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference]
|
||||
See the [@../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference]
|
||||
for details.
|
||||
|
||||
[h2 init and optional]
|
||||
@@ -1267,7 +1271,7 @@ associated with the C++ type passed as its first parameter.
|
||||
The scope is a class that has an associated global Python object which
|
||||
controls the Python namespace in which new extension classes and wrapped
|
||||
functions will be defined as attributes. Details can be found
|
||||
[@/libs/python/doc/v2/scope.html here].]
|
||||
[@../../../v2/scope.html here].]
|
||||
|
||||
You can access those values in Python as
|
||||
|
||||
@@ -1328,7 +1332,7 @@ in Boost's [^/libs/python/build/bin-stage] subdirectory. On Windows, the
|
||||
variants are called [^boost_python.lib] (for release builds) and
|
||||
[^boost_python_debug.lib] (for debugging). If you can't find the libraries,
|
||||
you probably haven't built Boost.Python yet. See
|
||||
[@/libs/python/doc/building.html Building and Testing] on how to do this.
|
||||
[@../../../building.html Building and Testing] on how to do this.
|
||||
|
||||
Python's library can be found in the [^/libs] subdirectory of
|
||||
your Python directory. On Windows it is called pythonXY.lib where X.Y is
|
||||
@@ -1386,8 +1390,8 @@ There is a difference however. While the reference-counting is fully
|
||||
automatic in Python, the Python\/C API requires you to do it
|
||||
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
|
||||
messy and especially hard to get right in the presence of C++ exceptions.
|
||||
Fortunately Boost.Python provides the [@/libs/python/doc/v2/handle.html handle] and
|
||||
[@/libs/python/doc/v2/object.html object] class templates to automate the process.
|
||||
Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and
|
||||
[@../../../v2/object.html object] class templates to automate the process.
|
||||
|
||||
[h2 Running Python code]
|
||||
|
||||
@@ -1450,7 +1454,7 @@ which returns the result directly:
|
||||
[h2 Exception handling]
|
||||
|
||||
If an exception occurs in the evaluation of the python expression,
|
||||
[@/libs/python/doc/v2/errors.html#error_already_set-spec error_already_set] is thrown:
|
||||
[@../../../v2/errors.html#error_already_set-spec error_already_set] is thrown:
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1954,13 +1958,13 @@ This method is recommended too if you are developing the C++ library and
|
||||
exporting it to Python at the same time: changes in a class will only demand
|
||||
the compilation of a single cpp, instead of the entire wrapper code.
|
||||
|
||||
[note If you're exporting your classes with [@/libs/python/doc/pyste/index.html Pyste],
|
||||
[note If you're exporting your classes with [@../../../../pyste/index.html Pyste],
|
||||
take a look at the [^--multiple] option, that generates the wrappers in
|
||||
various files as demonstrated here.]
|
||||
|
||||
[note This method is useful too if you are getting the error message
|
||||
['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling
|
||||
a large source file, as explained in the [@/libs/python/doc/v2/faq.html#c1204 FAQ].]
|
||||
a large source file, as explained in the [@../../../v2/faq.html#c1204 FAQ].]
|
||||
|
||||
[endsect]
|
||||
[endsect] [/ General Techniques]
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<td valign="top"><code>P::extract_return_type</code></td>
|
||||
|
||||
<td>A model of <a href=
|
||||
"../../../doc/refmanual/metafunction.html">Metafunction</a>.</td>
|
||||
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a>.</td>
|
||||
|
||||
<td>An MPL unary <a href=
|
||||
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Dereferenceable Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Extractor Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Holder Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
|
||||
@@ -74,6 +74,32 @@
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#const_objattribute_policies-spec">Class
|
||||
<code>const_objattribute_policies</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#const_objattribute_policies-spec-synopsis">Class
|
||||
<code>const_objattribute_policies</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href="#const_objattribute_policies-spec-statics">Class
|
||||
<code>const_objattribute_policies</code> static functions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#objattribute_policies-spec">Class
|
||||
<code>objattribute_policies</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#objattribute_policies-spec-synopsis">Class
|
||||
<code>objattribute_policies</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href="#objattribute_policies-spec-statics">Class
|
||||
<code>objattribute_policies</code> static functions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#const_item_policies-spec">Class
|
||||
<code>const_item_policies</code></a></dt>
|
||||
|
||||
@@ -328,6 +354,102 @@ static void del(object const&target, char const* key);
|
||||
<!-- end -->
|
||||
<!-- begin -->
|
||||
|
||||
<h3><a name="const_objattribute_policies-spec"></a>Class
|
||||
<code>const_objattribute_policies</code></h3>
|
||||
|
||||
<p>The policies which are used for proxies representing an attribute
|
||||
access to a <code>const object</code> when the attribute name is
|
||||
given as a <code>const object</code>.</p>
|
||||
|
||||
<h4><a name="const_objattribute_policies-spec-synopsis"></a>Class
|
||||
<code>const_objattribute_policies</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python { namespace api
|
||||
{
|
||||
struct const_objattribute_policies
|
||||
{
|
||||
typedef object const& key_type;
|
||||
static object get(object const& target, object const& key);
|
||||
};
|
||||
}}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="const_objattribute_policies-spec-statics"></a>Class
|
||||
<code>const_objattribute_policies</code> static functions</h4>
|
||||
<pre>
|
||||
static object get(object const& target, object const& key);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
|
||||
holding a string.</dt>
|
||||
|
||||
<dt><b>Effects:</b> accesses the attribute of <code>target</code> named
|
||||
by <code>key</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> An <code>object</code> managing the result of the
|
||||
attribute access.</dt>
|
||||
|
||||
<dt><b>Throws:</b> <code><a href=
|
||||
"errors.html#error_already_set-spec">error_already_set</a></code> if a
|
||||
Python exception is raised.</dt>
|
||||
</dl>
|
||||
|
||||
<h3><a name="objattribute_policies-spec"></a>Class
|
||||
<code>objattribute_policies</code></h3>
|
||||
|
||||
<p>The policies which are used for proxies representing an attribute
|
||||
access to a mutable <code>object</code> when the attribute name is
|
||||
given as a <code>const object</code>.</p>
|
||||
|
||||
<h4><a name="objattribute_policies-spec-synopsis"></a>Class
|
||||
<code>objattribute_policies</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python { namespace api
|
||||
{
|
||||
struct objattribute_policies : const_objattribute_policies
|
||||
{
|
||||
static object const& set(object const& target, object const& key, object const& value);
|
||||
static void del(object const&target, object const& key);
|
||||
};
|
||||
}}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="objattribute_policies-spec-statics"></a>Class
|
||||
<code>objattribute_policies</code> static functions</h4>
|
||||
<pre>
|
||||
static object const& set(object const& target, object const& key, object const& value);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
|
||||
holding a string.</dt>
|
||||
|
||||
<dt><b>Effects:</b> sets the attribute of <code>target</code> named by
|
||||
<code>key</code> to <code>value</code>.</dt>
|
||||
|
||||
<dt><b>Throws:</b> <code><a href=
|
||||
"errors.html#error_already_set-spec">error_already_set</a></code> if a
|
||||
Python exception is raised.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
static void del(object const&target, object const& key);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>key</code> is an <code>object</code>
|
||||
holding a string.</dt>
|
||||
|
||||
<dt><b>Effects:</b> deletes the attribute of <code>target</code> named
|
||||
by <code>key</code>.</dt>
|
||||
|
||||
<dt><b>Throws:</b> <code><a href=
|
||||
"errors.html#error_already_set-spec">error_already_set</a></code> if a
|
||||
Python exception is raised.</dt>
|
||||
</dl>
|
||||
<!-- end -->
|
||||
<!-- begin -->
|
||||
|
||||
<h3><a name="const_item_policies-spec"></a>Class
|
||||
<code>const_item_policies</code></h3>
|
||||
|
||||
@@ -542,6 +664,8 @@ namespace boost { namespace python { namespace api
|
||||
//
|
||||
proxy<const_object_attribute> attr(char const*) const;
|
||||
proxy<object_attribute> attr(char const*);
|
||||
proxy<const_object_objattribute> attr(object const&) const;
|
||||
proxy<object_objattribute> attr(object const&);
|
||||
|
||||
// item access
|
||||
//
|
||||
@@ -608,6 +732,21 @@ proxy<object_attribute> attr(char const* name);
|
||||
<code>name</code> as its key.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
proxy<const_object_objattribute> attr(const object& name) const;
|
||||
proxy<object_objattribute> attr(const object& name);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> name is a <code>object</code> holding a string.</dt>
|
||||
|
||||
<dt><b>Effects:</b> accesses the named attribute of
|
||||
<code>*this</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> a proxy object which binds
|
||||
<code>object(*static_cast<U*>(this))</code> as its target, and
|
||||
<code>name</code> as its key.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class T>
|
||||
proxy<const_object_item> operator[](T const& key) const;
|
||||
template <class T>
|
||||
@@ -938,11 +1077,11 @@ object sum_items(object seq)
|
||||
</pre>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 January, 2006
|
||||
27 May, 2008
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2006.</i></p>
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2008.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,112 +1,93 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<title>Boost.Python Pickle Support</title>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Boost.Python Pickle Support</title>
|
||||
</head>
|
||||
|
||||
<div>
|
||||
<body>
|
||||
<div>
|
||||
<img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"center" width="277" height="86" />
|
||||
<hr />
|
||||
|
||||
<img src="../../../../boost.png"
|
||||
alt="boost.png (6897 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
<h1>Boost.Python Pickle Support</h1>Pickle is a Python module for object
|
||||
serialization, also known as persistence, marshalling, or flattening.
|
||||
|
||||
<hr>
|
||||
<h1>Boost.Python Pickle Support</h1>
|
||||
<p>It is often necessary to save and restore the contents of an object to
|
||||
a file. One approach to this problem is to write a pair of functions that
|
||||
read and write data from a file in a special format. A powerful
|
||||
alternative approach is to use Python's pickle module. Exploiting
|
||||
Python's ability for introspection, the pickle module recursively
|
||||
converts nearly arbitrary Python objects into a stream of bytes that can
|
||||
be written to a file.</p>
|
||||
|
||||
Pickle is a Python module for object serialization, also known
|
||||
as persistence, marshalling, or flattening.
|
||||
<p>The Boost Python Library supports the pickle module through the
|
||||
interface as described in detail in the <a href=
|
||||
"http://www.python.org/doc/current/lib/module-pickle.html">Python Library
|
||||
Reference for pickle.</a> This interface involves the special methods
|
||||
<tt>__getinitargs__</tt>, <tt>__getstate__</tt> and <tt>__setstate__</tt>
|
||||
as described in the following. Note that Boost.Python is also fully
|
||||
compatible with Python's cPickle module.</p>
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
It is often necessary to save and restore the contents of an object to
|
||||
a file. One approach to this problem is to write a pair of functions
|
||||
that read and write data from a file in a special format. A powerful
|
||||
alternative approach is to use Python's pickle module. Exploiting
|
||||
Python's ability for introspection, the pickle module recursively
|
||||
converts nearly arbitrary Python objects into a stream of bytes that
|
||||
can be written to a file.
|
||||
<h2>The Boost.Python Pickle Interface</h2>At the user level, the
|
||||
Boost.Python pickle interface involves three special methods:
|
||||
|
||||
<p>
|
||||
The Boost Python Library supports the pickle module
|
||||
through the interface as described in detail in the
|
||||
<a href="http://www.python.org/doc/current/lib/module-pickle.html"
|
||||
>Python Library Reference for pickle.</a> This interface
|
||||
involves the special methods <tt>__getinitargs__</tt>,
|
||||
<tt>__getstate__</tt> and <tt>__setstate__</tt> as described
|
||||
in the following. Note that Boost.Python is also fully compatible
|
||||
with Python's cPickle module.
|
||||
<dl>
|
||||
<dt><strong><tt>__getinitargs__</tt></strong></dt>
|
||||
|
||||
<hr>
|
||||
<h2>The Boost.Python Pickle Interface</h2>
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getinitargs__</tt> method.
|
||||
This method must return a Python tuple (it is most convenient to use
|
||||
a boost::python::tuple). When the instance is restored by the
|
||||
unpickler, the contents of this tuple are used as the arguments for
|
||||
the class constructor.
|
||||
|
||||
At the user level, the Boost.Python pickle interface involves three special
|
||||
methods:
|
||||
<p>If <tt>__getinitargs__</tt> is not defined, <tt>pickle.load</tt>
|
||||
will call the constructor (<tt>__init__</tt>) without arguments;
|
||||
i.e., the object must be default-constructible.</p>
|
||||
</dd>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<strong><tt>__getinitargs__</tt></strong>
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getinitargs__</tt> method.
|
||||
This method must return a Python tuple (it is most convenient to use
|
||||
a boost::python::tuple). When the instance is restored by the
|
||||
unpickler, the contents of this tuple are used as the arguments for
|
||||
the class constructor.
|
||||
<dt><strong><tt>__getstate__</tt></strong></dt>
|
||||
|
||||
<p>
|
||||
If <tt>__getinitargs__</tt> is not defined, <tt>pickle.load</tt>
|
||||
will call the constructor (<tt>__init__</tt>) without arguments;
|
||||
i.e., the object must be default-constructible.
|
||||
<dd>When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getstate__</tt> method. This
|
||||
method should return a Python object representing the state of the
|
||||
instance.</dd>
|
||||
|
||||
<p>
|
||||
<dt>
|
||||
<strong><tt>__getstate__</tt></strong>
|
||||
<dt><strong><tt>__setstate__</tt></strong></dt>
|
||||
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getstate__</tt> method.
|
||||
This method should return a Python object representing the state of
|
||||
the instance.
|
||||
<dd>When an instance of a Boost.Python extension class is restored by
|
||||
the unpickler (<tt>pickle.load</tt>), it is first constructed using the
|
||||
result of <tt>__getinitargs__</tt> as arguments (see above).
|
||||
Subsequently the unpickler tests if the new instance has a
|
||||
<tt>__setstate__</tt> method. If so, this method is called with the
|
||||
result of <tt>__getstate__</tt> (a Python object) as the argument.</dd>
|
||||
</dl>The three special methods described above may be <tt>.def()</tt>'ed
|
||||
individually by the user. However, Boost.Python provides an easy to use
|
||||
high-level interface via the
|
||||
<strong><tt>boost::python::pickle_suite</tt></strong> class that also
|
||||
enforces consistency: <tt>__getstate__</tt> and <tt>__setstate__</tt>
|
||||
must be defined as pairs. Use of this interface is demonstrated by the
|
||||
following examples.
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
<dt>
|
||||
<strong><tt>__setstate__</tt></strong>
|
||||
<h2>Examples</h2>There are three files in <tt>boost/libs/python/test</tt>
|
||||
that show how to provide pickle support.
|
||||
<hr />
|
||||
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is restored by the
|
||||
unpickler (<tt>pickle.load</tt>), it is first constructed using the
|
||||
result of <tt>__getinitargs__</tt> as arguments (see above). Subsequently
|
||||
the unpickler tests if the new instance has a <tt>__setstate__</tt>
|
||||
method. If so, this method is called with the result of
|
||||
<tt>__getstate__</tt> (a Python object) as the argument.
|
||||
<h3><a href="../../test/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>The C++
|
||||
class in this example can be fully restored by passing the appropriate
|
||||
argument to the constructor. Therefore it is sufficient to define the
|
||||
pickle interface method <tt>__getinitargs__</tt>. This is done in the
|
||||
following way:
|
||||
|
||||
</dl>
|
||||
|
||||
The three special methods described above may be <tt>.def()</tt>'ed
|
||||
individually by the user. However, Boost.Python provides an easy to use
|
||||
high-level interface via the
|
||||
<strong><tt>boost::python::pickle_suite</tt></strong> class that also
|
||||
enforces consistency: <tt>__getstate__</tt> and <tt>__setstate__</tt>
|
||||
must be defined as pairs. Use of this interface is demonstrated by the
|
||||
following examples.
|
||||
|
||||
<hr>
|
||||
<h2>Examples</h2>
|
||||
|
||||
There are three files in
|
||||
<tt>boost/libs/python/test</tt> that show how to
|
||||
provide pickle support.
|
||||
|
||||
<hr>
|
||||
<h3><a href="../../test/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>
|
||||
|
||||
The C++ class in this example can be fully restored by passing the
|
||||
appropriate argument to the constructor. Therefore it is sufficient
|
||||
to define the pickle interface method <tt>__getinitargs__</tt>.
|
||||
This is done in the following way:
|
||||
|
||||
<ul>
|
||||
<li>1. Definition of the C++ pickle function:
|
||||
<pre>
|
||||
<ul>
|
||||
<li>1. Definition of the C++ pickle function:
|
||||
<pre>
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static
|
||||
@@ -117,26 +98,28 @@ provide pickle support.
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<li>2. Establishing the Python binding:
|
||||
<pre>
|
||||
</li>
|
||||
|
||||
<li>2. Establishing the Python binding:
|
||||
<pre>
|
||||
class_<world>("world", args<const std::string&>())
|
||||
// ...
|
||||
.def_pickle(world_pickle_suite())
|
||||
// ...
|
||||
</pre>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<hr />
|
||||
|
||||
<hr>
|
||||
<h3><a href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>
|
||||
<h3><a href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>The C++
|
||||
class in this example contains member data that cannot be restored by any
|
||||
of the constructors. Therefore it is necessary to provide the
|
||||
<tt>__getstate__</tt>/<tt>__setstate__</tt> pair of pickle interface
|
||||
methods:
|
||||
|
||||
The C++ class in this example contains member data that cannot be
|
||||
restored by any of the constructors. Therefore it is necessary to
|
||||
provide the <tt>__getstate__</tt>/<tt>__setstate__</tt> pair of
|
||||
pickle interface methods:
|
||||
|
||||
<ul>
|
||||
<li>1. Definition of the C++ pickle functions:
|
||||
<pre>
|
||||
<ul>
|
||||
<li>1. Definition of the C++ pickle functions:
|
||||
<pre>
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static
|
||||
@@ -161,92 +144,76 @@ provide pickle support.
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<li>2. Establishing the Python bindings for the entire suite:
|
||||
<pre>
|
||||
</li>
|
||||
|
||||
<li>2. Establishing the Python bindings for the entire suite:
|
||||
<pre>
|
||||
class_<world>("world", args<const std::string&>())
|
||||
// ...
|
||||
.def_pickle(world_pickle_suite())
|
||||
// ...
|
||||
</pre>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
For simplicity, the <tt>__dict__</tt> is not included in the result
|
||||
of <tt>__getstate__</tt>. This is not generally recommended, but a
|
||||
valid approach if it is anticipated that the object's
|
||||
<tt>__dict__</tt> will always be empty. Note that the safety guard
|
||||
described below will catch the cases where this assumption is violated.
|
||||
<p>For simplicity, the <tt>__dict__</tt> is not included in the result of
|
||||
<tt>__getstate__</tt>. This is not generally recommended, but a valid
|
||||
approach if it is anticipated that the object's <tt>__dict__</tt> will
|
||||
always be empty. Note that the safety guard described below will catch
|
||||
the cases where this assumption is violated.</p>
|
||||
<hr />
|
||||
|
||||
<hr>
|
||||
<h3><a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>
|
||||
<h3><a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>This
|
||||
example is similar to <a href=
|
||||
"../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the object's
|
||||
<tt>__dict__</tt> is included in the result of <tt>__getstate__</tt>.
|
||||
This requires a little more code but is unavoidable if the object's
|
||||
<tt>__dict__</tt> is not always empty.
|
||||
<hr />
|
||||
|
||||
This example is similar to <a
|
||||
href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the
|
||||
object's <tt>__dict__</tt> is included in the result of
|
||||
<tt>__getstate__</tt>. This requires a little more code but is
|
||||
unavoidable if the object's <tt>__dict__</tt> is not always empty.
|
||||
<h2>Pitfall and Safety Guard</h2>The pickle protocol described above has
|
||||
an important pitfall that the end user of a Boost.Python extension module
|
||||
might not be aware of:
|
||||
|
||||
<hr>
|
||||
<h2>Pitfall and Safety Guard</h2>
|
||||
<p><strong><tt>__getstate__</tt> is defined and the instance's
|
||||
<tt>__dict__</tt> is not empty.</strong></p>
|
||||
|
||||
The pickle protocol described above has an important pitfall that the
|
||||
end user of a Boost.Python extension module might not be aware of:
|
||||
<p>
|
||||
<strong>
|
||||
<tt>__getstate__</tt> is defined and the instance's <tt>__dict__</tt>
|
||||
is not empty.
|
||||
</strong>
|
||||
<p>
|
||||
<p>The author of a Boost.Python extension class might provide a
|
||||
<tt>__getstate__</tt> method without considering the possibilities
|
||||
that:</p>
|
||||
|
||||
The author of a Boost.Python extension class might provide a
|
||||
<tt>__getstate__</tt> method without considering the possibilities
|
||||
that:
|
||||
<ul>
|
||||
<li>his class is used in Python as a base class. Most likely the
|
||||
<tt>__dict__</tt> of instances of the derived class needs to be pickled
|
||||
in order to restore the instances correctly.</li>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
his class is used in Python as a base class. Most likely the
|
||||
<tt>__dict__</tt> of instances of the derived class needs to be
|
||||
pickled in order to restore the instances correctly.
|
||||
<li>the user adds items to the instance's <tt>__dict__</tt> directly.
|
||||
Again, the <tt>__dict__</tt> of the instance then needs to be
|
||||
pickled.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<li>
|
||||
the user adds items to the instance's <tt>__dict__</tt> directly.
|
||||
Again, the <tt>__dict__</tt> of the instance then needs to be
|
||||
pickled.
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
To alert the user to this highly unobvious problem, a safety guard is
|
||||
provided. If <tt>__getstate__</tt> is defined and the instance's
|
||||
<tt>__dict__</tt> is not empty, Boost.Python tests if the class has
|
||||
an attribute <tt>__getstate_manages_dict__</tt>. An exception is
|
||||
raised if this attribute is not defined:
|
||||
|
||||
<pre>
|
||||
<p>To alert the user to this highly unobvious problem, a safety guard is
|
||||
provided. If <tt>__getstate__</tt> is defined and the instance's
|
||||
<tt>__dict__</tt> is not empty, Boost.Python tests if the class has an
|
||||
attribute <tt>__getstate_manages_dict__</tt>. An exception is raised if
|
||||
this attribute is not defined:</p>
|
||||
<pre>
|
||||
RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
</pre>
|
||||
|
||||
To resolve this problem, it should first be established that the
|
||||
<tt>__getstate__</tt> and <tt>__setstate__</tt> methods manage the
|
||||
instances's <tt>__dict__</tt> correctly. Note that this can be done
|
||||
either at the C++ or the Python level. Finally, the safety guard
|
||||
should intentionally be overridden. E.g. in C++ (from
|
||||
<a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a>):
|
||||
|
||||
<pre>
|
||||
</pre>To resolve this problem, it should first be established that the <tt>
|
||||
__getstate__</tt> and <tt>__setstate__</tt> methods manage the
|
||||
instances's <tt>__dict__</tt> correctly. Note that this can be done
|
||||
either at the C++ or the Python level. Finally, the safety guard should
|
||||
intentionally be overridden. E.g. in C++ (from <a href=
|
||||
"../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a>):
|
||||
<pre>
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
// ...
|
||||
|
||||
static bool getstate_manages_dict() { return true; }
|
||||
};
|
||||
</pre>
|
||||
|
||||
Alternatively in Python:
|
||||
|
||||
<pre>
|
||||
</pre>Alternatively in Python:
|
||||
<pre>
|
||||
import your_bpl_module
|
||||
class your_class(your_bpl_module.your_class):
|
||||
__getstate_manages_dict__ = 1
|
||||
@@ -255,54 +222,41 @@ is not empty.
|
||||
def __setstate__(self, state):
|
||||
# your code here
|
||||
</pre>
|
||||
<hr />
|
||||
|
||||
<hr>
|
||||
<h2>Practical Advice</h2>
|
||||
<h2>Practical Advice</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
In Boost.Python extension modules with many extension classes,
|
||||
providing complete pickle support for all classes would be a
|
||||
significant overhead. In general complete pickle support should
|
||||
only be implemented for extension classes that will eventually
|
||||
be pickled.
|
||||
<ul>
|
||||
<li>In Boost.Python extension modules with many extension classes,
|
||||
providing complete pickle support for all classes would be a
|
||||
significant overhead. In general complete pickle support should only be
|
||||
implemented for extension classes that will eventually be pickled.</li>
|
||||
|
||||
<p>
|
||||
<li>
|
||||
Avoid using <tt>__getstate__</tt> if the instance can also be
|
||||
reconstructed by way of <tt>__getinitargs__</tt>. This automatically
|
||||
avoids the pitfall described above.
|
||||
<li>Avoid using <tt>__getstate__</tt> if the instance can also be
|
||||
reconstructed by way of <tt>__getinitargs__</tt>. This automatically
|
||||
avoids the pitfall described above.</li>
|
||||
|
||||
<p>
|
||||
<li>
|
||||
If <tt>__getstate__</tt> is required, include the instance's
|
||||
<tt>__dict__</tt> in the Python object that is returned.
|
||||
<li>If <tt>__getstate__</tt> is required, include the instance's
|
||||
<tt>__dict__</tt> in the Python object that is returned.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
|
||||
</ul>
|
||||
<h2>Light-weight alternative: pickle support implemented in Python</h2>
|
||||
|
||||
<hr>
|
||||
<h2>Light-weight alternative: pickle support implemented in Python</h2>
|
||||
|
||||
<h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>
|
||||
|
||||
The <tt>pickle4.cpp</tt> example demonstrates an alternative technique
|
||||
for implementing pickle support. First we direct Boost.Python via
|
||||
the <tt>class_::enable_pickling()</tt> member function to define only
|
||||
the basic attributes required for pickling:
|
||||
|
||||
<pre>
|
||||
<h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>The
|
||||
<tt>pickle4.cpp</tt> example demonstrates an alternative technique for
|
||||
implementing pickle support. First we direct Boost.Python via the
|
||||
<tt>class_::enable_pickling()</tt> member function to define only the
|
||||
basic attributes required for pickling:
|
||||
<pre>
|
||||
class_<world>("world", args<const std::string&>())
|
||||
// ...
|
||||
.enable_pickling()
|
||||
// ...
|
||||
</pre>
|
||||
|
||||
This enables the standard Python pickle interface as described
|
||||
in the Python documentation. By "injecting" a
|
||||
<tt>__getinitargs__</tt> method into the definition of the wrapped
|
||||
class we make all instances pickleable:
|
||||
|
||||
<pre>
|
||||
</pre>This enables the standard Python pickle interface as described in the
|
||||
Python documentation. By "injecting" a <tt>__getinitargs__</tt> method into
|
||||
the definition of the wrapped class we make all instances pickleable:
|
||||
<pre>
|
||||
# import the wrapped world class
|
||||
from pickle4_ext import world
|
||||
|
||||
@@ -312,18 +266,15 @@ class we make all instances pickleable:
|
||||
|
||||
# now inject __getinitargs__ (Python is a dynamic language!)
|
||||
world.__getinitargs__ = world_getinitargs
|
||||
</pre>
|
||||
</pre>See also the <a href=
|
||||
"../tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python">
|
||||
tutorial section</a> on injecting additional methods from Python.
|
||||
<hr />
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001-2004. Distributed under the
|
||||
Boost Software License, Version 1.0. (See accompanying file
|
||||
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
See also the
|
||||
<a href="../tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python"
|
||||
>tutorial section</a> on injecting additional methods from Python.
|
||||
|
||||
<hr>
|
||||
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001-2004. Distributed under
|
||||
the Boost Software License, Version 1.0. (See accompanying file
|
||||
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
<p>
|
||||
Updated: Feb 2004.
|
||||
</div>
|
||||
<p>Updated: Feb 2004.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_*)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ struct const_attribute_policies
|
||||
{
|
||||
typedef char const* key_type;
|
||||
static object get(object const& target, char const* key);
|
||||
static object get(object const& target, object const& key);
|
||||
};
|
||||
|
||||
struct attribute_policies : const_attribute_policies
|
||||
@@ -25,6 +26,18 @@ struct attribute_policies : const_attribute_policies
|
||||
static void del(object const&target, char const* key);
|
||||
};
|
||||
|
||||
struct const_objattribute_policies
|
||||
{
|
||||
typedef object const key_type;
|
||||
static object get(object const& target, object const& key);
|
||||
};
|
||||
|
||||
struct objattribute_policies : const_objattribute_policies
|
||||
{
|
||||
static object const& set(object const& target, object const& key, object const& value);
|
||||
static void del(object const&target, object const& key);
|
||||
};
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
@@ -42,11 +55,30 @@ inline const_object_attribute object_operators<U>::attr(char const* name) const
|
||||
return const_object_attribute(x, name);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline object_objattribute object_operators<U>::attr(object const& name)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_objattribute(x, name);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline const_object_objattribute object_operators<U>::attr(object const& name) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_objattribute(x, name);
|
||||
}
|
||||
|
||||
inline object const_attribute_policies::get(object const& target, char const* key)
|
||||
{
|
||||
return python::getattr(target, key);
|
||||
}
|
||||
|
||||
inline object const_objattribute_policies::get(object const& target, object const& key)
|
||||
{
|
||||
return python::getattr(target, key);
|
||||
}
|
||||
|
||||
inline object const& attribute_policies::set(
|
||||
object const& target
|
||||
, char const* key
|
||||
@@ -56,6 +88,15 @@ inline object const& attribute_policies::set(
|
||||
return value;
|
||||
}
|
||||
|
||||
inline object const& objattribute_policies::set(
|
||||
object const& target
|
||||
, object const& key
|
||||
, object const& value)
|
||||
{
|
||||
python::setattr(target, key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void attribute_policies::del(
|
||||
object const& target
|
||||
, char const* key)
|
||||
@@ -63,6 +104,13 @@ inline void attribute_policies::del(
|
||||
python::delattr(target, key);
|
||||
}
|
||||
|
||||
inline void objattribute_policies::del(
|
||||
object const& target
|
||||
, object const& key)
|
||||
{
|
||||
python::delattr(target, key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::api
|
||||
|
||||
#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace api
|
||||
|
||||
struct const_attribute_policies;
|
||||
struct attribute_policies;
|
||||
struct const_objattribute_policies;
|
||||
struct objattribute_policies;
|
||||
struct const_item_policies;
|
||||
struct item_policies;
|
||||
struct const_slice_policies;
|
||||
@@ -67,6 +69,8 @@ namespace api
|
||||
|
||||
typedef proxy<const_attribute_policies> const_object_attribute;
|
||||
typedef proxy<attribute_policies> object_attribute;
|
||||
typedef proxy<const_objattribute_policies> const_object_objattribute;
|
||||
typedef proxy<objattribute_policies> object_objattribute;
|
||||
typedef proxy<const_item_policies> const_object_item;
|
||||
typedef proxy<item_policies> object_item;
|
||||
typedef proxy<const_slice_policies> const_object_slice;
|
||||
@@ -108,6 +112,8 @@ namespace api
|
||||
//
|
||||
const_object_attribute attr(char const*) const;
|
||||
object_attribute attr(char const*);
|
||||
const_object_objattribute attr(object const&) const;
|
||||
object_objattribute attr(object const&);
|
||||
|
||||
// item access
|
||||
//
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Based on boost/ref.hpp, thus:
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2001 Peter Dimov
|
||||
|
||||
# if _MSC_VER+0 >= 1020
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# include <boost/operators.hpp>
|
||||
# include <typeinfo>
|
||||
# include <cstring>
|
||||
# include <ostream>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
@@ -68,8 +68,9 @@ struct with_custodian_and_ward : BasePolicy_
|
||||
|
||||
bool result = BasePolicy_::precall(args_);
|
||||
|
||||
if (!result)
|
||||
if (!result) {
|
||||
Py_DECREF(life_support);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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}"
|
||||
)
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *f = python::extract<char *>(filename);
|
||||
// Let python open the file to avoid potential binary incompatibilities.
|
||||
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
|
||||
PyObject *pyfile = PyFile_FromString(f, "r");
|
||||
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
|
||||
python::handle<> file(pyfile);
|
||||
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
@@ -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, "()"))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ extern "C"
|
||||
{
|
||||
propertyobject *gs = (propertyobject *)self;
|
||||
|
||||
return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
|
||||
return PyObject_CallFunction(gs->prop_get, "()");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -95,9 +95,9 @@ extern "C"
|
||||
return -1;
|
||||
}
|
||||
if (value == NULL)
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("()"));
|
||||
res = PyObject_CallFunction(func, "()");
|
||||
else
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
|
||||
res = PyObject_CallFunction(func, "(O)", value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
@@ -108,7 +108,7 @@ extern "C"
|
||||
static PyTypeObject static_data_object = {
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.StaticProperty"),
|
||||
"Boost.Python.StaticProperty",
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
@@ -212,7 +212,7 @@ extern "C"
|
||||
static PyTypeObject class_metatype_object = {
|
||||
PyObject_HEAD_INIT(0)//&PyType_Type)
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.class"),
|
||||
"Boost.Python.class",
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
@@ -316,7 +316,7 @@ namespace objects
|
||||
{
|
||||
// Attempt to find the __instance_size__ attribute. If not present, no problem.
|
||||
PyObject* d = type_->tp_dict;
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");
|
||||
|
||||
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
|
||||
|
||||
@@ -357,20 +357,20 @@ namespace objects
|
||||
|
||||
|
||||
static PyGetSetDef instance_getsets[] = {
|
||||
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{"__dict__", instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static PyMemberDef instance_members[] = {
|
||||
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static PyTypeObject class_type_object = {
|
||||
PyObject_HEAD_INIT(0) //&class_metatype_object)
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.instance"),
|
||||
"Boost.Python.instance",
|
||||
offsetof(instance<>,storage), /* tp_basicsize */
|
||||
1, /* tp_itemsize */
|
||||
instance_dealloc, /* tp_dealloc */
|
||||
@@ -572,7 +572,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -582,7 +582,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -591,7 +591,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr()));
|
||||
PyObject_CallFunction(static_data(), "O", fget.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -600,7 +600,7 @@ namespace objects
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
|
||||
PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
@@ -615,13 +615,13 @@ namespace objects
|
||||
{
|
||||
extern "C" PyObject* no_init(PyObject*, PyObject*)
|
||||
{
|
||||
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
|
||||
::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
|
||||
return NULL;
|
||||
}
|
||||
static ::PyMethodDef no_init_def = {
|
||||
const_cast<char*>("__init__"), no_init, METH_VARARGS,
|
||||
const_cast<char*>("Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n")
|
||||
"__init__", no_init, METH_VARARGS,
|
||||
"Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -650,7 +650,7 @@ namespace objects
|
||||
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
|
||||
, "staticmethod expects callable object; got an object of type %s, which is not callable"
|
||||
, callable->ob_type->tp_name
|
||||
);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ struct enum_object
|
||||
};
|
||||
|
||||
static PyMemberDef enum_members[] = {
|
||||
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ extern "C"
|
||||
{
|
||||
static PyObject* enum_repr(PyObject* self_)
|
||||
{
|
||||
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
|
||||
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
|
||||
enum_object* self = downcast<enum_object>(self_);
|
||||
if (!self->name)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ extern "C"
|
||||
static PyTypeObject enum_type_object = {
|
||||
PyObject_HEAD_INIT(0) // &PyType_Type
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.enum"),
|
||||
"Boost.Python.enum",
|
||||
sizeof(enum_object), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
|
||||
@@ -297,7 +297,7 @@ object function::signatures(bool show_return_type) const
|
||||
void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
static handle<> exception(
|
||||
PyErr_NewException(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
|
||||
PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0));
|
||||
|
||||
object message = "Python argument types in\n %s.%s("
|
||||
% make_tuple(this->m_namespace, this->m_name);
|
||||
@@ -440,7 +440,7 @@ void function::add_to_namespace(
|
||||
else if (PyType_Check(ns))
|
||||
dict = ((PyTypeObject*)ns)->tp_dict;
|
||||
else
|
||||
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
|
||||
dict = PyObject_GetAttrString(ns, "__dict__");
|
||||
|
||||
if (dict == 0)
|
||||
throw_error_already_set();
|
||||
@@ -487,7 +487,7 @@ void function::add_to_namespace(
|
||||
new_func->m_name = name;
|
||||
|
||||
handle<> name_space_name(
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__")));
|
||||
|
||||
if (name_space_name)
|
||||
new_func->m_namespace = object(name_space_name);
|
||||
@@ -656,18 +656,18 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyGetSetDef function_getsetlist[] = {
|
||||
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{"__name__", (getter)function_get_name, 0, 0, 0 },
|
||||
{"func_name", (getter)function_get_name, 0, 0, 0 },
|
||||
{"__class__", (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{"__doc__", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{"func_doc", (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{NULL, 0, 0, 0, 0} /* Sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject function_type = {
|
||||
PyObject_HEAD_INIT(0)
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.function"),
|
||||
"Boost.Python.function",
|
||||
sizeof(function),
|
||||
0,
|
||||
(destructor)function_dealloc, /* tp_dealloc */
|
||||
@@ -753,8 +753,7 @@ namespace detail
|
||||
}
|
||||
void BOOST_PYTHON_DECL pure_virtual_called()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
|
||||
PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C"
|
||||
PyTypeObject life_support_type = {
|
||||
PyObject_HEAD_INIT(0)//(&PyType_Type)
|
||||
0,
|
||||
const_cast<char*>("Boost.Python.life_support"),
|
||||
"Boost.Python.life_support",
|
||||
sizeof(life_support),
|
||||
0,
|
||||
life_support_dealloc, /* tp_dealloc */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace boost { namespace python { namespace detail {
|
||||
detail::new_reference str_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyString_Type, const_cast<char*>("(O)"),
|
||||
(PyObject*)&PyString_Type, "(O)",
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
@@ -68,9 +68,8 @@ str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const
|
||||
return str(new_reference( \
|
||||
expect_non_null( \
|
||||
PyObject_CallMethod( \
|
||||
this->ptr(), const_cast<char*>( #name ), \
|
||||
const_cast<char*>( \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
|
||||
this->ptr(), #name, \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \
|
||||
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -171,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)
|
||||
# {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -59,7 +59,7 @@ void eval_test()
|
||||
void exec_test()
|
||||
{
|
||||
// Register the module with the interpreter
|
||||
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"), initembedded_hello) == -1)
|
||||
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
|
||||
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
|
||||
"builtin modules");
|
||||
// Retrieve the main module
|
||||
|
||||
@@ -34,7 +34,7 @@ struct NoddyObject : PyObject
|
||||
PyTypeObject NoddyType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
const_cast<char*>("Noddy"),
|
||||
"Noddy",
|
||||
sizeof(NoddyObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -106,7 +106,7 @@ struct extract_simple_object
|
||||
PyTypeObject SimpleType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
const_cast<char*>("Simple"),
|
||||
"Simple",
|
||||
sizeof(SimpleObject),
|
||||
0,
|
||||
dealloc, /* tp_dealloc */
|
||||
@@ -159,7 +159,7 @@ PyTypeObject SimpleType = {
|
||||
PyObject* new_simple()
|
||||
{
|
||||
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
simple->x.s = const_cast<char*>("hello, world");
|
||||
simple->x.s = "hello, world";
|
||||
return (PyObject*)simple;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# endif
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# include <eh.h> // for _set_se_translator()
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4297)
|
||||
# pragma warning(disable:4535)
|
||||
|
||||
@@ -38,26 +38,61 @@ object obj_getattr(object x, char const* name)
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
object obj_objgetattr(object x, object const& name)
|
||||
{
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
object obj_const_getattr(object const& x, char const* name)
|
||||
{
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
object obj_const_objgetattr(object const& x, object const& name)
|
||||
{
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
void obj_setattr(object x, char const* name, object value)
|
||||
{
|
||||
x.attr(name) = value;
|
||||
}
|
||||
|
||||
void obj_objsetattr(object x, object const& name, object value)
|
||||
{
|
||||
x.attr(name) = value;
|
||||
}
|
||||
|
||||
void obj_setattr42(object x, char const* name)
|
||||
{
|
||||
x.attr(name) = 42;
|
||||
}
|
||||
|
||||
void obj_objsetattr42(object x, object const& name)
|
||||
{
|
||||
x.attr(name) = 42;
|
||||
}
|
||||
|
||||
void obj_moveattr(object& x, char const* src, char const* dst)
|
||||
{
|
||||
x.attr(dst) = x.attr(src);
|
||||
}
|
||||
|
||||
void obj_objmoveattr(object& x, object const& src, object const& dst)
|
||||
{
|
||||
x.attr(dst) = x.attr(src);
|
||||
}
|
||||
|
||||
void obj_delattr(object x, char const* name)
|
||||
{
|
||||
x.attr(name).del();
|
||||
}
|
||||
|
||||
void obj_objdelattr(object x, object const& name)
|
||||
{
|
||||
x.attr(name).del();
|
||||
}
|
||||
|
||||
object obj_getitem(object x, object key)
|
||||
{
|
||||
return x[key];
|
||||
@@ -108,11 +143,21 @@ bool test_attr(object y, char* name)
|
||||
return y.attr(name);
|
||||
}
|
||||
|
||||
bool test_objattr(object y, object& name)
|
||||
{
|
||||
return y.attr(name);
|
||||
}
|
||||
|
||||
bool test_not_attr(object y, char* name)
|
||||
{
|
||||
return !y.attr(name);
|
||||
}
|
||||
|
||||
bool test_not_objattr(object y, object& name)
|
||||
{
|
||||
return !y.attr(name);
|
||||
}
|
||||
|
||||
bool test_item(object y, object key)
|
||||
{
|
||||
return y[key];
|
||||
@@ -301,11 +346,17 @@ BOOST_PYTHON_MODULE(object_ext)
|
||||
def("number", number);
|
||||
|
||||
def("obj_getattr", obj_getattr);
|
||||
def("obj_objgetattr", obj_objgetattr);
|
||||
def("obj_const_getattr", obj_const_getattr);
|
||||
def("obj_const_objgetattr", obj_const_objgetattr);
|
||||
def("obj_setattr", obj_setattr);
|
||||
def("obj_objsetattr", obj_objsetattr);
|
||||
def("obj_setattr42", obj_setattr42);
|
||||
def("obj_objsetattr42", obj_objsetattr42);
|
||||
def("obj_moveattr", obj_moveattr);
|
||||
|
||||
def("obj_objmoveattr", obj_objmoveattr);
|
||||
def("obj_delattr", obj_delattr);
|
||||
def("obj_objdelattr", obj_objdelattr);
|
||||
|
||||
def("obj_getitem", obj_getitem);
|
||||
def("obj_getitem3", obj_getitem);
|
||||
@@ -319,7 +370,9 @@ BOOST_PYTHON_MODULE(object_ext)
|
||||
def("test_not", test_not);
|
||||
|
||||
def("test_attr", test_attr);
|
||||
def("test_objattr", test_objattr);
|
||||
def("test_not_attr", test_not_attr);
|
||||
def("test_not_objattr", test_not_objattr);
|
||||
|
||||
def("test_item", test_item);
|
||||
def("test_not_item", test_not_item);
|
||||
|
||||
@@ -34,29 +34,68 @@
|
||||
>>> try: obj_getattr(x, 'foo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
>>> try: obj_objgetattr(x, 'objfoo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
|
||||
>>> obj_setattr(x, 'foo', 1)
|
||||
>>> x.foo
|
||||
1
|
||||
>>> obj_objsetattr(x, 'objfoo', 1)
|
||||
>>> try:obj_objsetattr(x, 1)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception'
|
||||
>>> x.objfoo
|
||||
1
|
||||
>>> obj_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_objgetattr(x, 'objfoo')
|
||||
1
|
||||
>>> try:obj_objgetattr(x, 1)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception'
|
||||
>>> obj_const_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_const_objgetattr(x, 'objfoo')
|
||||
1
|
||||
>>> obj_setattr42(x, 'foo')
|
||||
>>> x.foo
|
||||
42
|
||||
>>> obj_objsetattr42(x, 'objfoo')
|
||||
>>> x.objfoo
|
||||
42
|
||||
>>> obj_moveattr(x, 'foo', 'bar')
|
||||
>>> x.bar
|
||||
42
|
||||
>>> obj_objmoveattr(x, 'objfoo', 'objbar')
|
||||
>>> x.objbar
|
||||
42
|
||||
>>> test_attr(x, 'foo')
|
||||
1
|
||||
>>> test_objattr(x, 'objfoo')
|
||||
1
|
||||
>>> test_not_attr(x, 'foo')
|
||||
0
|
||||
>>> test_not_objattr(x, 'objfoo')
|
||||
0
|
||||
>>> x.foo = None
|
||||
>>> test_attr(x, 'foo')
|
||||
0
|
||||
>>> x.objfoo = None
|
||||
>>> test_objattr(x, 'objfoo')
|
||||
0
|
||||
>>> test_not_attr(x, 'foo')
|
||||
1
|
||||
>>> test_not_objattr(x, 'objfoo')
|
||||
1
|
||||
>>> obj_delattr(x, 'foo')
|
||||
>>> obj_objdelattr(x, 'objfoo')
|
||||
>>> try:obj_delattr(x, 'foo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
>>> try:obj_objdelattr(x, 'objfoo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
|
||||
Items
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace boost_python_test {
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& _country) : secret_number(0) {
|
||||
this->country = _country;
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace boost_python_test {
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& _country) {
|
||||
this->country = _country;
|
||||
world(const std::string& country) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
|
||||
@@ -100,11 +100,7 @@ bool accept_slice( slice) { return true; }
|
||||
|| BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
|
||||
int check_slice_get_indicies(slice index);
|
||||
#endif
|
||||
int check_slice_get_indicies(
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
const
|
||||
#endif
|
||||
slice index)
|
||||
int check_slice_get_indicies(const slice index)
|
||||
{
|
||||
// A vector of integers from [-5, 5].
|
||||
std::vector<int> coll(11);
|
||||
|
||||
@@ -20,7 +20,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
@@ -12,16 +12,6 @@
|
||||
3
|
||||
4
|
||||
5
|
||||
>>> def generator():
|
||||
... yield 1
|
||||
... yield 2
|
||||
... raise RuntimeError, "oops"
|
||||
>>> try:
|
||||
... x.assign(iter(generator()))
|
||||
... print "NOT OK"
|
||||
... except RuntimeError:
|
||||
... print "OK"
|
||||
OK
|
||||
'''
|
||||
def run(args = None):
|
||||
import sys
|
||||
|
||||
@@ -13,7 +13,7 @@ struct test_class
|
||||
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
|
||||
virtual ~test_class() { BOOST_TEST(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int _x) { BOOST_TEST(magic == 7654321 + n); this->x = _x; }
|
||||
void set(int x) { BOOST_TEST(magic == 7654321 + n); this->x = x; }
|
||||
int value() const { BOOST_TEST(magic == 7654321 + n); return x; }
|
||||
operator int() const { return x; }
|
||||
static int count() { return counter; }
|
||||
|
||||
@@ -65,7 +65,7 @@ struct B
|
||||
B() : x(0) {}
|
||||
B(A* x_) : x(x_) {}
|
||||
|
||||
inner const* adopt(A* _x) { this->x = _x; return &_x->get_inner(); }
|
||||
inner const* adopt(A* x) { this->x = x; return &x->get_inner(); }
|
||||
|
||||
std::string a_content()
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ struct X
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
|
||||
void set(int x) { BOOST_ASSERT(magic == 7654321); this->x = x; }
|
||||
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user