2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 04:42:28 +00:00

Compare commits

..

94 Commits

Author SHA1 Message Date
Daniel James
6f77be9a3c Merge from trunk.
[SVN r40260]
2007-10-21 07:28:23 +00:00
Daniel James
daf6d97640 Merge with the offending files removed.
[SVN r39995]
2007-10-13 23:18:35 +00:00
Daniel James
8c70f0540a Merge from trunk.
[SVN r39287]
2007-09-14 22:24:22 +00:00
Daniel James
9630425051 Create a development branch for the hash library.
[SVN r38869]
2007-08-23 19:28:19 +00:00
Vladimir Prus
04e54d670c Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +00:00
Stefan Seefeld
dd7c0a7f3d Fix ticket #1115.
[SVN r38289]
2007-07-26 16:11:18 +00:00
Ralf W. Grosse-Kunstleve
9de994c0d1 Hans Meine's extra new-line for epydoc with reST compatibility
[SVN r37906]
2007-06-06 00:00:57 +00:00
Stefan Seefeld
e9caacc428 More fixes for embedding python docs.
[SVN r37709]
2007-05-18 15:52:55 +00:00
Stefan Seefeld
5070e84f70 Enhance documentation for embedding python.
[SVN r37708]
2007-05-18 15:22:43 +00:00
Stefan Seefeld
fe23d9885f Add new eval() function.
[SVN r37560]
2007-05-02 13:11:20 +00:00
Ralf W. Grosse-Kunstleve
e7ee17b71b MIPSpro: undo Python 2.5.1 define (the define leads to many warnings)
[SVN r37502]
2007-04-25 04:45:17 +00:00
Dave Abrahams
5edb63d01c Some progress on Python build guide. Minor fixes to getting started guide.
[SVN r37418]
2007-04-11 23:35:08 +00:00
Dave Abrahams
f4b3aab7d4 Checkpoint before reorg
[SVN r37370]
2007-04-05 20:13:13 +00:00
Dave Abrahams
6af67d1a4c kill off BBv1 project archive
[SVN r37367]
2007-04-05 17:19:20 +00:00
Dave Abrahams
16d975ba5c Bringing forward BBv2/Python support and a few other things that were
obviously more up-to-date on the RC branch.

Removed the Boost.Python v1 zip archive.


[SVN r37346]
2007-04-03 17:10:53 +00:00
Dave Abrahams
4fc5cafd40 Some progress on new build/test guide.
[SVN r37333]
2007-04-02 05:24:25 +00:00
Stefan Seefeld
1b5cd10f7c Fix reference counting error.
[SVN r37312]
2007-03-28 18:12:08 +00:00
Stefan Seefeld
0f91872518 Fix import_ failure.
[SVN r37142]
2007-03-05 18:51:04 +00:00
Stefan Seefeld
dc6b2979e4 Add copyright notice.
[SVN r37132]
2007-03-02 17:16:51 +00:00
Stefan Seefeld
50034140c4 Fix boost::python::import.
[SVN r37120]
2007-03-01 15:17:29 +00:00
Dave Abrahams
08a6f35ec2 Correct testing bugs:
either changing assert(...) or BOOST_ASSERT(...) to BOOST_TEST
    (in my code only)

    or adding "return boost::report_errors();" where it was clearly
    missing (and a pure bug, in anyone's code).


[SVN r37057]
2007-02-24 22:40:59 +00:00
Dave Abrahams
67236ffbad New build instructions in progress
[SVN r36879]
2007-02-03 16:55:07 +00:00
Dave Abrahams
96ab7a80a4 Remove BBv1 for good
[SVN r36323]
2006-12-11 05:02:34 +00:00
Dave Abrahams
d8c3ff199e Remove BBv1 for good
[SVN r36321]
2006-12-11 03:35:10 +00:00
Dave Abrahams
0c4ebef579 Fix auto-link to look at the right variable.
Make boost-build.jam point at the v2 Boost.


[SVN r36318]
2006-12-11 02:54:48 +00:00
Dave Abrahams
8fe9d41b58 Cleaned out flotsam and improved comments
[SVN r36317]
2006-12-11 02:50:55 +00:00
Dave Abrahams
8a4590b2ef Enable auto-linking
[SVN r36291]
2006-12-07 17:44:05 +00:00
Ralf W. Grosse-Kunstleve
d67b040683 fixes to support pickling of enums (by Shashank Bapat)
[SVN r36256]
2006-12-03 20:43:48 +00:00
Beman Dawes
2db61657f2 Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
Dave Abrahams
6d2ee96ba3 improve error message
[SVN r35822]
2006-11-03 16:34:53 +00:00
Stefan Seefeld
a74c8e3da3 Fix symbol visibility.
[SVN r35754]
2006-10-27 21:19:47 +00:00
Ralf W. Grosse-Kunstleve
9f4d39d9fe correct trivial, obvious accident: stray line removed
[SVN r35599]
2006-10-13 22:06:17 +00:00
Dave Abrahams
31c19644ed make numpy tests portable to Darwin with older docutils
[SVN r35597]
2006-10-13 21:34:26 +00:00
Dave Abrahams
600d444136 Fix some problems with testing on old docutils installations
[SVN r35594]
2006-10-13 19:35:28 +00:00
Dave Abrahams
c3bd0fcbad Make object comparison operators return object instead of bool, to
accomodate strange beasts like numarray arrays that return arrays that
can't be used as truth values from their comparison ops.

Fix numpy test for portability with old doctest (again!)


[SVN r35572]
2006-10-12 09:07:07 +00:00
Dave Abrahams
991a7c198a Workaround vc6 bugs
[SVN r35568]
2006-10-12 06:41:55 +00:00
Dave Abrahams
9b67f0447d Suppress a couple of msvc class/struct warnings
[SVN r35567]
2006-10-12 06:41:18 +00:00
Dave Abrahams
b714f6cc23 Adjust tests to account for numarray behavior differences
[SVN r35539]
2006-10-10 22:44:09 +00:00
Dave Abrahams
479a6ba4fc Try for backward compatibility with older versions of doctest
[SVN r35535]
2006-10-10 18:12:43 +00:00
Dave Abrahams
d78836b828 Fix lots of bugs in the numeric interface and tests.
Tests:
* Coerce a result to bool to deal with Python's new Bool type
* Better reporting of mismatches in expected and received results
* Remove bogus nullary y.astype() call
* Fix all uses of trace and diagonal so they don't cause errors
* Use appropriate typecodes
* Use doctest detailed API to run just the relevant tests
* Factor out error handling from macro

API:
* Added get_module_name() function to get current numeric module
* new_(x) now returns an array instead of object
* Fixed the signatures of the factory() family of functions
* Updated docs accordingly.


[SVN r35528]
2006-10-09 04:05:25 +00:00
Dave Abrahams
7a59131d37 Fix missing #include
[SVN r35524]
2006-10-08 05:17:20 +00:00
Dave Abrahams
5ab00bc9c8 Fix long-standing misnaming of "factory" method as "array"
[SVN r35428]
2006-09-29 22:24:12 +00:00
Dave Abrahams
94500ae36d Tests and fixes for a bad interaction between wrapper<> and operators
support.  "self" arguments weren't getting unwrapped properly.


[SVN r35365]
2006-09-28 14:41:01 +00:00
Dave Abrahams
5e5d34cc36 Fixed broken links
[SVN r35329]
2006-09-26 04:23:32 +00:00
Ralf W. Grosse-Kunstleve
c6f2aa4ef2 new boost/python/ssize_t.hpp; avoids potential clash of Py_ssize_t typedef and PY_SSIZE_T_MIN/MAX macros with definitions from other libraries
[SVN r35325]
2006-09-26 00:25:07 +00:00
Dave Abrahams
c7fb2f7047 Attempt GCC-3.4.4 and 4.0.1 workarounds
[SVN r35276]
2006-09-22 15:12:04 +00:00
Vladimir Prus
afedc1cd9a Add tests
[SVN r35244]
2006-09-21 07:26:35 +00:00
Gottfried Ganßauge
070e02d7d5 Renamed from opaque_pointer_converter.html
[SVN r35242]
2006-09-21 07:07:14 +00:00
Dave Abrahams
ccc56c2a4c Apply Boost license, with permission from Prabhu Ramachandran.
[SVN r35240]
2006-09-21 03:43:59 +00:00
Dave Abrahams
e00a88ff49 Fix inspection issues
[SVN r35239]
2006-09-21 02:40:19 +00:00
Stefan Seefeld
e527bc860f Fix copyright issues.
[SVN r35236]
2006-09-20 22:30:39 +00:00
Dave Abrahams
921e306b9a Fix license/copyright
[SVN r35234]
2006-09-20 21:59:03 +00:00
Dave Abrahams
bed1d26904 Return an int, not a string, on success from
check_numeric_array_rich_slice, since that's what the tests expect.


[SVN r35184]
2006-09-18 22:21:50 +00:00
Dave Abrahams
41a342f026 vc6/7 workaround
[SVN r35164]
2006-09-18 18:25:12 +00:00
Dave Abrahams
cee8e07046 Checkin missing op_repr definition
[SVN r35153]
2006-09-18 02:59:31 +00:00
Dave Abrahams
0806e89964 More informative error messages
Better autoconfiguration


[SVN r35140]
2006-09-17 02:41:20 +00:00
Dave Abrahams
f5421ca6b2 Default to Python 2.4 in Unix builds
Applied contributed patches http://tinyurl.com/ndljr and
http://tinyurl.com/18r


[SVN r35138]
2006-09-16 18:43:53 +00:00
Ralf W. Grosse-Kunstleve
eea7697175 if __name__ == '__main__'
[SVN r35114]
2006-09-14 21:57:56 +00:00
Ralf W. Grosse-Kunstleve
777ce7b561 magic coding: iso-latin1 comment added to avoid Python SyntaxError
[SVN r35113]
2006-09-14 21:53:00 +00:00
Gottfried Ganßauge
864ece5539 cross module compatibility test for opaque
[SVN r35111]
2006-09-14 19:06:33 +00:00
Gottfried Ganßauge
2610eb9acb Type object for opaque initialized with PyType_Clear.
opaque is registered only if not another module has already registered
a conversion for that pointer type.
Doc update.


[SVN r35104]
2006-09-14 05:59:29 +00:00
Dave Abrahams
567a2c7b89 attempt unverified workaround for http://tinyurl.com/gvrgd
[SVN r35103]
2006-09-13 22:47:11 +00:00
Dave Abrahams
05070faf12 Attempt to capture better debugging info in output
[SVN r35079]
2006-09-12 23:58:40 +00:00
Dave Abrahams
ad8069314d Move definition of BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION back
where it belongs.


[SVN r35076]
2006-09-12 22:37:09 +00:00
Dave Abrahams
9366c48351 add missing license/copyright info
[SVN r35068]
2006-09-11 22:08:18 +00:00
Dave Abrahams
5a14319753 SunPro workarounds
[SVN r35067]
2006-09-11 10:38:14 +00:00
Joel de Guzman
279a4f7888 Update
[SVN r35006]
2006-08-31 06:01:57 +00:00
Dave Abrahams
d3418d494c Restort BOOST_PYTHON_STATIC_LIB. We don't want to create exported symbols.
[SVN r34942]
2006-08-24 19:03:35 +00:00
Dave Abrahams
c839427246 Sun workaround
[SVN r34939]
2006-08-24 13:04:59 +00:00
Dave Abrahams
dd3a136b18 Attempted Sun workaround
[SVN r34914]
2006-08-22 11:50:35 +00:00
Dave Abrahams
48696918de Try not specifying static link, to see if it makes Darwin happy
[SVN r34871]
2006-08-11 15:50:21 +00:00
Dave Abrahams
88be35ddc2 Attempt Sun-5.8 workaround
[SVN r34864]
2006-08-11 00:47:48 +00:00
Gennaro Prota
9ee0d36a1d removed tabs (inspect tool)
[SVN r34722]
2006-07-24 22:25:35 +00:00
Gennaro Prota
f240e0bab6 removed tabs (inspect tool)
[SVN r34720]
2006-07-24 22:20:25 +00:00
Gennaro Prota
4081605e4b removed tabs (inspect tool)
[SVN r34719]
2006-07-24 22:14:15 +00:00
Gennaro Prota
f332ff2d89 minor fix: violation of min/max guidelines
[SVN r34717]
2006-07-24 22:04:05 +00:00
Vladimir Prus
ec77608840 Clarify comment
[SVN r34668]
2006-07-22 12:53:49 +00:00
Vladimir Prus
f5a69a1dab Windows fix: use <library>/pytho/python_for_extensions, not <use>, so that
we actually link to Python import lib on windows.


[SVN r34666]
2006-07-22 12:28:00 +00:00
Vladimir Prus
a1e865061c Don't link Boost.Python to python library, and don't require
<threading>multi for embedding applications.

* libs/python/build/Jamfile.v2: (boost_python): Don't link
  to /python//python. Use /python//python_for_extensions.

* libs/python/test/Jamfile.v2: Remove <threading>multi project
  requirements.
  (py-run): Link to /python//python.
  (exec): Likewise.

* tools/build/v2/tools/python.jam: (pthread): Declare.
  (init-unix): Add 'pthread' to extra-libs.
  (


[SVN r34662]
2006-07-22 07:12:10 +00:00
Ralf W. Grosse-Kunstleve
596e92404a old misunderstanding corrected (L-BFGS)
[SVN r34504]
2006-07-11 04:09:41 +00:00
Joel de Guzman
2640f5af94 new css
[SVN r34426]
2006-06-29 09:35:52 +00:00
Joel de Guzman
0605e9fdcf minor tweak
[SVN r34375]
2006-06-22 13:43:09 +00:00
Joel de Guzman
cf68da0b19 added test for vector<string>
[SVN r34374]
2006-06-22 13:33:46 +00:00
Joel de Guzman
d3c474b295 terminology tweak
[SVN r34360]
2006-06-20 14:01:12 +00:00
Joel de Guzman
c9300e07c2 added custom converter test for map indexing suite
[SVN r34359]
2006-06-20 00:33:22 +00:00
Ralf W. Grosse-Kunstleve
cab94a7bba adjustments for new MIPSpro 7.4.4
[SVN r34132]
2006-06-02 05:39:50 +00:00
Ralf W. Grosse-Kunstleve
caa9cb8268 Python 2.5 compatibility
[SVN r34017]
2006-05-18 22:41:14 +00:00
Ralf W. Grosse-Kunstleve
66ac61450e avoid Visual C++ 7.1 "resolved overload was found by argument-dependent lookup" warning
[SVN r34016]
2006-05-18 22:09:20 +00:00
Ralf W. Grosse-Kunstleve
59f81def56 Python include must appear before any system include
[SVN r34010]
2006-05-18 18:47:12 +00:00
Ralf W. Grosse-Kunstleve
92862028b7 MIPSpro 7.3.1 compatibility
[SVN r34009]
2006-05-18 18:46:26 +00:00
Ralf W. Grosse-Kunstleve
b0ba7dfc50 also exercise OVERLOADS with docstring
[SVN r34006]
2006-05-18 16:15:59 +00:00
Ralf W. Grosse-Kunstleve
fe3abeda9f much more informative pickle error messages if pickling is not enabled
[SVN r34004]
2006-05-18 15:49:41 +00:00
Markus Schöpflin
3fdfb30e33 Include python first, fixes error on Tru64/CXX.
[SVN r33454]
2006-03-23 09:38:03 +00:00
Vladimir Prus
cdcf8633bb Force multithreading for Python test.
Workaround for problem described in
http://thread.gmane.org/gmane.comp.lib.boost.devel/139601


[SVN r33434]
2006-03-22 09:53:34 +00:00
125 changed files with 3388 additions and 1539 deletions

View File

@@ -7,26 +7,13 @@ import modules ;
import python ;
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
{
# Attempt default configuration of python
import toolset : using ;
using python ;
if ! [ python.configured ]
{
ECHO "WARNING: No python installation configured and autoconfiguration" ;
ECHO " failed. See http://www.boost.org/libs/python/doc/building.html" ;
ECHO " for configuration instructions or pass --without-python to" ;
ECHO " suppress this message and silently skip all Boost.Python targets" ;
}
}
if [ python.configured ] {
project boost/python
: source-location ../src
;
: source-location ../src
;
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
lib boost_python
: # sources
@@ -38,6 +25,7 @@ lib boost_python
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
@@ -58,6 +46,7 @@ lib boost_python
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
@@ -74,19 +63,16 @@ lib boost_python
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
<library>/python//python_for_extensions
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<link>shared:<define>BOOST_PYTHON_DYNAMIC_LIB
;
}
else
{
ECHO "warning: Python location is not configured" ;
ECHO "warning: the Boost.Python library won't be built" ;
}

View File

@@ -95,6 +95,10 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\src\aix_init_module.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\arg_to_python_base.cpp
# End Source File
# Begin Source File
@@ -210,6 +214,10 @@ SOURCE=..\..\src\exec.cpp
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp
# End Source File
# Begin Source File

View File

@@ -9,63 +9,60 @@
</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" href="../index.htm"><img alt="Boost C++ Libraries:" class="boost-logo" src="../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at -->
<!-- http://www.boost.org/LICENSE_1_0.txt) -->
<div class="contents sidebar small topic" id="contents">
<p class="topic-title first">Contents</p>
<div class="contents sidebar small topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference internal" href="#requirements" id="id25">1&nbsp;&nbsp;&nbsp;Requirements</a></li>
<li><a class="reference internal" href="#background" id="id26">2&nbsp;&nbsp;&nbsp;Background</a></li>
<li><a class="reference internal" href="#no-install-quickstart" id="id27">3&nbsp;&nbsp;&nbsp;No-Install Quickstart</a><ul class="auto-toc">
<li><a class="reference internal" href="#basic-procedure" id="id28">3.1&nbsp;&nbsp;&nbsp;Basic Procedure</a></li>
<li><a class="reference internal" href="#in-case-of-trouble" id="id29">3.2&nbsp;&nbsp;&nbsp;In Case of Trouble</a></li>
<li><a class="reference internal" href="#in-case-everything-seemed-to-work" id="id30">3.3&nbsp;&nbsp;&nbsp;In Case Everything Seemed to Work</a></li>
<li><a class="reference internal" href="#modifying-the-example-project" id="id31">3.4&nbsp;&nbsp;&nbsp;Modifying the Example Project</a></li>
<li><a class="reference" href="#requirements" id="id20" name="id20">1&nbsp;&nbsp;&nbsp;Requirements</a></li>
<li><a class="reference" href="#background" id="id21" name="id21">2&nbsp;&nbsp;&nbsp;Background</a></li>
<li><a class="reference" href="#getting-boost-python-binaries" id="id22" name="id22">3&nbsp;&nbsp;&nbsp;Getting Boost.Python Binaries</a><ul class="auto-toc">
<li><a class="reference" href="#no-install-quickstart" id="id23" name="id23">3.1&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></li>
<li><a class="reference" href="#installing-boost-python-on-your-system" id="id24" name="id24">3.2&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></li>
</ul>
</li>
<li><a class="reference internal" href="#installing-boost-python-on-your-system" id="id32">4&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></li>
<li><a class="reference internal" href="#configuring-boost-build" id="id33">5&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a><ul class="auto-toc">
<li><a class="reference internal" href="#python-configuration-parameters" id="id34">5.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></li>
<li><a class="reference internal" href="#examples" id="id35">5.2&nbsp;&nbsp;&nbsp;Examples</a></li>
<li><a class="reference" href="#configuring-boost-build" id="id25" name="id25">4&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></li>
<li><a class="reference" href="#building-an-extension-module" id="id26" name="id26">5&nbsp;&nbsp;&nbsp;Building an Extension Module</a></li>
<li><a class="reference" href="#testing" id="id27" name="id27">6&nbsp;&nbsp;&nbsp;Testing</a></li>
<li><a class="reference" href="#advanced-configuration" id="id28" name="id28">7&nbsp;&nbsp;&nbsp;Advanced Configuration</a><ul class="auto-toc">
<li><a class="reference" href="#python-configuration-parameters" id="id29" name="id29">7.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></li>
<li><a class="reference" href="#examples" id="id30" name="id30">7.2&nbsp;&nbsp;&nbsp;Examples</a></li>
</ul>
</li>
<li><a class="reference internal" href="#choosing-a-boost-python-library-binary" id="id36">6&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a><ul class="auto-toc">
<li><a class="reference internal" href="#the-dynamic-binary" id="id37">6.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></li>
<li><a class="reference internal" href="#the-static-binary" id="id38">6.2&nbsp;&nbsp;&nbsp;The Static Binary</a></li>
<li><a class="reference" href="#choosing-a-boost-python-library-binary" id="id31" name="id31">8&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a><ul class="auto-toc">
<li><a class="reference" href="#the-dynamic-binary" id="id32" name="id32">8.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></li>
<li><a class="reference" href="#the-static-binary" id="id33" name="id33">8.2&nbsp;&nbsp;&nbsp;The Static Binary</a></li>
</ul>
</li>
<li><a class="reference internal" href="#include-issues" id="id39">7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></li>
<li><a class="reference internal" href="#python-debugging-builds" id="id40">8&nbsp;&nbsp;&nbsp;Python Debugging Builds</a></li>
<li><a class="reference internal" href="#testing-boost-python" id="id41">9&nbsp;&nbsp;&nbsp;Testing Boost.Python</a></li>
<li><a class="reference internal" href="#notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" id="id42">10&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></li>
<li><a class="reference" href="#notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" id="id34" name="id34">9&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></li>
</ul>
</div>
<div class="section" id="requirements">
<h1><a class="toc-backref" href="#id25">1&nbsp;&nbsp;&nbsp;Requirements</a></h1>
<p>Boost.Python requires <a class="reference external" href="http://www.python.org/2.2">Python 2.2</a><a class="footnote-reference" href="#id22" id="id2"><sup>1</sup></a> <em>or</em> <a class="reference external" href="http://www.python.org"><em>newer</em></a>.</p>
<div class="section">
<h1><a class="toc-backref" href="#id20" id="requirements" name="requirements">1&nbsp;&nbsp;&nbsp;Requirements</a></h1>
<p>Boost.Python requires <a class="reference" href="http://www.python.org/2.2">Python 2.2</a><a class="footnote-reference" href="#id16" id="id2" name="id2"><sup>1</sup></a> <em>or</em> <a class="reference" href="http://www.python.org"><em>newer</em></a>.</p>
</div>
<div class="section" id="background">
<h1><a class="toc-backref" href="#id26">2&nbsp;&nbsp;&nbsp;Background</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id21" id="background" name="background">2&nbsp;&nbsp;&nbsp;Background</a></h1>
<p>There are two basic models for combining C++ and Python:</p>
<ul class="simple">
<li><a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a>, in which the end-user launches the Python interpreter
<li><a class="reference" href="http://www.python.org/doc/current/ext/intro.html">extending</a>, in which the end-user launches the Python interpreter
executable and imports Python “extension modules” written in C++.
Think of taking a library written in C++ and giving it a Python
interface so Python programmers can use it. From Python, these
modules look just like regular Python modules.</li>
<li><a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a>, in which the end-user launches a program written
<li><a class="reference" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a>, in which the end-user launches a program written
in C++ that in turn invokes the Python interpreter as a library
subroutine. Think of adding scriptability to an existing
application.</li>
</ul>
<p>The key distinction between extending and embedding is the location
of the C++ <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
of C++' <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
or in some other program, respectively. Note that even when
embedding Python in another program, <a class="reference external" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
embedding Python in another program, <a class="reference" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
the best way to make C/C++ functionality accessible to Python
code</a>, so the use of extension modules is really at the heart of
both models.</p>
@@ -74,281 +71,127 @@ dynamically-loaded libraries with a single entry point, which means
you can change them without rebuilding either the other extension
modules or the executable containing <tt class="docutils literal"><span class="pre">main()</span></tt>.</p>
</div>
<div class="section" id="no-install-quickstart">
<span id="quickstart"></span><h1><a class="toc-backref" href="#id27">3&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></h1>
<p>There is no need to “install Boost” in order to get started using
Boost.Python. These instructions use <a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> projects,
<div class="section">
<h1><a class="toc-backref" href="#id22" id="getting-boost-python-binaries" name="getting-boost-python-binaries">3&nbsp;&nbsp;&nbsp;Getting Boost.Python Binaries</a></h1>
<p>Since Boost.Python is a separately-compiled (as opposed to
<a class="reference" href="../../../more/getting_started/windows.html#header-only-libraries">header-only</a>) library, its user relies on the services of a
Boost.Python library binary.</p>
<div class="section">
<h2><a class="toc-backref" href="#id23" id="no-install-quickstart" name="no-install-quickstart">3.1&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></h2>
<p>If you just want to get started quickly building and testing
Boost.Python extension modules, or embedding Python in an
executable, you don't need to worry about installing Boost.Python
binaries explicitly. These instructions use <a class="reference" href="../../../tools/build">Boost.Build</a> projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration and figuring out the right
compiler options to use yourself.</p>
<!-- .. raw:: html
<div style="width:50%"> -->
for a specific compiler configuration.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p>Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost. Moreover <strong>99% of all “I can't
build Boost.Python” problems come from trying to use another
build system</strong> without first following these instructions.</p>
<p>If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> with the</p>
<pre class="literal-block">
<tt class="docutils literal"><span class="pre">-a</span> <span class="pre">-o</span></tt><em>filename</em>
</pre>
<p class="last">options to dump the build commands it executes to a file, so
you can see what your alternate build system needs to do.</p>
</div>
<!-- .. raw:: html
</div> -->
<div class="section" id="basic-procedure">
<h2><a class="toc-backref" href="#id28">3.1&nbsp;&nbsp;&nbsp;Basic Procedure</a></h2>
<ol class="arabic">
<li><p class="first">Get Boost; see sections 1 and 2 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#get-boost">Unix/Linux</a>, <a class="reference external" href="../../../more/getting_started/windows.html#get-boost">Windows</a>] of the
Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
</li>
<li><p class="first">Get the <tt class="docutils literal"><span class="pre">bjam</span></tt> build driver. See section 5 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary">Unix/Linux</a>,
<a class="reference external" href="../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary">Windows</a>] of the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
</li>
<li><p class="first">cd into the <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory of your
Boost installation, which contains a small example project.</p>
</li>
<li><p class="first">Invoke <tt class="docutils literal"><span class="pre">bjam</span></tt>. Replace the “<tt class="docutils literal"><span class="pre">stage</span></tt>“ argument from the
example invocation from section 5 of the <a class="reference external" href="../../../more/getting_started/index.html">Getting Started
Guide</a> with “<tt class="docutils literal"><span class="pre">test</span></tt>,“ to build all the test targets. Also add
the argument “<tt class="docutils literal"><span class="pre">--verbose-test</span></tt>” to see the output generated by
the tests when they are run.</p>
<p>On Windows, your <tt class="docutils literal"><span class="pre">bjam</span></tt> invocation might look something like:</p>
<pre class="literal-block">
C:\boost_1_34_0\…\quickstart&gt; <strong>bjam toolset=msvc --verbose-test test</strong>
</pre>
<p>and on Unix variants, perhaps,</p>
<pre class="literal-block">
~/boost_1_34_0/…/quickstart$ <strong>bjam toolset=gcc --verbose-test test</strong>
</pre>
</li>
</ol>
<div class="admonition-note-to-windows-users admonition">
<p class="first admonition-title">Note to Windows Users</p>
<p class="last">For the sake of concision, the rest of this guide will use
unix-style forward slashes in pathnames instead of the
backslashes with which you may be more familiar. The forward
slashes should work everywhere except in <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">Command Prompt</a>
windows, where you should use backslashes.</p>
</div>
<p>If you followed this procedure successfully, you will have built an
extension module called <tt class="docutils literal"><span class="pre">extending</span></tt> and tested it by running a
Python script called <tt class="docutils literal"><span class="pre">test_extending.py</span></tt>. You will also have
built and run a simple application called <tt class="docutils literal"><span class="pre">embedding</span></tt> that embeds
python.</p>
</div>
<div class="section" id="in-case-of-trouble">
<h2><a class="toc-backref" href="#id29">3.2&nbsp;&nbsp;&nbsp;In Case of Trouble</a></h2>
<p>If you're seeing lots of compiler and/or linker error messages,
it's probably because Boost.Build is having trouble finding your
Python installation. You might want to pass the
<tt class="docutils literal"><span class="pre">--debug-configuration</span></tt> option to <tt class="docutils literal"><span class="pre">bjam</span></tt> the first few times
you invoke it, to make sure that Boost.Build is correctly locating
all the parts of your Python installation. If it isn't, consider
<a class="reference internal" href="#configuring-boost-build">Configuring Boost.Build</a> as detailed below.</p>
<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="../../../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="../../../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">
<h2><a class="toc-backref" href="#id30">3.3&nbsp;&nbsp;&nbsp;In Case Everything Seemed to Work</a></h2>
<p>Rejoice! If you're new to Boost.Python, at this point it might be
a good idea to ignore build issues for a while and concentrate on
learning the library by going through the <a class="reference external" href="tutorial/index.html">tutorial</a> and perhaps
some of the <a class="reference external" href="v2/reference.html">reference documentation</a>, trying out what you've
learned about the API by modifying the quickstart project.</p>
</div>
<div class="section" id="modifying-the-example-project">
<h2><a class="toc-backref" href="#id31">3.4&nbsp;&nbsp;&nbsp;Modifying the Example Project</a></h2>
<p>If you're content to keep your extension module forever in one
source file called <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>, inside your Boost
distribution, and import it forever as <tt class="docutils literal"><span class="pre">extending</span></tt>, then you can
stop here. However, it's likely that you will want to make a few
changes. There are a few things you can do without having to learn
<a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> in depth.</p>
<p>The project you just built is specified in two files in the current
directory: <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a>, which tells <tt class="docutils literal"><span class="pre">bjam</span></tt> where it can
find the interpreted code of the Boost build system, and
<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, which describes the targets you just built. These
files are heavily commented, so they should be easy to modify.
Take care, however, to preserve whitespace. Punctuation such as
<tt class="docutils literal"><span class="pre">;</span></tt> will not be recognized as intended by <tt class="docutils literal"><span class="pre">bjam</span></tt> if it is not
surrounded by whitespace.</p>
<div class="section" id="relocate-the-project">
<h3>Relocate the Project</h3>
<p>You'll probably want to copy this project elsewhere so you can
change it without modifying your Boost distribution. To do that,
simply</p>
<ol class="loweralpha simple">
<li>copy the entire <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory
into a new directory.</li>
<li>In the new copies of <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> and <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, locate
the relative path near the top of the file that is clearly
marked by a comment, and edit that path so that it refers to the
same directory your Boost distribution as it referred to when
the file was in its original location in the
<tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory.</li>
</ol>
<p>For example, if you moved the project from
<tt class="docutils literal"><span class="pre">/home/dave/boost_1_34_0/libs/python/example/quickstart</span></tt> to
<tt class="docutils literal"><span class="pre">/home/dave/my-project</span></tt>, you could change the first path in
<a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> from</p>
<pre class="literal-block">
<strong>../../../..</strong>/tools/build/v2
</pre>
<p>to</p>
<pre class="literal-block">
<strong>/home/dave/boost_1_34_0</strong>/tools/build/v2
</pre>
<p>and change the first path in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> from</p>
<pre class="literal-block">
<strong>../../../..</strong>
</pre>
<p>to</p>
<pre class="literal-block">
<strong>/home/dave/boost_1_34_0</strong>
</pre>
</div>
<div class="section" id="add-new-or-change-names-of-existing-source-files">
<h3>Add New or Change Names of Existing Source Files</h3>
<p>The names of additional source files involved in building your
extension module or embedding application can be listed in
<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> right alongside <tt class="docutils literal"><span class="pre">extending.cpp</span></tt> or <tt class="docutils literal"><span class="pre">embedding.cpp</span></tt>
respectively. Just be sure to leave whitespace around each
filename:</p>
<pre class="literal-block">
… file1.cpp file2.cpp file3.cpp …
</pre>
<p>Naturally, if you want to change the name of a source file you can
tell Boost.Build about it by editing the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>.</p>
</div>
<div class="section" id="change-the-name-of-your-extension-module">
<h3>Change the Name of your Extension Module</h3>
<p>The name of the extension module is determined by two things:</p>
<ol class="arabic simple">
<li>the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> immediately following <tt class="docutils literal"><span class="pre">python-extension</span></tt>, and</li>
<li>the name passed to <tt class="docutils literal"><span class="pre">BOOST_PYTHON_MODULE</span></tt> in <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>.</li>
</ol>
<p>To change the name of the extension module from <tt class="docutils literal"><span class="pre">extending</span></tt> to
<tt class="docutils literal"><span class="pre">hello</span></tt>, you'd edit <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, changing</p>
<pre class="literal-block">
python-extension <strong>extending</strong> : extending.cpp ;
</pre>
<p>to</p>
<pre class="literal-block">
python-extension <strong>hello</strong> : extending.cpp ;
</pre>
<p>and you'd edit extending.cpp, changing</p>
<pre class="literal-block">
BOOST_PYTHON_MODULE(<strong>extending</strong>)
</pre>
<p>to</p>
<pre class="literal-block">
BOOST_PYTHON_MODULE(<strong>hello</strong>)
</pre>
officially supported by Boost and <strong>99% of all “I can't build
Boost.Python” problems come from trying to use another build
system</strong>.</p>
<p class="last">If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> with the
<tt class="docutils literal"><span class="pre">-a</span> <span class="pre">-o</span></tt><em>filename</em> option to dump the build commands it executes
to a file, so you can see what your build system needs to do.</p>
</div>
</div>
</div>
<div class="section" id="installing-boost-python-on-your-system">
<h1><a class="toc-backref" href="#id32">4&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></h1>
<p>Since Boost.Python is a separately-compiled (as opposed to
<a class="reference external" href="../../../more/getting_started/windows.html#header-only-libraries">header-only</a>) library, its user relies on the services of a
Boost.Python library binary.</p>
<p>If you need a regular installation of the Boost.Python library
binaries on your system, the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a> will
walk you through the steps of creating one. If building binaries
<div class="section">
<h2><a class="toc-backref" href="#id24" id="installing-boost-python-on-your-system" name="installing-boost-python-on-your-system">3.2&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></h2>
<p>If you need a regular, installation of the Boost.Python library
binaries on your system, the Boost <a class="reference" href="../../../more/getting_started/index.html">Getting Started Guide</a> will
walk you through the steps of installing one. If building binaries
from source, you might want to supply the <tt class="docutils literal"><span class="pre">--with-python</span></tt>
argument to <tt class="docutils literal"><span class="pre">bjam</span></tt> (or the <tt class="docutils literal"><span class="pre">--with-libraries=python</span></tt> argument
to <tt class="docutils literal"><span class="pre">configure</span></tt>), so only the Boost.Python binary will be built,
rather than all the Boost binaries.</p>
</div>
<div class="section" id="configuring-boost-build">
<h1><a class="toc-backref" href="#id33">5&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></h1>
<p>As described in the <a class="reference external" href="http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration">Boost.Build reference manual</a>, a file called
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory<a class="footnote-reference" href="#home-dir" id="id11"><sup>6</sup></a> is used to
specify the tools and libraries available to the build system. You
may need to create or edit <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> to tell Boost.Build
how to invoke Python, <tt class="docutils literal"><span class="pre">#include</span></tt> its headers, and link with its
libraries.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id25" id="configuring-boost-build" name="configuring-boost-build">4&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></h1>
<p>As described in the <a class="reference" href="http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration">Boost.Build reference manual</a>, a file called
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home
directory<a class="footnote-reference" href="#home-dir" id="id5" name="id5"><sup>7</sup></a> is used to
describe the build resources available to the build system. You'll
need to tell it about your Python installation.</p>
<div class="admonition-users-of-unix-variant-oses admonition">
<p class="first admonition-title">Users of Unix-Variant OSes</p>
<p class="last">If you are using a unix-variant OS and you ran Boost's
<tt class="docutils literal"><span class="pre">configure</span></tt> script, it may have generated a
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> for you.<a class="footnote-reference" href="#overwrite" id="id13"><sup>4</sup></a> If your <tt class="docutils literal"><span class="pre">configure</span></tt>/<tt class="docutils literal"><span class="pre">make</span></tt> sequence was successful and Boost.Python binaries
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> for you.<a class="footnote-reference" href="#overwrite" id="id7" name="id7"><sup>4</sup></a> If your <tt class="docutils literal"><span class="pre">configure</span></tt>/<tt class="docutils literal"><span class="pre">make</span></tt> sequence was successful and Boost.Python binaries
were built, your <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file is probably already
correct.</p>
</div>
<p>If you have one fairly “standard” python installation for your
platform, you might not need to do anything special to describe it. If
you haven't configured python in <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> (and you don't
specify <tt class="docutils literal"><span class="pre">--without-python</span></tt> on the Boost.Build command line),
Boost.Build will automatically execute the equivalent of</p>
<p>If you have a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having</p>
<pre class="literal-block">
import toolset : using ;
using python ;
</pre>
<p>which automatically looks for Python in the most likely places.
However, that only happens when using the Boost.Python project file
(e.g. when referred to by another project as in the <a class="reference internal" href="#quickstart">quickstart</a>
method). If instead you are linking against separately-compiled
Boost.Python binaries, you should set up a <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file
with at least the minimal incantation above.</p>
<div class="section" id="python-configuration-parameters">
<h2><a class="toc-backref" href="#id34">5.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></h2>
<p>in a <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file in your home directory<a class="footnote-reference" href="#home-dir" id="id8" name="id8"><sup>7</sup></a>
should be enough.<a class="footnote-reference" href="#user-config-jam" id="id9" name="id9"><sup>6</sup></a> For more complicated setups,
see <a class="reference" href="#advanced-configuration">Advanced Configuration</a>.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">You might want to pass the <tt class="docutils literal"><span class="pre">--debug-configuration</span></tt>
option to <tt class="docutils literal"><span class="pre">bjam</span></tt> the first few times you invoke it, to make
sure that Boost.Build is correctly locating all the parts of
your Python installation. If it isn't, consider passing some of
the optional <a class="reference" href="#python-configuration-parameters">Python configuration parameters</a> detailed below.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id26" id="building-an-extension-module" name="building-an-extension-module">5&nbsp;&nbsp;&nbsp;Building an Extension Module</a></h1>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id27" id="testing" name="testing">6&nbsp;&nbsp;&nbsp;Testing</a></h1>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id28" id="advanced-configuration" name="advanced-configuration">7&nbsp;&nbsp;&nbsp;Advanced Configuration</a></h1>
<p>If you have several versions of Python installed, or Python is
installed in an unusual way, you may want to supply any or all of
the following optional parameters to <tt class="docutils literal"><span class="pre">using</span> <span class="pre">python</span></tt>.</p>
<div class="section">
<h2><a class="toc-backref" href="#id29" id="python-configuration-parameters" name="python-configuration-parameters">7.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></h2>
<dl class="docutils">
<dt>version</dt>
<dd>the version of Python to use. Should be in Major.Minor
format, for example, <tt class="docutils literal"><span class="pre">2.3</span></tt>. Do not include the subminor
version (i.e. <em>not</em> <tt class="docutils literal"><span class="pre">2.5.1</span></tt>). If you have multiple Python
versions installed, the version will usually be the only
configuration argument required.</dd>
additional argument required.</dd>
<dt>cmd-or-prefix</dt>
<dd>preferably, a command that invokes a Python interpreter.
Alternatively, the installation prefix for Python libraries and
header files. Only use the alternative formulation if there is
no appropriate Python executable available.</dd>
<dd>preferably, a command that invokes a Python
interpreter. Alternatively, the installation prefix for Python
libraries and header files. Use the alternative formulation if
there is no appropriate Python executable available.</dd>
<dt>includes</dt>
<dd>the <tt class="docutils literal"><span class="pre">#include</span></tt> paths for Python headers. Normally the correct
path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt> and/or
<tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
<dd>the <tt class="docutils literal"><span class="pre">#include</span></tt> path for Python headers.</dd>
<dt>libraries</dt>
<dd>the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework. Normally the
correct path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt>
and/or <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
you can also pass the path of the Python framework.</dd>
<dt>condition</dt>
<dd>if specified, should be a set of Boost.Build
properties that are matched against the build configuration when
Boost.Build selects a Python configuration to use. See examples
below for details.</dd>
Boost.Build selects a Python configuration to use.</dd>
<dt>extension-suffix</dt>
<dd>A string to append to the name of extension
modules before the true filename extension. You almost certainly
don't need to use this. Usually this suffix is only used when
targeting a Windows debug build of Python, and will be set
automatically for you based on the value of the
<a class="reference internal" href="#python-debugging"><tt class="docutils literal"><span class="pre">&lt;python-debugging&gt;</span></tt></a> feature. However, at least one Linux
<tt class="docutils literal"><span class="pre">&lt;python-debugging&gt;</span></tt> feature. However, at least one Linux
distribution (Ubuntu Feisty Fawn) has a specially configured
<a class="reference external" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
<a class="reference" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
</dl>
</div>
<div class="section" id="examples">
<h2><a class="toc-backref" href="#id35">5.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id30" id="examples" name="examples">7.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
<p>Note that in the examples below, case and <em>especially whitespace</em> are
significant.</p>
<ul>
@@ -386,19 +229,8 @@ using python
;
</pre>
</li>
<li><p class="first">If you have downloaded the Python sources and built both the
normal and the “<a class="reference internal" href="#id19">python debugging</a>” builds from source on
Windows, you might see:</p>
<pre class="literal-block">
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
: # includes
: # libs
: &lt;python-debugging&gt;on ;
</pre>
</li>
<li><p class="first">You can set up your user-config.jam so a bjam built under Windows
can build/test both Windows and <a class="reference external" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
can build/test both Windows and <a class="reference" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
<tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> in the <tt class="docutils literal"><span class="pre">condition</span></tt> parameter
for the cygwin python installation:</p>
<pre class="literal-block">
@@ -409,16 +241,16 @@ using python ;
using python : : c:\\cygwin\\bin\\python2.5 : : : &lt;target-os&gt;cygwin ;
</pre>
<p>when you put target-os=cygwin in your build request, it should build
with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id15"><sup>5</sup></a></p>
with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id11" name="id11"><sup>5</sup></a></p>
<blockquote>
<p>bjam target-os=cygwin toolset=gcc</p>
</blockquote>
<p>This is supposed to work the other way, too (targeting windows
python with a <a class="reference external" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
python with a <a class="reference" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
Boost.Build's toolsets for building that way is broken at the
time of this writing.</p>
</li>
<li><p class="first">Note that because of <a class="reference external" href="http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection">the way Boost.Build currently selects target
<li><p class="first">Note that because of <a class="reference" href="http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection">the way Boost.Build currently selects target
alternatives</a>, you might have be very explicit in your build
requests. For example, given:</p>
<pre class="literal-block">
@@ -437,35 +269,35 @@ bjam target-os=cygwin/python=2.4
</ul>
</div>
</div>
<div class="section" id="choosing-a-boost-python-library-binary">
<h1><a class="toc-backref" href="#id36">6&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a></h1>
<p>If—instead of letting Boost.Build construct and link with the right
<div class="section">
<h1><a class="toc-backref" href="#id31" id="choosing-a-boost-python-library-binary" name="choosing-a-boost-python-library-binary">8&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a></h1>
<p>If—instead of letting Boost.Build construct and link withthe right
libraries automatically—you choose to use a pre-built Boost.Python
library, you'll need to think about which one to link with. The
Boost.Python binary comes in both static and dynamic flavors. Take
care to choose the right flavor for your application.<a class="footnote-reference" href="#naming" id="id17"><sup>2</sup></a></p>
<div class="section" id="the-dynamic-binary">
<h2><a class="toc-backref" href="#id37">6.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></h2>
care to choose the right flavor for your application.<a class="footnote-reference" href="#naming" id="id13" name="id13"><sup>2</sup></a></p>
<div class="section">
<h2><a class="toc-backref" href="#id32" id="the-dynamic-binary" name="the-dynamic-binary">8.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></h2>
<p>The dynamic library is the safest and most-versatile choice:</p>
<ul class="simple">
<li>A single copy of the library code is used by all extension
modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id18"><sup>3</sup></a></li>
modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id14" name="id14"><sup>3</sup></a></li>
<li>The library contains a type conversion registry. Because one
registry is shared among all extension modules, instances of a
class exposed to Python in one dynamically-loaded extension
module can be passed to functions exposed in another such module.</li>
</ul>
</div>
<div class="section" id="the-static-binary">
<h2><a class="toc-backref" href="#id38">6.2&nbsp;&nbsp;&nbsp;The Static Binary</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id33" id="the-static-binary" name="the-static-binary">8.2&nbsp;&nbsp;&nbsp;The Static Binary</a></h2>
<p>It might be appropriate to use the static Boost.Python library in
any of the following cases:</p>
<ul class="simple">
<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a> python and the types exposed in your
<li>You are <a class="reference" href="http://www.python.org/doc/current/ext/intro.html">extending</a> python and the types exposed in your
dynamically-loaded extension module don't need to be used by any
other Boost.Python extension modules, and you don't care if the
core library code is duplicated among them.</li>
<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a> python in your application and either:<ul>
<li>You are <a class="reference" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a> python in your application and either:<ul>
<li>You are targeting a Unix variant OS other than MacOS or AIX,
where the dynamically-loaded extension modules can “see” the
Boost.Python library symbols that are part of the executable.</li>
@@ -479,73 +311,22 @@ modules (and vice-versa).</li>
</ul>
</div>
</div>
<div class="section" id="include-issues">
<h1><a class="toc-backref" href="#id39">7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></h1>
<ol class="arabic simple">
<li>If you should ever have occasion to <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">&quot;python.h&quot;</span></tt>
directly in a translation unit of a program using Boost.Python,
use <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">&quot;boost/python/detail/wrap_python.hpp&quot;</span></tt> instead.
It handles several issues necessary for use with Boost.Python,
one of which is mentioned in the next section.</li>
<li>Be sure not to <tt class="docutils literal"><span class="pre">#include</span></tt> any system headers before
<tt class="docutils literal"><span class="pre">wrap_python.hpp</span></tt>. This restriction is actually imposed by
Python, or more properly, by Python's interaction with your
operating system. See
<a class="reference external" href="http://docs.python.org/ext/simpleExample.html">http://docs.python.org/ext/simpleExample.html</a> for details.</li>
</ol>
</div>
<div class="section" id="python-debugging-builds">
<span id="id19"></span><span id="python-debugging"></span><h1><a class="toc-backref" href="#id40">8&nbsp;&nbsp;&nbsp;Python Debugging Builds</a></h1>
<p>Python can be built in a special “python debugging” configuration
that adds extra checks and instrumentation that can be very useful
for developers of extension modules. The data structures used by
the debugging configuration contain additional members, so <strong>a
Python executable built with python debugging enabled cannot be
used with an extension module or library compiled without it, and
vice-versa.</strong></p>
<p>Since pre-built “python debugging” versions of the Python
executable and libraries are not supplied with most distributions
of Python,<a class="footnote-reference" href="#get-debug-build" id="id20"><sup>7</sup></a> and we didn't want to force our users
to build them, Boost.Build does not automatically enable python
debugging in its <tt class="docutils literal"><span class="pre">debug</span></tt> build variant (which is the default).
Instead there is a special build property called
<tt class="docutils literal"><span class="pre">python-debugging</span></tt> that, when used as a build property, will
define the right preprocessor symbols and select the right
libraries to link with.</p>
<p>On unix-variant platforms, the debugging versions of Python's data
structures will only be used if the symbol <tt class="docutils literal"><span class="pre">Py_DEBUG</span></tt> is defined.
On many windows compilers, when extension modules are built with
the preprocessor symbol <tt class="docutils literal"><span class="pre">_DEBUG</span></tt>, Python defaults to force
linking with a special debugging version of the Python DLL. Since
that symbol is very commonly used even when Python is not present,
Boost.Python temporarily undefines _DEBUG when Python.h
is #included from <tt class="docutils literal"><span class="pre">boost/python/detail/wrap_python.hpp</span></tt> - unless
<tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined. The upshot is that if you want
“python debugging”and you aren't using Boost.Build, you should make
sure <tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined, or python debugging will be
suppressed.</p>
</div>
<div class="section" id="testing-boost-python">
<h1><a class="toc-backref" href="#id41">9&nbsp;&nbsp;&nbsp;Testing Boost.Python</a></h1>
<p>To run the full test suite for Boost.Python, invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> in the
<tt class="docutils literal"><span class="pre">libs/python/test</span></tt> subdirectory of your Boost distribution.</p>
</div>
<div class="section" id="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users">
<h1><a class="toc-backref" href="#id42">10&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id34" id="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" name="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users">9&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></h1>
<p>If you are using a version of Python prior to 2.4.1 with a MinGW
prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need to
create a MinGW-compatible version of the Python library; the one
shipped with Python will only work with a Microsoft-compatible
linker. Follow the instructions in the “Non-Microsoft” section of
the “Building Extensions: Tips And Tricks” chapter in <a class="reference external" href="http://www.python.org/doc/current/inst/index.html">Installing
the “Building Extensions: Tips And Tricks” chapter in <a class="reference" href="http://www.python.org/doc/current/inst/index.html">Installing
Python Modules</a> to create <tt class="docutils literal"><span class="pre">libpythonXX.a</span></tt>, where <tt class="docutils literal"><span class="pre">XX</span></tt>
corresponds to the major and minor version numbers of your Python
installation.</p>
<hr class="docutils" />
<table class="docutils footnote" frame="void" id="id22" rules="none">
<table class="docutils footnote" frame="void" id="id16" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>Note that although we tested earlier versions of
<tr><td class="label"><a class="fn-backref" href="#id2" name="id16">[1]</a></td><td>Note that although we tested earlier versions of
Boost.Python with Python 2.2, and we don't <em>think</em> we've done
anything to break compatibility, this release of Boost.Python
may not have been tested with versions of Python earlier than
@@ -556,21 +337,24 @@ supported.</td></tr>
<table class="docutils footnote" frame="void" id="naming" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id17">[2]</a></td><td><p class="first">Information about how to identify the
<tr><td class="label"><a class="fn-backref" href="#id13" name="naming">[2]</a></td><td><p class="first">Information about how to identify the
static and dynamic builds of Boost.Python:</p>
<ul class="simple">
<li><a class="reference external" href="../../../more/getting_started/windows.html#library-naming">on Windows</a></li>
<li><a class="reference external" href="../../../more/getting_started/unix-variants.html#library-naming">on Unix variants</a></li>
<li><a class="reference" href="../../../more/getting_started/windows.html#library-naming">on Windows</a></li>
<li><a class="reference" href="../../../more/getting_started/unix-variants.html#library-naming">on Unix variants</a></li>
</ul>
<p class="last">Be sure to read this section even if your compiler supports
auto-linking, as Boost.Python does not yet take advantage of
that feature.</p>
</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="toolset-specific" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id18">[3]</a></td><td>Because of the way most *nix platforms
share symbols among dynamically-loaded objects, I'm not certain
that extension modules built with different compiler toolsets
<tr><td class="label"><a class="fn-backref" href="#id14" name="toolset-specific">[3]</a></td><td>Because of the way most *nix platforms
share symbols among dynamically-loaded objects, I'm not
certainextension modules built with different compiler toolsets
will always use different copies of the Boost.Python library
when loaded into the same Python instance. Not using different
libraries could be a good thing if the compilers have compatible
@@ -585,7 +369,7 @@ happens.</td></tr>
<table class="docutils footnote" frame="void" id="overwrite" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id13">[4]</a></td><td><tt class="docutils literal"><span class="pre">configure</span></tt> overwrites the existing
<tr><td class="label"><a class="fn-backref" href="#id7" name="overwrite">[4]</a></td><td><tt class="docutils literal"><span class="pre">configure</span></tt> overwrites the existing
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory
(if any) after making a backup of the old version.</td></tr>
</tbody>
@@ -593,43 +377,38 @@ happens.</td></tr>
<table class="docutils footnote" frame="void" id="flavor" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id15">[5]</a></td><td>Note that the <tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> feature is
<tr><td class="label"><a class="fn-backref" href="#id11" name="flavor">[5]</a></td><td>Note that the <tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> feature is
different from the <tt class="docutils literal"><span class="pre">&lt;flavor&gt;cygwin</span></tt> subfeature of the <tt class="docutils literal"><span class="pre">gcc</span></tt>
toolset, and you might need handle both explicitly if you also
have a MinGW GCC installed.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="user-config-jam" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id9" name="user-config-jam">[6]</a></td><td>Create the <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file if you don't
already have one.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="home-dir" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id11">[6]</a></td><td><p class="first">Windows users, your home directory can be
<tr><td class="label"><a name="home-dir">[7]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id8">2</a>)</em> <p>Windows users, your home directory can be
found by typing:</p>
<pre class="literal-block">
ECHO %HOMEDRIVE%%HOMEPATH%
</pre>
<p class="last">into a <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">command prompt</a> window.</p>
<p class="last">into a <a class="reference" href="../../../more/getting_started/windows.html#or-build-from-the-command-prompt">Windows command prompt</a></p>
</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="get-debug-build" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id20">[7]</a></td><td>On Unix and similar platforms, a debugging
python and associated libraries are built by adding
<tt class="docutils literal"><span class="pre">--with-pydebug</span></tt> when configuring the Python build. On
Windows, the debugging version of Python is generated by
the &quot;Win32 Debug&quot; target of the Visual Studio project in the
PCBuild subdirectory of a full Python source code distribution.
You may also find</td></tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<hr class="footer" />
<a class="reference external" href="./building.rst">View document source</a>.
Generated on: 2007-07-02 13:46 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
<a class="reference" href="./building.rst">View document source</a>.
Generated on: 2007-04-05 20:04 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>

View File

@@ -7,7 +7,7 @@
|(logo)|__ Boost.Python Build and Test HOWTO
==============================================
.. |(logo)| image:: ../../../boost.png
.. |(logo)| image:: ../boost.png
:alt: Boost C++ Libraries:
:class: boost-logo
@@ -31,6 +31,36 @@ Boost.Python requires `Python 2.2`_ [#2.2]_ *or* |newer|__.
.. _Python 2.2: http://www.python.org/2.2
__ http://www.python.org
No-Install Quickstart
=====================
There is no need to install Boost in order to get started using
Boost.Python. These instructions use Boost.Build_ projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration.
.. Note:: Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost. Moreover **99% of all “I can't
build Boost.Python” problems come from trying to use another
build system**.
If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke ``bjam`` with the
``-a -o``\ *filename* option to dump the build commands it executes
to a file, so you can see what your build system needs to do.
1. Get Boost; see sections 1 and 2 of the Boost `Getting Started Guide`_.
2. Get the ``bjam`` build driver. See sections 5.2.1-5.2.3 of the
Boost `Getting Started Guide`_.
3. cd into the ``libs/python/test/example`` directory.
.. _Getting Started Guide: ../../../more/getting_started/index.html
Background
==========
@@ -51,7 +81,7 @@ There are two basic models for combining C++ and Python:
.. _embedding: http://www.python.org/doc/current/ext/embedding.html
The key distinction between extending and embedding is the location
of the C++ ``main()`` function: in the Python interpreter executable,
of C++' ``main()`` function: in the Python interpreter executable,
or in some other program, respectively. Note that even when
embedding Python in another program, `extension modules are often
the best way to make C/C++ functionality accessible to Python
@@ -65,254 +95,8 @@ dynamically-loaded libraries with a single entry point, which means
you can change them without rebuilding either the other extension
modules or the executable containing ``main()``.
.. _quickstart:
No-Install Quickstart
=====================
There is no need to “install Boost” in order to get started using
Boost.Python. These instructions use Boost.Build_ projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration and figuring out the right
compiler options to use yourself.
.. .. raw:: html
<div style="width:50%">
.. Note:: Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost. Moreover **99% of all “I can't
build Boost.Python” problems come from trying to use another
build system** without first following these instructions.
If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke ``bjam`` with the
.. parsed-literal::
``-a -o``\ *filename*
options to dump the build commands it executes to a file, so
you can see what your alternate build system needs to do.
.. .. raw:: html
</div>
.. _Boost.Build: ../../../tools/build/index.html
Basic Procedure
---------------
1. Get Boost; see sections 1 and 2 [`Unix/Linux`__, `Windows`__\ ] of the
Boost `Getting Started Guide`_.
__ ../../../more/getting_started/unix-variants.html#get-boost
__ ../../../more/getting_started/windows.html#get-boost
2. Get the ``bjam`` build driver. See section 5 [`Unix/Linux`__,
`Windows`__\ ] of the Boost `Getting Started Guide`_.
__ ../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary
__ ../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary
3. cd into the ``libs/python/example/quickstart/`` directory of your
Boost installation, which contains a small example project.
4. Invoke ``bjam``. Replace the “\ ``stage``\ “ argument from the
example invocation from section 5 of the `Getting Started
Guide`_ with “\ ``test``\ ,“ to build all the test targets. Also add
the argument “\ ``--verbose-test``\ ” to see the output generated by
the tests when they are run.
On Windows, your ``bjam`` invocation might look something like:
.. parsed-literal::
C:\\boost_1_34_0\\…\\quickstart> **bjam toolset=msvc --verbose-test test**
and on Unix variants, perhaps,
.. parsed-literal::
~/boost_1_34_0/…/quickstart$ **bjam toolset=gcc --verbose-test test**
.. Admonition:: Note to Windows Users
For the sake of concision, the rest of this guide will use
unix-style forward slashes in pathnames instead of the
backslashes with which you may be more familiar. The forward
slashes should work everywhere except in `Command Prompt`_
windows, where you should use backslashes.
.. _Command Prompt: ../../../more/getting_started/windows.html#command-prompt
If you followed this procedure successfully, you will have built an
extension module called ``extending`` and tested it by running a
Python script called ``test_extending.py``. You will also have
built and run a simple application called ``embedding`` that embeds
python.
.. _Getting Started Guide: ../../../more/getting_started/index.html
In Case of Trouble
------------------
If you're seeing lots of compiler and/or linker error messages,
it's probably because Boost.Build is having trouble finding your
Python installation. You might want to pass the
``--debug-configuration`` option to ``bjam`` the first few times
you invoke it, to make sure that Boost.Build is correctly locating
all the parts of your Python installation. If it isn't, consider
`Configuring Boost.Build`_ as detailed below.
If you're still having trouble, Someone on one of the following
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
__ ../../../more/mailing_lists.htm#jamboost
__ ../../../more/mailing_lists.htm#cplussig
In Case Everything Seemed to Work
---------------------------------
Rejoice! If you're new to Boost.Python, at this point it might be
a good idea to ignore build issues for a while and concentrate on
learning the library by going through the tutorial_ and perhaps
some of the `reference documentation`_, trying out what you've
learned about the API by modifying the quickstart project.
.. _reference documentation: v2/reference.html
.. _tutorial: tutorial/index.html
Modifying the Example Project
-----------------------------
If you're content to keep your extension module forever in one
source file called |extending.cpp|_, inside your Boost
distribution, and import it forever as ``extending``, then you can
stop here. However, it's likely that you will want to make a few
changes. There are a few things you can do without having to learn
Boost.Build_ in depth.
The project you just built is specified in two files in the current
directory: |boost-build.jam|_, which tells ``bjam`` where it can
find the interpreted code of the Boost build system, and
|Jamroot|_, which describes the targets you just built. These
files are heavily commented, so they should be easy to modify.
Take care, however, to preserve whitespace. Punctuation such as
``;`` will not be recognized as intended by ``bjam`` if it is not
surrounded by whitespace.
.. |boost-build.jam| replace:: ``boost-build.jam``
.. _boost-build.jam: ../example/quickstart/boost-build.jam
.. |Jamroot| replace:: ``Jamroot``
.. _Jamroot: ../example/quickstart/Jamroot
.. |extending.cpp| replace:: ``extending.cpp``
.. _extending.cpp: ../example/quickstart/extending.cpp
Relocate the Project
....................
You'll probably want to copy this project elsewhere so you can
change it without modifying your Boost distribution. To do that,
simply
a. copy the entire ``libs/python/example/quickstart/`` directory
into a new directory.
b. In the new copies of |boost-build.jam|_ and |Jamroot|_, locate
the relative path near the top of the file that is clearly
marked by a comment, and edit that path so that it refers to the
same directory your Boost distribution as it referred to when
the file was in its original location in the
``libs/python/example/quickstart/`` directory.
For example, if you moved the project from
``/home/dave/boost_1_34_0/libs/python/example/quickstart`` to
``/home/dave/my-project``, you could change the first path in
|boost-build.jam|_ from
.. parsed-literal::
**../../../..**\ /tools/build/v2
to
.. parsed-literal::
**/home/dave/boost_1_34_0**\ /tools/build/v2
and change the first path in |Jamroot|_ from
.. parsed-literal::
**../../../..**
to
.. parsed-literal::
**/home/dave/boost_1_34_0**
Add New or Change Names of Existing Source Files
................................................
The names of additional source files involved in building your
extension module or embedding application can be listed in
|Jamroot|_ right alongside ``extending.cpp`` or ``embedding.cpp``
respectively. Just be sure to leave whitespace around each
filename::
… file1.cpp file2.cpp file3.cpp …
Naturally, if you want to change the name of a source file you can
tell Boost.Build about it by editing the name in |Jamroot|_.
Change the Name of your Extension Module
........................................
The name of the extension module is determined by two things:
1. the name in |Jamroot|_ immediately following ``python-extension``, and
2. the name passed to ``BOOST_PYTHON_MODULE`` in |extending.cpp|_.
To change the name of the extension module from ``extending`` to
``hello``, you'd edit |Jamroot|_, changing
.. parsed-literal::
python-extension **extending** : extending.cpp ;
to
.. parsed-literal::
python-extension **hello** : extending.cpp ;
and you'd edit extending.cpp, changing
.. parsed-literal::
BOOST_PYTHON_MODULE(\ **extending**\ )
to
.. parsed-literal::
BOOST_PYTHON_MODULE(\ **hello**\ )
Installing Boost.Python on your System
======================================
Getting Boost.Python Binaries
=============================
Since Boost.Python is a separately-compiled (as opposed to
`header-only`_) library, its user relies on the services of a
@@ -320,24 +104,25 @@ Boost.Python library binary.
.. _header-only: ../../../more/getting_started/windows.html#header-only-libraries
If you need a regular installation of the Boost.Python library
Installing Boost.Python on your System
--------------------------------------
If you need a regular, installation of the Boost.Python library
binaries on your system, the Boost `Getting Started Guide`_ will
walk you through the steps of creating one. If building binaries
walk you through the steps of installing one. If building binaries
from source, you might want to supply the ``--with-python``
argument to ``bjam`` (or the ``--with-libraries=python`` argument
to ``configure``), so only the Boost.Python binary will be built,
rather than all the Boost binaries.
Configuring Boost.Build
=======================
As described in the `Boost.Build reference manual`__, a file called
``user-config.jam`` in your home directory [#home-dir]_ is used to
specify the tools and libraries available to the build system. You
may need to create or edit ``user-config.jam`` to tell Boost.Build
how to invoke Python, ``#include`` its headers, and link with its
libraries.
``user-config.jam`` in your home
directory [#home-dir]_ is used to
describe the build resources available to the build system. You'll
need to tell it about your Python installation.
__ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
@@ -350,58 +135,66 @@ __ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
were built, your ``user-config.jam`` file is probably already
correct.
If you have one fairly “standard” python installation for your
platform, you might not need to do anything special to describe it. If
you haven't configured python in ``user-config.jam`` (and you don't
specify ``--without-python`` on the Boost.Build command line),
Boost.Build will automatically execute the equivalent of ::
If you have a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having ::
import toolset : using ;
using python ;
which automatically looks for Python in the most likely places.
However, that only happens when using the Boost.Python project file
(e.g. when referred to by another project as in the quickstart_
method). If instead you are linking against separately-compiled
Boost.Python binaries, you should set up a ``user-config.jam`` file
with at least the minimal incantation above.
in a ``user-config.jam`` file in your home directory [#home-dir]_
should be enough. [#user-config.jam]_ For more complicated setups,
see `Advanced Configuration`_.
Python Configuration Parameters
-------------------------------
.. Note:: You might want to pass the ``--debug-configuration``
option to ``bjam`` the first few times you invoke it, to make
sure that Boost.Build is correctly locating all the parts of
your Python installation. If it isn't, consider passing some of
the optional `Python configuration parameters`_ detailed below.
Building an Extension Module
============================
Testing
=======
Advanced Configuration
======================
If you have several versions of Python installed, or Python is
installed in an unusual way, you may want to supply any or all of
the following optional parameters to ``using python``.
Python Configuration Parameters
-------------------------------
version
the version of Python to use. Should be in Major.Minor
format, for example, ``2.3``. Do not include the subminor
version (i.e. *not* ``2.5.1``). If you have multiple Python
versions installed, the version will usually be the only
configuration argument required.
additional argument required.
cmd-or-prefix
preferably, a command that invokes a Python interpreter.
Alternatively, the installation prefix for Python libraries and
header files. Only use the alternative formulation if there is
no appropriate Python executable available.
preferably, a command that invokes a Python
interpreter. Alternatively, the installation prefix for Python
libraries and header files. Use the alternative formulation if
there is no appropriate Python executable available.
includes
the ``#include`` paths for Python headers. Normally the correct
path(s) will be automatically deduced from ``version`` and/or
``cmd-or-prefix``.
the ``#include`` path for Python headers.
libraries
the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework. Normally the
correct path(s) will be automatically deduced from ``version``
and/or ``cmd-or-prefix``.
you can also pass the path of the Python framework.
condition
if specified, should be a set of Boost.Build
properties that are matched against the build configuration when
Boost.Build selects a Python configuration to use. See examples
below for details.
Boost.Build selects a Python configuration to use.
extension-suffix
A string to append to the name of extension
@@ -409,12 +202,10 @@ extension-suffix
don't need to use this. Usually this suffix is only used when
targeting a Windows debug build of Python, and will be set
automatically for you based on the value of the
|python-debugging|_ feature. However, at least one Linux
``<python-debugging>`` feature. However, at least one Linux
distribution (Ubuntu Feisty Fawn) has a specially configured
`python-dbg`__ package that claims to use such a suffix.
.. |python-debugging| replace:: ``<python-debugging>``
__ https://wiki.ubuntu.com/PyDbgBuilds
@@ -456,17 +247,6 @@ significant.
: <toolset>intel # condition
;
- If you have downloaded the Python sources and built both the
normal and the “\ `python debugging`_\ ” builds from source on
Windows, you might see::
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
: # includes
: # libs
: <python-debugging>on ;
- You can set up your user-config.jam so a bjam built under Windows
can build/test both Windows and Cygwin_ python extensions. Just pass
``<target-os>cygwin`` in the ``condition`` parameter
@@ -510,7 +290,7 @@ __ http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection
Choosing a Boost.Python Library Binary
======================================
If—instead of letting Boost.Build construct and link with the right
If—instead of letting Boost.Build construct and link withthe right
libraries automatically—you choose to use a pre-built Boost.Python
library, you'll need to think about which one to link with. The
Boost.Python binary comes in both static and dynamic flavors. Take
@@ -552,64 +332,6 @@ any of the following cases:
use the types exposed by your statically-linked extension
modules (and vice-versa).
``#include`` Issues
===================
1. If you should ever have occasion to ``#include "python.h"``
directly in a translation unit of a program using Boost.Python,
use ``#include "boost/python/detail/wrap_python.hpp"`` instead.
It handles several issues necessary for use with Boost.Python,
one of which is mentioned in the next section.
2. Be sure not to ``#include`` any system headers before
``wrap_python.hpp``. This restriction is actually imposed by
Python, or more properly, by Python's interaction with your
operating system. See
http://docs.python.org/ext/simpleExample.html for details.
.. _python-debugging:
.. _python debugging:
Python Debugging Builds
=======================
Python can be built in a special “python debugging” configuration
that adds extra checks and instrumentation that can be very useful
for developers of extension modules. The data structures used by
the debugging configuration contain additional members, so **a
Python executable built with python debugging enabled cannot be
used with an extension module or library compiled without it, and
vice-versa.**
Since pre-built “python debugging” versions of the Python
executable and libraries are not supplied with most distributions
of Python, [#get-debug-build]_ and we didn't want to force our users
to build them, Boost.Build does not automatically enable python
debugging in its ``debug`` build variant (which is the default).
Instead there is a special build property called
``python-debugging`` that, when used as a build property, will
define the right preprocessor symbols and select the right
libraries to link with.
On unix-variant platforms, the debugging versions of Python's data
structures will only be used if the symbol ``Py_DEBUG`` is defined.
On many windows compilers, when extension modules are built with
the preprocessor symbol ``_DEBUG``, Python defaults to force
linking with a special debugging version of the Python DLL. Since
that symbol is very commonly used even when Python is not present,
Boost.Python temporarily undefines _DEBUG when Python.h
is #included from ``boost/python/detail/wrap_python.hpp`` - unless
``BOOST_DEBUG_PYTHON`` is defined. The upshot is that if you want
“python debugging”and you aren't using Boost.Build, you should make
sure ``BOOST_DEBUG_PYTHON`` is defined, or python debugging will be
suppressed.
Testing Boost.Python
====================
To run the full test suite for Boost.Python, invoke ``bjam`` in the
``libs/python/test`` subdirectory of your Boost distribution.
Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users
=======================================================
@@ -643,9 +365,13 @@ __ http://www.python.org/doc/current/inst/index.html
__ ../../../more/getting_started/windows.html#library-naming
__ ../../../more/getting_started/unix-variants.html#library-naming
Be sure to read this section even if your compiler supports
auto-linking, as Boost.Python does not yet take advantage of
that feature.
.. [#toolset-specific] Because of the way most \*nix platforms
share symbols among dynamically-loaded objects, I'm not certain
that extension modules built with different compiler toolsets
share symbols among dynamically-loaded objects, I'm not
certainextension modules built with different compiler toolsets
will always use different copies of the Boost.Python library
when loaded into the same Python instance. Not using different
libraries could be a good thing if the compilers have compatible
@@ -665,17 +391,14 @@ __ http://www.python.org/doc/current/inst/index.html
toolset, and you might need handle both explicitly if you also
have a MinGW GCC installed.
.. [#user-config.jam] Create the ``user-config.jam`` file if you don't
already have one.
.. [#home-dir] Windows users, your home directory can be
found by typing::
ECHO %HOMEDRIVE%%HOMEPATH%
into a `command prompt`_ window.
into a `Windows command prompt`__
.. [#get-debug-build] On Unix and similar platforms, a debugging
python and associated libraries are built by adding
``--with-pydebug`` when configuring the Python build. On
Windows, the debugging version of Python is generated by
the "Win32 Debug" target of the Visual Studio project in the
PCBuild subdirectory of a full Python source code distribution.
You may also find
__ ../../../more/getting_started/windows.html#or-build-from-the-command-prompt

View File

@@ -147,9 +147,7 @@
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="http://www.language-binding.net/pyplusplus/pyplusplus.html">Py++ Boost.Python code generator</a></dt>
<dt><a href="../pyste/index.html">Pyste Boost.Python code generator (no longer maintained)</a></dt>
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</a></dt>
<dt><a href="internals.html">Internals Documentation</a></dt>

View File

@@ -32,7 +32,43 @@
<hr>
<dl class="page-index">
<dt>Current CVS</dt>
<dt>Current SVN</dt>
<dd>
<ul>
<li>Pythonic signatures are now automatically appended to the
docstrings.
<li>Use <a href="v2/docstring_options.html"
><code>docstring_options.hpp</code></a> header
control the content of docstrings.
<li>This new feature increases the size of the modules by about 14%.
If this is not acceptable it can be turned off by defining the macro
BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
defined are compatible.
</li>
<li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
with older version of Boost.Python (see <a href="v2/pytype_function.html#examples">here</a>).
</li>
<li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
of another 14% size increase, proper pythonic type is generated for the "self"
parameter of the __init__ methods.
</li>
<li> To support this new feature changes were made to the
<a href="v2/to_python_converter.html"><code>to_python_converter.hpp</code></a>,
<a href="v2/default_call_policies.html"><code>default_call_policies</code></a>,
<a href="v2/ResultConverter.html"><code>ResultConverter</code></a>,
<a href="v2/CallPolicies.html"><code>CallPolicies</code></a> and some others.
Efforts were made not to have interface breaking changes.
</li>
</ul>
</dd>
<dt>12 May 2007 - 1.34.0 release</dt>
<dd>
<ul>

View File

@@ -31,7 +31,7 @@
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id3128483"></a><p>
<a name="id2632684"></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><h3>
<a name="id3090903"></a>
<a name="id2595112"></a>
Hello World
</h3>
<p>
@@ -132,14 +132,20 @@
</pre>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World module
from start to finish...</strong></span></em></span>
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World
module from start to finish...</strong></span></em></span>
</p>
<p>
</p>
</blockquote></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><small><p>Last revised: May 18, 2007 at 15:45:45 GMT</p></small></td>
<td align="left"><small><p>Last revised: May 18, 2007 at 15:46:01 GMT</p></small></td>
<td align="right"><small></small></td>
</tr></table>
<hr>

View File

@@ -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><h3>
<a name="id3150903"></a>
<a name="id2654982"></a>
Building embedded programs
</h3>
<p>
@@ -82,7 +82,7 @@ exe embedded_program # name of the executable
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
<a name="embedding.getting_started"></a><h3>
<a name="id3150996"></a>
<a name="id2655076"></a>
Getting started
</h3>
<p>
@@ -91,9 +91,7 @@ exe embedded_program # name of the executable
</p>
<div class="orderedlist"><ol type="1">
<li>
#include
 <code class="literal">&lt;boost/python.hpp&gt;</code><br><br>
#include <code class="literal">&lt;boost/python.hpp&gt;</code><br><br>
</li>
<li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
@@ -104,20 +102,27 @@ exe embedded_program # name of the executable
Call other Python C API routines to use the interpreter.<br><br>
</li>
</ol></div>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Note that at this time
you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Note that at this time you must
not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
</p>
</div>
<p>
(Of course, there can be other C++ code between all of these steps.)
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</strong></span></em></span>
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</strong></span></em></span>
</p>
<p>
</p>
</blockquote></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
@@ -125,14 +130,14 @@ exe embedded_program # name of the executable
As you probably already know, objects in Python are reference-counted. Naturally,
the <code class="literal">PyObject</code>s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully automatic
in Python, the Python/C API requires you to do it <a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by
hand</a>. This is messy and especially hard to get right in the presence
in Python, the Python<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
by hand]. This is messy and especially hard to get right in the presence
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
automate the process.
</p>
<a name="using_the_interpreter.running_python_code"></a><h3>
<a name="id3151190"></a>
<a name="id2655255"></a>
Running Python code
</h3>
<p>
@@ -183,7 +188,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><h3>
<a name="id3151717"></a>
<a name="id2655783"></a>
Manipulating Python objects
</h3>
<p>
@@ -210,7 +215,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">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
</pre>
<a name="using_the_interpreter.exception_handling"></a><h3>
<a name="id3152050"></a>
<a name="id2656116"></a>
Exception handling
</h3>
<p>
@@ -233,10 +238,10 @@ exe embedded_program # name of the executable
The <code class="literal">error_already_set</code> exception class doesn't carry any
information in itself. To find out more about the Python exception that occurred,
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
handling functions</a> of the Python/C API in your catch-statement. This
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
to print the exception's traceback to the console, or comparing the type
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
This can be as simple as calling [@http:</em></span>/www.python.org/doc/api/exceptionHandling.html#l2h-70
PyErr_Print()] to print the exception's traceback to the console, or comparing
the type of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
exceptions</a>:
</p>
<pre class="programlisting">

View File

@@ -379,13 +379,14 @@
The <code class="computeroutput"><span class="identifier">wrapper</span></code> template makes
the job of wrapping classes that are meant to overridden in Python, easier.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write
<code class="computeroutput"><span class="identifier">f</span></code> as:<br> <br>
<code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></code>.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <code class="computeroutput"><span class="identifier">f</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></code>.
</p>
</div>
<p>
BaseWrap's overridden virtual member function <code class="computeroutput"><span class="identifier">f</span></code>
in effect calls the corresponding method of the Python object through <code class="computeroutput"><span class="identifier">get_override</span></code>.
@@ -403,14 +404,13 @@
that the function <code class="computeroutput"><span class="identifier">f</span></code> is a
pure virtual function.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>member function and
methods</strong></span><br> <br> Python, like many object oriented languages
uses the term <span class="bold"><strong>methods</strong></span>. Methods correspond
roughly to C++'s <span class="bold"><strong>member functions</strong></span>
</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>member function and methods</strong></span><br>
<br> Python, like many object oriented languages uses the term <span class="bold"><strong>methods</strong></span>. Methods correspond roughly to C++'s <span class="bold"><strong>member functions</strong></span>
</p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
@@ -464,12 +464,15 @@
we have to check if there is an override for <code class="computeroutput"><span class="identifier">f</span></code>.
If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
the line with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
the line with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.
</p>
</div>
<p>
Finally, exposing:
</p>
@@ -516,7 +519,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><h3>
<a name="id3142031"></a>
<a name="id2646169"></a>
Python Operators
</h3>
<p>
@@ -565,7 +568,7 @@
expressions".
</p>
<a name="class_operators_special_functions.special_methods"></a><h3>
<a name="id3142715"></a>
<a name="id2646853"></a>
Special Methods
</h3>
<p>
@@ -593,11 +596,15 @@
<p>
Need we say more?
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>? Well, the method <code class="computeroutput"><span class="identifier">str</span></code> requires the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
is used by the method defined by <code class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></code>.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>? Well, the method <code class="computeroutput"><span class="identifier">str</span></code>
requires the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> is used by the method defined by
<code class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></code>.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>

View File

@@ -38,9 +38,15 @@
see facilities that will make it even easier for us to expose C++ functions
that take advantage of C++ features such as overloading and default arguments.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em>Read on...</em></span>
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em>Read on...</em></span>
</p>
<p>
</p>
</blockquote></div>
<p>
But before you do, you might want to fire up Python 2.2 or later and type
<code class="literal">&gt;&gt;&gt; import this</code>.
@@ -90,9 +96,9 @@ Namespaces are one honking great idea -- let's do more of those!
Here's an example where it didn't
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">y</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> # <span class="identifier">CRASH</span><span class="special">!</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
</pre>
<p>
What's the problem?
@@ -166,9 +172,9 @@ Namespaces are one honking great idea -- let's do more of those!
a raw pointer. Now we have a potential dangling pointer problem inside Y:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> # <span class="identifier">Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> # <span class="identifier">CRASH</span><span class="special">!</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
</pre>
<p>
For reference, here's the implementation of <code class="literal">f</code> again:
@@ -206,7 +212,7 @@ Namespaces are one honking great idea -- let's do more of those!
<li><span class="bold"><strong>BOOM!</strong></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h3>
<a name="id3144432"></a>
<a name="id2648560"></a>
Call Policies
</h3>
<p>
@@ -287,13 +293,14 @@ Namespaces are one honking great idea -- let's do more of those!
and hold the instance
</li>
</ul></div>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span><br>
<br> "Explicit is better than implicit"<br> "In
the face of ambiguity, refuse the temptation to guess"<br>
</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span><br>
<br> "Explicit is better than implicit"<br> "In the face
of ambiguity, refuse the temptation to guess"<br>
</p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
@@ -404,7 +411,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><h3>
<a name="id3146300"></a>
<a name="id2650414"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h3>
<p>
@@ -434,7 +441,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><h3>
<a name="id3146587"></a>
<a name="id2650701"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h3>
<p>
@@ -480,7 +487,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><h3>
<a name="id3146923"></a>
<a name="id2651031"></a>
init and optional
</h3>
<p>
@@ -554,7 +561,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><h3>
<a name="id3147627"></a>
<a name="id2651734"></a>
Manual Wrapping
</h3>
<p>

View File

@@ -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><h3>
<a name="id3091224"></a>
<a name="id2595436"></a>
From Start To Finish
</h3>
<p>
@@ -35,17 +35,19 @@
necessary to achieve that. We shall use the build tool that comes bundled with
every boost distribution: <span class="bold"><strong>bjam</strong></span>.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Building without bjam</strong></span><br>
<br> Besides bjam, there are of course other ways to get your module
built. What's written here should not be taken as "the one and only
way". There are of course other build tools apart from <code class="literal">bjam</code>.<br>
<br> Take note however that the preferred build tool for Boost.Python
is bjam. There are so many ways to set up the build incorrectly. Experience
shows that 90% of the "I can't build Boost.Python" problems
come from people who had to use a different tool. </td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Building without bjam</strong></span><br>
<br> Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as "the one and only way".
There are of course other build tools apart from <code class="literal">bjam</code>.<br>
<br> Take note however that the preferred build tool for Boost.Python is
bjam. There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
</p>
</div>
<p>
We shall 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
@@ -99,7 +101,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><h3>
<a name="id3091427"></a>
<a name="id2595623"></a>
Let's Jam!
</h3>
<p>
@@ -150,16 +152,22 @@ extension hello # Declare a Python extension called hello
The last part tells BJam that we are depending on the Boost Python Library.
</p>
<a name="hello.running_bjam"></a><h3>
<a name="id3091556"></a>
<a name="id2595752"></a>
Running bjam
</h3>
<p>
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
interpreter.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Start it up.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
Start it up.
</p>
<p>
</p>
</blockquote></div>
<p>
Make sure that the environment is set so that we can invoke the C++ compiler.
With MSVC, that would mean running the <code class="literal">Vcvars32.bat</code> batch
@@ -178,11 +186,13 @@ set PYTHON_VERSION=2.2
The above assumes that the Python installation is in <code class="literal">c:/dev/tools/python</code>
and that we are using Python version 2.2. You'll have to tweak these appropriately.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><strong>not</strong></span> "2.2.1", even if that's the version
you have.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><strong>not</strong></span> "2.2.1", even if that's the version you
have.
</p>
</div>
<p>
Take note that you may also do that through the Jamrules file we put in our
project as detailed above. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
@@ -272,9 +282,15 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
</pre>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="bold"><strong>There you go... Have fun!</strong></span>
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="bold"><strong>There you go... Have fun!</strong></span>
</p>
<p>
</p>
</blockquote></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>

View File

@@ -176,12 +176,14 @@
% x,y,z</code> in Python, which is useful since there's no easy way to
do that in std C++.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the
common pitfall of forgetting that the constructors of most of Python's
mutable types make copies, just as in Python. </td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
of forgetting that the constructors of most of Python's mutable types make
copies, just as in Python.
</p>
</div>
<p>
Python:
</p>
@@ -197,7 +199,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><h3>
<a name="id3149441"></a>
<a name="id2653534"></a>
class_&lt;T&gt; as objects
</h3>
<p>
@@ -295,14 +297,15 @@
above creates a Python class derived from Python's <code class="literal">int</code>
type which is associated with the C++ type passed as its first parameter.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>what is a scope?</strong></span><br>
<br> 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 <a href="../../../../v2/scope.html" target="_top">here</a>.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>what is a scope?</strong></span><br>
<br> 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 <a href="../../../../v2/scope.html" target="_top">here</a>.
</p>
</div>
<p>
You can access those values in Python as
</p>

View File

@@ -96,13 +96,15 @@
Compiling these files will generate the following Python extensions: <code class="literal">core.pyd</code>,
<code class="literal">io.pyd</code> and <code class="literal">filters.pyd</code>.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <code class="literal">.pyd</code> is used
for python extension modules, which are just shared libraries. Using
the default for your system, like <code class="literal">.so</code> for Unix and
<code class="literal">.dll</code> for Windows, works just as well.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <code class="literal">.pyd</code> is used for python
extension modules, which are just shared libraries. Using the default for
your system, like <code class="literal">.so</code> for Unix and <code class="literal">.dll</code>
for Windows, works just as well.
</p>
</div>
<p>
Now, we create this directory structure for our Python package:
</p>
@@ -165,12 +167,12 @@
__init__.py
core/
__init__.py
_core.pyd
<span class="underline">core.pyd
filters/
__init__.py
_filters.pyd
\</span>_init__.py
<span class="underline">filters.pyd
io/
__init__.py
\</span>_init__.py
_io.pyd
</pre>
<p>
@@ -425,19 +427,23 @@
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.
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
take a look at the <code class="literal">--multiple</code> option, that generates
the wrappers in various files as demonstrated here.</td></tr></tbody>
</table></div>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> This method is useful too if you are getting the
error message <span class="emphasis"><em>"fatal error C1204:Compiler limit:internal
structure overflow"</em></span> when compiling a large source file,
as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.</td></tr></tbody>
</table></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
take a look at the <code class="literal">--multiple</code> option, that generates the
wrappers in various files as demonstrated here.
</p>
</div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> This method is useful too if you are getting the error
message <span class="emphasis"><em>"fatal error C1204:Compiler limit:internal structure
overflow"</em></span> when compiling a large source file, as explained
in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>

View File

@@ -8,7 +8,7 @@
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<title>Boost.Python - CallPolicies Concept</title>
</head>
@@ -60,6 +60,7 @@
<li><code>postcall</code> - Python argument tuple and result management
after the wrapped object is invoked</li>
<li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
</ol>
<h2><a name="composition"></a>CallPolicies Composition</h2>
@@ -132,7 +133,16 @@
reference count must be decremented; if another existing object is
returned, its reference count must be incremented.</td>
</tr>
</table>
<tr>
<td valign="top"><code>P::extract_return_type</code></td>
<td>A model of <a href=
"../../../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>
</tr>
</table>
Models of CallPolicies are required to be <a href=
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
<hr>

View File

@@ -1,10 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<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 - ResultConverter Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -24,10 +26,12 @@
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dl class="page-index">
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
</dl>
<dd>
<dl class="page-index">
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
</dl>
</dd>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
@@ -79,6 +83,13 @@ denotes an object of type <code><b>R</b></code>.
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
should return non-zero.</td>
</tr>
<tr>
<td valign="top"><code>c.get_pytype()</code></td>
<td><code>PyTypeObject const*</code></td>
<td>A pointer to a Python Type object corresponding to result of the conversion,
or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
the generated type in the documentation will be <b>object</b> .</td>
</tr>
</table>
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>

View File

@@ -139,6 +139,41 @@
compares <code>typeid(T).name()</code> instead of using and comparing
the <code>std::type_info</code> objects directly.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined for a module no pythonic signatures are generated
for the docstrings of the module functions, and no python type is associated with any
of the converters registered by the module. This also reduces the binary size of the
module by about 14% (gcc compiled).<br>
If defined for the boost_python runtime library, the default for the
<code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
<td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
<td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
which do not support pythonic signatures. For example usage see
<a href="pytype_function.html#examples">here</a>.
</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
</tr>
</table>
<hr>

View File

@@ -82,6 +82,7 @@ namespace boost { namespace python
static PyObject* postcall(PyObject*, PyObject* result);
typedef <a href=
"#default_result_converter-spec">default_result_converter</a> result_converter;
template &lt;class Sig&gt; struct extract_return_type : mpl::front&lt;Sig&gt;{};
};
}}
</pre>
@@ -161,7 +162,7 @@ struct return_value_policy : Base
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
11 June, 2007
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->

View File

@@ -103,6 +103,8 @@ namespace boost { namespace python {
docstring_options(bool show_user_defined, bool show_signatures);
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
~docstring_options();
void
@@ -117,6 +119,18 @@ namespace boost { namespace python {
void
enable_signatures();
void
disable_py_signatures();
void
enable_py_signatures();
void
disable_cpp_signatures();
void
enable_cpp_signatures();
void
disable_all();
@@ -139,7 +153,7 @@ docstring_options(bool show_all=true);
object which controls the appearance of function and
member-function docstrings defined in the code that follows. If
<code>show_all</code> is <code>true</code>, both the
user-defined docstrings and the automatically generated C++
user-defined docstrings and the automatically generated Python and C++
signatures are shown. If <code>show_all</code> is
<code>false</code> the <code>__doc__</code> attributes are
<code>None</code>.</dt>
@@ -154,12 +168,29 @@ docstring_options(bool show_user_defined, bool show_signatures);
member-function docstrings defined in the code that follows.
Iff <code>show_user_defined</code> is <code>true</code>, the
user-defined docstrings are shown. Iff
<code>show_signatures</code> is <code>true</code>, C++
<code>show_signatures</code> is <code>true</code>, Python and C++
signatures are automatically added. If both
<code>show_user_defined</code> and <code>show_signatures</code>
are <code>false</code>, the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<pre>
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
object which controls the appearance of function and
member-function docstrings defined in the code that follows.
Iff <code>show_user_defined</code> is <code>true</code>, the
user-defined docstrings are shown. Iff
<code>show_py_signatures</code> is <code>true</code>, Python
signatures are automatically added. Iff
<code>show_cpp_signatures</code> is <code>true</code>, C++
signatures are automatically added. If all parameters are
<code>false</code>, the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<h4><a name="docstring_options-spec-dtors" id=
"docstring_options-spec-dtors"></a>Class
@@ -186,6 +217,10 @@ void disable_user_defined();
void enable_user_defined();
void disable_signatures();
void enable_signatures();
void disable_py_signatures();
void enable_py_signatures();
void disable_cpp_signatures();
void enable_cpp_signatures();
void disable_all();
void enable_all();
</pre>
@@ -196,7 +231,7 @@ void enable_all();
<code>*_user_defined()</code> and <code>*_signatures()</code>
member functions are provided for fine-grained control. The
<code>*_all()</code> member functions are convenient shortcuts
to manipulate both settings simultaneously.</dt>
to manipulate all settings simultaneously.</dt>
</dl>
<h2><a name="examples" id="examples"></a>Examples</h2>
@@ -219,7 +254,7 @@ BOOST_PYTHON_MODULE(demo)
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo.__doc__
foo doc
foo() -&gt; None : foo doc
C++ signature:
foo(void) -&gt; void
</pre>If compiled with
@@ -253,21 +288,33 @@ BOOST_PYTHON_MODULE(demo)
def("foo3", foo3, arg("f"), "foo3 doc");
doc_options.enable_user_defined();
def("foo4", foo4, arg("d"), "foo4 doc");
doc_options.enable_py_signatures();
def("foo5", foo4, arg("d"), "foo5 doc");
doc_options.disable_py_signatures();
doc_options.enable_cpp_signatures();
def("foo6", foo4, arg("d"), "foo6 doc");
}
</pre>Python code:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo1.__doc__
foo1 doc
foo1( (int)i) -&gt; int : foo1 doc
C++ signature:
foo1(int i) -&gt; int
&gt;&gt;&gt; print demo.foo2.__doc__
foo2( (int)l) -&gt; int :
C++ signature:
foo2(long l) -&gt; int
&gt;&gt;&gt; print demo.foo3.__doc__
None
&gt;&gt;&gt; print demo.foo4.__doc__
foo4 doc
&gt;&gt;&gt; print demo.foo5.__doc__
foo5( (float)d) -&gt; int : foo5 doc
&gt;&gt;&gt; print demo.foo6.__doc__
foo6 doc
C++ signature:
foo6(double d) -&gt; int
</pre>
<h4>Wrapping from multiple C++ scopes</h4>

View File

@@ -89,7 +89,7 @@ namespace boost { namespace python
template &lt;class T&gt;
class enum_ : public <a href="object.html#object-spec">object</a>
{
enum_(char const* name);
enum_(char const* name, char const* doc = 0);
enum_&lt;T&gt;&amp; value(char const* name, T);
enum_&lt;T&gt;&amp; export_values();
};
@@ -99,7 +99,7 @@ namespace boost { namespace python
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
constructors</h4>
<pre>
enum_(char const* name);
enum_(char const* name, char const* doc=0);
</pre>
<dl class="function-semantics">
@@ -131,7 +131,7 @@ inline enum_&lt;T&gt;&amp; value(char const* name, T x);
<dt><b>Effects:</b> adds an instance of the wrapped enumeration
type with value <code>x</code> to the type's dictionary as the
<code>name</code>d attribute</dt>.
<code>name</code>d attribute.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
@@ -146,7 +146,7 @@ inline enum_&lt;T&gt;&amp; export_values();
<dt><b>Effects:</b> sets attributes in the current <a
href="scope.html#scope-spec"><code>scope</code></a> with the
same names and values as all enumeration values exposed so far
by calling <code>value()</code></dt>.
by calling <code>value()</code>.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>

View File

@@ -127,7 +127,7 @@ void greet()
// Define greet function in Python.
object result = exec(
"def greet(self): \n"
"def greet(): \n"
" return 'Hello from Python!' \n",
global, global);
@@ -144,7 +144,7 @@ void greet()
we could also store it in an a file...</para>
<pre>
def greet(self):
def greet():
return 'Hello from Python!'
</pre>
<para>... and execute that instead.</para>

View File

@@ -0,0 +1,216 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright Nikolay Mladenov 2007. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/doobject/function_doc_signature.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../boost.png" border=
"0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href=
"../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/object/function_doc_signature.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#function_doc_signature_generator-spec">Class
<code>function_doc_signature_generator</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#function_doc_signature_generator-spec-synopsis">Class
<code>function_doc_signature_generator</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction" id=
"introduction"></a>Introduction</h2>
<p>Boost.Python supports docstrings with automatic
appending of Pythonic and C++ signatures. This feature is implemented
by <code>class function_doc_signature_generator</code>
The class uses all of the overloads, supplied arg names and default values, as well as
the user-defined docstrings, to generate documentation for a given function.</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h3><a name="function_doc_signature_generator-spec" id=
"function_doc_signature_generator-spec"></a>Class
<code>function_doc_signature_generator</code></h3>
<p>
The class has only one public function which returns a list of strings documenting the
overloads of a function.
</p>
<h4><a name="function_doc_signature_generator-spec-synopsis" id=
"function_doc_signature_generator-spec-synopsis"></a>Class
<code>function_doc_signature_generator</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator
{
public:
static list function_doc_signatures(function const *f);
};
}}}
</pre>
<h2><a name="examples" id="examples"></a>Examples</h2>
<h4>Docstrings generated with <code>function_doc_signature_generator</code></h4>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
#include &lt;boost/python/tuple.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/overloads.hpp&gt;
#include &lt;boost/python/raw_function.hpp&gt;
using namespace boost::python;
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
struct X
{
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
tuple raw_func(tuple args, dict kw)
{
return make_tuple(args, kw);
}
BOOST_PYTHON_MODULE(args_ext)
{
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
, "This is f's docstring"
);
def("raw", raw_function(raw_func));
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
class_&lt;X&gt;("X", "This is X's docstring", init&lt;&gt;(args("self")))
.def("f", &amp;X::f
, "This is X.f's docstring"
, args("self","x", "y", "z"))
;
}
</pre>
Python code:
<pre>
&gt;&gt;&gt; import args_ext
&gt;&gt;&gt; help(args_ext)
Help on module args_ext:
NAME
args_ext
FILE
args_ext.pyd
CLASSES
Boost.Python.instance(__builtin__.object)
X
class X(Boost.Python.instance)
| This is X's docstring
|
| Method resolution order:
| X
| Boost.Python.instance
| __builtin__.object
|
| Methods defined here:
|
| __init__(...)
| __init__( (object)self) -> None :
| C++ signature:
| void __init__(struct _object *)
|
| f(...)
| f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring
| C++ signature:
| class boost::python::tuple f(struct X {lvalue},int,double,char const *)
|
| .................
|
FUNCTIONS
f(...)
f([ (int)x=1 [, (float)y=4.25 [, (str)z='wow']]]) -> tuple : This is f's docstring
C++ signature:
class boost::python::tuple f([ int=1 [,double=4.25 [,char const *='wow']]])
f1(...)
f1([ (int)x [, (float)y [, (str)z]]]) -> tuple : f1's docstring
C++ signature:
class boost::python::tuple f1([ int [,double [,char const *]]])
raw(...)
object raw(tuple args, dict kwds) :
C++ signature:
object raw(tuple args, dict kwds)
</pre>
<p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
</body>
</html>

View File

@@ -214,6 +214,9 @@ namespace boost { namespace python { namespace self_ns {
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; str(self_t);
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; repr(self_t);
}}};
</pre>
The tables below describe the methods generated when the results of the
@@ -765,6 +768,15 @@ namespace boost { namespace python { namespace self_ns {
<td><code><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
</tr>
<tr>
<td><code>repr</code></td>
<td><code>__repr__</code></td>
<td><code><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
</tr>
</table>
<h3><a name="other-spec"></a>Class Template <code>other</code></h3>

370
doc/v2/pytype_function.html Normal file
View File

@@ -0,0 +1,370 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright Nikolay Mladenov 2007. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/doobject/pytype_function.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../boost.png" border=
"0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href=
"../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/converter/pytype_function.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#wrap_pytype-spec">Class
<code>wrap_pytype</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#wrap_pytype-spec-synopsis">Class
<code>wrap_pytype</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#registered_pytype-spec">Class
<code>registered_pytype</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#registered_pytype-spec-synopsis">Class
<code>registered_pytype</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#expected_from_python_type-spec">Class
<code>expected_from_python_type</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#expected_from_python_type-spec-synopsis">Class
<code>expected_from_python_type</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#to_python_target_type-spec">Class
<code>to_python_target_type</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#to_python_target_type-spec-synopsis">Class
<code>to_python_target_type</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction" id=
"introduction"></a>Introduction</h2>
<p>To support Pythonic signatures the converters should supply a <code>get_pytype</code> function
returning a pointer to the associated <code>PyTypeObject</code>. See for example
<a href="ResultConverter.html#ResultConverter-concept">ResultConverter</a> or
<a href="to_python_converter.html#to_python_converter-spec">to_python_converter</a>.
The classes in this header file are meant to be used when implmenting <code>get_pytype</code>.
There are also <code>_direct</code> versions of the templates of <code>class T</code> which
should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h3><a name="wrap_pytype-spec" id=
"wrap_pytype-spec"></a>Class
<code>wrap_pytype</code></h3>
<p>
This template generates a static <code>get_pytype</code> member returning the template parameter.
</p>
<h4><a name="wrap_pytype-spec-synopsis" id=
"wrap_pytype-spec-synopsis"></a>Class
<code>wrap_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; PyTypeObject const *pytype &gt;
class wrap_pytype
{
public:
static PyTypeObject const *get_pytype(){return pytype; }
};
}}}
</pre>
<h3><a name="registered_pytype-spec" id=
"registered_pytype-spec"></a>Class
<code>registered_pytype</code></h3>
<p>
This template should be used with template parameters which are (possibly decorated)
types exported to python using <a href="class.html"><code>class_</code></a>.
The generated a static <code>get_pytype</code> member
returns the corresponding python type.
</p>
<h4><a name="registered_pytype-spec-synopsis" id=
"registered_pytype-spec-synopsis"></a>Class
<code>registered_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class registered_pytype
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h3><a name="expected_from_python_type-spec" id=
"expected_from_python_type-spec"></a>Class
<code>expected_from_python_type</code></h3>
<p>
This template generates a static <code>get_pytype</code> member which inspects the registered
<code>from_python</code> converters for the type <code>T</code> and returns a matching python type.
</p>
<h4><a name="expected_from_python_type-spec-synopsis" id=
"expected_from_python_type-spec-synopsis"></a>Class
<code>expected_from_python_type</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class expected_from_python_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h3><a name="to_python_target_type-spec" id=
"to_python_target_type-spec"></a>Class
<code>to_python_target_type</code></h3>
<p>
This template generates a static <code>get_pytype</code> member returning the
python type to which T can be converted.
</p>
<h4><a name="to_python_target_type-spec-synopsis" id=
"to_python_target_type-spec-synopsis"></a>Class
<code>to_python_target_type</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class to_python_target_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h2><a name="examples" id="examples"></a>Examples</h2>
This example presumes that someone has implemented the standard <a href=
"http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
module</a> from the Python documentation, and placed the corresponding
declarations in <code>"noddy.h"</code>. Because
<code>noddy_NoddyObject</code> is the ultimate trivial extension type,
the example is a bit contrived: it wraps a function for which all
information is contained in the <i>type</i> of its return value.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/reference.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include "noddy.h"
struct tag {};
tag make_tag() { return tag(); }
using namespace boost::python;
struct tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
: wrap_pytype<&amp;noddy_NoddyType> //inherits get_pytype from wrap_pytype
#endif
{
static PyObject* convert(tag const&amp; x)
{
return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
}
};
BOOST_PYTHON_MODULE(to_python_converter)
{
def("make_tag", make_tag);
to_python_converter&lt;tag, tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
, true
#endif
&gt;(); //"true" because tag_to_noddy has member get_pytype
}
</pre>
<p>The following example registers to and from python converters using the templates
<code>expected_from_python_type</code> and <code>to_pyhton_target_type</code>.
</p>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/extract.hpp&gt;
#include &lt;boost/python/to_python_converter.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
using namespace boost::python;
struct A
{
};
struct B
{
A a;
B(const A& a_):a(a_){}
};
// Converter from A to python int
struct BToPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
: converter::to_python_target_type&lt;A&gt; //inherits get_pytype
#endif
{
static PyObject* convert(const B& b)
{
return incref(object(b.a).ptr());
}
};
// Conversion from python int to A
struct BFromPython
{
BFromPython()
{
boost::python::converter::registry::push_back
( &amp;convertible
, &amp;construct
, type_id&lt; B &gt;()
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
, &amp;converter::expected_from_python_type&lt;A&gt;::get_pytype//convertible to A can be converted to B
#endif
);
}
static void* convertible(PyObject* obj_ptr)
{
extract&lt;const A&&gt; ex(obj_ptr);
if (!ex.check()) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(converter::rvalue_from_python_storage&lt; B &gt;*)data)-&gt; storage.bytes;
extract&lt;const A&&gt; ex(obj_ptr);
new (storage) B(ex());
data->convertible = storage;
}
};
B func(const B& b) { return b ; }
BOOST_PYTHON_MODULE(pytype_function_ext)
{
to_python_converter&lt; B , BToPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
,true
#endif
&gt;(); //has get_pytype
BFromPython();
class_&lt;A&gt;("A") ;
def("func", &amp;func);
}
&gt;&gt;&gt; from pytype_function_ext import *
&gt;&gt;&gt; print func.__doc__
func( (A)arg1) -> A :
C++ signature:
struct B func(struct B)
</pre>
<p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
</body>
</html>

View File

@@ -609,6 +609,66 @@
</dl>
</dd>
<dd>
<a name="function_documentation"></a>
<h3>Function documentation</h3>
<dl class="index">
<dt><a href=
"function_doc_signature.html">function_doc_signature.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"function_doc_signature.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"function_doc_signature.html#function_doc_signature_generator-spec">function_doc_signature_generator</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html">pytype_function.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"pytype_function.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"pytype_function.html#wrap_pytype-spec">wrap_pytype</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#expected_from_python_type-spec">expected_from_python_type</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#to_python_target_type-spec">to_python_target_type</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#registered_pytype-spec">registered_pytype</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
<dd>
<a name="models_of_call_policies"></a>

View File

@@ -125,6 +125,8 @@ namespace boost { namespace python
{
static PyObject* postcall(PyObject*, PyObject* result);
struct result_converter{ template &lt;class T&gt; struct apply; };
template &lt;class Sig&gt; struct extract_return_type : mpl::at_c&lt;Sig, arg_pos&gt;{};
};
}}
</pre>

View File

@@ -108,6 +108,23 @@
<td>A class type whose static member function <code>convert</code>
does the real work of the conversion.</td>
</tr>
<tr>
<td><code>bool has_get_pytype = false</code></td>
<td>
<code>PyTypeObject const * p = Conversion::get_pytype() </code>.</td>
<td><b>Optional member</b> - if <code>Conversion</code> has <code>get_pytype</code> member supply
<code>true</code> for this parameters.
If present <code>get_pytype</code> is used to document the return type
of functions using this conversion. The <code>get_pytype</code> may be implemented
using the classes and functions
from <a href="pytype_function.html"><code>pytype_function.hpp</code></a>
<b>NOTE :</b> For backward compatibility this parameter may be passed after
checking if <code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code> is defined (see
<a href="pytype_function.html#examples">here</a>).
</td>
</tr>
</table>
<h4><a name="to_python_converter-spec-synopsis"></a>Class template
@@ -115,7 +132,7 @@
<pre>
namespace boost { namespace python
{
template &lt;class T, class Conversion&gt;
template &lt;class T, class Conversion, bool convertion_has_get_pytype_member=false&gt;
struct to_python_converter
{
to_python_converter();
@@ -160,12 +177,16 @@ struct tag_to_noddy
{
return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
}
static PyTypeObject const* get_pytype()
{
return &amp;noddy_NoddyType;
}
};
BOOST_PYTHON_MODULE(to_python_converter)
{
def("make_tag", make_tag);
to_python_converter&lt;tag, tag_to_noddy&gt;();
to_python_converter&lt;tag, tag_to_noddy, true&gt;(); //"true" because tag_to_noddy has member get_pytype
}
</pre>
@@ -195,7 +216,7 @@ BOOST_PYTHON_MODULE(to_python_converter)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
11 June, 2007
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

BIN
example/project.zip Normal file

Binary file not shown.

View File

@@ -1,43 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Specify the path to the Boost project. If you move this project,
# adjust the path to refer to the Boost root directory.
use-project boost
: ../../../.. ;
# Set up the project-wide requirements that everything uses the
# boost_python library defined in the project whose global ID is
# /boost/python.
project boost-python-quickstart
: requirements <library>/boost/python//boost_python
;
# Make the definition of the python-extension rule available
import python ;
# Declare a Python extension called hello.
python-extension extending : extending.cpp ;
# Declare an executable called embedding that embeds Python
exe embedding : embedding.cpp /python//python ;
import testing ;
# Declare a test of the extension module
testing.make-test run-pyd : extending test_extending.py : : test_ext ;
# Declare a test of the embedding application
testing.run embedding
: # any ordinary arguments
: script.py # any arguments that should be treated as relative paths
: # requirements
: test_embed ; # name of test
# Create a "test" target that runs all the tests
alias test : test_ext test_embed ;
# make sure the tests don't run by default
explicit test_ext test_embed test ;

View File

@@ -1,7 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Edit this path to point at the tools/build/v2 subdirectory of your
# Boost installation. Absolute paths work, too.
boost-build ../../../../tools/build/v2 ;

View File

@@ -1,154 +0,0 @@
// Copyright Stefan Seefeld 2005.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
namespace python = boost::python;
// An abstract base class
class Base : public boost::noncopyable
{
public:
virtual ~Base() {};
virtual std::string hello() = 0;
};
// C++ derived class
class CppDerived : public Base
{
public:
virtual ~CppDerived() {}
virtual std::string hello() { return "Hello from C++!";}
};
// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, python::wrapper<Base>
{
virtual std::string hello()
{
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// workaround for VC++ 6.x or 7.0, see
// http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
return python::call<std::string>(this->get_override("hello").ptr());
#else
return this->get_override("hello")();
#endif
}
};
// Pack the Base class wrapper into a module
BOOST_PYTHON_MODULE(embedded_hello)
{
python::class_<BaseWrap, boost::noncopyable> base("Base");
}
void exec_test()
{
std::cout << "registering extension module embedded_hello..." << std::endl;
// Register the module with the interpreter
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
"builtin modules");
std::cout << "defining Python class derived from Base..." << std::endl;
// Retrieve the main module
python::object main = python::import("__main__");
// Retrieve the main module's namespace
python::object global(main.attr("__dict__"));
// Define the derived class in Python.
python::object result = python::exec(
"from embedded_hello import * \n"
"class PythonDerived(Base): \n"
" def hello(self): \n"
" return 'Hello from Python!' \n",
global, global);
python::object PythonDerived = global["PythonDerived"];
// Creating and using instances of the C++ class is as easy as always.
CppDerived cpp;
BOOST_TEST(cpp.hello() == "Hello from C++!");
std::cout << "testing derived class from C++..." << std::endl;
// But now creating and using instances of the Python class is almost
// as easy!
python::object py_base = PythonDerived();
Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;
// Make sure the right 'hello' method is called.
BOOST_TEST(py.hello() == "Hello from Python!");
std::cout << "success!" << std::endl;
}
void exec_file_test(std::string const &script)
{
std::cout << "running file " << script << "..." << std::endl;
// Run a python script in an empty environment.
python::dict global;
python::object result = python::exec_file(script.c_str(), global, global);
// Extract an object the script stored in the global dictionary.
BOOST_TEST(python::extract<int>(global["number"]) == 42);
std::cout << "success!" << std::endl;
}
void exec_test_error()
{
std::cout << "intentionally causing a python exception..." << std::endl;
// Execute a statement that raises a python exception.
python::dict global;
python::object result = python::exec("print unknown \n", global, global);
std::cout << "Oops! This statement should be skipped due to an exception" << std::endl;
}
int main(int argc, char **argv)
{
BOOST_TEST(argc == 2);
std::string script = argv[1];
// Initialize the interpreter
Py_Initialize();
bool error_expected = false;
if (
python::handle_exception(exec_test)
|| python::handle_exception(boost::bind(exec_file_test, script))
|| (
(error_expected = true)
&& python::handle_exception(exec_test_error)
)
)
{
if (PyErr_Occurred())
{
if (!error_expected)
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception translator registered.");
}
}
// Boost.Python doesn't support Py_Finalize yet, so don't call it!
return boost::report_errors();
}

View File

@@ -1,41 +0,0 @@
// Copyright Ralf W. Grosse-Kunstleve 2002-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)
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <iostream>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A friendly class.
class hello
{
public:
hello(const std::string& country) { this->country = country; }
std::string greet() const { return "Hello from " + country; }
private:
std::string country;
};
// A function taking a hello object as an argument.
std::string invite(const hello& w) {
return w.greet() + "! Please come soon!";
}
}
BOOST_PYTHON_MODULE(extending)
{
using namespace boost::python;
class_<hello>("hello", init<std::string>())
// Add a regular member function.
.def("greet", &hello::greet)
// Add invite() as a member of hello!
.def("invite", invite)
;
// Also add invite() as a regular function to the module.
def("invite", invite);
}

View File

@@ -1,6 +0,0 @@
# Copyright Stefan Seefeld 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
print 'Hello World !'
number = 42

View File

@@ -1,36 +0,0 @@
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Using the doctest module here to ensure that the results are as expected.
r'''>>> from extending import *
>>> hi = hello('California')
>>> hi.greet()
'Hello from California'
>>> invite(hi)
'Hello from California! Please come soon!'
>>> hi.invite()
'Hello from California! Please come soon!'
>>> class wordy(hello):
... def greet(self):
... return hello.greet(self) + ', where the weather is fine'
...
>>> hi2 = wordy('Florida')
>>> hi2.greet()
'Hello from Florida, where the weather is fine'
>>> invite(hi2)
'Hello from Florida! Please come soon!'
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_extending
return doctest.testmod(test_extending, verbose=True)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -18,6 +18,7 @@ namespace { // Avoid cluttering the global namespace.
return boost::python::incref(
boost::python::make_tuple(p.first, p.second).ptr());
}
static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
};
// Helper for convenience.
@@ -28,7 +29,9 @@ namespace { // Avoid cluttering the global namespace.
{
boost::python::to_python_converter<
std::pair<T1, T2>,
std_pair_to_tuple<T1, T2> >();
std_pair_to_tuple<T1, T2>,
true //std_pair_to_tuple has get_pytype
>();
}
};

View File

@@ -39,6 +39,9 @@ struct as_to_python_function
// but c'est la vie.
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
#endif
};
}}} // namespace boost::python::converter

View File

@@ -47,7 +47,7 @@ namespace detail
}
// Use expr to create the PyObject corresponding to x
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
@@ -55,6 +55,10 @@ namespace detail
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
@@ -63,6 +67,10 @@ namespace detail
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
};
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
@@ -77,25 +85,25 @@ namespace detail
}
// Specialize argument and return value converters for T using expr
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
// Specialize converters for signed and unsigned T to Python Int
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
unsigned T \
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
(std::numeric_limits<long>::max)()) \
? ::PyLong_FromUnsignedLong(x) \
: ::PyInt_FromLong(x))
: ::PyInt_FromLong(x), &PyInt_Type)
// Bool is not signed.
#if PY_VERSION_HEX >= 0x02030000
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
#else
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
#endif
// note: handles signed char and unsigned char, but not char (see below)
@@ -108,25 +116,25 @@ BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
# endif
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE

View File

@@ -18,6 +18,9 @@ struct pyobject_traits<PyObject>
// All objects are convertible to PyObject
static bool check(PyObject*) { return true; }
static PyObject* checked_downcast(PyObject* x) { return x; }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const* get_pytype() { return 0; }
#endif
};
//

View File

@@ -14,7 +14,7 @@ BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*);
// Used as a base class for specializations which need to provide
// Python type checking capability.
template <class Object, PyTypeObject* pytype>
struct pyobject_type
struct pyobject_type
{
static bool check(PyObject* x)
{
@@ -27,6 +27,9 @@ struct pyobject_type
(checked_downcast_impl)(x, pytype)
);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const* get_pytype() { return pytype; }
#endif
};
}}} // namespace boost::python::converter

View File

@@ -0,0 +1,132 @@
// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef WRAP_PYTYPE_NM20070606_HPP
# define WRAP_PYTYPE_NM20070606_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/unwind_type.hpp>
namespace boost { namespace python {
namespace converter
{
template <PyTypeObject const* python_type>
struct wrap_pytype
{
static PyTypeObject const* get_pytype()
{
return python_type;
}
};
typedef PyTypeObject const* (*pytype_function)();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
namespace detail
{
struct unwind_type_id_helper{
typedef python::type_info result_type;
template <class U>
static result_type execute(U* ){
return python::type_id<U>();
}
};
template <class T>
inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
{
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
}
inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
{
return type_id<void>();
}
template <class T>
inline python::type_info unwind_type_id(boost::type<T>* p= 0)
{
return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
}
}
template <class T>
struct expected_pytype_for_arg
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->expected_from_python_type(): 0;
}
};
template <class T>
struct registered_pytype
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->m_class_object: 0;
}
};
template <class T>
struct registered_pytype_direct
{
static PyTypeObject const* get_pytype()
{
return registered<T>::converters.m_class_object;
}
};
template <class T>
struct expected_from_python_type : expected_pytype_for_arg<T>{};
template <class T>
struct expected_from_python_type_direct
{
static PyTypeObject const* get_pytype()
{
return registered<T>::converters.expected_from_python_type();
}
};
template <class T>
struct to_python_target_type
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->to_python_target_type(): 0;
}
};
template <class T>
struct to_python_target_type_direct
{
static PyTypeObject const *get_pytype()
{
return registered<T>::converters.to_python_target_type();
}
};
#endif
}}} // namespace boost::python
#endif // WRAP_PYTYPE_NM20070606_HPP

View File

@@ -27,6 +27,7 @@ struct rvalue_from_python_chain
{
convertible_function convertible;
constructor_function construct;
PyTypeObject const* (*expected_pytype)();
rvalue_from_python_chain* next;
};
@@ -34,6 +35,7 @@ struct BOOST_PYTHON_DECL registration
{
public: // member functions
explicit registration(type_info target, bool is_shared_ptr = false);
~registration();
// Convert the appropriately-typed data to Python
PyObject* to_python(void const volatile*) const;
@@ -42,6 +44,11 @@ struct BOOST_PYTHON_DECL registration
// exception if no class has been registered.
PyTypeObject* get_class_object() const;
// Return common denominator of the python class objects,
// convertable to target. Inspects the m_class_object and the value_chains.
PyTypeObject const* expected_from_python_type() const;
PyTypeObject const* to_python_target_type() const;
public: // data members. So sue me.
const python::type_info target_type;
@@ -56,6 +63,8 @@ struct BOOST_PYTHON_DECL registration
// The unique to_python converter for the associated C++ type.
to_python_function_t m_to_python;
PyTypeObject const* (*m_to_python_target_type)();
// True iff this type is a shared_ptr. Needed for special rvalue
// from_python handling.
@@ -76,6 +85,7 @@ inline registration::registration(type_info target_type, bool is_shared_ptr)
, rvalue_chain(0)
, m_class_object(0)
, m_to_python(0)
, m_to_python_target_type(0)
, is_shared_ptr(is_shared_ptr)
{}

View File

@@ -27,16 +27,17 @@ namespace registry
// Return a pointer to the corresponding registration, if one exists
BOOST_PYTHON_DECL registration const* query(type_info);
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info, PyTypeObject const* (*to_python_target_type)() = 0);
// Insert an lvalue from_python converter
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info, PyTypeObject const* (*expected_pytype)() = 0);
// Insert an rvalue from_python converter
BOOST_PYTHON_DECL void insert(
convertible_function
, constructor_function
, type_info
, PyTypeObject const* (*expected_pytype)() = 0
);
// Insert an rvalue from_python converter at the tail of the
@@ -45,6 +46,7 @@ namespace registry
convertible_function
, constructor_function
, type_info
, PyTypeObject const* (*expected_pytype)() = 0
);
}

View File

@@ -10,6 +10,9 @@
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registered.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/shared_ptr.hpp>
namespace boost { namespace python { namespace converter {
@@ -19,7 +22,11 @@ struct shared_ptr_from_python
{
shared_ptr_from_python()
{
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &converter::expected_from_python_type_direct<T>::get_pytype
#endif
);
}
private:

View File

@@ -13,6 +13,7 @@
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/front.hpp>
namespace boost { namespace python {
@@ -49,6 +50,12 @@ struct default_call_policies
typedef default_result_converter result_converter;
typedef PyObject* argument_package;
template <class Sig>
struct extract_return_type : mpl::front<Sig>
{
};
};
struct default_result_converter

View File

@@ -11,12 +11,15 @@
# include <boost/python/type_id.hpp>
# include <boost/python/handle.hpp>
# include <boost/detail/indirect_traits.hpp>
# include <boost/python/detail/invoke.hpp>
# include <boost/python/detail/signature.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/cat.hpp>
@@ -89,6 +92,27 @@ inline ResultConverter create_result_converter(
{
return ResultConverter();
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
template <class ResultConverter>
struct converter_target_type
{
static PyTypeObject const *get_pytype()
{
return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
}
};
template < >
struct converter_target_type <void_result_to_python >
{
static PyTypeObject const *get_pytype()
{
return 0;
}
};
#endif
template <unsigned> struct caller_arity;
@@ -203,11 +227,26 @@ struct caller_arity<N>
static unsigned min_arity() { return N; }
static signature_element const* signature()
static py_func_sig_info signature()
{
return detail::signature<Sig>::elements();
const signature_element * sig = detail::signature<Sig>::elements();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
typedef typename select_result_converter<Policies, rtype>::type result_converter;
static const signature_element ret = {
(boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
, &detail::converter_target_type<result_converter>::get_pytype
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
};
py_func_sig_info res = {sig, &ret };
#else
py_func_sig_info res = {sig, sig };
#endif
return res;
}
private:
compressed_pair<F,Policies> m_data;
};

View File

@@ -134,4 +134,8 @@
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -155,7 +155,7 @@ namespace detail
, T3 const&
, T4 const&
, default_call_policies
, keywords<0>
, detail::keywords<0>
, char const*
, void(not_specified::*)() // A function pointer type which is never an
// appropriate default implementation

View File

@@ -168,7 +168,7 @@ namespace detail
char const* doc)
{
// define the NTH stub function of stubs
define_stub_function<N>::define(name, stubs, kw, policies, name_space, 0);
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
if (kw.second > kw.first)
--kw.second;

View File

@@ -248,7 +248,7 @@ namespace detail
BOOST_PYTHON_GEN_MEM_FUNCTION( \
fname, void_return_type, n_args, n_dflts, ;) \
\
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
};
# else // !defined(BOOST_NO_VOID_RETURNS)
@@ -273,7 +273,7 @@ namespace detail
fname, non_void_return_type, n_args, n_dflts, return) \
\
typedef non_void_return_type void_return_type; \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
};
# endif // !defined(BOOST_NO_VOID_RETURNS)

View File

@@ -57,6 +57,9 @@ object make_keyword_range_constructor(
, Holder* = 0
, ArgList* = 0, Arity* = 0)
{
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
#endif
return detail::make_keyword_range_function(
objects::make_holder<Arity::value>
::template apply<Holder,ArgList>::execute

View File

@@ -47,7 +47,8 @@ enum operator_id
op_ixor,
op_ior,
op_complex,
op_nonzero
op_nonzero,
op_repr
};
}}} // namespace boost::python::detail

View File

@@ -0,0 +1,37 @@
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
#define BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
#include <boost/python/converter/registered.hpp>
namespace boost {namespace python {namespace detail{
template <class T> struct python_class : PyObject
{
typedef python_class<T> this_type;
typedef T type;
static void *converter (PyObject *p){
return p;
}
static void register_()
{
static bool first_time = true;
if ( !first_time ) return;
first_time = false;
converter::registry::insert(&converter, boost::python::type_id<this_type>(), &converter::registered_pytype_direct<T>::get_pytype);
}
};
}}} //namespace boost :: python :: detail
#endif //BOOST_PYTHON_OBJECT_PYTHON_TYPE_H

View File

@@ -12,6 +12,7 @@
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/converter/pytype_function.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/iteration/local.hpp>
@@ -24,9 +25,16 @@ namespace boost { namespace python { namespace detail {
struct signature_element
{
char const* basename;
converter::pytype_function pytype_f;
bool lvalue;
};
struct py_func_sig_info
{
signature_element const *signature;
signature_element const *ret;
};
template <unsigned> struct signature_arity;
# define BOOST_PP_ITERATION_PARAMS_1 \
@@ -68,15 +76,25 @@ struct signature_arity<N>
{
static signature_element const result[N+2] = {
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# define BOOST_PP_LOCAL_MACRO(i) \
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, &converter::expected_pytype_for_arg<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::get_pytype \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
#else
# define BOOST_PP_LOCAL_MACRO(i) \
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, 0 \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
#endif
# define BOOST_PP_LOCAL_LIMITS (0, N)
# include BOOST_PP_LOCAL_ITERATE()
{0,0}
{0,0,0}
};
return result;
}

View File

@@ -0,0 +1,170 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef UNWIND_TYPE_DWA200222_HPP
# define UNWIND_TYPE_DWA200222_HPP
# include <boost/python/detail/cv_category.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
namespace boost { namespace python { namespace detail {
#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(U const& p, Generator* = 0);
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(boost::type<U>*p = 0, Generator* = 0);
#endif
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
{
return Generator::execute(p);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const* p, const_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_ptr_type(U* p, Generator* = 0)
{
typedef typename cv_category<U>::type tag;
return unwind_type_cv<Generator>(p, tag());
}
template <bool is_ptr>
struct unwind_helper
{
template <class Generator, class U>
static typename Generator::result_type
execute(U p, Generator* = 0)
{
return unwind_ptr_type(p, (Generator*)0);
}
};
template <>
struct unwind_helper<false>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U& p, Generator* = 0)
{
return unwind_ptr_type(&p, (Generator*)0);
}
};
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
unwind_type(U const& p, Generator*)
#else
unwind_type(U const& p, Generator* = 0)
#endif
{
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
}
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
template <int indirection> struct unwind_helper2;
template <>
struct unwind_helper2<direct_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U*(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_to_pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type(U(0), (Generator*)0);
}
};
// Call this one with both template parameters explicitly specified
// and no function arguments:
//
// return unwind_type<my_generator,T>();
//
// Doesn't work if T is an array type; we could handle that case, but
// why bother?
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
unwind_type(boost::type<U>*p, Generator*)
#else
unwind_type(boost::type<U>*p =0, Generator* =0)
#endif
{
BOOST_STATIC_CONSTANT(int, indirection
= (boost::is_pointer<U>::value ? pointer_ : 0)
+ (indirect_traits::is_reference_to_pointer<U>::value
? reference_to_pointer_
: boost::is_reference<U>::value
? reference_
: 0));
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
}
}}} // namespace boost::python::detail
#endif // UNWIND_TYPE_DWA200222_HPP

View File

@@ -17,23 +17,38 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
docstring_options(bool show_all=true)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_signatures_ = show_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
show_user_defined_ = show_all;
show_signatures_ = show_all;
show_cpp_signatures_ = show_all;
show_py_signatures_ = show_all;
}
docstring_options(bool show_user_defined, bool show_signatures)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_signatures_ = show_signatures_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
show_user_defined_ = show_user_defined;
show_signatures_ = show_signatures;
show_cpp_signatures_ = show_signatures;
show_py_signatures_ = show_signatures;
}
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
show_user_defined_ = show_user_defined;
show_cpp_signatures_ = show_cpp_signatures;
show_py_signatures_ = show_py_signatures;
}
~docstring_options()
{
show_user_defined_ = previous_show_user_defined_;
show_signatures_ = previous_show_signatures_;
show_cpp_signatures_ = previous_show_cpp_signatures_;
show_py_signatures_ = previous_show_py_signatures_;
}
void
@@ -43,32 +58,68 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
enable_user_defined() { show_user_defined_ = true; }
void
disable_signatures() { show_signatures_ = false; }
disable_py_signatures()
{
show_py_signatures_ = false;
}
void
enable_signatures() { show_signatures_ = true; }
enable_py_signatures()
{
show_py_signatures_ = true;
}
void
disable_cpp_signatures()
{
show_cpp_signatures_ = false;
}
void
enable_cpp_signatures()
{
show_cpp_signatures_ = true;
}
void
disable_signatures()
{
show_cpp_signatures_ = false;
show_py_signatures_ = false;
}
void
enable_signatures()
{
show_cpp_signatures_ = true;
show_py_signatures_ = true;
}
void
disable_all()
{
show_user_defined_ = false;
show_signatures_ = false;
show_cpp_signatures_ = false;
show_py_signatures_ = false;
}
void
enable_all()
{
show_user_defined_ = true;
show_signatures_ = true;
show_cpp_signatures_ = true;
show_py_signatures_ = true;
}
friend struct objects::function;
private:
static volatile bool show_user_defined_;
static volatile bool show_signatures_;
static volatile bool show_cpp_signatures_;
static volatile bool show_py_signatures_;
bool previous_show_user_defined_;
bool previous_show_signatures_;
bool previous_show_cpp_signatures_;
bool previous_show_py_signatures_;
};
}} // namespace boost::python

View File

@@ -19,7 +19,7 @@ struct enum_ : public objects::enum_base
typedef objects::enum_base base;
// Declare a new enumeration type in the current scope()
enum_(char const* name);
enum_(char const* name, char const* doc = 0);
// Add a new enumeration value with the given name and value.
inline enum_<T>& value(char const* name, T);
@@ -34,13 +34,15 @@ struct enum_ : public objects::enum_base
};
template <class T>
inline enum_<T>::enum_(char const* name)
inline enum_<T>::enum_(char const* name, char const* doc )
: base(
name
, &enum_<T>::to_python
, &enum_<T>::convertible_from_python
, &enum_<T>::construct
, type_id<T>())
, type_id<T>()
, doc
)
{
}

View File

@@ -9,6 +9,9 @@
# include <boost/type.hpp>
# include <boost/python/converter/implicit.hpp>
# include <boost/python/converter/registry.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/type_id.hpp>
namespace boost { namespace python {
@@ -21,7 +24,11 @@ void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
converter::registry::push_back(
&functions::convertible
, &functions::construct
, type_id<Target>());
, type_id<Target>()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &converter::expected_from_python_type_direct<Source>::get_pytype
#endif
);
}
}} // namespace boost::python

View File

@@ -245,7 +245,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: base(doc_, kw.range())
{
typedef typename detail::error::more_keywords_than_init_arguments<
N, n_arguments::value
N, n_arguments::value + 1
>::too_many_keywords assertion;
}
@@ -254,7 +254,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: base(doc_, kw.range())
{
typedef typename detail::error::more_keywords_than_init_arguments<
N, n_arguments::value
N, n_arguments::value + 1
>::too_many_keywords assertion;
}
@@ -363,7 +363,7 @@ namespace detail
, char const* doc
, detail::keyword_range keywords)
{
detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
if (keywords.second > keywords.first)
--keywords.second;

View File

@@ -6,6 +6,9 @@
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
# include <boost/python/detail/prefix.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/type_id.hpp>
# include <boost/python/converter/registry.hpp>
@@ -81,12 +84,17 @@ struct extract_identity
// Extractor's static execute function from Python objects whose type
// object is python_type.
template <class Extractor, PyTypeObject const* python_type>
struct lvalue_from_pytype
struct lvalue_from_pytype
{
lvalue_from_pytype()
{
converter::registry::insert(
&extract, detail::extractor_type_id(&Extractor::execute));
converter::registry::insert
( &extract
, detail::extractor_type_id(&Extractor::execute)
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &get_pytype
#endif
);
}
private:
static void* extract(PyObject* op)
@@ -98,6 +106,9 @@ struct lvalue_from_pytype
: 0
;
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const*get_pytype() { return python_type; }
#endif
};
}} // namespace boost::python

View File

@@ -23,6 +23,7 @@
# include <boost/mpl/int.hpp>
# include <boost/mpl/push_front.hpp>
# include <boost/mpl/pop_front.hpp>
# include <boost/mpl/assert.hpp>
namespace boost { namespace python {
@@ -103,13 +104,23 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
BOOST_STATIC_ASSERT((
is_same<
#if defined _MSC_VER && _MSC_VER < 1300
typedef is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value
));
> same_result_converter;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
#else
BOOST_MPL_ASSERT_MSG(
(is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value)
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
, (typename BasePolicy_::result_converter)
);
#endif
typedef constructor_result_converter result_converter;
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
};

View File

@@ -26,7 +26,23 @@ extern "C" __declspec(dllexport) void init##name() \
} \
void init_module_##name()
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# elif defined(_AIX) && !defined(BOOST_PYTHON_STATIC_MODULE)
# include <boost/python/detail/aix_init_module.hpp>
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" \
{ \
extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \
void init##name() \
{ \
boost::python::detail::aix_init_module( \
_PyImport_LoadDynamicModule, #name, &init_module_##name); \
} \
} \
void init_module_##name()
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
@@ -36,7 +52,7 @@ extern "C" __attribute__ ((visibility("default"))) void init##name() \
} \
void init_module_##name()
# else
# else
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \

View File

@@ -238,6 +238,14 @@ struct class_metadata
//
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_*)
{
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
}
#endif
template <class T2>
inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
{
@@ -247,6 +255,10 @@ struct class_metadata
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
>()
);
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
}
//
// Support for registering to-python converters
@@ -258,6 +270,10 @@ struct class_metadata
inline static void maybe_register_class_to_python(T2*, mpl::false_)
{
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
}
//

View File

@@ -6,6 +6,9 @@
# define CLASS_WRAPPER_DWA20011221_HPP
# include <boost/python/to_python_converter.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/ref.hpp>
namespace boost { namespace python { namespace objects {
@@ -19,22 +22,28 @@ namespace boost { namespace python { namespace objects {
template <class Src, class MakeInstance>
struct class_cref_wrapper
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> >
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> ,true>
{
static PyObject* convert(Src const& x)
{
return MakeInstance::execute(boost::ref(x));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() { return converter::registered_pytype_direct<Src>::get_pytype(); }
#endif
};
template <class Src, class MakeInstance>
struct class_value_wrapper
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> >
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> ,true>
{
static PyObject* convert(Src x)
{
return MakeInstance::execute(x);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() { return MakeInstance::get_pytype(); }
#endif
};
}}} // namespace boost::python::objects

View File

@@ -21,7 +21,9 @@ struct BOOST_PYTHON_DECL enum_base : python::api::object
, converter::to_python_function_t
, converter::convertible_function
, converter::constructor_function
, type_info);
, type_info
, const char *doc = 0
);
void add_value(char const* name, long value);
void export_values();

View File

@@ -14,6 +14,7 @@
namespace boost { namespace python { namespace objects {
struct BOOST_PYTHON_DECL function : PyObject
{
function(
@@ -53,6 +54,7 @@ struct BOOST_PYTHON_DECL function : PyObject
object m_doc;
object m_arg_names;
unsigned m_nkeyword_values;
friend class function_doc_signature_generator;
};
//

View File

@@ -0,0 +1,36 @@
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_SIGNATURE_20070531_HPP
# define FUNCTION_SIGNATURE_20070531_HPP
#include <boost/python/object/function.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/str.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/detail/signature.hpp>
#include <vector>
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator{
static const char * py_type_str(const python::detail::signature_element &s);
static bool arity_cmp( function const *f1, function const *f2 );
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
static std::vector<function const*> flatten(function const *f);
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
public:
static list function_doc_signatures( function const * f);
};
}}}//end of namespace boost::python::objects
#endif //FUNCTION_SIGNATURE_20070531_HPP

View File

@@ -11,6 +11,10 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/object/instance.hpp>
# include <boost/python/converter/registry.hpp>
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
# include <boost/python/detail/python_type.hpp>
#endif
# include <boost/python/object/forward.hpp>
# include <boost/python/detail/preprocessor.hpp>
@@ -74,7 +78,11 @@ struct make_holder<N>
# endif
static void execute(
PyObject* p
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
#else
PyObject *p
#endif
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
{
typedef instance<Holder> instance_t;

View File

@@ -29,7 +29,12 @@ struct make_ptr_instance
{
return get_class_object_impl(get_pointer(x));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static inline PyTypeObject const* get_pytype()
{
return converter::registered<T>::converters.get_class_object();
}
#endif
private:
template <class U>
static inline PyTypeObject* get_class_object_impl(U const volatile* p)

View File

@@ -23,7 +23,7 @@ struct BOOST_PYTHON_DECL py_function_impl_base
virtual PyObject* operator()(PyObject*, PyObject*) = 0;
virtual unsigned min_arity() const = 0;
virtual unsigned max_arity() const;
virtual python::detail::signature_element const* signature() const = 0;
virtual python::detail::py_func_sig_info signature() const = 0;
};
template <class Caller>
@@ -43,7 +43,7 @@ struct caller_py_function_impl : py_function_impl_base
return m_caller.min_arity();
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return m_caller.signature();
}
@@ -69,9 +69,11 @@ struct signature_py_function_impl : py_function_impl_base
return mpl::size<Sig>::value - 1;
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return python::detail::signature<Sig>::elements();
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
python::detail::py_func_sig_info res = {sig, sig};
return res;
}
private:
@@ -102,9 +104,11 @@ struct full_py_function_impl : py_function_impl_base
return m_max_arity;
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return python::detail::signature<Sig>::elements();
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
python::detail::py_func_sig_info res = {sig, sig};
return res;
}
private:
@@ -151,7 +155,12 @@ struct py_function
python::detail::signature_element const* signature() const
{
return m_impl->signature();
return m_impl->signature().signature;
}
python::detail::signature_element const& get_return_type() const
{
return *m_impl->signature().ret;
}
private:

View File

@@ -470,6 +470,9 @@ namespace converter
{
return python::detail::new_non_null_reference(x);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() {return 0;}
#endif
};
}

View File

@@ -1,4 +1,4 @@
// Copyright Gottfried Ganßauge 2003..2006
// Copyright Gottfried Ganßauge 2003..2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -93,8 +93,13 @@ private:
if ((existing == 0) || (existing->m_to_python == 0))
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
#else
converter::registry::insert(&extract, type_id<Pointee>());
converter::registry::insert(&wrap, type_id<Pointee*>());
#endif
}
}
@@ -105,6 +110,9 @@ private:
};
static PyTypeObject type_object;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype(){return &type_object; }
#endif
};
template <class Pointee>

View File

@@ -347,6 +347,7 @@ BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
BOOST_PYTHON_UNARY_OPERATOR(repr, lexical_cast<std::string>, repr)
# undef BOOST_PYTHON_UNARY_OPERATOR
}} // namespace boost::python
@@ -358,6 +359,7 @@ using boost::python::self_ns::long_;
using boost::python::self_ns::float_;
using boost::python::self_ns::complex_;
using boost::python::self_ns::str;
using boost::python::self_ns::repr;
using boost::python::self_ns::pow;
# endif

View File

@@ -8,10 +8,15 @@
# include <boost/python/detail/none.hpp>
# include <boost/python/detail/value_arg.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/at.hpp>
# include <boost/static_assert.hpp>
# include <boost/python/refcount.hpp>
@@ -44,6 +49,9 @@ namespace detail
{
return none();
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
PyTypeObject const *get_pytype() const { return converter::expected_pytype_for_arg<T>::get_pytype() ; }
#endif
};
};
};
@@ -82,6 +90,12 @@ struct return_arg : Base
Py_DECREF(result);
return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
}
template <class Sig>
struct extract_return_type : mpl::at_c<Sig, arg_pos>
{
};
};
template <

View File

@@ -9,13 +9,67 @@
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/as_to_python_function.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/type_id.hpp>
namespace boost { namespace python {
template <class T, class Conversion>
struct to_python_converter
#if 0 //get_pytype member detection
namespace detail
{
typedef char yes_type;
typedef struct {char a[2]; } no_type;
template<PyTypeObject const * (*f)()> struct test_get_pytype1 { };
template<PyTypeObject * (*f)()> struct test_get_pytype2 { };
template<class T> yes_type tester(test_get_pytype1<&T::get_pytype>*);
template<class T> yes_type tester(test_get_pytype2<&T::get_pytype>*);
template<class T> no_type tester(...);
template<class T>
struct test_get_pytype_base
{
BOOST_STATIC_CONSTANT(bool, value= (sizeof(detail::tester<T>(0)) == sizeof(yes_type)));
};
template<class T>
struct test_get_pytype : boost::mpl::bool_<test_get_pytype_base<T>::value>
{
};
}
#endif
template < class T, class Conversion, bool has_get_pytype=false >
struct to_python_converter
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
#if 0 //defined _MSC_VER && _MSC_VER >=1310
//probably other compilers could come here as well
typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
#else
typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
#endif
static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
{
return Conversion::get_pytype();
}
static PyTypeObject const* get_pytype_1(boost::mpl::false_ *)
{
return 0;
}
static PyTypeObject const* get_pytype_impl()
{
return get_pytype_1((HasGetPytype*)0);
}
#endif
to_python_converter();
};
@@ -23,18 +77,23 @@ struct to_python_converter
// implementation
//
template <class T, class Conversion>
to_python_converter<T,Conversion>::to_python_converter()
template <class T, class Conversion ,bool has_get_pytype>
to_python_converter<T,Conversion, has_get_pytype>::to_python_converter()
{
typedef converter::as_to_python_function<
T, Conversion
> normalized;
converter::registry::insert(
&normalized::convert
, type_id<T>());
, type_id<T>()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &get_pytype_impl
#endif
);
}
}} // namespace boost::python
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP

View File

@@ -12,6 +12,10 @@
# include <boost/python/detail/none.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/refcount.hpp>
# include <boost/type_traits/is_pointer.hpp>
@@ -36,7 +40,13 @@ struct to_python_indirect
{
return this->execute(const_cast<U&>(ref), is_pointer<U>());
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
inline PyTypeObject const*
get_pytype()const
{
return converter::registered_pytype<T>::get_pytype();
}
#endif
private:
template <class U>
inline PyObject* execute(U* ptr, mpl::true_) const

View File

@@ -9,12 +9,12 @@
# include <boost/python/refcount.hpp>
# include <boost/python/tag.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/python/converter/shared_ptr_to_python.hpp>
# include <boost/python/detail/value_is_shared_ptr.hpp>
@@ -24,17 +24,57 @@
# include <boost/mpl/if.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/is_const.hpp>
namespace boost { namespace python {
namespace detail
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
template <bool is_const_ref>
struct object_manager_get_pytype
{
template <class U>
static PyTypeObject const* get( U& (*p)() =0)
{
return converter::object_manager_traits<U>::get_pytype();
}
};
template <>
struct object_manager_get_pytype<true>
{
template <class U>
static PyTypeObject const* get( U const& (*p)() =0)
{
return converter::object_manager_traits<U>::get_pytype();
}
};
#endif
template <class T>
struct object_manager_to_python_value
{
typedef typename value_arg<T>::type argument_type;
PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
PyTypeObject const* get_pytype() const {
return get_pytype_aux((is_t_handle*)0);
}
inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
{
return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
}
#endif
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
@@ -49,6 +89,9 @@ namespace detail
typedef typename value_arg<T>::type argument_type;
PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
#endif
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
@@ -62,11 +105,20 @@ namespace detail
typedef typename value_arg<T>::type argument_type;
PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
#endif
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
// but it will have to serve for now.
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
private:
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
template <class U>
PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
template <class U>
PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
#endif
};
}

141
src/aix_init_module.cpp Normal file
View File

@@ -0,0 +1,141 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifdef _AIX
#include <cstdio>
#include <cstdlib>
extern "C"
{
#include <sys/stat.h>
#include <unistd.h>
}
# include <string>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/detail/aix_init_module.hpp>
# include <boost/python/module.hpp>
namespace boost { namespace python { namespace detail {
namespace
{
static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
extern "C" void initlibboost_python()
{
Py_InitModule("libboost_python", initial_methods);
}
struct find_and_open_file
{
FILE* fp;
std::string libpath; // -- search path
std::string filename; // -- filename to look for
std::string fullpath; // -- full path to file
find_and_open_file(
const std::string& libpath_env
, const std::string& file);
};
find_and_open_file::find_and_open_file(
const std::string& libpath_env
, const std::string& file)
: fp(0)
{
char* value = std::getenv(libpath_env.c_str());
if(value == 0)
return;
libpath = value;
if (libpath == "")
return;
std::string::size_type pos = 0, prev_pos = 0;
// -- loop through all search paths looking for file
while((pos = libpath.find_first_of(":",pos)) != std::string::npos)
{
fullpath = libpath.substr(prev_pos,pos - prev_pos) + "/" + file;
if (::access(fullpath.c_str(), R_OK) == 0)
{
struct stat filestat;
::stat(fullpath.c_str(), &filestat);
if (!S_ISDIR(filestat.st_mode))
{
fp = std::fopen(fullpath.c_str(), "r");
if (fp)
{
filename = file;
}
return;
}
}
prev_pos = ++pos;
}
// -- mop up odd path
if (libpath.find_first_of(":", prev_pos) == std::string::npos)
{
fullpath = libpath.substr(prev_pos, libpath.size() - prev_pos) + "/" + file;
if (::access(fullpath.c_str(), R_OK) == 0)
{
struct stat filestat;
::stat(fullpath.c_str(),&filestat);
if (!S_ISDIR(filestat.st_mode))
{
fp = std::fopen(fullpath.c_str(), "r");
filename = file;
}
}
}
}
}
void aix_init_module(
so_load_function load_dynamic_module
, char const* module_name
, void (*init_module)())
{
static bool initialized;
if (!initialized)
{
char const* const name = "libboost_python.so";
find_and_open_file dynlib("LIBPATH", name);
if (dynlib.fp == 0)
{
fprintf(stderr, " Error: could not find %s\n", name);
return;
}
std::string::size_type pos = pos = dynlib.filename.rfind(".so");
if (pos != dynlib.filename.size() - 3)
{
fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str());
return;
}
PyObject* m =
load_dynamic_module(
const_cast<char*>(dynlib.filename.substr(0,pos).c_str()),
const_cast<char*>(dynlib.fullpath.c_str()),
dynlib.fp);
if (m == 0)
{
fprintf(stderr, "failed to load library %s\n", name);
return;
}
Py_DECREF(m);
initialized = true;
}
python::detail::init_module(module_name, init_module);
}
}}} // namespace boost::python
#endif

View File

@@ -16,6 +16,7 @@
#include <boost/python/converter/registry.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/converter/shared_ptr_deleter.hpp>
#include <boost/python/converter/pytype_function.hpp>
#include <boost/cast.hpp>
#include <string>
@@ -56,6 +57,7 @@ namespace
&slot_rvalue_from_python<T,SlotPolicy>::convertible
, &slot_rvalue_from_python<T,SlotPolicy>::construct
, type_id<T>()
, &SlotPolicy::get_pytype
);
}
@@ -100,6 +102,7 @@ namespace
return (PyInt_Check(obj) || PyLong_Check(obj))
? &number_methods->nb_int : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
template <class T>
@@ -135,6 +138,7 @@ namespace
return (PyInt_Check(obj) || PyLong_Check(obj))
? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
template <class T>
@@ -173,6 +177,7 @@ namespace
else
return 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
@@ -228,6 +233,15 @@ namespace
{
return PyObject_IsTrue(intermediate);
}
static PyTypeObject const* get_pytype()
{
#if PY_VERSION_HEX >= 0x02030000
return &PyBool_Type;
#else
return &PyInt_Type;
#endif
}
};
// A SlotPolicy for extracting floating types from Python objects.
@@ -259,6 +273,7 @@ namespace
return PyFloat_AS_DOUBLE(intermediate);
}
}
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
};
// A SlotPolicy for extracting C++ strings from Python objects.
@@ -276,6 +291,7 @@ namespace
{
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
}
static PyTypeObject const* get_pytype() { return &PyString_Type;}
};
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
@@ -316,6 +332,7 @@ namespace
}
return result;
}
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
};
#endif
@@ -346,6 +363,7 @@ namespace
return PyFloat_AS_DOUBLE(intermediate);
}
}
static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
};
}
@@ -411,7 +429,7 @@ void initialize_builtin_converters()
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
// Add an lvalue converter for char which gets us char const*
registry::insert(convert_to_cstring,type_id<char>());
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
// Register by-value converters to std::string, std::wstring
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)

View File

@@ -20,6 +20,35 @@
#endif
namespace boost { namespace python { namespace converter {
BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
{
if (this->m_class_object != 0)
return this->m_class_object;
std::set<PyTypeObject const*> pool;
for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
if(r->expected_pytype)
pool.insert(r->expected_pytype());
//for now I skip the search for common base
if (pool.size()==1)
return *pool.begin();
return 0;
}
BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
{
if (this->m_class_object != 0)
return this->m_class_object;
if (this->m_to_python_target_type != 0)
return this->m_to_python_target_type();
return 0;
}
BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
{
@@ -57,6 +86,24 @@ BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source)
: this->m_to_python(const_cast<void*>(source));
}
namespace
{
template< typename T >
void delete_node( T* node )
{
if( !!node && !!node->next )
delete_node( node->next );
delete node;
}
}
registration::~registration()
{
delete_node(lvalue_chain);
delete_node(rvalue_chain);
}
namespace // <unnamed>
{
typedef registration entry;
@@ -150,15 +197,15 @@ namespace // <unnamed>
namespace registry
{
void insert(to_python_function_t f, type_info source_t)
void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
{
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "inserting to_python " << source_t << "\n";
# endif
to_python_function_t& slot = get(source_t)->m_to_python;
entry* slot = get(source_t);
assert(slot == 0); // we have a problem otherwise
if (slot != 0)
assert(slot->m_to_python == 0); // we have a problem otherwise
if (slot->m_to_python != 0)
{
std::string msg = (
std::string("to-Python converter for ")
@@ -171,11 +218,12 @@ namespace registry
throw_error_already_set();
}
}
slot = f;
slot->m_to_python = f;
slot->m_to_python_target_type = to_python_target_type;
}
// Insert an lvalue from_python converter
void insert(convertible_function convert, type_info key)
void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
{
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "inserting lvalue from_python " << key << "\n";
@@ -186,13 +234,14 @@ namespace registry
registration->next = found->lvalue_chain;
found->lvalue_chain = registration;
insert(convert, 0, key);
insert(convert, 0, key,exp_pytype);
}
// Insert an rvalue from_python converter
void insert(void* (*convertible)(PyObject*)
, constructor_function construct
, type_info key)
, type_info key
, PyTypeObject const* (*exp_pytype)())
{
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "inserting rvalue from_python " << key << "\n";
@@ -201,6 +250,7 @@ namespace registry
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
registration->convertible = convertible;
registration->construct = construct;
registration->expected_pytype = exp_pytype;
registration->next = found->rvalue_chain;
found->rvalue_chain = registration;
}
@@ -208,7 +258,8 @@ namespace registry
// Insert an rvalue from_python converter
void push_back(void* (*convertible)(PyObject*)
, constructor_function construct
, type_info key)
, type_info key
, PyTypeObject const* (*exp_pytype)())
{
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "push_back rvalue from_python " << key << "\n";
@@ -220,6 +271,7 @@ namespace registry
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
registration->convertible = convertible;
registration->construct = construct;
registration->expected_pytype = exp_pytype;
registration->next = 0;
*found = registration;
}

View File

@@ -171,4 +171,14 @@ list dict_base::values() const
}
}
static struct register_dict_pytype_ptr
{
register_dict_pytype_ptr()
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::dict>())
).m_class_object = &PyDict_Type;
}
}register_dict_pytype_ptr_;
}}} // namespace boost::python

View File

@@ -137,4 +137,14 @@ long list_base::count(object_cref value) const
return result;
}
static struct register_list_pytype_ptr
{
register_list_pytype_ptr()
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::list>())
).m_class_object = &PyList_Type;
}
}register_list_pytype_ptr_;
}}} // namespace boost::python

View File

@@ -532,6 +532,10 @@ namespace objects
if (scope().ptr() != Py_None)
scope().attr(name) = result;
// For pickle. Will lead to informative error messages if pickling
// is not enabled.
result.attr("__reduce__") = object(make_instance_reduce_function());
return result;
}
}
@@ -629,7 +633,6 @@ namespace objects
void class_base::enable_pickling_(bool getstate_manages_dict)
{
setattr("__reduce__", object(make_instance_reduce_function()));
setattr("__safe_for_unpickling__", object(true));
if (getstate_manages_dict)

View File

@@ -32,10 +32,11 @@ extern "C"
{
static PyObject* enum_repr(PyObject* self_)
{
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, "__module__"));
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
return PyString_FromFormat("%s(%ld)", self_->ob_type->tp_name, PyInt_AS_LONG(self_));
return PyString_FromFormat("%s.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
}
else
{
@@ -43,7 +44,7 @@ extern "C"
if (name == 0)
return 0;
return PyString_FromFormat("%s.%s", self_->ob_type->tp_name, name);
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
}
}
@@ -120,7 +121,7 @@ object module_prefix();
namespace
{
object new_enum_type(char const* name)
object new_enum_type(char const* name, char const *doc)
{
if (enum_type_object.tp_dict == 0)
{
@@ -141,10 +142,11 @@ namespace
object module_name = module_prefix();
if (module_name)
module_name += '.';
d["__module__"] = module_name;
if (doc)
d["__doc__"] = doc;
object result = (object(metatype))(
module_name + name, make_tuple(base), d);
object result = (object(metatype))(name, make_tuple(base), d);
scope().attr(name) = result;
@@ -158,8 +160,9 @@ enum_base::enum_base(
, converter::convertible_function convertible
, converter::constructor_function construct
, type_info id
, char const *doc
)
: object(new_enum_type(name))
: object(new_enum_type(name, doc))
{
converter::registration& converters
= const_cast<converter::registration&>(

View File

@@ -6,6 +6,7 @@
#include <boost/python/docstring_options.hpp>
#include <boost/python/object/function_object.hpp>
#include <boost/python/object/function_handle.hpp>
#include <boost/python/object/function_doc_signature.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/str.hpp>
#include <boost/python/object_attributes.hpp>
@@ -17,6 +18,7 @@
#include <boost/python/ssize_t.hpp>
#include <boost/python/detail/signature.hpp>
#include <boost/python/detail/none.hpp>
#include <boost/mpl/vector/vector10.hpp>
#include <boost/bind.hpp>
@@ -30,7 +32,12 @@
namespace boost { namespace python {
volatile bool docstring_options::show_user_defined_ = true;
volatile bool docstring_options::show_signatures_ = true;
volatile bool docstring_options::show_cpp_signatures_ = true;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
volatile bool docstring_options::show_py_signatures_ = true;
#else
volatile bool docstring_options::show_py_signatures_ = false;
#endif
}}
namespace boost { namespace python { namespace objects {
@@ -411,6 +418,12 @@ void function::add_to_namespace(
add_to_namespace(name_space, name_, attribute, 0);
}
namespace detail
{
extern char py_signature_tag[];
extern char cpp_signature_tag[];
}
void function::add_to_namespace(
object const& name_space, char const* name_, object const& attribute, char const* doc)
{
@@ -487,6 +500,7 @@ void function::add_to_namespace(
throw_error_already_set();
object mutable_attribute(attribute);
/*
if (doc != 0 && docstring_options::show_user_defined_)
{
// Accumulate documentation
@@ -507,7 +521,8 @@ void function::add_to_namespace(
{
if ( PyObject_HasAttrString(mutable_attribute.ptr(), "__doc__")
&& mutable_attribute.attr("__doc__")) {
mutable_attribute.attr("__doc__") += "\n";
mutable_attribute.attr("__doc__") += (
mutable_attribute.attr("__doc__")[-1] != "\n" ? "\n\n" : "\n");
}
else {
mutable_attribute.attr("__doc__") = "";
@@ -516,6 +531,28 @@ void function::add_to_namespace(
mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
"C++ signature:", f->signature(true)));
}
*/
str _doc;
if (docstring_options::show_py_signatures_)
{
_doc += str(reinterpret_cast<const char*>(detail::py_signature_tag));
}
if (doc != 0 && docstring_options::show_user_defined_)
_doc += doc;
if (docstring_options::show_cpp_signatures_)
{
// if(len(_doc))
// _doc += "\n"+str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
// else
_doc += str(reinterpret_cast<const char*>(detail::cpp_signature_tag));
}
if(_doc)
{
object mutable_attribute(attribute);
mutable_attribute.attr("__doc__")= _doc;
}
}
BOOST_PYTHON_DECL void add_to_namespace(
@@ -590,7 +627,10 @@ extern "C"
static PyObject* function_get_doc(PyObject* op, void*)
{
function* f = downcast<function>(op);
return python::incref(f->doc().ptr());
list signatures = function_doc_signature_generator::function_doc_signatures(f);
if(!signatures) return python::detail::none();
signatures.reverse();
return python::incref( str("\n").join(signatures).ptr());
}
static int function_set_doc(PyObject* op, PyObject* doc, void*)

View File

@@ -0,0 +1,342 @@
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/converter/registrations.hpp>
#include <boost/python/object/function_doc_signature.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/str.hpp>
#include <boost/python/args.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/detail/signature.hpp>
#include <vector>
namespace boost { namespace python { namespace objects {
bool function_doc_signature_generator::arity_cmp( function const *f1, function const *f2 )
{
return f1->m_fn.max_arity() < f2->m_fn.max_arity();
}
bool function_doc_signature_generator::are_seq_overloads( function const *f1, function const *f2 , bool check_docs)
{
py_function const & impl1 = f1->m_fn;
py_function const & impl2 = f2->m_fn;
//the number of parameters differs by 1
if (impl2.max_arity()-impl1.max_arity() != 1)
return false;
// if check docs then f1 shold not have docstring or have the same docstring as f2
if (check_docs && f2->doc() != f1->doc() && f1->doc())
return false;
python::detail::signature_element const* s1 = impl1.signature();
python::detail::signature_element const* s2 = impl2.signature();
unsigned size = impl1.max_arity()+1;
for (unsigned i = 0; i != size; ++i)
{
//check if the argument types are the same
if (s1[i].basename != s2[i].basename)
return false;
//return type
if (!i) continue;
//check if the argument default values are the same
bool f1_has_names = bool(f1->m_arg_names);
bool f2_has_names = bool(f2->m_arg_names);
if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
|| f1_has_names && !f2_has_names
|| !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
)
return false;
}
return true;
}
std::vector<function const*> function_doc_signature_generator::flatten(function const *f)
{
object name = f->name();
std::vector<function const*> res;
while (f) {
//this if takes out the not_implemented_function
if (f->name() == name)
res.push_back(f);
f=f->m_overloads.get();
}
//std::sort(res.begin(),res.end(), &arity_cmp);
return res;
}
std::vector<function const*> function_doc_signature_generator::split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change)
{
std::vector<function const*> res;
std::vector<function const*>::const_iterator fi = funcs.begin();
function const * last = *fi;
while (++fi != funcs.end()){
//check if fi starts a new chain of overloads
if (!are_seq_overloads( last, *fi, split_on_doc_change ))
res.push_back(last);
last = *fi;
}
if (last)
res.push_back(last);
return res;
}
str function_doc_signature_generator::raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
{
str res("object");
res = str("%s %s(%s)" % make_tuple( res, f->m_name, str("tuple args, dict kwds")) );
return res;
}
const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
{
if (s.basename==std::string("void")){
static const char * none = "None";
return none;
}
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
if ( py_type )
return py_type->tp_name;
else{
static const char * object = "object";
return object;
}
}
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
{
str param;
python::detail::signature_element const * s = f.signature();
if (cpp_types)
{
if(!n)
s = &f.get_return_type();
if (s[n].basename == 0)
{
return str("...");
}
param = str(s[n].basename);
if (s[n].lvalue)
param += " {lvalue}";
}
else
{
if (n) //we are processing an argument and trying to come up with a name for it
{
object kv;
if ( arg_names && (kv = arg_names[n-1]) )
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
else
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
}
else //we are processing the return type
param = py_type_str(f.get_return_type());
}
//an argument - check for default value and append it
if(n && arg_names)
{
object kv(arg_names[n-1]);
if (kv && len(kv) == 2)
{
param = str("%s=%r" % make_tuple(param, kv[1]));
}
}
return param;
}
str function_doc_signature_generator::pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
{
py_function
const& impl = f->m_fn;
;
unsigned arity = impl.max_arity();
if(arity == unsigned(-1))// is this the proper raw function test?
{
return raw_function_pretty_signature(f,n_overloads,cpp_types);
}
list formal_params;
size_t n_extra_default_args=0;
for (unsigned n = 0; n <= arity; ++n)
{
str param;
formal_params.append(
parameter_string(impl, n, f->m_arg_names, cpp_types)
);
// find all the arguments with default values preceeding the arity-n_overloads
if (n && f->m_arg_names)
{
object kv(f->m_arg_names[n-1]);
if (kv && len(kv) == 2)
{
//default argument preceeding the arity-n_overloads
if( n <= arity-n_overloads)
++n_extra_default_args;
}
else
//argument without default, preceeding the arity-n_overloads
if( n <= arity-n_overloads)
n_extra_default_args = 0;
}
}
n_overloads+=n_extra_default_args;
if (!arity && cpp_types)
formal_params.append("void");
str ret_type (formal_params.pop(0));
if (cpp_types )
{
return str(
"%s %s(%s%s%s%s)"
% make_tuple
( ret_type
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
, std::string(n_overloads,']')
));
}else{
return str(
"%s(%s%s%s%s) -> %s"
% make_tuple
( f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
, std::string(n_overloads,']')
, ret_type
));
}
return str(
"%s %s(%s%s%s%s) %s"
% make_tuple
( cpp_types?ret_type:str("")
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
, std::string(n_overloads,']')
, cpp_types?str(""):ret_type
));
}
namespace detail {
char py_signature_tag[] = "PY signature :";
char cpp_signature_tag[] = "C++ signature :";
}
list function_doc_signature_generator::function_doc_signatures( function const * f)
{
list signatures;
std::vector<function const*> funcs = flatten( f);
std::vector<function const*> split_funcs = split_seq_overloads( funcs, true);
std::vector<function const*>::const_iterator sfi=split_funcs.begin(), fi;
size_t n_overloads=0;
for (fi=funcs.begin(); fi!=funcs.end(); ++fi)
{
if(*sfi == *fi){
if((*fi)->doc())
{
str func_doc = str((*fi)->doc());
int doc_len = len(func_doc);
bool show_py_signature = doc_len >= int(sizeof(detail::py_signature_tag)/sizeof(char)-1)
&& str(detail::py_signature_tag) == func_doc.slice(0, int(sizeof(detail::py_signature_tag)/sizeof(char))-1);
if(show_py_signature)
{
func_doc = str(func_doc.slice(int(sizeof(detail::py_signature_tag)/sizeof(char))-1, _));
doc_len = len(func_doc);
}
bool show_cpp_signature = doc_len >= int(sizeof(detail::cpp_signature_tag)/sizeof(char)-1)
&& str(detail::cpp_signature_tag) == func_doc.slice( 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char)), _);
if(show_cpp_signature)
{
func_doc = str(func_doc.slice(_, 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char))));
doc_len = len(func_doc);
}
str res="\n";
str pad = "\n";
if(show_py_signature)
{
str sig = pretty_signature(*fi, n_overloads,false);
res+=sig;
if(doc_len || show_cpp_signature )res+=" :";
pad+= str(" ");
}
if(doc_len)
{
if(show_py_signature)
res+=pad;
res+= pad.join(func_doc.split("\n"));
}
if( show_cpp_signature)
{
if(len(res)>1)
res+="\n"+pad;
res+=detail::cpp_signature_tag+pad+" "+pretty_signature(*fi, n_overloads,true);
}
signatures.append(res);
}
++sfi;
n_overloads = 0;
}else
++n_overloads ;
}
return signatures;
}
}}}

View File

@@ -8,6 +8,7 @@
#include <boost/python/tuple.hpp>
#include <boost/python/list.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/str.hpp>
namespace boost { namespace python {
@@ -19,6 +20,22 @@ namespace {
object instance_class(instance_obj.attr("__class__"));
result.append(instance_class);
object none;
if (!getattr(instance_obj, "__safe_for_unpickling__", none))
{
str type_name(getattr(instance_class, "__name__"));
str module_name(getattr(instance_class, "__module__", object("")));
if (module_name)
module_name += ".";
PyErr_SetObject(
PyExc_RuntimeError,
( "Pickling of \"%s\" instances is not enabled"
" (http://www.boost.org/libs/python/doc/v2/pickle.html)"
% (module_name+type_name)).ptr()
);
throw_error_already_set();
}
object getinitargs = getattr(instance_obj, "__getinitargs__", none);
tuple initargs;
if (getinitargs.ptr() != none.ptr()) {

View File

@@ -349,5 +349,15 @@ BOOST_PYTHON_DEFINE_STR_METHOD(title, 0)
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1)
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2)
BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0)
static struct register_str_pytype_ptr
{
register_str_pytype_ptr()
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::str>())
).m_class_object = &PyString_Type;
}
}register_str_pytype_ptr_;
}}} // namespace boost::python

View File

@@ -21,4 +21,15 @@ tuple_base::tuple_base(object_cref sequence)
: object(call(sequence))
{}
static struct register_tuple_pytype_ptr
{
register_tuple_pytype_ptr()
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::tuple>())
).m_class_object = &PyTuple_Type;
}
}register_tuple_pytype_ptr_;
}}} // namespace boost::python

View File

@@ -2,12 +2,20 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
use-project /boost/python : ../build ;
project /boost/python/test ;
local PY = ;
if [ python.configured ]
{
PY = /python//python ;
}
rule py-run ( sources * : input-file ? )
{
return [ run $(sources) /boost/python//boost_python /python//python
return [ run $(sources) /boost/python//boost_python $(PY)
: # args
: $(input-file)
: #requirements
@@ -27,33 +35,25 @@ rule py-compile-fail ( sources * )
}
#template py-unit-test
# :
# : $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
# [ difference $(PYTHON_PROPERTIES) : <define>BOOST_PYTHON_DYNAMIC_LIB ] <define>BOOST_PYTHON_STATIC_LIB
# ;
test-suite python
:
[
run exec.cpp ../build//boost_python/<link>static /python//python
: # program args
: exec.py # input files
: # requirements
: # target-name
]
[
run exec.cpp ../build//boost_python/<link>shared /python//python
run exec.cpp ../build//boost_python/<link>static $(PY)
: # program args
: exec.py
: # requirements
: exec-dynamic # target-name
<define>BOOST_PYTHON_STATIC_MODULE
]
# [
# run import_.cpp ../build//boost_python /python//python
# : # program args
# : import_.py # input files
# : # requirements
# : # target-name
# ]
[
bpl-test crossmod_exception
: crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp
@@ -76,7 +76,7 @@ bpl-test crossmod_exception
[ 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 numpy : printer.py numeric_tests.py numarray_tests.py numpy.py numpy.cpp ]
[ bpl-test enum ]
[ bpl-test exception_translator ]
[ bpl-test pearu1 : test_cltree.py cltree.cpp ]
@@ -85,11 +85,12 @@ bpl-test crossmod_exception
[ bpl-test keywords : keywords.cpp keywords_test.py ]
[ python-extension builtin_converters_ext : test_builtin_converters.cpp /boost/python//boost_python ]
[ bpl-test builtin_converters : test_builtin_converters.py builtin_converters_ext ]
[ python-extension builtin_converters.ext : test_builtin_converters.cpp /boost/python//boost_python ]
[ bpl-test builtin_converters : test_builtin_converters.py builtin_converters.ext ]
[ bpl-test test_pointer_adoption ]
[ bpl-test operators ]
[ bpl-test operators_wrapper ]
[ bpl-test callbacks ]
[ bpl-test defaults ]
@@ -142,6 +143,7 @@ bpl-test crossmod_opaque
[ bpl-test nested ]
[ bpl-test docstring ]
[ bpl-test pytype_function ]
[ bpl-test vector_indexing_suite ]
@@ -152,13 +154,14 @@ bpl-test crossmod_opaque
# Whenever the cause for the failure of the polymorphism test is found
# and fixed, this should be retested.
<toolset>hp_cxx:<build>no ]
[ python-extension map_indexing_suite_ext
: map_indexing_suite.cpp int_map_indexing_suite.cpp
: map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
/boost/python//boost_python ]
[ bpl-test
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
[ py-run import_.cpp : import_.py ]
# if $(TEST_BIENSTMAN_NON_BUGS)
# {
# bpl-test bienstman4 ;
@@ -188,7 +191,7 @@ bpl-test crossmod_opaque
:
:
: <define>BOOST_PYTHON_STATIC_LIB
<use>/python//python
<use>$(PY)
]

84
test/a_map_indexing_suite.cpp Executable file
View File

@@ -0,0 +1,84 @@
// Copyright Joel de Guzman 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)
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
using namespace boost::python;
struct A
{
int value;
A() : value(0){};
A(int v) : value(v) {};
};
bool operator==(const A& v1, const A& v2)
{
return (v1.value == v2.value);
}
struct B
{
A a;
};
// Converter from A to python int
struct AToPython
{
static PyObject* convert(const A& s)
{
return boost::python::incref(boost::python::object((int)s.value).ptr());
}
};
// Conversion from python int to A
struct AFromPython
{
AFromPython()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id< A >());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyInt_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(boost::python::converter::rvalue_from_python_storage< A >*)
data)-> storage.bytes;
new (storage) A((int)PyInt_AsLong(obj_ptr));
data->convertible = storage;
}
};
void a_map_indexing_suite()
{
to_python_converter< A , AToPython >();
AFromPython();
class_< std::map<int, A> >("AMap")
.def(map_indexing_suite<std::map<int, A>, true >())
;
class_< B >("B")
.add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
make_setter(&B::a, return_value_policy<return_by_value>()))
;
}

View File

@@ -51,7 +51,7 @@ tuple raw_func(tuple args, dict kw)
BOOST_PYTHON_MODULE(args_ext)
{
def("f", f, args("x", "y", "z")
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
, "This is f's docstring"
);
@@ -72,24 +72,24 @@ BOOST_PYTHON_MODULE(args_ext)
.def("raw", raw_function(raw_func))
;
class_<X>("X", "This is X's docstring")
.def(init<int, optional<int> >(args("a0", "a1")))
class_<X>("X", "This is X's docstring", init<>(args("self")))
.def(init<int, optional<int> >(args("self", "a0", "a1")))
.def("f", &X::f
, "This is X.f's docstring"
, args("x", "y", "z"))
, args("self","x", "y", "z"))
// Just to prove that all the different argument combinations work
.def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring")
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n"))
.def("inner0", &X::inner, return_internal_reference<>(), args("self", "n"), "docstring")
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("self", "n"))
.def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring")
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n"))
.def("inner2", &X::inner, args("self", "n"), return_internal_reference<>(), "docstring")
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("self", "n"))
.def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>())
.def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>())
.def("inner4", &X::inner, args("self", "n"), "docstring", return_internal_reference<>())
.def("inner5", &X::inner, "docstring", args("self", "n"), return_internal_reference<>())
.def("f1", &X::f, X_f_overloads(args("x", "y", "z")))
.def("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
.def("f1", &X::f, X_f_overloads(args("self", "x", "y", "z")))
.def("f2", &X::f, X_f_overloads(args("self", "x", "y", "z"), "f2's docstring"))
;
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());

View File

@@ -84,22 +84,27 @@
(2, 4.25, 'wow')
>>> q.f1()
(1, 4.25, 'wow')
>>> q.f2.__doc__.splitlines()[1]
'f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple :'
>>> X.f.__doc__.splitlines()[:2]
["This is X.f's docstring", 'C++ signature:']
>>> q.f2.__doc__.splitlines()[2]
" f2's docstring"
>>> X.f.__doc__.splitlines()[1:5]
['f( (X)self, (int)x, (float)y, (str)z) -> tuple :', " This is X.f's docstring", '', ' C++ signature :']
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
>>> for f in xfuncs:
... print f(q,1).value(),
... print f(q, n = 1).value(),
... print f(q, n = 0).value(),
... print f.__doc__.splitlines()[:2]
1 1 0 ['docstring', 'C++ signature:']
1 1 0 ['docstring', 'C++ signature:']
1 1 0 ['docstring', 'C++ signature:']
1 1 0 ['docstring', 'C++ signature:']
1 1 0 ['docstring', 'C++ signature:']
1 1 0 ['docstring', 'C++ signature:']
... print f.__doc__.splitlines()[1:5]
1 1 0 ['inner0( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner1( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner2( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner3( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner4( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner5( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
>>> x = X(a1 = 44, a0 = 22)
>>> x.inner0(0).value()
@@ -134,49 +139,9 @@ if __name__ == '__main__':
import sys
status = run()[0]
if (status == 0): print "Done."
import args_ext
help(args_ext)
sys.exit(status)

View File

@@ -64,6 +64,24 @@
... except TypeError: pass
... else: print 'expected a TypeError exception'
>>> print look.__doc__.splitlines()[1]
look( (X)arg1) -> int :
>>> print steal.__doc__.splitlines()[1]
steal( (X)arg1) -> int :
>>> print maybe_steal.__doc__.splitlines()[1]
maybe_steal( (X)arg1, (bool)arg2) -> int :
>>> print make.__doc__.splitlines()[1]
make() -> X :
>>> print callback.__doc__.splitlines()[1]
callback( (object)arg1) -> X :
>>> print extract.__doc__.splitlines()[1]
extract( (object)arg1) -> X :
'''
def run(args = None):

View File

@@ -16,6 +16,9 @@
>>> assert y_identity(y) is y
>>> y_equality(y, y)
1
>>> print y_identity.__doc__.splitlines()[1]
y_identity( (Y)arg1) -> object :
'''
def run(args = None):

View File

@@ -12,6 +12,7 @@
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/call.hpp>
#include <boost/python/object.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
using namespace boost::python;

View File

@@ -52,7 +52,7 @@ int Var::static1 = 0;
Y Var::static2(0);
// Compilability regression tests
namespace
namespace boost_python_test
{
struct trivial
{
@@ -86,6 +86,7 @@ namespace
BOOST_PYTHON_MODULE(data_members_ext)
{
using namespace boost_python_test;
class_<X>("X", init<int>())
.def("value", &X::value)
.def("set", &X::set)

View File

@@ -159,10 +159,10 @@ BOOST_PYTHON_MODULE(defaults_ext)
.def("get_state", &Y::get_state)
;
class_<X>("X")
class_<X>("X",no_init)
.def(init<int, optional<char, std::string, double> >("doc of init"))
.def(init<std::string, bool>()[default_call_policies()]) // what's a good policy here?
.def(init<optional<int, char, std::string, double> >("doc of init", args("self", "a", "b", "c", "d")))
.def(init<std::string, bool>(args("self", "s", "b"))[default_call_policies()]) // what's a good policy here?
.def("get_state", &X::get_state)
.def("bar", &X::bar, X_bar_stubs())
.def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])

View File

@@ -113,28 +113,22 @@
... doc = obj.__doc__.splitlines()
... return "\\n".join(["|"+doc[i] for i in args])
>>> print selected_doc(X.__init__, 0, 2, 4, 6, 8, 9, 10, 12)
|C++ signature:
|C++ signature:
|C++ signature:
|C++ signature:
|
|doc of init
|C++ signature:
|C++ signature:
>>> print selected_doc(X.__init__, 1, 2, 4, 7, 9)
|__init__( (object)self [, (int)a [, (str)b [, (str)c [, (float)d]]]]) -> None :
| doc of init
| C++ signature :
|__init__( (object)self, (str)s, (bool)b) -> None :
| C++ signature :
>>> print selected_doc(Y.__init__, 0, 1)
|doc of Y init
|C++ signature:
>>> print selected_doc(Y.__init__, 1, 2, 4)
|__init__( (object)arg1) -> None :
| doc of Y init
| C++ signature :
>>> print selected_doc(X.bar2, 0, 2, 4, 6, 8, 9, 10)
|C++ signature:
|C++ signature:
|C++ signature:
|C++ signature:
|
|doc of X::bar2
|C++ signature:
>>> print selected_doc(X.bar2, 1, 2, 4)
|bar2( (X)arg1 [, (int)arg2 [, (str)arg3 [, (str)arg4 [, (float)arg5]]]]) -> Y :
| doc of X::bar2
| C++ signature :
"""
def run(args = None):

View File

@@ -43,55 +43,74 @@ BOOST_PYTHON_MODULE(docstring_ext)
, init<int>(
"this is the __init__ function\n"
"its documentation has two lines."
, args("self", "value")
)
)
.def("value", &X::value,
"gets the value of the object")
"gets the value of the object"
, args("self"))
.def( "value", &X::value,
"also gets the value of the object")
"also gets the value of the object"
, args("self"))
;
def("create", create, return_value_policy<manage_new_object>(),
"creates a new X object");
"creates a new X object", args("value"));
def("fact", fact, "compute the factorial");
def("fact", fact, "compute the factorial", args("n"));
{
docstring_options doc_options;
doc_options.disable_user_defined();
def("fact_usr_off_1", fact, "usr off 1");
def("fact_usr_off_1", fact, "usr off 1", args("n"));
doc_options.enable_user_defined();
def("fact_usr_on_1", fact, "usr on 1");
def("fact_usr_on_1", fact, "usr on 1", args("n"));
doc_options.disable_user_defined();
def("fact_usr_off_2", fact, "usr off 2");
def("fact_usr_off_2", fact, "usr off 2", args("n"));
}
def("fact_usr_on_2", fact, "usr on 2");
def("fact_usr_on_2", fact, "usr on 2", args("n"));
{
docstring_options doc_options(true, false);
def("fact_sig_off_1", fact, "sig off 1");
def("fact_sig_off_1", fact, "sig off 1", args("n"));
doc_options.enable_signatures();
def("fact_sig_on_1", fact, "sig on 1");
def("fact_sig_on_1", fact, "sig on 1", args("n"));
doc_options.disable_signatures();
def("fact_sig_off_2", fact, "sig off 2");
def("fact_sig_off_2", fact, "sig off 2", args("n"));
}
def("fact_sig_on_2", fact, "sig on 2");
def("fact_sig_on_2", fact, "sig on 2", args("n"));
{
docstring_options doc_options(false);
def("fact_usr_off_sig_off_1", fact, "usr off sig off 1");
def("fact_usr_off_sig_off_1", fact, "usr off sig off 1", args("n"));
{
docstring_options nested_doc_options;
def("fact_usr_on_sig_on_1", fact, "usr on sig on 1");
def("fact_usr_on_sig_on_1", fact, "usr on sig on 1", args("n"));
nested_doc_options.disable_all();
nested_doc_options.enable_user_defined();
def("fact_usr_on_sig_off_1", fact, "usr on sig off 1");
def("fact_usr_on_sig_off_1", fact, "usr on sig off 1", args("n"));
nested_doc_options.enable_all();
def("fact_usr_on_sig_on_2", fact, "usr on sig on 2");
def("fact_usr_on_sig_on_2", fact, "usr on sig on 2", args("n"));
}
def("fact_usr_off_sig_off_2", fact, "usr off sig off 2");
def("fact_usr_off_sig_off_2", fact, "usr off sig off 2", args("n"));
}
{
docstring_options doc_options(true);
doc_options.disable_cpp_signatures();
def("fact_usr_on_psig_on_csig_off_1", fact, "usr on psig on csig off 1", args("n"));
doc_options.enable_cpp_signatures();
doc_options.disable_py_signatures();
def("fact_usr_on_psig_off_csig_on_1", fact, "usr on psig off csig on 1", args("n"));
doc_options.enable_py_signatures();
doc_options.disable_user_defined();
doc_options.disable_cpp_signatures();
def("fact_usr_off_psig_on_csig_off_1", fact, "usr off psig on csig off 1", args("n"));
doc_options.enable_cpp_signatures();
doc_options.disable_py_signatures();
def("fact_usr_off_psig_off_csig_on_1", fact, "usr off psig off csig on 1", args("n"));
}
}
#include "module_tail.cpp"

View File

@@ -8,82 +8,114 @@
... doc = obj.__doc__.splitlines()
... return "\\n".join(["|"+doc[i] for i in args])
>>> print selected_doc(X.__init__, 0, 1, 2)
|this is the __init__ function
|its documentation has two lines.
|C++ signature:
>>> print selected_doc(X.value, 0, 1, 3, 4, 5)
|gets the value of the object
|C++ signature:
>>> print selected_doc(X.__init__, 1, 2, 3, 4, 5)
|__init__( (object)self, (int)value) -> None :
| this is the __init__ function
| its documentation has two lines.
|
|also gets the value of the object
|C++ signature:
| C++ signature :
>>> print selected_doc(create, 0, 1)
|creates a new X object
|C++ signature:
>>> print selected_doc(X.value, 1, 2, 4, 7, 8, 10)
|value( (X)self) -> int :
| gets the value of the object
| C++ signature :
|value( (X)self) -> int :
| also gets the value of the object
| C++ signature :
>>> print selected_doc(fact, 0, 1)
|compute the factorial
|C++ signature:
>>> print selected_doc(create, 1, 2, 3, 4)
|create( (int)value) -> X :
| creates a new X object
|
| C++ signature :
>>> print selected_doc(fact, 1, 2, 3, 4)
|fact( (int)n) -> int :
| compute the factorial
|
| C++ signature :
>>> len(fact_usr_off_1.__doc__.splitlines())
2
>>> print selected_doc(fact_usr_off_1, 0)
|C++ signature:
5
>>> print selected_doc(fact_usr_off_1, 1, 3)
|fact_usr_off_1( (int)n) -> int :
| C++ signature :
>>> len(fact_usr_on_1.__doc__.splitlines())
3
>>> print selected_doc(fact_usr_on_1, 0, 1)
|usr on 1
|C++ signature:
6
>>> print selected_doc(fact_usr_on_1, 1, 2, 4)
|fact_usr_on_1( (int)n) -> int :
| usr on 1
| C++ signature :
>>> len(fact_usr_off_2.__doc__.splitlines())
2
>>> print selected_doc(fact_usr_off_2, 0)
|C++ signature:
5
>>> print selected_doc(fact_usr_off_2, 1, 3)
|fact_usr_off_2( (int)n) -> int :
| C++ signature :
>>> len(fact_usr_on_2.__doc__.splitlines())
3
>>> print selected_doc(fact_usr_on_2, 0, 1)
|usr on 2
|C++ signature:
6
>>> print selected_doc(fact_usr_on_2, 1, 2, 4)
|fact_usr_on_2( (int)n) -> int :
| usr on 2
| C++ signature :
>>> len(fact_sig_off_1.__doc__.splitlines())
1
>>> print selected_doc(fact_sig_off_1, 0)
2
>>> print selected_doc(fact_sig_off_1, 1)
|sig off 1
>>> len(fact_sig_on_1.__doc__.splitlines())
3
>>> print selected_doc(fact_sig_on_1, 0, 1)
|sig on 1
|C++ signature:
6
>>> print selected_doc(fact_sig_on_1, 1, 2, 4)
|fact_sig_on_1( (int)n) -> int :
| sig on 1
| C++ signature :
>>> len(fact_sig_off_2.__doc__.splitlines())
1
>>> print selected_doc(fact_sig_off_2, 0)
2
>>> print selected_doc(fact_sig_off_2, 1)
|sig off 2
>>> len(fact_sig_on_2.__doc__.splitlines())
3
>>> print selected_doc(fact_sig_on_2, 0, 1)
|sig on 2
|C++ signature:
6
>>> print selected_doc(fact_sig_on_2, 1, 2, 4)
|fact_sig_on_2( (int)n) -> int :
| sig on 2
| C++ signature :
>>> print fact_usr_off_sig_off_1.__doc__
None
>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
3
>>> print selected_doc(fact_usr_on_sig_on_1, 0, 1)
|usr on sig on 1
|C++ signature:
6
>>> print selected_doc(fact_usr_on_sig_on_1, 1, 2, 4)
|fact_usr_on_sig_on_1( (int)n) -> int :
| usr on sig on 1
| C++ signature :
>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
1
>>> print selected_doc(fact_usr_on_sig_off_1, 0)
2
>>> print selected_doc(fact_usr_on_sig_off_1, 1)
|usr on sig off 1
>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
3
>>> print selected_doc(fact_usr_on_sig_on_2, 0, 1)
|usr on sig on 2
|C++ signature:
>>> print fact_usr_off_sig_off_2.__doc__
None
6
>>> print selected_doc(fact_usr_on_sig_on_2, 1, 2, 4)
|fact_usr_on_sig_on_2( (int)n) -> int :
| usr on sig on 2
| C++ signature :
>>> print selected_doc(fact_usr_on_psig_on_csig_off_1, 1, 2)
|fact_usr_on_psig_on_csig_off_1( (int)n) -> int :
| usr on psig on csig off 1
>>> print selected_doc(fact_usr_on_psig_off_csig_on_1, 1, 3)
|usr on psig off csig on 1
|C++ signature :
>>> print fact_usr_off_psig_on_csig_off_1.__doc__.splitlines()[1]
fact_usr_off_psig_on_csig_off_1( (int)n) -> int
>>> print selected_doc(fact_usr_off_psig_off_csig_on_1,1)
|C++ signature :
'''

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