diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index c236ba6d..e01a27b7 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -22,11 +22,12 @@ if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] ) } } -if [ python.configured ] { - project boost/python - : source-location ../src - ; + : source-location ../src + ; + +rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } } +rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } } lib boost_python : # sources @@ -58,6 +59,7 @@ lib boost_python wrapper.cpp import.cpp exec.cpp + object/function_doc_signature.cpp : # requirements static:BOOST_PYTHON_STATIC_LIB BOOST_PYTHON_SOURCE @@ -74,19 +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. - /python//python_for_extensions - + [ cond [ python.configured ] : /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 ] : no ] + on:BOOST_DEBUG_PYTHON - : # default build shared : # usage requirements static:BOOST_PYTHON_STATIC_LIB on: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 ; diff --git a/doc/building.html b/doc/building.html index 49d83be8..ad42d02b 100644 --- a/doc/building.html +++ b/doc/building.html @@ -620,7 +620,7 @@ python and associated libraries are built by adding 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 + diff --git a/doc/building.rst b/doc/building.rst index d3a93800..37700e35 100644 --- a/doc/building.rst +++ b/doc/building.rst @@ -678,4 +678,3 @@ __ http://www.python.org/doc/current/inst/index.html 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 \ No newline at end of file diff --git a/doc/news.html b/doc/news.html index 6e637a04..45a5b2f5 100644 --- a/doc/news.html +++ b/doc/news.html @@ -32,7 +32,43 @@
-
Current CVS
+
Current SVN
+ +
+
    +
  • Pythonic signatures are now automatically appended to the + docstrings. + +
  • Use docstring_options.hpp header + control the content of docstrings. + +
  • 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. +
  • +
  • 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 here). +
  • +
  • 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. +
  • + +
  • To support this new feature changes were made to the + to_python_converter.hpp, + default_call_policies, + ResultConverter, + CallPolicies and some others. + Efforts were made not to have interface breaking changes. +
  • + +
+
+ +
12 May 2007 - 1.34.0 release
    diff --git a/doc/tutorial/doc/Jamfile.v2 b/doc/tutorial/doc/Jamfile.v2 index 963f9346..f9b10f86 100644 --- a/doc/tutorial/doc/Jamfile.v2 +++ b/doc/tutorial/doc/Jamfile.v2 @@ -12,4 +12,5 @@ boostbook tutorial : boost.root=../../../../../.. boost.libraries=../../../../../../libs/libraries.htm + html.stylesheet=../../../../../../doc/html/boostbook.css ; diff --git a/doc/tutorial/doc/html/boostbook.css b/doc/tutorial/doc/html/boostbook.css deleted file mode 100644 index d84d5384..00000000 --- a/doc/tutorial/doc/html/boostbook.css +++ /dev/null @@ -1,511 +0,0 @@ -/*============================================================================= - Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ - - Use, modification and distribution is subject to 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) -=============================================================================*/ - -/*============================================================================= - Body defaults -=============================================================================*/ - - body - { - margin: 1em; - font-family: sans-serif; - } - -/*============================================================================= - Paragraphs -=============================================================================*/ - - p - { - text-align: left; - font-size: 10pt; - line-height: 1.15; - } - -/*============================================================================= - Program listings -=============================================================================*/ - - /* Code on paragraphs */ - p tt.computeroutput - { - font-size: 9pt; - } - - pre.synopsis - { - font-size: 90%; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - .programlisting, - .screen - { - font-size: 9pt; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - /* Program listings in tables don't get borders */ - td .programlisting, - td .screen - { - margin: 0pc 0pc 0pc 0pc; - padding: 0pc 0pc 0pc 0pc; - } - -/*============================================================================= - Headings -=============================================================================*/ - - h1, h2, h3, h4, h5, h6 - { - text-align: left; - margin: 1em 0em 0.5em 0em; - font-weight: bold; - } - - h1 { font: 140% } - h2 { font: bold 140% } - h3 { font: bold 130% } - h4 { font: bold 120% } - h5 { font: italic 110% } - h6 { font: italic 100% } - - /* Top page titles */ - title, - h1.title, - h2.title - h3.title, - h4.title, - h5.title, - h6.title, - .refentrytitle - { - font-weight: bold; - margin-bottom: 1pc; - } - - h1.title { font-size: 140% } - h2.title { font-size: 140% } - h3.title { font-size: 130% } - h4.title { font-size: 120% } - h5.title { font-size: 110% } - h6.title { font-size: 100% } - - .section h1 - { - margin: 0em 0em 0.5em 0em; - font-size: 140%; - } - - .section h2 { font-size: 140% } - .section h3 { font-size: 130% } - .section h4 { font-size: 120% } - .section h5 { font-size: 110% } - .section h6 { font-size: 100% } - - /* Code on titles */ - h1 tt.computeroutput { font-size: 140% } - h2 tt.computeroutput { font-size: 140% } - h3 tt.computeroutput { font-size: 130% } - h4 tt.computeroutput { font-size: 120% } - h5 tt.computeroutput { font-size: 110% } - h6 tt.computeroutput { font-size: 100% } - -/*============================================================================= - Author -=============================================================================*/ - - h3.author - { - font-size: 100% - } - -/*============================================================================= - Lists -=============================================================================*/ - - li - { - font-size: 10pt; - line-height: 1.3; - } - - /* Unordered lists */ - ul - { - text-align: left; - } - - /* Ordered lists */ - ol - { - text-align: left; - } - -/*============================================================================= - Links -=============================================================================*/ - - a - { - text-decoration: none; /* no underline */ - } - - a:hover - { - text-decoration: underline; - } - -/*============================================================================= - Spirit style navigation -=============================================================================*/ - - .spirit-nav - { - text-align: right; - } - - .spirit-nav a - { - color: white; - padding-left: 0.5em; - } - - .spirit-nav img - { - border-width: 0px; - } - -/*============================================================================= - Table of contents -=============================================================================*/ - - .toc - { - margin: 1pc 4% 0pc 4%; - padding: 0.1pc 1pc 0.1pc 1pc; - font-size: 80%; - line-height: 1.15; - } - - .boost-toc - { - float: right; - padding: 0.5pc; - } - -/*============================================================================= - Tables -=============================================================================*/ - - .table-title, - div.table p.title - { - margin-left: 4%; - padding-right: 0.5em; - padding-left: 0.5em; - } - - .informaltable table, - .table table - { - width: 92%; - margin-left: 4%; - margin-right: 4%; - } - - div.informaltable table, - div.table table - { - padding: 4px; - } - - /* Table Cells */ - div.informaltable table tr td, - div.table table tr td - { - padding: 0.5em; - text-align: left; - font-size: 9pt; - } - - div.informaltable table tr th, - div.table table tr th - { - padding: 0.5em 0.5em 0.5em 0.5em; - border: 1pt solid white; - font-size: 80%; - } - -/*============================================================================= - Blurbs -=============================================================================*/ - - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - font-size: 9pt; /* A little bit smaller than the main text */ - line-height: 1.2; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - p.blurb img - { - padding: 1pt; - } - -/*============================================================================= - Variable Lists -=============================================================================*/ - - /* Make the terms in definition lists bold */ - div.variablelist dl dt, - span.term - { - font-weight: bold; - font-size: 10pt; - } - - div.variablelist table tbody tr td - { - text-align: left; - vertical-align: top; - padding: 0em 2em 0em 0em; - font-size: 10pt; - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - - div.variablelist dl dt - { - margin-bottom: 0.2em; - } - - div.variablelist dl dd - { - margin: 0em 0em 0.5em 2em; - font-size: 10pt; - } - - div.variablelist table tbody tr td p, - div.variablelist dl dd p - { - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - -/*============================================================================= - Misc -=============================================================================*/ - - /* Title of books and articles in bibliographies */ - span.title - { - font-style: italic; - } - - span.underline - { - text-decoration: underline; - } - - span.strikethrough - { - text-decoration: line-through; - } - - /* Copyright, Legal Notice */ - div div.legalnotice p - { - text-align: left - } - -/*============================================================================= - Colors -=============================================================================*/ - - @media screen - { - /* Links */ - a - { - color: #005a9c; - } - - a:visited - { - color: #9c5a9c; - } - - h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, - h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, - h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited - { - text-decoration: none; /* no underline */ - color: #000000; - } - - /* Syntax Highlighting */ - .keyword { color: #0000AA; } - .identifier { color: #000000; } - .special { color: #707070; } - .preprocessor { color: #402080; } - .char { color: teal; } - .comment { color: #800000; } - .string { color: teal; } - .number { color: teal; } - .white_bkd { background-color: #FFFFFF; } - .dk_grey_bkd { background-color: #999999; } - - /* Copyright, Legal Notice */ - .copyright - { - color: #666666; - font-size: small; - } - - div div.legalnotice p - { - color: #666666; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid #DCDCDC; - } - - .programlisting, - .screen - { - border: 1px solid #DCDCDC; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Blurbs */ - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - border: 1px solid #DCDCDC; - } - - /* Table of contents */ - .toc - { - border: 1px solid #DCDCDC; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - } - - div.informaltable table tr th, - div.table table tr th - { - background-color: #F0F0F0; - border: 1px solid #DCDCDC; - } - - /* Misc */ - span.highlight - { - color: #00A000; - } - } - - @media print - { - /* Links */ - a - { - color: black; - } - - a:visited - { - color: black; - } - - .spirit-nav - { - display: none; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid gray; - } - - .programlisting, - .screen - { - border: 1px solid gray; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Table of contents */ - .toc - { - border: 1px solid gray; - } - - .informaltable table, - .table table - { - border: 1px solid gray; - border-collapse: collapse; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid gray; - } - - div.informaltable table tr th, - div.table table tr th - { - border: 1px solid gray; - } - - /* Misc */ - span.highlight - { - font-weight: bold; - } - } diff --git a/doc/tutorial/doc/html/index.html b/doc/tutorial/doc/html/index.html index 6562206f..5c65cb68 100644 --- a/doc/tutorial/doc/html/index.html +++ b/doc/tutorial/doc/html/index.html @@ -2,22 +2,22 @@ Chapter 1. python 1.0 - - + + - + - +
    -
    Boost C++ Libraries Home Libraries People FAQ More
    +
    -
    Next
    +
    Next

    @@ -31,7 +31,7 @@
    -

    +

    Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt ) @@ -93,10 +93,10 @@ code takes on the look of a kind of declarative interface definition language (IDL).

    -

    - +

    + Hello World -

    +

    Following C/C++ tradition, let's start with the "hello, world". A C++ Function: @@ -112,10 +112,10 @@

     #include <boost/python.hpp>
    -using namespace boost::python;
     
    -BOOST_PYTHON_MODULE(hello)
    +BOOST_PYTHON_MODULE(hello_ext)
     {
    +    using namespace boost::python;
         def("greet", greet);
     }
     
    @@ -126,23 +126,29 @@

    ->>> import hello
    +>>> import hello_ext
     >>> print hello.greet()
     hello, world
     

    -

    - Next stop... Building your Hello World module - from start to finish... -

    +
    +

    +

    +

    + Next stop... Building your Hello World + module from start to finish... +

    +

    +

    +
    - - + +

    Last revised: May 18, 2007 at 15:45:45 GMT

    Last revised: November 07, 2007 at 03:34:24 GMT


    -
    Next
    +
    Next
    diff --git a/doc/tutorial/doc/html/python/embedding.html b/doc/tutorial/doc/html/python/embedding.html index 2b2cb2b8..89365fef 100644 --- a/doc/tutorial/doc/html/python/embedding.html +++ b/doc/tutorial/doc/html/python/embedding.html @@ -2,25 +2,25 @@ Embedding - - + + - + - +
    -
    Boost C++ Libraries Home Libraries People FAQ More
    +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -39,28 +39,28 @@ a lot easier and, in a future version, it may become unnecessary to touch the Python/C API at all. So stay tuned... smiley

    -

    - +

    + Building embedded programs -

    +

    To be able to embed python into your programs, you have to link to both Boost.Python's as well as Python's own runtime library.

    Boost.Python's library comes in two variants. Both are located in Boost's - /libs/python/build/bin-stage subdirectory. On Windows, the - variants are called boost_python.lib (for release builds) - and boost_python_debug.lib (for debugging). If you can't + /libs/python/build/bin-stage subdirectory. On Windows, the + variants are called boost_python.lib (for release builds) + and boost_python_debug.lib (for debugging). If you can't find the libraries, you probably haven't built Boost.Python yet. See Building and Testing on how to do this.

    - Python's library can be found in the /libs subdirectory + Python's library can be found in the /libs subdirectory of your Python directory. On Windows it is called pythonXY.lib where X.Y is your major Python version number.

    - Additionally, Python's /include subdirectory has to be added + Additionally, Python's /include subdirectory has to be added to your include path.

    @@ -81,60 +81,67 @@ exe embedded_program # name of the executable <library-path>$(PYTHON_LIB_PATH) <find-library>$(PYTHON_EMBEDDED_LIBRARY) ; -

    - +

    + Getting started -

    +

    Being able to build is nice, but there is nothing to build yet. Embedding the Python interpreter into one of your C++ programs requires these 4 steps:

    1. - -#include -  <boost/python.hpp>

      + #include <boost/python.hpp>
    2. Call Py_Initialize() - to start the interpreter and create the _main_ - module.

      -
    3. + to start the interpreter and create the _main_ + module. +
    4. - Call other Python C API routines to use the interpreter.

      -
    5. + Call other Python C API routines to use the interpreter. +
    -
    - - +
    note Note that at this time - you must not call Py_Finalize() - to stop the interpreter. This may be fixed in a future version of boost.python. -
    + + + + +
    [Note]Note

    + Note that at this time you must not call Py_Finalize() + to stop the interpreter. This may be fixed in a future version of boost.python. +

    (Of course, there can be other C++ code between all of these steps.)

    -

    - Now that we can embed the interpreter in - our programs, lets see how to put it to use... -

    +
    +

    +

    +

    + Now that we can embed the interpreter in + our programs, lets see how to put it to use... +

    +

    +

    +

    Using the interpreter

    As you probably already know, objects in Python are reference-counted. Naturally, - the PyObjects of the Python/C API are also reference-counted. + the PyObjects of the Python/C API are also reference-counted. There is a difference however. While the reference-counting is fully automatic - in Python, the Python/C API requires you to do it by - hand. This is messy and especially hard to get right in the presence + in Python, the PythonC API requires you to do it [@http:/www.python.org/doc/current/api/refcounts.html + by hand]. This is messy and especially hard to get right in the presence of C++ exceptions. Fortunately Boost.Python provides the handle and object class templates to automate the process.

    -

    - +

    + Running Python code -

    +

    Boost.python provides three related functions to run Python code from C++.

    @@ -149,10 +156,10 @@ exe embedded_program # name of the executable and exec_file executes the code contained in the given file.

    - The globals and locals parameters are + The globals and locals parameters are Python dictionaries containing the globals and locals of the context in which to run the code. For most intents and purposes you can use the namespace - dictionary of the _main_ + dictionary of the _main_ module for both parameters.

    @@ -166,7 +173,7 @@ exe embedded_program # name of the executable first), and returns it.

    - Let's import the _main_ + Let's import the _main_ module and run some Python code in its namespace:

    @@ -182,15 +189,15 @@ exe embedded_program # name of the executable
             This should create a file called 'hello.txt' in the current directory containing
             a phrase that is well-known in programming circles.
           

    -

    - +

    + Manipulating Python objects -

    +

    Often we'd like to have a class to manipulate Python objects. But we have already seen such a class above, and in the previous - section: the aptly named object class and its - derivatives. We've already seen that they can be constructed from a handle. + section: the aptly named object class and its + derivatives. We've already seen that they can be constructed from a handle. The following examples should further illustrate this fact:

    @@ -200,7 +207,7 @@ exe embedded_program # name of the executable
     int five_squared = extract<int>(main_namespace["result"]);
     

    - Here we create a dictionary object for the _main_ + Here we create a dictionary object for the _main_ module's namespace. Then we assign 5 squared to the result variable and read this variable from the dictionary. Another way to achieve the same result is to use eval instead, which returns the result directly: @@ -209,10 +216,10 @@ exe embedded_program # name of the executable object result = eval("5 ** 2"); int five_squared = extract<int>(result);

    -

    - +

    + Exception handling -

    +

    If an exception occurs in the evaluation of the python expression, error_already_set is thrown: @@ -230,13 +237,13 @@ exe embedded_program # name of the executable }

    - The error_already_set exception class doesn't carry any + The error_already_set exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the exception - handling functions of the Python/C API in your catch-statement. This - can be as simple as calling PyErr_Print() - to print the exception's traceback to the console, or comparing the type - of the exception with those of the standard + handling functions of the PythonC API in your catch-statement. + This can be as simple as calling [@http:/www.python.org/doc/api/exceptionHandling.html#l2h-70 + PyErr_Print()] to print the exception's traceback to the console, or comparing + the type of the exception with those of the standard exceptions:

    @@ -261,12 +268,17 @@ exe embedded_program # name of the executable
     
    - +
    Copyright © 2002-2005 Joel - de Guzman, David Abrahams

    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/tutorial/doc/html/python/exception.html b/doc/tutorial/doc/html/python/exception.html index c86133c2..7a9b5c74 100644 --- a/doc/tutorial/doc/html/python/exception.html +++ b/doc/tutorial/doc/html/python/exception.html @@ -1,26 +1,26 @@ -Exception Translation - - + Exception Translation + + - + - +
    -
    Boost C++ Libraries Home Libraries People FAQ More
    +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -49,12 +49,17 @@

    - +
    Copyright © 2002-2005 Joel - de Guzman, David Abrahams

    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/tutorial/doc/html/python/exposing.html b/doc/tutorial/doc/html/python/exposing.html index da3c5873..3f28366b 100644 --- a/doc/tutorial/doc/html/python/exposing.html +++ b/doc/tutorial/doc/html/python/exposing.html @@ -1,26 +1,26 @@ -Exposing Classes - - + Exposing Classes + + - + - +
    -
    Boost C++ Libraries Home Libraries People FAQ More
    +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -64,9 +64,9 @@ }

    - Here, we wrote a C++ class wrapper that exposes the member functions greet - and set. Now, after building our module as a shared library, - we may use our class World in Python. Here's a sample Python + Here, we wrote a C++ class wrapper that exposes the member functions greet + and set. Now, after building our module as a shared library, + we may use our class World in Python. Here's a sample Python session:

    @@ -82,7 +82,7 @@

    Constructors

    - Our previous example didn't have any explicit constructors. Since World + Our previous example didn't have any explicit constructors. Since World is declared as a plain struct, it has an implicit default constructor. Boost.Python exposes the default constructor by default, which is why we were able to write @@ -106,9 +106,9 @@ };

    - This time World has no default constructor; our previous + This time World has no default constructor; our previous wrapping code would fail to compile when the library tried to expose it. - We have to tell class_<World> about the constructor + We have to tell class_<World> about the constructor we want to expose instead.

    @@ -124,13 +124,13 @@
     }
     

    - init<std::string>() exposes the constructor taking - in a std::string (in Python, constructors are spelled - ""_init_""). + init<std::string>() exposes the constructor taking + in a std::string (in Python, constructors are spelled + ""_init_"").

    - We can expose additional constructors by passing more init<...>s - to the def() member function. Say for example we have + We can expose additional constructors by passing more init<...>s + to the def() member function. Say for example we have another World constructor taking in two doubles:

    @@ -142,13 +142,13 @@
     

    On the other hand, if we do not wish to expose any constructors at all, we - may use no_init instead: + may use no_init instead:

     class_<Abstract>("Abstract", no_init)
     

    - This actually adds an _init_ + This actually adds an _init_ method which always raises a Python RuntimeError exception.

    @@ -158,8 +158,8 @@

    Data members may also be exposed to Python so that they can be accessed as attributes of the corresponding Python class. Each data member that we wish - to be exposed may be regarded as read-only - or read-write. Consider this class Var: + to be exposed may be regarded as read-only + or read-write. Consider this class Var:

     struct Var
    @@ -170,7 +170,7 @@
     };
     

    - Our C++ Var class and its data members can be exposed + Our C++ Var class and its data members can be exposed to Python:

    @@ -191,8 +191,8 @@
     pi is around 3.14
     

    - Note that name is exposed as read-only - while value is exposed as read-write. + Note that name is exposed as read-only + while value is exposed as read-write.

     >>> x.name = 'e' # can't change name
    @@ -224,7 +224,7 @@
     

    However, in Python attribute access is fine; it doesn't neccessarily break encapsulation to let users handle attributes directly, because the attributes - can just be a different syntax for a method call. Wrapping our Num + can just be a different syntax for a method call. Wrapping our Num class using Boost.Python:

    @@ -245,8 +245,8 @@
     >>> x.rovalue = 2.17 # error!
     

    - Take note that the class property rovalue is exposed as - read-only since the rovalue + Take note that the class property rovalue is exposed as + read-only since the rovalue setter member function is not passed in:

    @@ -273,7 +273,7 @@ struct Derived : Base {};

    - And a set of C++ functions operating on Base and Derived + And a set of C++ functions operating on Base and Derived object instances:

    @@ -282,7 +282,7 @@
     Base* factory() { return new Derived; }
     

    - We've seen how we can wrap the base class Base: + We've seen how we can wrap the base class Base:

     class_<Base>("Base")
    @@ -290,8 +290,8 @@
         ;
     

    - Now we can inform Boost.Python of the inheritance relationship between Derived - and its base class Base. Thus: + Now we can inform Boost.Python of the inheritance relationship between Derived + and its base class Base. Thus:

     class_<Derived, bases<Base> >("Derived")
    @@ -307,15 +307,15 @@
               member functions)
             
     
  • -If Base is polymorphic, Derived +If Base is polymorphic, Derived objects which have been passed to Python via a pointer or reference to - Base can be passed where a pointer or reference to - Derived is expected. + Base can be passed where a pointer or reference to + Derived is expected.
  • - Now, we shall expose the C++ free functions b and d - and factory: + Now, we will expose the C++ free functions b and d + and factory:

     def("b", b);
    @@ -323,12 +323,12 @@
     def("factory", factory);
     

    - Note that free function factory is being used to generate - new instances of class Derived. In such cases, we use - return_value_policy<manage_new_object> to instruct - Python to adopt the pointer to Base and hold the instance - in a new Python Base object until the the Python object - is destroyed. We shall see more of Boost.Python call + Note that free function factory is being used to generate + new instances of class Derived. In such cases, we use + return_value_policy<manage_new_object> to instruct + Python to adopt the pointer to Base and hold the instance + in a new Python Base object until the the Python object + is destroyed. We will see more of Boost.Python call policies later.

    @@ -341,9 +341,9 @@
     

    Class Virtual Functions

    - In this section, we shall learn how to make functions behave polymorphically + In this section, we will learn how to make functions behave polymorphically through virtual functions. Continuing our example, let us add a virtual function - to our Base class: + to our Base class:

     struct Base
    @@ -356,11 +356,11 @@
             One of the goals of Boost.Python is to be minimally intrusive on an existing
             C++ design. In principle, it should be possible to expose the interface for
             a 3rd party library without changing it. It is not ideal to add anything
    -        to our class Base. Yet, when
    +        to our class Base. Yet, when
             you have a virtual function that's going to be overridden in Python and called
    -        polymorphically from C++, we'll need to
    +        polymorphically from C++, we'll need to
             add some scaffoldings to make things work properly. What we'll do is write
    -        a class wrapper that derives from Base
    +        a class wrapper that derives from Base
             that will unintrusively hook into the virtual functions so that a Python
             override may be called:
           

    @@ -374,24 +374,28 @@ };

    - Notice too that in addition to inheriting from Base, - we also multiply- inherited wrapper<Base> (See Wrapper). - The wrapper template makes + Notice too that in addition to inheriting from Base, + we also multiply- inherited wrapper<Base> (See Wrapper). + The wrapper template makes the job of wrapping classes that are meant to overridden in Python, easier.

    -
    - - -
    alert MSVC6/7 Workaround
    -
    If you are using Microsoft Visual C++ 6 or 7, you have to write - f as:

    - return call<int>(this->get_override("f").ptr());.
    + +

    + BaseWrap's overridden virtual member function f + in effect calls the corresponding method of the Python object through get_override. +

    +

    + Finally, exposing Base:

     class_<BaseWrap, boost::noncopyable>("Base")
    @@ -399,17 +403,24 @@
         ;
     

    - pure_virtual signals Boost.Python - that the function f is a + pure_virtual signals Boost.Python + that the function f is a pure virtual function.

    -
    - - +
    note member function and - methods

    Python, like many object oriented languages - uses the term methods. Methods correspond - roughly to C++'s member functions -
    + + + + +
    [Note]Note
    +

    + member function and methods +

    +

    + Python, like many object oriented languages uses the term methods. + Methods correspond roughly to C++'s member functions +

    +
    @@ -418,7 +429,7 @@

    We've seen in the previous section how classes with pure virtual functions are wrapped using Boost.Python's class - wrapper facilities. If we wish to wrap non-pure-virtual + wrapper facilities. If we wish to wrap non-pure-virtual functions instead, the mechanism is a bit different.

    @@ -433,8 +444,8 @@ };

    - had a pure virtual function f. If, however, its member - function f was not declared as pure virtual: + had a pure virtual function f. If, however, its member + function f was not declared as pure virtual:

     struct Base
    @@ -460,16 +471,22 @@
     };
     

    - Notice how we implemented BaseWrap::f. Now, - we have to check if there is an override for f. - If none, then we call Base::f(). + Notice how we implemented BaseWrap::f. Now, + we have to check if there is an override for f. + If none, then we call Base::f().

    -
    - - -
    alert MSVC6/7 Workaround
    -
    If you are using Microsoft Visual C++ 6 or 7, you have to rewrite - the line with the *note* as:

    return call<char const*>(f.ptr());.
    +

    Finally, exposing:

    @@ -479,10 +496,10 @@ ;

    - Take note that we expose both &Base::f and &BaseWrap::default_f. Boost.Python needs to keep track - of 1) the dispatch function f and 2) the forwarding function - to its default implementation default_f. There's a special - def function for this purpose. + Take note that we expose both &Base::f and &BaseWrap::default_f. Boost.Python needs to keep track + of 1) the dispatch function f and 2) the forwarding function + to its default implementation default_f. There's a special + def function for this purpose.

    In Python, the results would be as expected: @@ -498,14 +515,14 @@ >>> derived = Derived()

    - Calling base.f(): + Calling base.f():

     >>> base.f()
     0
     

    - Calling derived.f(): + Calling derived.f():

     >>> derived.f()
    @@ -515,17 +532,17 @@
     

    Class Operators/Special Functions

    -

    - +

    + Python Operators -

    +

    C is well known for the abundance of operators. C++ extends this to the extremes by allowing operator overloading. Boost.Python takes advantage of this and makes it easy to wrap C++ operator-powered classes.

    - Consider a file position class FilePos and a set of operators + Consider a file position class FilePos and a set of operators that take on FilePos instances:

    @@ -558,16 +575,16 @@

    The code snippet above is very clear and needs almost no explanation at all. It is virtually the same as the operators' signatures. Just take note that - self refers to FilePos object. Also, not every class - T that you might need to interact with in an operator - expression is (cheaply) default-constructible. You can use other<T>() - in place of an actual T instance when writing "self + self refers to FilePos object. Also, not every class + T that you might need to interact with in an operator + expression is (cheaply) default-constructible. You can use other<T>() + in place of an actual T instance when writing "self expressions".

    -

    - +

    + Special Methods -

    +

    Python has a few more Special Methods. Boost.Python supports all of the standard special method names supported by real Python @@ -593,21 +610,31 @@

    Need we say more?

    -
    - - +
    note What is the business of operator<<? Well, the method str requires the operator<< to do its work (i.e. operator<< - is used by the method defined by def(str(self)).
    + + + + +
    [Note]Note

    + What is the business of operator<<? Well, the method str requires the operator<< to do its work (i.e. operator<< + is used by the method defined by def(str(self)). +

    - +
    Copyright © 2002-2005 Joel - de Guzman, David Abrahams

    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/tutorial/doc/html/python/functions.html b/doc/tutorial/doc/html/python/functions.html index 40955dbb..9e230a2b 100644 --- a/doc/tutorial/doc/html/python/functions.html +++ b/doc/tutorial/doc/html/python/functions.html @@ -2,25 +2,25 @@ Functions - - + + - - + + - +
    -
    Boost C++ Libraries Home Libraries People FAQ More
    +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -33,17 +33,23 @@

In this chapter, we'll look at Boost.Python powered functions in closer detail. - We shall see some facilities to make exposing C++ functions to Python safe - from potential pifalls such as dangling pointers and references. We shall also - see facilities that will make it even easier for us to expose C++ functions - that take advantage of C++ features such as overloading and default arguments. + We will see some facilities to make exposing C++ functions to Python safe from + potential pifalls such as dangling pointers and references. We will also see + facilities that will make it even easier for us to expose C++ functions that + take advantage of C++ features such as overloading and default arguments.

-

- Read on... -

+
+

+

+

+ Read on... +

+

+

+

But before you do, you might want to fire up Python 2.2 or later and type - >>> import this. + >>> import this.

>>> import this
 The Zen of Python, by Tim Peters
@@ -62,7 +68,7 @@ In the face of ambiguity, refuse the temptation to guess.
 There should be one-- and preferably only one --obvious way to do it
 Although that way may not be obvious at first unless you're Dutch.
 Now is better than never.
-Although never is often better than right now.
+Although never is often better than right now.
 If the implementation is hard to explain, it's a bad idea.
 If the implementation is easy to explain, it may be a good idea.
 Namespaces are one honking great idea -- let's do more of those!
@@ -90,9 +96,9 @@ Namespaces are one honking great idea -- let's do more of those!
         Here's an example where it didn't
       

->>> x = f(y, z) # x refers to some C++ X
+>>> x = f(y, z) # x refers to some C++ X
 >>> del y
->>> x.some_method() # CRASH!
+>>> x.some_method() # CRASH!
 

What's the problem? @@ -120,19 +126,19 @@ Namespaces are one honking great idea -- let's do more of those!

  1. -f is called passing in a reference to y - and a pointer to z +f is called passing in a reference to y + and a pointer to z
  2. - A reference to y.x is returned + A reference to y.x is returned
  3. -y is deleted. x is a dangling reference +y is deleted. x is a dangling reference
  4. -x.some_method() is called +x.some_method() is called
  5. -
  6. BOOM!
  7. +
  8. BOOM!

We could copy result into a new object: @@ -162,16 +168,16 @@ Namespaces are one honking great idea -- let's do more of those! };

- Notice that the data member z is held by class Y using + Notice that the data member z is held by class Y using a raw pointer. Now we have a potential dangling pointer problem inside Y:

->>> x = f(y, z) # y refers to z
->>> del z       # Kill the z object
->>> y.z_value() # CRASH!
+>>> x = f(y, z) # y refers to z
+>>> del z       # Kill the z object
+>>> y.z_value() # CRASH!
 

- For reference, here's the implementation of f again: + For reference, here's the implementation of f again:

 X& f(Y& y, Z* z)
@@ -185,33 +191,33 @@ Namespaces are one honking great idea -- let's do more of those!
       

  1. -f is called passing in a reference to y - and a pointer to z +f is called passing in a reference to y + and a pointer to z
  2. - A pointer to z is held by y + A pointer to z is held by y
  3. - A reference to y.x is returned + A reference to y.x is returned
  4. -z is deleted. y.z is a dangling pointer +z is deleted. y.z is a dangling pointer
  5. -y.z_value() is called +y.z_value() is called
  6. -z->value() is called +z->value() is called
  7. -
  8. BOOM!
  9. +
  10. BOOM!
-

- +

+ Call Policies -

+

Call Policies may be used in situations such as the example detailed above. - In our example, return_internal_reference and with_custodian_and_ward + In our example, return_internal_reference and with_custodian_and_ward are our friends:

@@ -220,27 +226,27 @@ Namespaces are one honking great idea -- let's do more of those!
         with_custodian_and_ward<1, 2> >());
 

- What are the 1 and 2 parameters, you + What are the 1 and 2 parameters, you ask?

 return_internal_reference<1
 

- Informs Boost.Python that the first argument, in our case Y& - y, is the owner of the returned reference: X&. - The "1" simply specifies the first argument. - In short: "return an internal reference X& owned - by the 1st argument Y& y". + Informs Boost.Python that the first argument, in our case Y& + y, is the owner of the returned reference: X&. + The "1" simply specifies the first argument. + In short: "return an internal reference X& owned + by the 1st argument Y& y".

 with_custodian_and_ward<1, 2>
 

Informs Boost.Python that the lifetime of the argument indicated by ward - (i.e. the 2nd argument: Z* z) is dependent on the lifetime - of the argument indicated by custodian (i.e. the 1st argument: Y& - y). + (i.e. the 2nd argument: Z* z) is dependent on the lifetime + of the argument indicated by custodian (i.e. the 1st argument: Y& + y).

It is also important to note that we have defined two policies above. Two @@ -257,43 +263,48 @@ Namespaces are one honking great idea -- let's do more of those!

  • -with_custodian_and_ward
    Ties lifetimes +with_custodian_and_ward: Ties lifetimes of the arguments
  • -with_custodian_and_ward_postcall
    - Ties lifetimes of the arguments and results +with_custodian_and_ward_postcall: Ties + lifetimes of the arguments and results
  • -return_internal_reference
    Ties lifetime +return_internal_reference: Ties lifetime of one argument to that of result
  • -return_value_policy<T> with T one of:
    -
  • +return_value_policy<T> with T one of:
    • -reference_existing_object
      naive - (dangerous) approach -
    • +reference_existing_object: naive (dangerous) + approach +
    • -copy_const_reference
      Boost.Python - v1 approach -
    • +copy_const_reference: Boost.Python + v1 approach +
    • -copy_non_const_reference
      -
    • +copy_non_const_reference: +
    • -manage_new_object
      Adopt a pointer - and hold the instance -
    • +manage_new_object: Adopt a pointer + and hold the instance +
    -
    - - -
    smiley Remember the Zen, Luke:
    -
    "Explicit is better than implicit"
    "In - the face of ambiguity, refuse the temptation to guess"
    -
    + +
+

@@ -331,7 +342,7 @@ Namespaces are one honking great idea -- let's do more of those! };

- Class X has 4 overloaded functions. We shall start by introducing some member + Class X has 4 overloaded functions. We will start by introducing some member function pointer variables:

@@ -355,21 +366,21 @@ Namespaces are one honking great idea -- let's do more of those!
 Default Arguments
 

Boost.Python wraps (member) function pointers. Unfortunately, C++ function - pointers carry no default argument info. Take a function f + pointers carry no default argument info. Take a function f with default arguments:

 int f(int, double = 3.14, char const* = "hello");
 

- But the type of a pointer to the function f has no information + But the type of a pointer to the function f has no information about its default arguments:

 int(*g)(int,double,char const*) = f;    // defaults lost!
 

- When we pass this function pointer to the def function, + When we pass this function pointer to the def function, there is no way to retrieve the default arguments:

@@ -403,10 +414,10 @@ Namespaces are one honking great idea -- let's do more of those!
           are overloaded with a common sequence of initial arguments
         
 
-

- +

+ BOOST_PYTHON_FUNCTION_OVERLOADS -

+

Boost.Python now has a way to make it easier. For instance, given a function:

@@ -424,19 +435,19 @@ Namespaces are one honking great idea -- let's do more of those!

will automatically create the thin wrappers for us. This macro will create - a class foo_overloads that can be passed on to def(...). + a class foo_overloads that can be passed on to def(...). The third and fourth macro argument are the minimum arguments and maximum - arguments, respectively. In our foo function the minimum - number of arguments is 1 and the maximum number of arguments is 4. The def(...) + arguments, respectively. In our foo function the minimum + number of arguments is 1 and the maximum number of arguments is 4. The def(...) function will automatically add all the foo variants for us:

 def("foo", foo, foo_overloads());
 
-

- +

+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS -

+

Objects here, objects there, objects here there everywhere. More frequently than anything else, we need to expose member functions of our classes to @@ -445,7 +456,7 @@ Namespaces are one honking great idea -- let's do more of those! play. Another macro is provided to make this a breeze.

- Like BOOST_PYTHON_FUNCTION_OVERLOADS, BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS + Like BOOST_PYTHON_FUNCTION_OVERLOADS, BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS may be used to automatically create the thin wrappers for wrapping member functions. Let's have an example:

@@ -466,11 +477,11 @@ Namespaces are one honking great idea -- let's do more of those! BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)

- will generate a set of thin wrappers for george's wack_em + will generate a set of thin wrappers for george's wack_em member function accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and fourth macro argument). The thin wrappers are all enclosed - in a class named george_overloads that can then be used - as an argument to def(...): + in a class named george_overloads that can then be used + as an argument to def(...):

 .def("wack_em", &george::wack_em, george_overloads());
@@ -479,13 +490,13 @@ Namespaces are one honking great idea -- let's do more of those!
         See the overloads
         reference for details.
       

-

- +

+ init and optional -

+

A similar facility is provided for class constructors, again, with default - arguments or a sequence of overloads. Remember init<...>? + arguments or a sequence of overloads. Remember init<...>? For example, given a class X with a constructor:

@@ -502,7 +513,7 @@ Namespaces are one honking great idea -- let's do more of those!
 .def(init<int, optional<char, std::string, double> >())
 

- Notice the use of init<...> and optional<...> + Notice the use of init<...> and optional<...> to signify the default (optional arguments).

@@ -510,8 +521,8 @@ Namespaces are one honking great idea -- let's do more of those!

Auto-Overloading

- It was mentioned in passing in the previous section that BOOST_PYTHON_FUNCTION_OVERLOADS - and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS can also be + It was mentioned in passing in the previous section that BOOST_PYTHON_FUNCTION_OVERLOADS + and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS can also be used for overloaded functions and member functions with a common sequence of initial arguments. Here is an example:

@@ -553,24 +564,24 @@ Namespaces are one honking great idea -- let's do more of those! Notice though that we have a situation now where we have a minimum of zero (0) arguments and a maximum of 3 arguments.

-

- +

+ Manual Wrapping -

+

- It is important to emphasize however that the overloaded - functions must have a common sequence of initial arguments. Otherwise, + It is important to emphasize however that the overloaded + functions must have a common sequence of initial arguments. Otherwise, our scheme above will not work. If this is not the case, we have to wrap our functions manually.

Actually, we can mix and match manual wrapping of overloaded functions and - automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - and its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following + automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS + and its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following up on our example presented in the section on overloading, since the first 4 overload functins have a common sequence - of initial arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - to automatically wrap the first three of the defs and + of initial arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS + to automatically wrap the first three of the defs and manually wrap just the last. Here's how we'll do this:

@@ -594,12 +605,17 @@ Namespaces are one honking great idea -- let's do more of those!
 
 
-
+
Copyright © 2002-2005 Joel - de Guzman, David Abrahams

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/tutorial/doc/html/python/hello.html b/doc/tutorial/doc/html/python/hello.html index 1572c90a..99c089ec 100644 --- a/doc/tutorial/doc/html/python/hello.html +++ b/doc/tutorial/doc/html/python/hello.html @@ -1,82 +1,71 @@ -Building Hello World - - + Building Hello World + + - + - +
-
Boost C++ Libraries Home Libraries People FAQ More
+
-PrevUpHomeNext +PrevUpHomeNext

Building Hello World

-

- +

+ From Start To Finish -

+

Now the first thing you'd want to do is to build the Hello World module and - try it for yourself in Python. In this section, we shall outline the steps - necessary to achieve that. We shall use the build tool that comes bundled with - every boost distribution: bjam. + try it for yourself in Python. In this section, we will outline the steps necessary + to achieve that. We will use the build tool that comes bundled with every boost + distribution: bjam.

-
- - +
note Building without bjam
-
Besides bjam, there are of course other ways to get your module - built. What's written here should not be taken as "the one and only - way". There are of course other build tools apart from bjam.
-
Take note however that the preferred build tool for Boost.Python - is bjam. There are so many ways to set up the build incorrectly. Experience - shows that 90% of the "I can't build Boost.Python" problems - come from people who had to use a different tool.
+ + + + +
[Note]Note
+

+ Building without bjam +

+

+ Besides bjam, there are of course other ways to get your module built. What's + written here should not be taken as "the one and only way". There + are of course other build tools apart from bjam. +

+

+ Take note however that the preferred build tool for Boost.Python is bjam. + There are so many ways to set up the build incorrectly. Experience shows + that 90% of the "I can't build Boost.Python" problems come from + people who had to use a different tool. +

+

- We shall skip over the details. Our objective will be to simply create the - hello world module and run it in Python. For a complete reference to building - Boost.Python, check out: building.html. - After this brief bjam tutorial, we should have built two - DLLs: -

-
    -
  • - boost_python.dll -
  • -
  • - hello.pyd -
  • -
-

- if you are on Windows, and -

-
    -
  • - libboost_python.so -
  • -
  • - hello.so -
  • -
-

- if you are on Unix. + We will skip over the details. Our objective will be to simply create the hello + world module and run it in Python. For a complete reference to building Boost.Python, + check out: building.html. After + this brief bjam tutorial, we should have built the DLLs + and run a python program using the extension.

- The tutorial example can be found in the directory: libs/python/example/tutorial. + The tutorial example can be found in the directory: libs/python/example/tutorial. There, you can find:

    @@ -84,206 +73,136 @@ hello.cpp
  • - Jamfile + hello.py +
  • +
  • + Jamroot

- The hello.cpp file is our C++ hello world example. The - Jamfile is a minimalist bjam script - that builds the DLLs for us. + The hello.cpp file is our C++ hello world example. The + Jamroot is a minimalist bjam script + that builds the DLLs for us. Finally, hello.py is our Python + program that uses the extension in hello.cpp.

Before anything else, you should have the bjam executable in your boost directory - or somewhere in your path such that bjam can be executed + or somewhere in your path such that bjam can be executed in the command line. Pre-built Boost.Jam executables are available for most platforms. The complete list of Bjam executables can be found here.

-

- +

+ Let's Jam! -

+

jam

- Here is our minimalist Jamfile: -

-
# This is the top of our own project tree
-project-root ;
-
-import python ;
-
-extension hello                     # Declare a Python extension called hello
-:   hello.cpp                       # source
-    # requirements and dependencies for Boost.Python extensions
-    <template>@boost/libs/python/build/extension
-    ;
-
-

- First, we need to specify our location. You may place your project anywhere. - project-root allows you to do that. -

-
project-root ;
-
-

- By doing so, you'll need a Jamrules file. Simply copy the one in the example/tutorial directory - and tweak the path-global BOOST_ROOT to where your boost - root directory is. The file has detailed - instructions you can follow. + Here is our minimalist + Jamroot file. Simply copy the file and tweak use-project boost + to where your boost root directory is and your OK.

- Then we will import the definitions needed by Python modules: + The comments contained in the Jamrules file above should be sufficient to get + you going.

-
import python ;
-
-

- Finally we declare our hello extension: -

-
extension hello                     # Declare a Python extension called hello
-:   hello.cpp                       # source
-
-    # requirements and dependencies for Boost.Python extensions
-    <template>@boost/libs/python/build/extension
-    ;
-
-

- The last part tells BJam that we are depending on the Boost Python Library. -

-

- +

+ Running bjam -

+

bjam is run using your operating system's command line interpreter.

-

- Start it up. -

+

- Make sure that the environment is set so that we can invoke the C++ compiler. - With MSVC, that would mean running the Vcvars32.bat batch - file. For instance: +

+

+ Start it up. +

+

+

+
+

+ A file called user-config.jam in your home directory is used to configure your + tools. In Windows, your home directory can be found by typing:

-
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
+
ECHO %HOMEDRIVE%%HOMEPATH%
 

- Some environment variables will have to be setup for proper building of our - Python modules. Example: + into a command prompt window. Your file should at least have the rules for + your compiler and your python installation. A specific example of this on Windows + would be:

-
set PYTHON_ROOT=c:/dev/tools/python
-set PYTHON_VERSION=2.2
+
#  MSVC configuration
+using msvc : 8.0 ;
+
+#  Python configuration
+using python : 2.4 : C:/dev/toolsPython ;
 

- The above assumes that the Python installation is in c:/dev/tools/python - and that we are using Python version 2.2. You'll have to tweak these appropriately. -

-
- - -
tip Be sure not to include a third number, e.g. not "2.2.1", even if that's the version - you have.
-

- Take note that you may also do that through the Jamrules file we put in our - project as detailed above. The file has detailed - instructions you can follow. + The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools. + The second rule provides information on Python, its version and where it is + located. The above assumes that the Python installation is in C:/dev/tools/Python/. + If you have one fairly "standard" python installation for your platform, + you might not need to do this.

- Now we are ready... Be sure to cd to libs/python/example/tutorial - where the tutorial "hello.cpp" and the "Jamfile" + Now we are ready... Be sure to cd to libs/python/example/tutorial + where the tutorial "hello.cpp" and the "Jamroot" is situated.

Finally:

-bjam -sTOOLS=vc-7_1
+bjam
 
-

- We are again assuming that we are using Microsoft Visual C++ version 7.1. If - not, then you will have to specify the appropriate tool. See Building - Boost Libraries for further details. -

It should be building now:

cd C:\dev\boost\libs\python\example\tutorial
-bjam -sTOOLS=msvc
+bjam
 ...patience...
-...found 1703 targets...
-...updating 40 targets...
+...found 1101 targets...
+...updating 35 targets...
 

And so on... Finally:

-
Creating library bin\boost\libs\python\build\boost_python.dll\vc-7_1\debug\th
-reading-multi\boost_python.lib and object bin\boost\libs\python\build\boost_pyth
-on.dll\vc-7_1\debug\threading-multi\boost_python.exp
-vc-C++ bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.obj
-hello.cpp
-vc-Link bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.pyd bin\tutori
-al\hello.pyd\vc-7_1\debug\threading-multi\hello.lib
-   Creating library bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.li
-b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
-...updated 31 targets...
+
Creating library path-to-boost_python.dll
+   Creating library path-to-'''hello_ext'''.exp
+**passed** ... hello.test
+...updated 35 targets...
 

- If all is well, you should now have: + Or something similar. If all is well, you should now have built the DLLs and + run the Python program.

-
    -
  • - boost_python.dll -
  • -
  • - hello.pyd -
  • -
+

- if you are on Windows, and -

-
    -
  • - libboost_python.so -
  • -
  • - hello.so -
  • -
+

- if you are on Unix. -

+ There you go... Have fun! +

- boost_python.dll and hello.pyd can be - found somewhere in your project's bin directory. After a - successful build, you make it possible for the system to find boost_python.dll - or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, - or some other variable on *nix and with PATH on Windows) and for Python to - find the hello module (Done with PYTHONPATH on all systems.) -

-

- You may now fire up Python and run our hello module: -

-

-

-
->>> import hello
->>> print hello.greet()
-hello, world
-
-

-

-

- There you go... Have fun! -

+

+
- +
Copyright © 2002-2005 Joel - de Guzman, David Abrahams

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/tutorial/doc/html/python/iterators.html b/doc/tutorial/doc/html/python/iterators.html index a937c377..ad012f8f 100644 --- a/doc/tutorial/doc/html/python/iterators.html +++ b/doc/tutorial/doc/html/python/iterators.html @@ -2,25 +2,25 @@ Iterators - - + + - + - +
-
Boost C++ Libraries Home Libraries People FAQ More
+
-PrevUpHomeNext +PrevUpHomeNext

@@ -30,7 +30,7 @@ iterators, but these are two very different beasts.

- C++ iterators: + C++ iterators:

  • @@ -45,7 +45,7 @@

- Python Iterators: + Python Iterators:

  • @@ -59,8 +59,8 @@

- The typical Python iteration protocol: for y - in x... is as follows: + The typical Python iteration protocol: for y + in x... is as follows:

@@ -74,7 +74,7 @@

Boost.Python provides some mechanisms to make C++ iterators play along nicely - as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that + as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that is compatible with the Python iteration protocol. For example:

@@ -91,7 +91,7 @@ .def("__iter__", iterator<vector<int> >())

- range + range

We can create a Python savvy iterator using the range function: @@ -119,14 +119,14 @@

- iterator + iterator

  • iterator<T, Policies>()

- Given a container T, iterator is a shortcut that simply - calls range with &T::begin, &T::end. + Given a container T, iterator is a shortcut that simply + calls range with &T::begin, &T::end.

Let's put this into action... Here's an example from some hypothetical bogon @@ -152,14 +152,14 @@ .property("bogons", range(&F::b_begin, &F::b_end));

- stl_input_iterator + stl_input_iterator

So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes we wish to go the other way, though: we'd like to pass a Python sequence to an STL algorithm or use it to initialize an STL container. We need to make - a Python iterator look like an STL iterator. For that, we use stl_input_iterator<>. - Consider how we might implement a function that exposes std::list<int>::assign() to Python: + a Python iterator look like an STL iterator. For that, we use stl_input_iterator<>. + Consider how we might implement a function that exposes std::list<int>::assign() to Python:

@@ -178,7 +178,7 @@ ;

- Now in Python, we can assign any integer sequence to list_int + Now in Python, we can assign any integer sequence to list_int objects:

@@ -190,12 +190,17 @@ - +
Copyright © 2002-2005 Joel - de Guzman, David Abrahams


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/tutorial/doc/html/python/object.html b/doc/tutorial/doc/html/python/object.html index 25d710f6..6f8920ab 100644 --- a/doc/tutorial/doc/html/python/object.html +++ b/doc/tutorial/doc/html/python/object.html @@ -1,26 +1,26 @@ -Object Interface - - + Object Interface + + - +
-
Boost C++ Libraries Home Libraries People FAQ More
+
-PrevUpHomeNext +PrevUpHomeNext

@@ -35,13 +35,13 @@ Python is dynamically typed, unlike C++ which is statically typed. Python variables may hold an integer, a float, list, dict, tuple, str, long etc., among other things. In the viewpoint of Boost.Python and C++, these Pythonic variables - are just instances of class object. We shall see in this + are just instances of class object. We will see in this chapter how to deal with Python objects.

As mentioned, one of the goals of Boost.Python is to provide a bidirectional mapping between C++ and Python while maintaining the Python feel. Boost.Python - C++ objects are as close as possible to Python. This should + C++ objects are as close as possible to Python. This should minimize the learning curve significantly.

@@ -51,10 +51,10 @@

Basic Interface

- Class object wraps PyObject*. All the - intricacies of dealing with PyObjects such as managing - reference counting are handled by the object class. C++ - object interoperability is seamless. Boost.Python C++ objects + Class object wraps PyObject*. All the + intricacies of dealing with PyObjects such as managing + reference counting are handled by the object class. C++ + object interoperability is seamless. Boost.Python C++ objects can in fact be explicitly constructed from any C++ object.

@@ -99,7 +99,7 @@

Derived Object types

- Boost.Python comes with a set of derived object types + Boost.Python comes with a set of derived object types corresponding to that of Python's:

    @@ -123,32 +123,32 @@

- These derived object types act like real Python types. + These derived object types act like real Python types. For instance:

 str(1) ==> "1"
 

- Wherever appropriate, a particular derived object has - corresponding Python type's methods. For instance, dict - has a keys() method: + Wherever appropriate, a particular derived object has + corresponding Python type's methods. For instance, dict + has a keys() method:

 d.keys()
 

- make_tuple is provided for declaring tuple literals. + make_tuple is provided for declaring tuple literals. Example:

 make_tuple(123, 'D', "Hello, World", 0.0);
 

- In C++, when Boost.Python objects are used as arguments + In C++, when Boost.Python objects are used as arguments to functions, subtype matching is required. For example, when a function - f, as declared below, is wrapped, it will only accept - instances of Python's str type and subtypes. + f, as declared below, is wrapped, it will only accept + instances of Python's str type and subtypes.

 void f(str name)
@@ -172,16 +172,15 @@
 object msg = "%s is bigger than %s" % make_tuple(NAME,name);
 

- Demonstrates that you can write the C++ equivalent of "format" - % x,y,z in Python, which is useful since there's no easy way to + Demonstrates that you can write the C++ equivalent of "format" + % x,y,z in Python, which is useful since there's no easy way to do that in std C++.

-
- - -
alert Beware the - common pitfall of forgetting that the constructors of most of Python's - mutable types make copies, just as in Python.
+

Python:

@@ -196,12 +195,12 @@ dict d(x.attr("__dict__")); // copies x.__dict__ d['whatever'] = 3; // modifies the copy -

- +

+ class_<T> as objects -

+

- Due to the dynamic nature of Boost.Python objects, any class_<T> + Due to the dynamic nature of Boost.Python objects, any class_<T> may also be one of these types! The following code snippet wraps the class (type) object.

@@ -223,15 +222,15 @@ Extracting C++ objects

At some point, we will need to get C++ values out of object instances. This - can be achieved with the extract<T> function. Consider + can be achieved with the extract<T> function. Consider the following:

 double x = o.attr("length"); // compile error
 

- In the code above, we got a compiler error because Boost.Python object - can't be implicitly converted to doubles. Instead, what + In the code above, we got a compiler error because Boost.Python object + can't be implicitly converted to doubles. Instead, what we wanted to do above can be achieved by writing:

@@ -241,14 +240,14 @@
 

The first line attempts to extract the "length" attribute of the - Boost.Python object. The second line attempts to extract - the Vec2 object from held by the Boost.Python object. + Boost.Python object. The second line attempts to extract + the Vec2 object from held by the Boost.Python object.

Take note that we said "attempt to" above. What if the Boost.Python - object does not really hold a Vec2 + object does not really hold a Vec2 type? This is certainly a possibility considering the dynamic nature of Python - objects. To be on the safe side, if the C++ type can't + objects. To be on the safe side, if the C++ type can't be extracted, an appropriate exception is thrown. To avoid an exception, we need to test for extractibility:

@@ -258,7 +257,7 @@ Vec2& v = x(); ...

- tip The astute reader might have noticed that the extract<T> + tip The astute reader might have noticed that the extract<T> facility in fact solves the mutable copying problem:

@@ -271,8 +270,8 @@
 Enums

Boost.Python has a nifty facility to capture and wrap C++ enums. While Python - has no enum type, we'll often want to expose our C++ enums - to Python as an int. Boost.Python's enum facility makes + has no enum type, we'll often want to expose our C++ enums + to Python as an int. Boost.Python's enum facility makes this easy while taking care of the proper conversions from Python's dynamic typing to C++'s strong static typing (in C++, ints cannot be implicitly converted to enums). To illustrate, given a C++ enum: @@ -291,17 +290,25 @@

can be used to expose to Python. The new enum type is created in the current - scope(), which is usually the current module. The snippet - above creates a Python class derived from Python's int + scope(), which is usually the current module. The snippet + above creates a Python class derived from Python's int type which is associated with the C++ type passed as its first parameter.

-
- - +
note what is a scope?
-
The scope is a class that has an associated global Python object - which controls the Python namespace in which new extension classes - and wrapped functions will be defined as attributes. Details can be - found here.
+ + + + +
[Note]Note
+

+ what is a scope? +

+

+ The scope is a class that has an associated global Python object which + controls the Python namespace in which new extension classes and wrapped + functions will be defined as attributes. Details can be found here. +

+

You can access those values in Python as @@ -334,12 +341,17 @@ - +
Copyright © 2002-2005 Joel - de Guzman, David Abrahams


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/tutorial/doc/html/python/techniques.html b/doc/tutorial/doc/html/python/techniques.html index fb5e9573..8598e927 100644 --- a/doc/tutorial/doc/html/python/techniques.html +++ b/doc/tutorial/doc/html/python/techniques.html @@ -1,25 +1,25 @@ -General Techniques - - + General Techniques + + - + - +
-
Boost C++ Libraries Home Libraries People FAQ More
+
-PrevUpHome +PrevUpHome

@@ -50,7 +50,7 @@

We have a C++ library that works with sounds: reading and writing various formats, applying filters to the sound data, etc. It is named (conveniently) - sounds. Our library already has a neat C++ namespace hierarchy, + sounds. Our library already has a neat C++ namespace hierarchy, like so:

@@ -93,15 +93,20 @@
 }
 

- Compiling these files will generate the following Python extensions: core.pyd, - io.pyd and filters.pyd. + Compiling these files will generate the following Python extensions: core.pyd, + io.pyd and filters.pyd.

-
- - +
note The extension .pyd is used - for python extension modules, which are just shared libraries. Using - the default for your system, like .so for Unix and - .dll for Windows, works just as well.
+ + + + +
[Note]Note

+ The extension .pyd is used for python extension modules, + which are just shared libraries. Using the default for your system, like + .so for Unix and .dll for Windows, + works just as well. +

Now, we create this directory structure for our Python package: @@ -113,12 +118,12 @@ io.pyd

- The file __init__.py is what tells Python that the directory - sounds/ is actually a Python package. It can be a empty + The file __init__.py is what tells Python that the directory + sounds/ is actually a Python package. It can be a empty file, but can also perform some magic, that will be shown later.

- Now our package is ready. All the user has to do is put sounds + Now our package is ready. All the user has to do is put sounds into his PYTHONPATH and fire up the interpreter:

@@ -157,7 +162,7 @@

Note that we added an underscore to the module name. The filename will have - to be changed to _core.pyd as well, and we do the same + to be changed to _core.pyd as well, and we do the same to the other extension modules. Now, we change our package hierarchy like so:

@@ -165,12 +170,12 @@ __init__.py core/ __init__.py - _core.pyd + core.pyd filters/ - __init__.py - _filters.pyd + \_init__.py + filters.pyd io/ - __init__.py + \_init__.py _io.pyd

@@ -185,11 +190,11 @@ >>> sounds.core._core.foo(...)

- which is not what we want. But here enters the __init__.py - magic: everything that is brought to the __init__.py namespace + which is not what we want. But here enters the __init__.py + magic: everything that is brought to the __init__.py namespace can be accessed directly by the user. So, all we have to do is bring the - entire namespace from _core.pyd to core/__init__.py. - So add this line of code to soundscore__init__.py: + entire namespace from _core.pyd to core/__init__.py. + So add this line of code to soundscore__init__.py:

 from _core import *
@@ -206,10 +211,10 @@
         with the additional benefit that we can easily add pure Python functions
         to any module, in a way that the user can't tell the difference between a
         C++ function and a Python function. Let's add a pure
-        Python function, echo_noise, to the filters
-        package. This function applies both the echo and noise
-        filters in sequence in the given sound object. We create
-        a file named sounds/filters/echo_noise.py and code our
+        Python function, echo_noise, to the filters
+        package. This function applies both the echo and noise
+        filters in sequence in the given sound object. We create
+        a file named sounds/filters/echo_noise.py and code our
         function:
       

@@ -220,14 +225,14 @@
     return s
 

- Next, we add this line to soundsfilters__init__.py: + Next, we add this line to soundsfilters__init__.py:

 from echo_noise import echo_noise
 

And that's it. The user now accesses this function like any other function - from the filters package: + from the filters package:

 >>> import sounds.filters
@@ -261,7 +266,7 @@
       

We can do the same with classes that were wrapped with Boost.Python. Suppose - we have a class point in C++: + we have a class point in C++:

@@ -275,7 +280,7 @@

If we are using the technique from the previous session, Creating - Packages, we can code directly into geom/__init__.py: + Packages, we can code directly into geom/__init__.py:

@@ -290,7 +295,7 @@ point.__str__ = point_str

- All point instances created from C++ will + All point instances created from C++ will also have this member function! This technique has several advantages:

    @@ -389,7 +394,7 @@ }

    - Now you create a file main.cpp, which contains the BOOST_PYTHON_MODULE + Now you create a file main.cpp, which contains the BOOST_PYTHON_MODULE macro, and call the various export functions inside it.

    @@ -425,29 +430,43 @@
             exporting it to Python at the same time: changes in a class will only demand
             the compilation of a single cpp, instead of the entire wrapper code.
           

    -
    - - +
    note If you're exporting your classes with Pyste, - take a look at the --multiple option, that generates - the wrappers in various files as demonstrated here.
    + + + + +
    [Note]Note

    + If you're exporting your classes with Pyste, + take a look at the --multiple option, that generates + the wrappers in various files as demonstrated here. +

    -
    - - +
    note This method is useful too if you are getting the - error message "fatal error C1204:Compiler limit:internal - structure overflow" when compiling a large source file, - as explained in the FAQ.
    + + + + +
    [Note]Note

    + This method is useful too if you are getting the error message "fatal + error C1204:Compiler limit:internal structure overflow" + when compiling a large source file, as explained in the FAQ. +

- +
Copyright © 2002-2005 Joel - de Guzman, David Abrahams

-PrevUpHome +PrevUpHome
diff --git a/doc/tutorial/doc/tutorial.qbk b/doc/tutorial/doc/tutorial.qbk index 13a2222a..bd02cd04 100644 --- a/doc/tutorial/doc/tutorial.qbk +++ b/doc/tutorial/doc/tutorial.qbk @@ -49,10 +49,10 @@ Function: can be exposed to Python by writing a Boost.Python wrapper: #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) + BOOST_PYTHON_MODULE(hello_ext) { + using namespace boost::python; def("greet", greet); } @@ -61,7 +61,7 @@ resulting DLL is now visible to Python. Here's a sample Python session: [python] - >>> import hello + >>> import hello_ext >>> print hello.greet() hello, world @@ -75,43 +75,39 @@ resulting DLL is now visible to Python. Here's a sample Python session: [h2 From Start To Finish] Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled +try it for yourself in Python. In this section, we will outline the steps +necessary to achieve that. We will use the build tool that comes bundled with every boost distribution: [*bjam]. -[blurb __note__ [*Building without bjam]\n\n - Besides bjam, there are of course other ways to get your module built. - What's written here should not be taken as "the one and only way". - There are of course other build tools apart from [^bjam].\n\n - Take note however that the preferred build tool for Boost.Python is bjam. - There are so many ways to set up the build incorrectly. Experience shows - that 90% of the "I can't build Boost.Python" problems come from people - who had to use a different tool. +[note [*Building without bjam] + +Besides bjam, there are of course other ways to get your module built. +What's written here should not be taken as "the one and only way". +There are of course other build tools apart from [^bjam]. + +Take note however that the preferred build tool for Boost.Python is bjam. +There are so many ways to set up the build incorrectly. Experience shows +that 90% of the "I can't build Boost.Python" problems come from people +who had to use a different tool. ] -We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: [@../../../building.html building.html]. -After this brief ['bjam] tutorial, we should have built two DLLs: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. +We will skip over the details. Our objective will be to simply create +the hello world module and run it in Python. For a complete reference to +building Boost.Python, check out: [@../../../building.html +building.html]. After this brief ['bjam] tutorial, we should have built +the DLLs and run a python program using the extension. The tutorial example can be found in the directory: [^libs/python/example/tutorial]. There, you can find: * hello.cpp -* Jamfile +* hello.py +* Jamroot -The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a -minimalist ['bjam] script that builds the DLLs for us. +The [^hello.cpp] file is our C++ hello world example. The [^Jamroot] is +a minimalist ['bjam] script that builds the DLLs for us. Finally, +[^hello.py] is our Python program that uses the extension in +[^hello.cpp]. Before anything else, you should have the bjam executable in your boost directory or somewhere in your path such that [^bjam] can be executed in @@ -122,51 +118,12 @@ platforms. The complete list of Bjam executables can be found [h2 Let's Jam!] __jam__ -Here is our minimalist Jamfile: +[@../../../../example/tutorial/Jamroot Here] is our minimalist Jamroot +file. Simply copy the file and tweak [^use-project boost] to where your +boost root directory is and your OK. -[pre -# This is the top of our own project tree -project-root ; - -import python ; - -extension hello # Declare a Python extension called hello -: hello.cpp # source - # requirements and dependencies for Boost.Python extensions -