From a05a0ae46bb779b81b9a0e39c7d46a3ac62cd0bf Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 2 May 2005 15:51:26 +0000 Subject: [PATCH] Python now correctly syntax colorized + some minor tweaks [SVN r28581] --- doc/tutorial/doc/Jamfile.v2 | 11 +- doc/tutorial/doc/html/boostbook.css | 593 +++++++++++-------- doc/tutorial/doc/html/index.html | 16 +- doc/tutorial/doc/html/python/embedding.html | 63 +- doc/tutorial/doc/html/python/exception.html | 4 +- doc/tutorial/doc/html/python/exposing.html | 77 +-- doc/tutorial/doc/html/python/functions.html | 49 +- doc/tutorial/doc/html/python/hello.html | 40 +- doc/tutorial/doc/html/python/iterators.html | 23 +- doc/tutorial/doc/html/python/object.html | 48 +- doc/tutorial/doc/html/python/techniques.html | 93 +-- doc/tutorial/doc/tutorial.qbk | 105 +++- 12 files changed, 672 insertions(+), 450 deletions(-) diff --git a/doc/tutorial/doc/Jamfile.v2 b/doc/tutorial/doc/Jamfile.v2 index a13adfca..0757fb31 100644 --- a/doc/tutorial/doc/Jamfile.v2 +++ b/doc/tutorial/doc/Jamfile.v2 @@ -1,8 +1,11 @@ project boost/libs/python/doc/tutorial/doc ; + import boostbook : boostbook ; +using quickbook ; -boostbook tutorial : tutorial.xml - : boost.root=../../../../../.. - boost.libraries=../../../../../libraries.htm +boostbook tutorial + : + tutorial.qbk + : + boost.root=../../../../../.. ; - diff --git a/doc/tutorial/doc/html/boostbook.css b/doc/tutorial/doc/html/boostbook.css index e3db08f3..87c8175a 100644 --- a/doc/tutorial/doc/html/boostbook.css +++ b/doc/tutorial/doc/html/boostbook.css @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2002 2004 Joel de Guzman + Copyright (c) 2004 Joel de Guzman http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software @@ -7,289 +7,414 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -/* CSS based on w3c documentation which I like a lot, and the classic Spirit -documentation. */ +/*============================================================================= + Body defaults +=============================================================================*/ -/* Body defaults */ -body -{ - padding: 2em 1em 2em 1em; - margin: 1em 1em 1em 1em; - font-family: sans-serif; -} - -/* Paragraphs */ -p -{ - text-align: justify; -} - -pre.synopsis -{ - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; -} - -/* Headings */ -h1, h2, h3, h4, h5, h6 { text-align: left; margin-top: 2pc; } -h1 { font: 170% sans-serif } -h2 { font: bold 140% sans-serif } -h3 { font: 120% sans-serif } -h4 { font: bold 100% sans-serif } -h5 { font: italic 100% sans-serif } -h6 { font: italic 100% sans-serif } - -/* Unordered lists */ -ul -{ - text-align: justify; -} - -/* Links */ -a -{ - text-decoration: none; /* no underline */ -} - -a:hover -{ - text-decoration: underline; -} - -/* Top page title */ -title, h1.title, h2.title, h3.title, - h4.title, h5.title, h6.title, - .refentrytitle -{ - font-weight: bold; - font-size: 2pc; - margin-bottom: 1pc; -} - -/* Spirit style navigation */ -.spirit-nav -{ - text-align: right; -} - -.spirit-nav a -{ - color: white; - padding-left: 0.5em; -} - -.spirit-nav img -{ - border-width: 0px; -} - -/* Program listing box */ -.programlisting, .screen -{ - display: block; - margin-left: 4%; - margin-right: 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; -} - -/* Table of contents */ -.toc -{ - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; -} - -.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; - font-size: 120%; -} - -.informaltable table, .table table -{ - width: 92%; - margin-left: 4%; - margin-right: 4%; -} - -div.informaltable table, div.table table -{ - padding: 4px 4px 4px 4px; -} - -div.informaltable table tr td, div.table table tr td -{ - padding: 0.5em 0.5em 0.5em 0.5em; - text-align: justify; -} - -div.informaltable table tr th, div.table table tr th -{ - padding: 0.5em 0.5em 0.5em 0.5em; - border: 1pt solid white; -} - -/* inlined images */ -.inlinemediaobject -{ - padding: 0.5em 0.5em 0.5em 0.5em; -} - -/* tone down the title of Parameter lists */ -div.variablelist p.title -{ - font-weight: bold; - font-size: 100%; - text-align: left; -} - -/* tabularize parameter lists */ -div.variablelist dl dt -{ - float: left; - clear: left; - display: block; - font-style: italic; -} - -div.variablelist dl dd -{ - display: block; - clear: right; - padding-left: 8pc; -} - -/* title of books and articles in bibliographies */ -span.title -{ - font-style: italic; -} - - -@media screen -{ - a + body { - color: #005a9c; + margin: 1em; + font-family: sans-serif; } - a:visited +/*============================================================================= + Paragraphs +=============================================================================*/ + + p { - color: #9c5a9c; + text-align: justify; + font-size: 11pt; + line-height: 1.2; } - /* Syntax Highlighting */ - .keyword { color: #0000AA; font-weight: bold; } - .identifier {} - .special { color: #707070; } - .preprocessor { color: #402080; font-weight: bold; } - .char { color: teal; } - .comment { color: #800000; } - .string { color: teal; } - .number { color: teal; } - .copyright { color: #666666; font-size: small; } - .white_bkd { background-color: #FFFFFF; } - .dk_grey_bkd { background-color: #999999; } +/*============================================================================= + Program listings +=============================================================================*/ + + tt.computeroutput + { + font-size: 10pt; + } pre.synopsis { - background-color: #f3f3f3; + font-size: 10pt; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; } - .programlisting, .screen + .programlisting, + .screen { - background-color: #f3f3f3; + font-size: 10pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; } - /* Table of contents */ - .toc +/*============================================================================= + Headings +=============================================================================*/ + + h1, + h2, + h3, + h4, + h5, + h6 + { + text-align: left; + margin-top: 2pc; + } + + h1 { font: 170% } + h2 { font: bold 140% } + h3 { font: bold 120% } + h4 { font: bold 100% } + h5 { font: italic 100% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle { - background-color: #f3f3f3; + font-weight: bold; + margin-bottom: 1pc; } - div.informaltable table tr td, div.table table tr td + h1.title { font-size: 220% } + h2.title { font-size: 220% } + h3.title { font-size: 170% } + h4.title { font-size: 140% } + h5.title { font-size: 120% } + h6.title { font-size: 120% } + +/*============================================================================= + Lists +=============================================================================*/ + + li { - background-color: #F3F3F3; - border: 1pt solid white; + font-size: 11pt; + line-height: 1.3; } - - div.informaltable table tr th, div.table table tr th + + /* Unordered lists */ + ul { - background-color: #e4e4e4; + text-align: justify; } - - span.highlight + + /* Ordered lists */ + ol { - color: #00A000; + text-align: justify; } -} -@media print -{ +/*============================================================================= + Links +=============================================================================*/ + a { - color: black; + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; } - a:visited - { - color: black; - } +/*============================================================================= + Spirit style navigation +=============================================================================*/ .spirit-nav { - display: none; + text-align: right; } - - /* Syntax Highlighting */ - .keyword + + .spirit-nav a { - font-weight: bold; + color: white; + padding-left: 0.5em; } - - pre.synopsis + + .spirit-nav img { - border: 1px solid gray; + border-width: 0px; } - .programlisting, .screen - { - border: 1px solid gray; - } +/*============================================================================= + Table of contents +=============================================================================*/ - /* Table of contents */ .toc { - border: 1px solid gray; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc; + font-size: 11pt; + line-height: 1.3; } - - .informaltable table, .table table + + .boost-toc { - border: 1px solid gray; - border-collapse: collapse; + float: right; + padding: 0.5pc; } - div.informaltable table tr td, div.table table tr td +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title { - border: 1px solid gray; + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + font-size: 120%; } - - div.informaltable table tr th, div.table table tr th + + .informaltable table, + .table table { - border: 1px solid gray; + 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: justify; + font-size: 11pt; } - span.highlight + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.informaltable table tr td.blurb + { + font-size: 10pt; /* A little bit smaller than the main text */ + line-height: 1.2; + } + + td.blurb img + { + padding: 1pt; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Tone down the title of Parameter lists */ + div.variablelist p.title { font-weight: bold; + font-size: 100%; + text-align: left; + } + + /* Tabularize parameter lists */ + div.variablelist dl dt + { + float: left; + clear: left; + display: block; + font-style: italic; + } + + div.variablelist dl dd + { + display: block; + clear: right; + padding-left: 8pc; + } + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + /* 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 + { + background-color: #F3F3F3; + border: 1pt solid #C0C0C0; + } + + .programlisting, + .screen + { + background-color: #F3F3F3; + border: 1pt solid #C0C0C0; + } + + /* Blurbs */ + div.informaltable table tr td.blurb + { + background-color: #FFFFF0; + border: 1pt solid #707070; + } + + /* Table of contents */ + .toc + { + background-color: #F3F3F3; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + background-color: #F0F0F0; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #E4E4E4; + } + + /* 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; + } + + /* 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 8a1e5410..5f112309 100644 --- a/doc/tutorial/doc/html/index.html +++ b/doc/tutorial/doc/html/index.html @@ -11,7 +11,7 @@ - + @@ -28,9 +28,9 @@

David Abrahams

-
+
-

+

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -96,7 +96,7 @@ metaprogramming techniques simplifies its syntax for users, so that wrapping code takes on the look of a kind of declarative interface definition language (IDL).

-Hello World

+Hello World

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

@@ -116,14 +116,16 @@ BOOST_PYTHON_MODULE( That's it. We're done. We can now build this as a shared library. The resulting DLL is now visible to Python. Here's a sample Python session:

-
>>> import hello
->>> print hello.greet()
+

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

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

boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
- +

Last revised: October 12, 2004 at 03:11:11 GMT

Last revised: May 02, 2005 at 15:44:52 GMT


diff --git a/doc/tutorial/doc/html/python/embedding.html b/doc/tutorial/doc/html/python/embedding.html index a5d816df..1c34f056 100644 --- a/doc/tutorial/doc/html/python/embedding.html +++ b/doc/tutorial/doc/html/python/embedding.html @@ -13,7 +13,7 @@ - + @@ -39,7 +39,7 @@ the gaps. However, Boost.Python already makes embedding a lot easier and, in a future version, it may become unnecessary to touch the Python/C API at all. So stay tuned...

-Building embedded programs

+Building embedded programs

To be able to use embedding in your programs, they have to be linked to both Boost.Python's and Python's static link library.

@@ -59,7 +59,7 @@ Additionally, Python's /include subdirectory has to be include path.

In a Jamfile, all the above boils down to:

-
    projectroot c:\projects\embedded_program ; # location of the program
+
projectroot c:\projects\embedded_program ; # location of the program
 
     # bring in the rules for python
     SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
@@ -75,23 +75,20 @@ In a Jamfile, all the above boils down to:

<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;

-Getting started

+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.

    -

    +Call Py_Initialize() to start the interpreter and create the _main_ module.

  3. -Call other Python C API routines to use the interpreter.

    -

    +Call other Python C API routines to use the interpreter.

  4. Call Py_Finalize() to stop the interpreter and release its resources. @@ -113,7 +110,7 @@ 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.

    -Reference-counting handles and objects

    +Reference-counting handles and objects

    There are two ways in which a function in the Python/C API can return a PyObject*: as a borrowed reference or as a new reference. Which of @@ -139,14 +136,12 @@ such function that returns a new reference is

boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
-
-Handle is a class template, so why haven't we been using any template parameters?

-

-handle has a single template parameter specifying the type of the managed object. This type is PyObject 99% of the time, so the parameter was defaulted to PyObject for convenience. Therefore we can use the shorthand handle<> instead of the longer, but equivalent, handle<PyObject>. +
+Handle is a class template, so why haven't we been using any template parameters?

handle has a single template parameter specifying the type of the managed object. This type is PyObject 99% of the time, so the parameter was defaulted to PyObject for convenience. Therefore we can use the shorthand handle<> instead of the longer, but equivalent, handle<PyObject>.

-Running Python code

+Running Python code

To run Python code from C++ there is a family of functions in the API starting with the PyRun prefix. You can find the full list of these @@ -161,7 +156,7 @@ The start parameter is the start symbol from the Python for interpreting the code. The possible values are:

-Start symbols +Start symbols

@@ -219,12 +214,17 @@ the object's ptr member function to retrieve the This should create a file called 'hello.txt' in the current directory containing a phrase that is well-known in programming circles.

-

Note that we wrap the return value of PyRun_String in a -(nameless) handle even though we are not interested in it. If we didn't -do this, the the returned object would be kept alive unnecessarily. Unless -you want to be a Dr. Frankenstein, always wrap PyObject*s in handles.

+
+ + +
+Note that we wrap the return value of PyRun_String in a + (nameless) handle even though we are not interested in it. If we didn't + do this, the the returned object would be kept alive unnecessarily. Unless + you want to be a Dr. Frankenstein, always wrap PyObject*s in handles. +

-Beyond handles

+Beyond handles

It's nice that handle manages the reference counting details for us, but other than that it doesn't do much. Often we'd like to have a more useful @@ -261,12 +261,17 @@ the dictionary. Another way to achieve the same result is to let )); int five_squared = extract<int>(result); -

Note that object's member function to return the wrapped -PyObject* is called ptr instead of get. This makes sense if you -take into account the different functions that object and handle -perform.

+
+ + +
+Note that object's member function to return the wrapped + PyObject* is called ptr instead of get. This makes sense if you + take into account the different functions that object and handle + perform. +

-Exception handling

+Exception handling

If an exception occurs in the execution of some Python code, the PyRun_String function returns a null pointer. Constructing a handle out of this null @@ -296,7 +301,7 @@ To find out more about the Python exception that occurred, you need to use the 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 exceptions:

+exception with those of the standard exceptions:

catch(error_already_set)
 {
     if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
@@ -331,7 +336,7 @@ if (!result<
 
 
-
+
Copyright © 2002-2004 Joel de Guzman, David AbrahamsCopyright © 2002-2005 Joel de Guzman, David Abrahams

diff --git a/doc/tutorial/doc/html/python/exception.html b/doc/tutorial/doc/html/python/exception.html index b401fe53..9052ffec 100644 --- a/doc/tutorial/doc/html/python/exception.html +++ b/doc/tutorial/doc/html/python/exception.html @@ -13,7 +13,7 @@ - + @@ -44,7 +44,7 @@ BOOST_PYTHON_MODULE(
boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
- +
Copyright © 2002-2004 Joel de Guzman, David AbrahamsCopyright © 2002-2005 Joel de Guzman, David Abrahams

diff --git a/doc/tutorial/doc/html/python/exposing.html b/doc/tutorial/doc/html/python/exposing.html index 4003878e..caac0e38 100644 --- a/doc/tutorial/doc/html/python/exposing.html +++ b/doc/tutorial/doc/html/python/exposing.html @@ -13,7 +13,7 @@ - + @@ -61,10 +61,11 @@ BOOST_PYTHON_MODULE(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:

-
>>> import hello
+

+
>>> import hello
 >>> planet = hello.World()
->>> planet.set('howdy')
->>> planet.greet()
+>>> planet.set('howdy')
+>>> planet.greet()
 'howdy'

@@ -78,6 +79,7 @@ which is why we were able to write

We may wish to wrap a class with a non-default constructor. Let us build on our previous example:

+

struct World
 {
     World(std::string msg): msg(msg) {} // added constructor
@@ -142,18 +144,18 @@ Our C++ Var class and its data members can be exposed t
 

Then, in Python, assuming we have placed our Var class inside the namespace hello as we did before:

-
>>> x = hello.Var('pi')
+

+
>>> x = hello.Var('pi')
 >>> x.value = 3.14
->>> print x.name, 'is around', x.value
-pi is around 3.14
+>>>
print x.name, 'is around', x.value +pi is around 3.14

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

-
    >>> x.name = 'e' # can't change name
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in ?
-    AttributeError: can't set attribute
-
+
>>> x.name = 'e' # can't change name
+Traceback (most recent call last):
+  File "<stdin>", line 1, in#
+AttributeError: can#t set attribute

@@ -164,6 +166,7 @@ upon. Well designed classes that take advantage of encapsulation hide the class' data members. The only way to access the class' data is through access (getter/setter) functions. Access functions expose class properties. Here's an example:

+

struct Num
 {
     Num();
@@ -181,14 +184,17 @@ attributes can just be a different syntax for a method call. Wrapping our
     .add_property("value", &Num::get, &Num::set);

And at last, in Python:

+

>>> x = Num()
 >>> x.value = 3.14
 >>> x.value, x.rovalue
 (3.14, 3.14)
->>> x.rovalue = 2.17 # error!
+>>> x.rovalue = 2.17 # error! +

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

+

.add_property("rovalue", &Num::get)
@@ -285,13 +291,10 @@ inherited wrapper
boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
- +If you are using Microsoft Visual C++ 6 or 7, you have to write f as:

return call<int>(this->get_override("f").ptr());.
- MSVC6/7 Workaround

-

+
+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 @@ -305,9 +308,8 @@ Finally, exposing Base

-
-member function and methods

-

+
+member function and methods

Python, like many object oriented languages uses the term methods. Methods correspond roughly to C++'s member functions @@ -356,14 +358,11 @@ Notice how we implemented Ba override for f. If none, then we call Base::f().

- +with the *note* as:

return call<char const*>(f.ptr());.
- MSVC6/7 Workaround

-

+
+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:

@@ -377,9 +376,10 @@ forwarding function to its default implementation default_f< special def function for this purpose.

In Python, the results would be as expected:

+

>>> base = Base()
 >>> class Derived(Base):
-...     def f(self):
+...     def f(self):
 ...         return 42
 ...
 >>> derived = Derived()
@@ -396,7 +396,7 @@ Calling derived.f():

Class Operators/Special Functions

-Python Operators

+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 @@ -404,6 +404,7 @@ this and makes it easy to wrap C++ operator-powered classes.

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

+

class FilePos { /*...*/ };
 
 FilePos     operator+(FilePos, int);
@@ -433,20 +434,20 @@ 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

+Special Methods

Python has a few more Special Methods. Boost.Python supports all of the standard special method names supported by real Python class instances. A similar set of intuitive interfaces can also be used to wrap C++ functions that correspond to these Python special functions. Example:

class Rational
-{ operator double() const; };
+{ public: operator double() const; };
 
 Rational pow(Rational, Rational);
 Rational abs(Rational);
 ostream& operator<<(ostream&,Rational);
 
-class_<Rational>()
+class_<Rational>("Rational")
     .def(float_(self))                  // __float__
     .def(pow(self, other<Rational>))    // __pow__
     .def(abs(self))                     // __abs__
@@ -456,16 +457,16 @@ class_<Rational<
 Need we say more?

- +
- What is the business of operator<<.def(str(self))? -Well, the method str requires the operator<< to do its work (i.e. -operator<< is used by the method defined by def(str(self)).
+ 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-2004 Joel de Guzman, David AbrahamsCopyright © 2002-2005 Joel de Guzman, David Abrahams

diff --git a/doc/tutorial/doc/html/python/functions.html b/doc/tutorial/doc/html/python/functions.html index b8fa2735..8c21cb5d 100644 --- a/doc/tutorial/doc/html/python/functions.html +++ b/doc/tutorial/doc/html/python/functions.html @@ -13,7 +13,7 @@ - + @@ -42,7 +42,7 @@ overloading and default arguments.

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
     Beautiful is better than ugly.
     Explicit is better than implicit.
@@ -121,15 +121,17 @@ A reference to y.x is returned
 
 

We could copy result into a new object:

-
>>> f(y, z).set(42) # Result disappears
->>> y.x.get()       # No crash, but still bad
-3.14
+

+
>>> f(y, z).set(42) # Result disappears
+>>> y.x.get()       # No crash, but still bad
+3.14

This is not really our intent of our C++ interface. We've broken our promise that the Python interface should reflect the C++ interface as closely as possible.

Our problems do not end there. Suppose Y is implemented as follows:

+

struct Y
 {
     X x; Z* z;
@@ -172,7 +174,7 @@ A reference to y.x is returned
 
  • BOOM!
  • -Call Policies

    +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 @@ -204,45 +206,44 @@ Here is the list of predefined call policies. A complete reference detailing these can be found here.

    • -with_custodian_and_ward

      +with_custodian_and_ward
      Ties lifetimes of the arguments
    • -with_custodian_and_ward_postcall

      +with_custodian_and_ward_postcall
      Ties lifetimes of the arguments and results
    • -return_internal_reference

      +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

      +reference_existing_object
      naive (dangerous) approach
    • -copy_const_reference

      +copy_const_reference
      Boost.Python v1 approach
    • -copy_non_const_reference

      +copy_non_const_reference
    • -manage_new_object

      +manage_new_object
      Adopt a pointer and hold the instance
    boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
    -
    -Remember the Zen, Luke:

    -

    +
    +Remember the Zen, Luke:

    -"Explicit is better than implicit"

    +"Explicit is better than implicit"
    -"In the face of ambiguity, refuse the temptation to guess"

    +"In the face of ambiguity, refuse the temptation to guess"
    @@ -335,7 +336,7 @@ are overloaded with a common sequence of initial arguments

    -BOOST_PYTHON_FUNCTION_OVERLOADS

    +BOOST_PYTHON_FUNCTION_OVERLOADS

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

    int foo(int a, char b = 1, unsigned c = 2, double d = 3)
    @@ -354,7 +355,7 @@ and the maximum number of arguments is 4. The def(...)
     automatically add all the foo variants for us:

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

    -BOOST_PYTHON_MEMBER_FUNCTION_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 @@ -386,7 +387,7 @@ fourth macro argument). The thin wrappers are all enclosed in a class named See the overloads reference for details.

    -init and optional

    +init and optional

    A similar facility is provided for class constructors, again, with default arguments or a sequence of overloads. Remember init<...>? For example, @@ -441,7 +442,7 @@ Then...

    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

    +Manual Wrapping

    It is important to emphasize however that the overloaded functions must have a common sequence of initial arguments. Otherwise, our scheme above @@ -469,7 +470,7 @@ Then...

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

    diff --git a/doc/tutorial/doc/html/python/hello.html b/doc/tutorial/doc/html/python/hello.html index c8ae53bc..a7d946c4 100644 --- a/doc/tutorial/doc/html/python/hello.html +++ b/doc/tutorial/doc/html/python/hello.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@

    Building Hello World

    -From Start To Finish

    +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 @@ -34,14 +34,12 @@ necessary to achieve that. We shall use the build tool that comes bundled with every boost distribution: bjam.

    boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
    -
    -Building without bjam

    -

    +
    +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.

    -

    + 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 @@ -95,11 +93,11 @@ 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!

    -

    +Let's Jam! +

    Here is our minimalist Jamfile:

    -
        subproject libs/python/example/tutorial ;
    +
    subproject libs/python/example/tutorial ;
     
         SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
         include python.jam ;
    @@ -113,22 +111,22 @@ Here is our minimalist Jamfile:

    First, we need to specify our location in the boost project hierarchy. It so happens that the tutorial example is located in /libs/python/example/tutorial. Thus:

    -
        subproject libs/python/example/tutorial ;
    +
    subproject libs/python/example/tutorial ;
     

    Then we will include the definitions needed by Python modules:

    -
        SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
    +
    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
         include python.jam ;
     

    Finally we declare our hello extension:

    -
        extension hello                     # Declare a Python extension called hello
    +
    extension hello                     # Declare a Python extension called hello
         :   hello.cpp                       # source
             <dll>../../build/boost_python   # dependencies
             ;
     

    -Running bjam

    +Running bjam

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

    Start it up.

    @@ -147,7 +145,7 @@ and that we are using Python version 2.2. You'll have to tweak this path appropriately.

    -
    +
    Be sure not to include a third number, e.g. not "2.2.1", even if that's the version you have.
    @@ -164,7 +162,7 @@ not, then you will have to specify the appropriate tool. See further details.

    It should be building now:

    -
        cd C:\dev\boost\libs\python\example\tutorial
    +
    cd C:\dev\boost\libs\python\example\tutorial
         bjam -sTOOLS=msvc
         ...patience...
         ...found 1703 targets...
    @@ -172,7 +170,7 @@ It should be building now:

    And so on... Finally:

    -
        vc-C++ ........\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
    +
    vc-C++ ........\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
         runtime-link-dynamic\hello.obj
         hello.cpp
         vc-Link ........\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
    @@ -213,14 +211,16 @@ can simply put these libraries inside the directory where the Python
     executable is.

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

    -
    >>> import hello
    ->>> print hello.greet()
    +

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

    There you go... Have fun!

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

    diff --git a/doc/tutorial/doc/html/python/iterators.html b/doc/tutorial/doc/html/python/iterators.html index d34df38a..54e28011 100644 --- a/doc/tutorial/doc/html/python/iterators.html +++ b/doc/tutorial/doc/html/python/iterators.html @@ -13,7 +13,7 @@ - + @@ -54,17 +54,20 @@ Raises StopIteration exception at end

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

    -
    iter = x.__iter__()         # get iterator
    -try:
    +

    +
    iter = x.__iter__()         # get iterator
    +try:
         while 1:
    -    y = iter.next()         # get each item
    -    ...                     # process y
    -except StopIteration: pass  # iterator exhausted
    + y
    = iter.next() # get each item + ... # process y +except StopIteration: pass # iterator exhausted +

    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 is compatible with the Python iteration protocol. For example:

    +

    object get_iterator = iterator<vector<int> >();
     object iter = get_iterator(v);
     object first = iter.next();
    @@ -105,20 +108,22 @@ with &T::begin, &T::end.

    Let's put this into action... Here's an example from some hypothetical bogon Particle accelerator code:

    +

    f = Field()
    -for x in f.pions:
    +for x in f.pions:
         smash(x)
    -for y in f.bogons:
    +for y in f.bogons:
         count(y)

    Now, our C++ Wrapper:

    +

    class_<F>("Field")
         .property("pions", range(&F::p_begin, &F::p_end))
         .property("bogons", range(&F::b_begin, &F::b_end));
    boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
    - +
    Copyright © 2002-2004 Joel de Guzman, David AbrahamsCopyright © 2002-2005 Joel de Guzman, David Abrahams

    diff --git a/doc/tutorial/doc/html/python/object.html b/doc/tutorial/doc/html/python/object.html index 25092680..ea66ed48 100644 --- a/doc/tutorial/doc/html/python/object.html +++ b/doc/tutorial/doc/html/python/object.html @@ -13,7 +13,7 @@ - + @@ -53,17 +53,19 @@ Class object wraps PyObject*. objects can in fact be explicitly constructed from any C++ object.

    To illustrate, this Python code snippet:

    -
    def f(x, y):
    -     if (y == 'foo'):
    -         x[3:7] = 'bar'
    +

    +
    def f(x, y):
    +     if (y == 'foo'):
    +         x[3:7] = 'bar'
          else:
              x.items += y(3, x)
    -     return x
    +     return x
     
     def getfunc():
        return f;

    Can be rewritten in C++ using Boost.Python facilities this way:

    +

    object f(object x, object y) {
          if (y == "foo")
              x.slice(3,7) = "bar";
    @@ -135,18 +137,27 @@ member functions.

    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++.

    -

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

    +
    boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
    + + +
    +Beware the common pitfall of forgetting that the constructors + of most of Python's mutable types make copies, just as in Python. +

    -Python:

    -
    >>> d = dict(x.__dict__)     # copies x.__dict__
    ->>> d['whatever']            # modifies the copy
    +Python: +

    +
    >>> d = dict(x.__dict__)     # copies x.__dict__
    +>>> d['whatever']            # modifies the copy
    +

    -C++:

    -
    dict d(x.attr("__dict__"));  # copies x.__dict__
    -d['whatever'] = 3;           # modifies the copy
    +C++: +

    +
    dict d(x.attr("__dict__"));  // copies x.__dict__
    +d['whatever'] = 3;           // modifies the copy
    +

    -class_<T> as objects

    +class_<T> as objects

    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 @@ -219,9 +230,8 @@ creates a Python class derived from Python's int type w associated with the C++ type passed as its first parameter.

    -
    -what is a scope?

    -

    +
    +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 @@ -229,11 +239,13 @@ attributes. Details can be found >>> my_module.choice.red my_module.choice.red

    where my_module is the module where the enum is declared. You can also create a new scope around a class:

    +

    scope in_X = class_<X>("X")
                     .def( ... )
                     .def( ... )
    @@ -248,7 +260,7 @@ create a new scope around a class:

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

    diff --git a/doc/tutorial/doc/html/python/techniques.html b/doc/tutorial/doc/html/python/techniques.html index db9c6e11..5fc5fbf7 100644 --- a/doc/tutorial/doc/html/python/techniques.html +++ b/doc/tutorial/doc/html/python/techniques.html @@ -12,7 +12,7 @@ - + @@ -83,14 +83,14 @@ Compiling these files will generate the following Python extensions: core.pyd, io.pyd and filters.pyd.

    boost.png (6897 bytes) HomeLibrariesLibraries People FAQ More
    -
    +
    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:

    -
        sounds/
    +
    sounds/
             _init_.py
             core.pyd
             filters.pyd
    @@ -104,9 +104,10 @@ magic, that will be shown later.

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

    -
    >>> import sounds.io
    ->>> import sounds.filters
    ->>> sound = sounds.io.open('file.mp3')
    +

    +
    >>> import sounds.io
    +>>> import sounds.filters
    +>>> sound = sounds.io.open('file.mp3')
     >>> new_sound = sounds.filters.echo(sound, 1.0)

    Nice heh?

    @@ -120,6 +121,7 @@ it.

    If we want this flexibility, we will have to complicate our package hierarchy a little. First, we will have to change the name of the extension modules:

    +

    /* file core.cpp */
     BOOST_PYTHON_MODULE(_core)
     {
    @@ -130,7 +132,7 @@ BOOST_PYTHON_MODULE(_core.pyd as well, and we do the same to the other extension modules.
     Now, we change our package hierarchy like so:

    -
        sounds/
    +
    sounds/
             _init_.py
             core/
                 _init_.py
    @@ -146,18 +148,19 @@ Now, we change our package hierarchy like so:

    Note that we created a directory for each extension module, and added a _init_.py to each one. But if we leave it that way, the user will have to access the functions in the core module with this syntax:

    -
    >>> import sounds.core._core
    +

    +
    >>> import sounds.core._core
     >>> 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 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 [^sounds/core/init_.py:

    -
    from _core import *
    +
    from _core import *

    We do the same for the other packages. Now the user accesses the functions and classes in the extension modules like before:

    -
    >>> import sounds.filters
    +
    >>> import sounds.filters
     >>> sounds.filters.echo(...)

    with the additional benefit that we can easily add pure Python functions to @@ -166,18 +169,18 @@ function and a Python function. Let's add a pure 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:

    -
    import _filters
    +
    import _filters
     def echo_noise(sound):
         s = _filters.echo(sound)
         s = _filters.noise(sound)
         return s

    Next, we add this line to soundsfilters_init_.py:

    -
    from echo_noise import echo_noise
    +
    from echo_noise import echo_noise

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

    -
    >>> import sounds.filters
    +
    >>> import sounds.filters
     >>> sounds.filters.echo_noise(...)
    @@ -186,16 +189,16 @@ from the filters package:

    Thanks to Python's flexibility, you can easily add new methods to a class, even after it was already created:

    -
    >>> class C(object): pass
    +
    >>> class C(object): pass
     >>>
    ->>> # a regular function
    ->>> def C_str(self): return 'A C instance!'
    +>>> # a regular function
    +>>> def C_str(self): return 'A C instance!'
     >>>
    ->>> # now we turn it in a member function
    ->>> C.__str__ = C_str
    +>>> # now we turn it in a member function
    +>>> C.__str__ = C_str
     >>>
     >>> c = C()
    ->>> print c
    +>>> print c
     A C instance!
     >>> C_str(c)
     A C instance!
    @@ -204,6 +207,7 @@ Yes, Python rox. We can do the same with classes that were wrapped with Boost.Python. Suppose we have a class point in C++:

    +

    class point {...};
     
     BOOST_PYTHON_MODULE(_geom)
    @@ -214,14 +218,15 @@ BOOST_PYTHON_MODULE(Creating Packages, we can code directly
     into geom/_init_.py:

    -
    from _geom import *
    +

    +
    from _geom import *
     
    -# a regular function
    -def point_str(self):
    -    return str((self.x, self.y))
    +# a regular function
    +def point_str(self):
    +    return str((self.x, self.y))
     
    -# now we turn it into a member function
    -point.__str__ = point_str
    +# now we turn it into a member function +point.__str__ = point_str

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