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

Compare commits

...

111 Commits

Author SHA1 Message Date
Dave Abrahams
aed45d59d8 Branch for developing Bitten client/server testing
[SVN r41004]
2007-11-10 22:53:12 +00:00
Dave Abrahams
6a3085ad5d Merging some of the more obvious changes from RC_1_34_0
[SVN r40714]
2007-11-03 03:25:13 +00:00
Joel de Guzman
190d0d7ea6 replacing reinterpret_cast with static_cast<PySliceObject*>(static_cast<void*>(i))
[SVN r40712]
2007-11-03 03:05:26 +00:00
Eric Niebler
8b915a15ff merge Changeset 37947
[SVN r40675]
2007-11-02 04:35:01 +00:00
Dave Abrahams
90c5c19220 Take out print statement I added for debugging purposes.
[SVN r40536]
2007-10-28 19:24:02 +00:00
Dave Abrahams
cfe6f96f69 Closes #1379, really this time. The old code would sandwich argv[1] between quotes and interpret it as a string, so backslashes in windows paths were interpreted as escape sequences.
[SVN r40535]
2007-10-28 19:22:21 +00:00
Vladimir Prus
77907c5369 Make sure every library can be installed by using
bjam stage|install

in libs/<library>/build.


[SVN r40475]
2007-10-26 09:04:25 +00:00
Rene Rivera
512b30c971 Do not refer to nonexistent target when python is not configured.
[SVN r40216]
2007-10-20 16:36:18 +00:00
Rene Rivera
f005518686 Fix build system error when Python is not configured, without preventing the BPL target from being declared. Instead the target is now unbuildable, and will be skipped when Python is not configured.
[SVN r40156]
2007-10-18 16:11:41 +00:00
Rene Rivera
274a219965 Remove BPL build conditional as it prevents normal build failures.
[SVN r39731]
2007-10-06 19:46:39 +00:00
Ralf W. Grosse-Kunstleve
abc4abf84a gcc 4.3.0 compatibility (resolves new "changes meaning" error)
[SVN r39434]
2007-09-20 23:20:45 +00:00
Nikolay Mladenov
94a3ced83a fixed cpp signature related test failure
[SVN r39372]
2007-09-18 17:51:47 +00:00
Nikolay Mladenov
7eb0c678ee epydoc friendlier formatting
[SVN r39371]
2007-09-18 17:32:06 +00:00
Nikolay Mladenov
92460adce6 tabs removes, code reformatting
[SVN r39370]
2007-09-18 17:28:23 +00:00
Nikolay Mladenov
8cfd3fb2ef epydoc friendlier formatting
[SVN r39368]
2007-09-18 17:16:31 +00:00
Nikolay Mladenov
62ef542eaf fixed problem reported by Neal Becker; added a test case
[SVN r39223]
2007-09-12 21:31:39 +00:00
Ralf W. Grosse-Kunstleve
5809078ba9 Patches by Nikolay Mladenov (nickm at sitius com): new pythonic signatures; docstring support for enums; fix unrelated Visual C++ 6 problem
[SVN r39191]
2007-09-11 16:53:50 +00:00
Stefan Seefeld
71f54cc920 Fix ticket #1115.
[SVN r38288]
2007-07-26 14:41:41 +00:00
Thomas Witt
2851325748 Doc and build fixes by Dave Abrahams.
[SVN r38154]
2007-07-06 19:47:17 +00:00
Thomas Witt
bd606e5017 Fix #583.
[SVN r37947]
2007-06-08 18:30:46 +00:00
Thomas Witt
a5706ec3b0 Fixes for #583.
[SVN r37929]
2007-06-07 18:08:54 +00:00
Rene Rivera
a346c577cf Fix the abolute reference to the Boost sources inserted by Dave.
[SVN r37837]
2007-05-31 22:03:06 +00:00
Dave Abrahams
217e4ca8f8 Repair auto-configuration and allow this project to work with --build-dir
[SVN r37829]
2007-05-31 13:49:45 +00:00
Stefan Seefeld
f2f47f85c0 Enhance embedding python docs.
[SVN r37710]
2007-05-18 15:54:25 +00:00
Stefan Seefeld
b130c93af6 Backport new eval() function from HEAD.
[SVN r37693]
2007-05-15 13:43:52 +00:00
Dave Abrahams
13432b504f Jamfile had extra bogus tst executable target
Build/test instructions were outdated somehow; a checkin must've failed.


[SVN r37620]
2007-05-07 19:00:01 +00:00
Dave Abrahams
0739bb7df8 Added reference to Py++
[SVN r37586]
2007-05-04 01:08:54 +00:00
Dave Abrahams
c253c5cc9c Updated build-and-test howto
[SVN r37585]
2007-05-04 00:56:22 +00:00
Dave Abrahams
8f263e1fdb Progress on the build docs
[SVN r37551]
2007-05-01 16:14:39 +00:00
Ralf W. Grosse-Kunstleve
a6125a3632 merged from trunk
[SVN r37520]
2007-04-27 22:16:47 +00:00
nobody
a784bfc0f8 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r37419]
2007-04-11 23:35:09 +00:00
Dave Abrahams
b8937d0bae Relieve need to explicitly configure Python
[SVN r37382]
2007-04-06 18:17:43 +00:00
Dave Abrahams
4827ae73d5 Trivial change to force a rebuild on incremental testers' machines.
[SVN r37327]
2007-04-02 00:54:48 +00:00
Dave Abrahams
8eddc7aa37 Support for --with-pydebug builds.
python.jam:

  Support for the specification of "_d" extension suffix.

  In compute-default-paths, fixed the check for residence in
  a "PCBuild.*" directory so we can build against Windows Python built
  in a source distribution.

common.jam:

  Fixed generation of the "y" tag to look for <python-debugging>on
  rather than the whole debug-python build variant.

  Fixed some grammar and spelling.

virtual-target.jam:

  Added the ability to forego the prepending of "." to a
  generated-target-suffix by specifying the suffix enclosed in <...>

libs/python/build/Jamfile.v2:

  #define BOOST_DEBUG_PYTHON when <python-debugging>on


[SVN r37326]
2007-04-02 00:51:15 +00:00
Stefan Seefeld
98a468dadc Fix reference counting error.
[SVN r37312]
2007-03-28 18:12:08 +00:00
Dave Abrahams
ea4e6c0a4c Trivial change to force a rebuild on incremental testers' machines.
[SVN r37311]
2007-03-28 12:44:57 +00:00
Dave Abrahams
7cd7f6d8ee Trivial change to force a rebuild on incremental testers' machines.
[SVN r37287]
2007-03-26 15:47:05 +00:00
Dave Abrahams
4c39e8c990 Making a trivial change to trigger a test run from incremental testers
[SVN r37278]
2007-03-24 18:57:19 +00:00
Dave Abrahams
6c6f654fbe Add commented-out test for import_ so it's easy to reinstate
[SVN r37256]
2007-03-21 17:44:57 +00:00
Dave Abrahams
b7eaea096e Eliminate import_ test, as it doesn't work consistently on Windows and Linux.
[SVN r37250]
2007-03-21 05:09:21 +00:00
Dave Abrahams
904ae8604c fix builtin_converters test so it can work (BBv1 allowed the
duplication of main target names; BBv2 does not)


[SVN r37216]
2007-03-17 20:26:21 +00:00
Dave Abrahams
44d53c448b libs/python/build/Jamfile.v2: remove needless <define> property.
libs/python/test/Jamfile.v2:
  * add dynamically-linked embedding test

  * fix builtin_converters test so it can work (BBv1 allowed the
    duplication of main target names; BBv2 does not)


libs/python/test/import_.cpp: move some more of the Python code within
  a handle_exception callback so at least we can better diagnose
  failures.


[SVN r37214]
2007-03-17 20:17:56 +00:00
Stefan Seefeld
e61401d27e Fix import_ failure.
[SVN r37141]
2007-03-05 18:44:45 +00:00
Stefan Seefeld
be7ca7d269 Add copyright notice.
[SVN r37132]
2007-03-02 17:16:51 +00:00
Stefan Seefeld
47b4b4efbb Fix boost::python::import.
[SVN r37123]
2007-03-01 18:31:10 +00:00
nobody
4fa07f2b3d This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r37121]
2007-03-01 15:17:30 +00:00
Dave Abrahams
c880e7d69d 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).

    or changing BOOST_TEST to BOOST_CHECK where the integer library
    was clearly using Boost.Test and not returning report_errors().


[SVN r37063]
2007-02-25 15:28:02 +00:00
Dave Abrahams
c73ad50286 Roll back improved error message because it causes problems for vc6/7
[SVN r36435]
2006-12-16 22:00:35 +00:00
Dave Abrahams
0910710ac4 Correct class/function mismatches for MSVC and bring across
documentation tweaks from HEAD.


[SVN r36355]
2006-12-13 15:08:26 +00:00
Dave Abrahams
04c528138b Fully switch to BBv2
[SVN r36327]
2006-12-11 05:22:04 +00:00
nobody
1b66cd9643 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r36324]
2006-12-11 05:02:35 +00:00
Dave Abrahams
c2dd9fa833 Fix auto-link to look at the right variable.
[SVN r36319]
2006-12-11 03:00:26 +00:00
Dave Abrahams
b085121369 merged from trunk
[SVN r36292]
2006-12-07 17:45:17 +00:00
Beman Dawes
fa219bce9b Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Rene Rivera
10b85d67e7 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Stefan Seefeld
ca91dc828e Fix symbol visibility.
[SVN r35754]
2006-10-27 21:19:47 +00:00
Dave Abrahams
3a53c1dec0 Add fixes somehow missed for darwin
[SVN r35612]
2006-10-14 19:10:30 +00:00
nobody
da8e309957 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35598]
2006-10-13 21:34:27 +00:00
Dave Abrahams
2bd9141d4a make numpy tests portable to Darwin with older docutils
[SVN r35597]
2006-10-13 21:34:26 +00:00
Dave Abrahams
c3bda6a903 Fix some problems with testing on old docutils installations
[SVN r35594]
2006-10-13 19:35:28 +00:00
Dave Abrahams
d61909d3ea 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
1755dad7e6 merged from trunk
[SVN r35569]
2006-10-12 06:42:20 +00:00
Dave Abrahams
3b392c99be Adjust tests to account for numarray behavior differences
[SVN r35539]
2006-10-10 22:44:09 +00:00
Dave Abrahams
24ba93607b Try for backward compatibility with older versions of doctest
[SVN r35535]
2006-10-10 18:12:43 +00:00
Dave Abrahams
49d4aac8ec 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
545be29ad3 (hopefully) grab the last bit of logic from HEAD for a bugfix I've been trying to apply to the branch for days(!)
[SVN r35436]
2006-10-01 18:25:44 +00:00
Dave Abrahams
8553c109c7 merged from HEAD
[SVN r35429]
2006-09-29 22:27:57 +00:00
Dave Abrahams
315c3d50ee Apply missing elements of previously-"applied" bug fix.
[SVN r35421]
2006-09-29 15:45:29 +00:00
Dave Abrahams
d5219979a4 Fix bugs uncovered by Roman Yakovenko
[SVN r35410]
2006-09-29 02:09:13 +00:00
Dave Abrahams
d42054f3a0 Cleans up license/copyright warnings
[SVN r35409]
2006-09-29 02:08:32 +00:00
nobody
72b06e70ee This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35366]
2006-09-28 14:41:02 +00:00
Dave Abrahams
375cc3aa93 Fix broken links
[SVN r35330]
2006-09-26 04:25:49 +00:00
Ralf W. Grosse-Kunstleve
4eb286a034 ssize_t patches merged from HEAD
[SVN r35327]
2006-09-26 00:48:44 +00:00
nobody
a824230155 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35326]
2006-09-26 00:25:08 +00:00
Gottfried Ganßauge
1bc3750ab3 repaired broken links
[SVN r35315]
2006-09-25 07:35:57 +00:00
Dave Abrahams
36abcee847 merged from HEAD
[SVN r35277]
2006-09-22 15:13:30 +00:00
Gottfried Ganßauge
b8b7768eb7 Test for cross module support of opaque
[SVN r35256]
2006-09-21 16:47:49 +00:00
Gottfried Ganßauge
7ad9dc6c64 Changed references to opaque_pointer_converter.html to point to opaque.html instead
[SVN r35255]
2006-09-21 16:47:31 +00:00
Gottfried Ganßauge
decc34551a Renamed to opaque.html because class name changed
[SVN r35254]
2006-09-21 16:47:00 +00:00
Gottfried Ganßauge
5acb44ede0 Renamed from opaque_pointer_converter.html because class name changed
[SVN r35253]
2006-09-21 16:46:42 +00:00
Gottfried Ganßauge
ef62f87963 type object gets initialized. Cross module support works
[SVN r35252]
2006-09-21 16:46:21 +00:00
Joel de Guzman
b5c893381f merge from head
[SVN r35246]
2006-09-21 10:52:01 +00:00
Vladimir Prus
815969bf8b Merge: Add tests
[SVN r35245]
2006-09-21 07:27:11 +00:00
nobody
0d57e9e808 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35243]
2006-09-21 07:07:15 +00:00
Dave Abrahams
7ba6a00617 Apply Boost license, with permission from Prabhu Ramachandran.
[SVN r35240]
2006-09-21 03:43:59 +00:00
Dave Abrahams
e70bbe4791 Fix license/copyright.
Also port some "glaringly obvious" bugfixes from HEAD.  Hope it
doesn't cause problems.


[SVN r35237]
2006-09-20 22:49:18 +00:00
Stefan Seefeld
7ff0f62729 Fix copyright issues.
[SVN r35236]
2006-09-20 22:30:39 +00:00
Dave Abrahams
95f0b39c90 merged from HEAD
[SVN r35185]
2006-09-18 22:22:31 +00:00
nobody
23057688f9 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35170]
2006-09-18 19:56:20 +00:00
Dave Abrahams
029618f719 merged from HEAD
[SVN r35165]
2006-09-18 18:25:57 +00:00
Dave Abrahams
38f7a4e9b6 merge from HEAD
[SVN r35141]
2006-09-17 02:42:51 +00:00
Dave Abrahams
326c871224 attempt unverified workaround for http://tinyurl.com/gvrgd
[SVN r35103]
2006-09-13 22:47:11 +00:00
Dave Abrahams
924eeccd53 merged from trunk
[SVN r35080]
2006-09-13 00:02:56 +00:00
Dave Abrahams
4a63cf4843 Move definition of BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION back
where it belongs.


[SVN r35076]
2006-09-12 22:37:09 +00:00
Dave Abrahams
1d65b74273 Add missing license/copyright
[SVN r35070]
2006-09-11 22:27:29 +00:00
Dave Abrahams
3c1ae689a7 merged from trunk
[SVN r34943]
2006-08-24 19:04:23 +00:00
Dave Abrahams
a99bd50e52 merged from trunk
[SVN r34940]
2006-08-24 13:05:30 +00:00
Dave Abrahams
8b178594ff merged from trunk
[SVN r34915]
2006-08-22 11:51:18 +00:00
Dave Abrahams
786aeef998 merged from trunk
[SVN r34872]
2006-08-11 15:51:09 +00:00
Dave Abrahams
45e4cf506f merged from trunk
[SVN r34865]
2006-08-11 00:48:19 +00:00
Gennaro Prota
8fb6e1f48d (merge from head)
removed tabs (inspect tool)


[SVN r34723]
2006-07-24 22:28:41 +00:00
Gennaro Prota
ecf70b05f2 (merge from head)
removed tabs (inspect tool)


[SVN r34721]
2006-07-24 22:21:39 +00:00
Gennaro Prota
c54acdb9db (merge from head)
minor fix: violation of min/max guidelines


[SVN r34718]
2006-07-24 22:06:09 +00:00
Vladimir Prus
489dae2b58 Clarify comment
[SVN r34668]
2006-07-22 12:53:49 +00:00
Vladimir Prus
f852ce6f7b Windows
[SVN r34667]
2006-07-22 12:28:43 +00:00
Vladimir Prus
e500919d25 Merge: Don't link Boost.Python to python library
[SVN r34663]
2006-07-22 07:16:18 +00:00
Markus Schöpflin
7a645a6d8a Merged header inclusion order fix from trunk to release branch.
[SVN r34195]
2006-06-06 09:44:35 +00:00
Markus Schöpflin
fa2185e5ab Merged header inclusion order fix from trunk to release branch.
[SVN r34194]
2006-06-06 09:39:16 +00:00
Vladimir Prus
5cc33461dd Merge from trunk
[SVN r33626]
2006-04-10 09:02:57 +00:00
Markus Schöpflin
7b93f2fdc5 Merged fix from HEAD for Tru64/CXX compilation error.
[SVN r33455]
2006-03-23 09:40:38 +00:00
nobody
219743964d This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
101 changed files with 4660 additions and 1748 deletions

View File

@@ -7,13 +7,28 @@ import modules ;
import python ;
if [ python.configured ] {
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" ;
}
}
project boost/python
: 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
numeric.cpp
@@ -24,7 +39,6 @@ lib boost_python
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
@@ -45,6 +59,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
@@ -61,17 +76,19 @@ 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
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<link>shared:<define>BOOST_PYTHON_DYNAMIC_LIB
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
else
{
ECHO "warning: Python location is not configured" ;
ECHO "warning: the Boost.Python library won't be built" ;
}
boost-install boost_python ;

File diff suppressed because it is too large Load Diff

View File

@@ -9,60 +9,63 @@
</head>
<body>
<div class="document" id="logo-boost-python-build-and-test-howto">
<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>
<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>
<!-- 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">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<div class="contents sidebar small topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="auto-toc simple">
<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>
<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>
</ul>
</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>
<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>
</ul>
</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>
<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>
</ul>
</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>
<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>
</ul>
</div>
<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 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>
<div class="section">
<h1><a class="toc-backref" href="#id21" id="background" name="background">2&nbsp;&nbsp;&nbsp;Background</a></h1>
<div class="section" id="background">
<h1><a class="toc-backref" href="#id26">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" 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 external" 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" 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 external" 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 C++' <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
of the 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" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
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
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>
@@ -71,127 +74,281 @@ 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">
<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,
<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,
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.</p>
for a specific compiler configuration and figuring out the right
compiler options to use yourself.</p>
<!-- .. raw:: html
<div style="width:50%"> -->
<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 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>
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>
</div>
</div>
<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
</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
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>
<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="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 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="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
<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
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 a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having</p>
<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>
<pre class="literal-block">
import toolset : using ;
using python ;
</pre>
<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>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>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
additional argument required.</dd>
configuration 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. 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. Only 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> path for Python headers.</dd>
<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>
<dt>libraries</dt>
<dd>the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework.</dd>
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>
<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.</dd>
Boost.Build selects a Python configuration to use. See examples
below for details.</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
<tt class="docutils literal"><span class="pre">&lt;python-debugging&gt;</span></tt> feature. However, at least one Linux
<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
distribution (Ubuntu Feisty Fawn) has a specially configured
<a class="reference" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
<a class="reference external" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id30" id="examples" name="examples">7.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
<div class="section" id="examples">
<h2><a class="toc-backref" href="#id35">5.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
<p>Note that in the examples below, case and <em>especially whitespace</em> are
significant.</p>
<ul>
@@ -229,8 +386,19 @@ 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" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
can build/test both Windows and <a class="reference external" 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">
@@ -241,16 +409,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="id11" name="id11"><sup>5</sup></a></p>
with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id15"><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" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
python with a <a class="reference external" 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" 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 external" 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">
@@ -269,35 +437,35 @@ bjam target-os=cygwin/python=2.4
</ul>
</div>
</div>
<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
<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
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="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>
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>
<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="id14" name="id14"><sup>3</sup></a></li>
modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id18"><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">
<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>
<div class="section" id="the-static-binary">
<h2><a class="toc-backref" href="#id38">6.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" 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 external" 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" 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 external" 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>
@@ -311,22 +479,73 @@ modules (and vice-versa).</li>
</ul>
</div>
</div>
<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>
<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>
<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" href="http://www.python.org/doc/current/inst/index.html">Installing
the “Building Extensions: Tips And Tricks” chapter in <a class="reference external" 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="id16" rules="none">
<table class="docutils footnote" frame="void" id="id22" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2" name="id16">[1]</a></td><td>Note that although we tested earlier versions of
<tr><td class="label"><a class="fn-backref" href="#id2">[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
@@ -337,24 +556,21 @@ 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="#id13" name="naming">[2]</a></td><td><p class="first">Information about how to identify the
<tr><td class="label"><a class="fn-backref" href="#id17">[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" 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>
<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>
</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="#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
<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
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
@@ -369,7 +585,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="#id7" name="overwrite">[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="#id13">[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>
@@ -377,28 +593,33 @@ 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="#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
<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
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 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
<tr><td class="label"><a class="fn-backref" href="#id11">[6]</a></td><td><p class="first">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" href="../../../more/getting_started/windows.html#or-build-from-the-command-prompt">Windows command prompt</a></p>
<p class="last">into a <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">command prompt</a> window.</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.
</td></tr>
</tbody>
</table>
@@ -406,9 +627,9 @@ ECHO %HOMEDRIVE%%HOMEPATH%
</div>
<div class="footer">
<hr class="footer" />
<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.
<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.
</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,36 +31,6 @@ 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
==========
@@ -81,7 +51,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 C++' ``main()`` function: in the Python interpreter executable,
of the 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
@@ -95,8 +65,254 @@ 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()``.
Getting Boost.Python Binaries
=============================
.. _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
======================================
Since Boost.Python is a separately-compiled (as opposed to
`header-only`_) library, its user relies on the services of a
@@ -104,25 +320,24 @@ Boost.Python library binary.
.. _header-only: ../../../more/getting_started/windows.html#header-only-libraries
Installing Boost.Python on your System
--------------------------------------
If you need a regular, installation of the Boost.Python library
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 installing one. If building binaries
walk you through the steps of creating 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
describe the build resources available to the build system. You'll
need to tell it about your Python installation.
``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.
__ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
@@ -135,66 +350,58 @@ __ 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 a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having ::
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 ::
import toolset : using ;
using python ;
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`_.
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.
.. 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
======================
Python Configuration Parameters
-------------------------------
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
additional argument required.
configuration argument required.
cmd-or-prefix
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.
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.
includes
the ``#include`` path for Python headers.
the ``#include`` paths for Python headers. Normally the correct
path(s) will be automatically deduced from ``version`` and/or
``cmd-or-prefix``.
libraries
the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework.
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``.
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.
Boost.Build selects a Python configuration to use. See examples
below for details.
extension-suffix
A string to append to the name of extension
@@ -202,10 +409,12 @@ 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
@@ -247,6 +456,17 @@ 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
@@ -290,7 +510,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 withthe right
If—instead of letting Boost.Build construct and link with the 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
@@ -332,6 +552,64 @@ 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
=======================================================
@@ -365,13 +643,9 @@ __ 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
certainextension modules built with different compiler toolsets
share symbols among dynamically-loaded objects, I'm not certain
that extension 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
@@ -391,14 +665,16 @@ __ 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 `Windows command prompt`__
into a `command prompt`_ window.
__ ../../../more/getting_started/windows.html#or-build-from-the-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.

View File

@@ -147,7 +147,9 @@
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</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="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

@@ -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

@@ -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>

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>

43
example/quickstart/Jamroot Executable file
View File

@@ -0,0 +1,43 @@
# 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

@@ -0,0 +1,7 @@
# 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

@@ -0,0 +1,154 @@
// 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

@@ -0,0 +1,41 @@
// 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

@@ -0,0 +1,6 @@
# 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

@@ -0,0 +1,36 @@
# 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;
};
@@ -43,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;
@@ -57,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.
@@ -77,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

@@ -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

@@ -104,6 +104,14 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
#if defined _MSC_VER && _MSC_VER < 1300
typedef is_same<
typename BasePolicy_::result_converter
, default_result_converter
> 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
@@ -112,7 +120,7 @@ namespace detail
, 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,23 +26,7 @@ extern "C" __declspec(dllexport) void init##name() \
} \
void init_module_##name()
# 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
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
@@ -52,7 +36,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

@@ -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

@@ -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

@@ -17,73 +17,73 @@
# include <boost/type_traits/is_same.hpp>
namespace boost { namespace python {
// indexing_suite class. This class is the facade class for
// the management of C++ containers intended to be integrated
// to Python. The objective is make a C++ container look and
// feel and behave exactly as we'd expect a Python container.
// By default indexed elements are returned by proxy. This can be
// disabled by supplying *true* in the NoProxy template parameter.
//
//
// Derived classes provide the hooks needed by the indexing_suite
// to do its job:
//
// static data_type&
// static data_type&
// get_item(Container& container, index_type i);
//
// static object
// static object
// get_slice(Container& container, index_type from, index_type to);
//
// static void
// static void
// set_item(Container& container, index_type i, data_type const& v);
//
// static void
// static void
// set_slice(
// Container& container, index_type from,
// Container& container, index_type from,
// index_type to, data_type const& v
// );
//
// template <class Iter>
// static void
// set_slice(Container& container, index_type from,
// static void
// set_slice(Container& container, index_type from,
// index_type to, Iter first, Iter last
// );
//
// static void
// static void
// delete_item(Container& container, index_type i);
//
// static void
//
// static void
// delete_slice(Container& container, index_type from, index_type to);
//
//
// static size_t
// size(Container& container);
//
// template <class T>
// static bool
// contains(Container& container, T const& val);
//
//
// static index_type
// convert_index(Container& container, PyObject* i);
//
//
// static index_type
// adjust_index(index_type current, index_type from,
// adjust_index(index_type current, index_type from,
// index_type to, size_type len
// );
//
// Most of these policies are self explanatory. convert_index and
// adjust_index, however, deserves some explanation.
// Most of these policies are self explanatory. convert_index and
// adjust_index, however, deserves some explanation.
//
// convert_index converts an Python index into a C++ index that the
// container can handle. For instance, negative indexes in Python, by
// convention, indexes from the right (e.g. C[-1] indexes the rightmost
// element in C). convert_index should handle the necessary conversion
// convert_index converts an Python index into a C++ index that the
// container can handle. For instance, negative indexes in Python, by
// convention, indexes from the right (e.g. C[-1] indexes the rightmost
// element in C). convert_index should handle the necessary conversion
// for the C++ container (e.g. convert -1 to C.size()-1). convert_index
// should also be able to convert the type of the index (A dynamic Python
// type) to the actual type that the C++ container expects.
//
// When a container expands or contracts, held indexes to its elements
// must be adjusted to follow the movement of data. For instance, if
// we erase 3 elements, starting from index 0 from a 5 element vector,
// we erase 3 elements, starting from index 0 from a 5 element vector,
// what used to be at index 4 will now be at index 1:
//
// [a][b][c][d][e] ---> [d][e]
@@ -104,7 +104,7 @@ namespace boost { namespace python {
, class Index = typename Container::size_type
, class Key = typename Container::value_type
>
class indexing_suite
class indexing_suite
: public def_visitor<
indexing_suite<
Container
@@ -117,7 +117,7 @@ namespace boost { namespace python {
> >
{
private:
typedef mpl::or_<
mpl::bool_<NoProxy>
, mpl::not_<is_class<Data> >
@@ -127,10 +127,10 @@ namespace boost { namespace python {
, is_same<Data, std::complex<double> >
, is_same<Data, std::complex<long double> > >::type>
no_proxy;
typedef detail::container_element<Container, Index, DerivedPolicies>
container_element_t;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct return_policy : return_internal_reference<> {};
#else
@@ -142,7 +142,7 @@ namespace boost { namespace python {
, iterator<Container>
, iterator<Container, return_policy> >::type
def_iterator;
typedef typename mpl::if_<
no_proxy
, detail::no_proxy_helper<
@@ -172,15 +172,15 @@ namespace boost { namespace python {
, Data
, Index> >::type
slice_handler;
public:
template <class Class>
void visit(Class& cl) const
{
// Hook into the class_ generic visitation .def function
proxy_handler::register_container_element();
cl
.def("__len__", base_size)
.def("__setitem__", &base_set_item)
@@ -189,12 +189,12 @@ namespace boost { namespace python {
.def("__contains__", &base_contains)
.def("__iter__", def_iterator())
;
DerivedPolicies::extension_def(cl);
}
}
template <class Class>
static void
static void
extension_def(Class& cl)
{
// default.
@@ -202,24 +202,24 @@ namespace boost { namespace python {
}
private:
static object
base_get_item(back_reference<Container&> container, PyObject* i)
{
{
if (PySlice_Check(i))
return slice_handler::base_get_slice(
container.get(), reinterpret_cast<PySliceObject*>(i));
container.get(), static_cast<PySliceObject*>(static_cast<void*>(i)));
return proxy_handler::base_get_item_(container, i);
}
static void
static void
base_set_item(Container& container, PyObject* i, PyObject* v)
{
if (PySlice_Check(i))
{
slice_handler::base_set_slice(container,
reinterpret_cast<PySliceObject*>(i), v);
slice_handler::base_set_slice(container,
static_cast<PySliceObject*>(static_cast<void*>(i)), v);
}
else
{
@@ -228,7 +228,7 @@ namespace boost { namespace python {
if (elem.check())
{
DerivedPolicies::
set_item(container,
set_item(container,
DerivedPolicies::
convert_index(container, i), elem());
}
@@ -239,7 +239,7 @@ namespace boost { namespace python {
if (elem.check())
{
DerivedPolicies::
set_item(container,
set_item(container,
DerivedPolicies::
convert_index(container, i), elem());
}
@@ -252,20 +252,20 @@ namespace boost { namespace python {
}
}
static void
static void
base_delete_item(Container& container, PyObject* i)
{
if (PySlice_Check(i))
{
slice_handler::base_delete_slice(
container, reinterpret_cast<PySliceObject*>(i));
container, static_cast<PySliceObject*>(static_cast<void*>(i)));
return;
}
Index index = DerivedPolicies::convert_index(container, i);
proxy_handler::base_erase_index(container, index, mpl::bool_<NoSlice>());
DerivedPolicies::delete_item(container, index);
}
}
static size_t
base_size(Container& container)
@@ -290,10 +290,10 @@ namespace boost { namespace python {
return DerivedPolicies::contains(container, x());
else
return false;
}
}
}
};
}} // namespace boost::python
}} // namespace boost::python
#endif // INDEXING_SUITE_JDG20036_HPP

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
};
}

View File

@@ -1,141 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#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
{
@@ -168,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 ")
@@ -189,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";
@@ -204,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";
@@ -219,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;
}
@@ -226,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";
@@ -238,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

@@ -121,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)
{
@@ -143,6 +143,8 @@ namespace
object module_name = module_prefix();
if (module_name)
d["__module__"] = module_name;
if (doc)
d["__doc__"] = doc;
object result = (object(metatype))(name, make_tuple(base), d);
@@ -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
@@ -517,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(
@@ -591,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

@@ -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,25 +35,33 @@ 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
run exec.cpp ../build//boost_python/<link>static $(PY)
: # program args
: exec.py # input files
: # requirements
: # target-name
]
[
run exec.cpp ../build//boost_python/<link>shared /python//python
: # program args
: exec.py
: # requirements
<define>BOOST_PYTHON_STATIC_MODULE
: exec-dynamic # target-name
]
# [
# 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
@@ -77,8 +93,8 @@ 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 ]
@@ -135,6 +151,7 @@ bpl-test crossmod_opaque
[ bpl-test nested ]
[ bpl-test docstring ]
[ bpl-test pytype_function ]
[ bpl-test vector_indexing_suite ]
@@ -145,9 +162,9 @@ 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 ]
@@ -182,7 +199,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,23 +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("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("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
;

View File

@@ -84,24 +84,27 @@
(2, 4.25, 'wow')
>>> q.f1()
(1, 4.25, 'wow')
>>> q.f2.__doc__.splitlines()[-4]
"f2's docstring"
>>> q.f2.__doc__.splitlines()[1]
'f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple :'
>>> X.f.__doc__.splitlines()[:3]
["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()[:3]
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()
@@ -136,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

@@ -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, 3, 6, 9, 11, 12, 14, 17)
|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, 2)
|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, 3, 6, 9, 11, 12, 14)
|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, 3)
|this is the __init__ function
|its documentation has two lines.
|C++ signature:
>>> print selected_doc(X.value, 0, 2, 4, 5, 7)
|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, 2)
|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, 2)
|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())
4
>>> print selected_doc(fact_usr_on_1, 0, 2)
|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())
4
>>> print selected_doc(fact_usr_on_2, 0, 2)
|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())
4
>>> print selected_doc(fact_sig_on_1, 0, 2)
|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())
4
>>> print selected_doc(fact_sig_on_2, 0, 2)
|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())
4
>>> print selected_doc(fact_usr_on_sig_on_1, 0, 2)
|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())
4
>>> print selected_doc(fact_usr_on_sig_on_2, 0, 2)
|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 :
'''

View File

@@ -13,6 +13,19 @@
>>> try: make_x('fool')
... except TypeError: pass
... else: print 'no error'
>>> print x_value.__doc__.splitlines()[1]
x_value( (X)arg1) -> int :
>>> print make_x.__doc__.splitlines()[1]
make_x( (object)arg1) -> X :
>>> print X.value.__doc__.splitlines()[1]
value( (X)arg1) -> int :
>>> print X.set.__doc__.splitlines()[1]
set( (X)arg1, (object)arg2) -> None :
'''
def run(args = None):

View File

@@ -6,13 +6,30 @@
#include <boost/python.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <sstream>
namespace bpl = boost::python;
void import_test()
void import_test(char const *py_file_path)
{
// Retrieve the main module
bpl::object main = bpl::import("__main__");
// Retrieve the main module's namespace
bpl::object global(main.attr("__dict__"));
// Inject search path for import_ module
bpl::str script(
"import sys, os.path\n"
"path = os.path.dirname(%r)\n"
"sys.path.insert(0, path)"
% bpl::str(py_file_path));
bpl::object result = bpl::exec(script, global, global);
// Retrieve the main module
bpl::object import_ = bpl::import("import_");
int value = bpl::extract<int>(import_.attr("value")) BOOST_EXTRACT_WORKAROUND;
@@ -27,19 +44,7 @@ int main(int argc, char **argv)
// Initialize the interpreter
Py_Initialize();
// Retrieve the main module
bpl::object main = bpl::import("__main__");
// Retrieve the main module's namespace
bpl::object global(main.attr("__dict__"));
// Inject search path for import_ module
std::ostringstream script;
script << "import sys, os.path\n"
<< "path = os.path.dirname('" << argv[1] << "')\n"
<< "sys.path.insert(0, path)\n";
bpl::object result = bpl::exec(bpl::str(script.str()), global, global);
if (bpl::handle_exception(import_test))
if (bpl::handle_exception(boost::bind(import_test,argv[1])))
{
if (PyErr_Occurred())
{

View File

@@ -80,8 +80,10 @@
>>> f.set(1,1.0,"1")
>>> f.a(), f.b(), f.n()
(1, 1.0, '1')
>>> f.set2.__doc__.splitlines()[-4]
"set2's docstring"
>>> f.set2.__doc__.splitlines()[1]
'set2( (Bar)arg1 [, (int)arg2 [, (float)arg3 [, (str)arg4]]]) -> None :'
>>> f.set2.__doc__.splitlines()[2]
" set2's docstring"
'''

View File

@@ -13,6 +13,7 @@
#include <boost/python/to_python_converter.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/converter/pytype_function.hpp>
#include <string.h>
#include "simple_type.hpp"
#include "complicated.hpp"
@@ -170,7 +171,8 @@ using boost::python::to_python_converter;
// Wrap a simple by copying it into a Simple
struct simple_to_python
: to_python_converter<simple, simple_to_python>
: to_python_converter<simple, simple_to_python, true>
//, boost::python::converter::wrap_pytype<&SimpleType>
{
static PyObject* convert(simple const& x)
{
@@ -178,6 +180,7 @@ struct simple_to_python
p->x = x;
return (PyObject*)p;
}
static PyTypeObject const *get_pytype(){return &SimpleType; }
};
struct int_from_noddy

View File

@@ -26,61 +26,6 @@ std::string x_value(X const& x)
return "gotya " + x.s;
}
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;
}
};
BOOST_PYTHON_MODULE(map_indexing_suite_ext)
{
@@ -115,17 +60,9 @@ BOOST_PYTHON_MODULE(map_indexing_suite_ext)
.def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
;
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>()))
;
void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
}
#include "module_tail.cpp"

View File

@@ -183,6 +183,8 @@ are a complicated constructor and member function, respectively.
>>> dd = take_d(d_as_a)
>>> dd.name()
'D'
>>> print g.__doc__.splitlines()[1]
g( (Simple)arg1) -> Simple :
"""

View File

@@ -19,7 +19,7 @@
#include <string>
namespace {
namespace boost_python_test {
// A friendly class.
class world
@@ -52,6 +52,7 @@ namespace {
BOOST_PYTHON_MODULE(pickle1_ext)
{
using namespace boost::python;
using namespace boost_python_test;
class_<world>("world", init<const std::string&>())
.def("greet", &world::greet)
.def_pickle(world_pickle_suite())

View File

@@ -28,7 +28,7 @@
#include <boost/python/tuple.hpp>
#include <boost/python/extract.hpp>
namespace { // Avoid cluttering the global namespace.
namespace boost_python_test {
// A friendly class.
class world
@@ -88,6 +88,7 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE(pickle2_ext)
{
using namespace boost_python_test;
boost::python::class_<world>(
"world", boost::python::init<const std::string&>())
.def("greet", &world::greet)

View File

@@ -29,7 +29,7 @@
# define make_tuple boost::python::make_tuple
#endif
namespace { // Avoid cluttering the global namespace.
namespace boost_python_test {
// A friendly class.
class world
@@ -100,6 +100,7 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE(pickle3_ext)
{
using namespace boost_python_test;
boost::python::class_<world>(
"world", boost::python::init<const std::string&>())
.def("greet", &world::greet)

View File

@@ -15,7 +15,7 @@
#include <string>
namespace {
namespace boost_python_test {
// A friendly class.
class world
@@ -35,6 +35,7 @@ namespace {
BOOST_PYTHON_MODULE(pickle4_ext)
{
using namespace boost::python;
using namespace boost_python_test;
class_<world>("world", init<const std::string&>())
.enable_pickling()
.def("greet", &world::greet)

85
test/pytype_function.cpp Normal file
View File

@@ -0,0 +1,85 @@
// 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/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/to_python_converter.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct A
{
};
struct B
{
A a;
B(const A& a_):a(a_){}
};
// Converter from A to python int
struct BToPython
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
: converter::to_python_target_type<A> //inherits get_pytype
#endif
{
static PyObject* convert(const B& b)
{
return boost::python::incref(boost::python::object(b.a).ptr());
}
};
// Conversion from python int to A
struct BFromPython
{
BFromPython()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id< B >()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &converter::expected_from_python_type<A>::get_pytype//convertible to A can be converted to B
#endif
);
}
static void* convertible(PyObject* obj_ptr)
{
extract<const A&> ex(obj_ptr);
if (!ex.check()) 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< B >*)data)-> storage.bytes;
extract<const A&> 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< B , BToPython,true >(); //has get_pytype
BFromPython();
class_<A>("A") ;
def("func", &func);
}
#include "module_tail.cpp"

27
test/pytype_function.py Executable file
View File

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

View File

@@ -5,9 +5,10 @@
#include <boost/python/type_id.hpp>
#include <iostream>
// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition
#if ((defined(__GNUC__) && __GNUC__ < 3)) \
|| (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
// gcc 2.95.x, MIPSpro 7.3.1.3 and IBM XL for Linux linker seem to demand this definition
#if (defined(__GNUC__) && (__GNUC__ < 3)) \
|| (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) \
|| (defined(__IBMCPP__) && defined(__linux__))
namespace boost { namespace python {
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>)
{

View File

@@ -43,6 +43,7 @@ struct functions
}
static shared_ptr<T> get() { return storage; }
static shared_ptr<T> &get1() { return storage; }
static int look_store()
{
@@ -71,6 +72,8 @@ struct functions
.staticmethod("identity")
.def("null", &null)
.staticmethod("null")
.def("get1", &get1, return_internal_reference<>())
.staticmethod("get1")
.def("get", &get)
.staticmethod("get")
.def("count", &T::count)
@@ -154,6 +157,14 @@ shared_ptr<Y> factory(int n)
// ------
// from Neal Becker
struct Test {
boost::shared_ptr<X> x;
};
// ------
BOOST_PYTHON_MODULE(shared_ptr_ext)
{
class_<A, boost::shared_ptr<A_Wrapper>, boost::noncopyable>("A")
@@ -193,6 +204,12 @@ BOOST_PYTHON_MODULE(shared_ptr_ext)
.def("value", &Z::value)
.def("v", &Z::v, &ZWrap::default_v)
);
// from Neal Becker
class_<Test> ("Test")
.def_readonly ("x", &Test::x, "x")
;
// ------
}
#include "module_tail.cpp"

View File

@@ -57,7 +57,7 @@ char const* rewrap_value_mutable_cstring(char* x) { return x; }
object identity_(object x) { return x; }
BOOST_PYTHON_MODULE(builtin_converters)
BOOST_PYTHON_MODULE(builtin_converters_ext)
{
def("get_type", get_type);
def("return_null_handle", return_null_handle);

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