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

Compare commits

...

6 Commits

Author SHA1 Message Date
nobody
522b979793 This commit was manufactured by cvs2svn to create tag
'Version_1_34_0_RC2'.

[SVN r37655]
2007-05-09 22:09:47 +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
15 changed files with 1290 additions and 606 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

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,252 @@ 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
=============================
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 +318,35 @@ 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.
.. Admonition:: Windows Users: No Auto-Link Support
Boost.Python does not yet support the `auto-link`_ feature, so if
you're not using the quickstart_ method, you'll have to pay
attention to the names of generated libraries and add extra link
arguments not shown in the `Getting Started Guide`_ to select the
right library.
.. _auto-link: ../../../more/getting_started/windows.html#link-your-program-to-a-boost-library
.. _quickstart: `no-install quickstart`_
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 +359,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 +418,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 +465,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 +519,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 +561,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
=======================================================
@@ -370,8 +657,8 @@ __ http://www.python.org/doc/current/inst/index.html
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 +678,17 @@ __ 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.
You may also find

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>

Binary file not shown.

View File

@@ -1,36 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements <library>/boost/python//boost_python ;
python-extension getting_started1 : getting_started1.cpp ;
bpl-test test1
: # Python test driver
test_getting_started1.py
# extension modules to use
getting_started1 ;
python-extension getting_started2 : getting_started2.cpp ;
bpl-test test2
: # Python test driver
test_getting_started2.py
# extension modules to use
getting_started2 ;
python-extension std_pair : std_pair.cpp ;
bpl-test test3
: # Python test driver
test_std_pair.py
# extension modules to use
std_pair_ext ;
# Don't run tests by default
explicit test1 test2 test3 ;
alias test : test1 test2 test3 ;
explicit test ;

View File

@@ -1,36 +0,0 @@
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
# and conditions of use.
# If you move this example from its place in the Boost tree, edit this
# path to point at the root directory of your Boost installation (the
# one containing a subdirectory called "boost/" and a sub-subdirectory
# "boost/python/" full of .hpp files). Absolute paths work, too.
#
path-global BOOST_ROOT : ../../.. ;
# Boost.Python configuration variables, as described in
# http://www.boost.org/libs/python/doc/building.html#configuration.
# Usually you don't need to set these; the defaults will work. If you
# do set them, try to change as few of them as possible, starting with
# the first ones.
# PYTHON_VERSION = <the two-part Major.Minor version number, e.g. 2.2> ;
# PYTHON_ROOT = <root directory of your Python installation, e.g. /usr> ;
# PYTHON_INCLUDES = <path to Python #include directories> ;
# PYTHON_LIB_PATH = <path to Python library object> ;
# You may need to configure your compiler toolset, especially if you
# want to build with a compiler that is not the "system default" or if
# it is installed in a nonstandard place; see
# http://www.boost.org/more/getting_started.html#Configuring for
# details.
# Makes a project id for boost so that other Boost.Build projects can
# refer to it by name.
#
project boost : $(BOOST_ROOT) ;
# Change this setting to have all your built products placed under a
# single directory:
#
# ALL_LOCATE_TARGET = <root directory for all built products>

Binary file not shown.

33
example/quickstart/Jamroot Executable file
View File

@@ -0,0 +1,33 @@
# 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
: requirements <library>/boost/python//boost_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

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

@@ -51,6 +51,7 @@
# if defined(_SGI_COMPILER_VERSION) && _SGI_COMPILER_VERSION >= 740
# undef _POSIX_C_SOURCE
# undef _XOPEN_SOURCE
# undef HAVE_STDINT_H // undo Python 2.5.1 define
# endif
//