[doc Pyste Documentation]

[/ Copyright 2003 Bruno da Silva de Oliveira and Joel de Guzman.
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) ]

[def GCCXML             [@http://www.gccxml.org GCCXML]]
[def Boost.Python       [@../../index.html Boost.Python]]

[page Introduction]

[h2 What is Pyste?]

Pyste is a Boost.Python code generator. The user specifies the classes and
functions to be exported using a simple ['interface file], which following the
Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to
parse all the headers and extract the necessary information to automatically
generate C++ code.

[h2 Example]

Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]: 

    struct World
    {
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

Here's the interface file for it, named [^world.pyste]:

    Class("World", "world.h")

and that's it!

The next step is invoke Pyste in the command-line:

[pre python pyste.py --module=hello world.pyste]

this will create a file "[^hello.cpp]" in the directory where the command was
run. 

Pyste supports the following features:

* Functions
* Classes
* Class Templates
* Virtual Methods
* Overloading
* Attributes 
* Enums (both "free" enums and class enums)
* Nested Classes
* Support for [^boost::shared_ptr] and [^std::auto_ptr]
* Global Variables

[page Running Pyste]

To run Pyste, you will need:

* Python 2.2, available at [@http://www.python.org python's website].
* The great [@http://effbot.org elementtree] library, from Fredrik Lundh.
* The excellent GCCXML, from Brad King.

Installation for the tools is available in their respective webpages.

[blurb 
[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so
that Pyste can call it. How to do this varies from platform to platform.
]

[h2 Ok, now what?]

Well, now let's fire it up:

[pre 
'''
>python pyste.py

Pyste version 0.9.26

Usage:
    pyste [options] interface-files

where options are:
    --module=<name>         The name of the module that will be generated;
                            defaults to the first interface filename, without
                            the extension.
    -I <path>               Add an include path
    -D <symbol>             Define symbol
    --multiple              Create various cpps, instead of only one
                            (useful during development)
    --out=<name>            Specify output filename (default: <module>.cpp)
                            in --multiple mode, this will be a directory
    --no-using              Do not declare "using namespace boost";
                            use explicit declarations instead
    --pyste-ns=<name>       Set the namespace where new types will be declared;
                            default is the empty namespace
    --debug                 Writes the xml for each file parsed in the current
                            directory
    --cache-dir=<dir>       Directory for cache files (speeds up future runs)
    --only-create-cache     Recreates all caches (doesn't generate code).
    --generate-main         Generates the _main.cpp file (in multiple mode)
    --file-list             A file with one pyste file per line. Use as a 
                            substitute for passing the files in the command
                            line.
    -h, --help              Print this help and exit
    -v, --version           Print version information
  
'''                        
]

Options explained:

The [^-I] and [^-D] are preprocessor flags, which are needed by GCCXML to parse
the header files correctly and by Pyste to find the header files declared in the
interface files.

[^--out] names the output file (default: [^<module>.cpp]), or in multiple mode,
names a output directory for the files (default: [^<module>]).

[^--no-using] tells Pyste to don't declare "[^using namespace boost;]" in the
generated cpp, using the namespace boost::python explicitly in all declarations.
Use only if you're having a name conflict in one of the files.

Use [^--pyste-ns] to change the namespace where new types are declared (for
instance, the virtual wrappers). Use only if you are having any problems. By
default, Pyste uses the empty namespace.

[^--debug] will write in the current directory a xml file as outputted by GCCXML
for each header parsed. Useful for bug reports.

[^--file-list] names a file where each line points to a Pyste file. Use this instead 
to pass the pyste files if you have a lot of them and your shell has some command line
size limit.

The other options are explained below, in [@#multiple_mode [*Multiple Mode]] and
[@#cache [*Cache]].

[^-h, --help, -v, --version] are self-explaining, I believe. ;)

So, the usage is simple enough:

[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...]

will generate a file [^mymodule.cpp] in the same dir where the command was
executed. Now you can compile the file using the same instructions of the
[@../../doc/tutorial/doc/building_hello_world.html tutorial]. 

[h2 Wait... how do I set those I and D flags?]

Don't worry: normally GCCXML is already configured correctly for your plataform, 
so the search path to the standard libraries and the standard defines should 
already be set. You only have to set the paths to other libraries that your code 
needs, like Boost, for example.

Plus, Pyste automatically uses the contents of the environment variable
[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file,
which for Visual C++ 6 is normally located at:

    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat

with that, you should have little trouble setting up the flags.

[blurb [$theme/note.gif][*A note about Psyco][br][br]
Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to
use Pyste, if you do, Pyste will make use of it to speed up the wrapper
generation. Speed ups of 30% can be achieved, so it's highly recommended.
]


[h2 Multiple Mode]

The multiple mode is useful in large projects, where the presence of multiple
classes in a single file makes the compilation unpractical (excessive memory
usage, mostly). 

The solution is make Pyste generate multiple files, more specifically one cpp
file for each Pyste file. This files will contain a function named after the
file, for instance Export_MyPysteFile, which will contain all the code to export
the classes, enums, etc. You can pass as much files as you want this way:

[pre >python pyste.py --module=mymodule file1.pyste file2.pyste]

This will create the files [^mymodule/file1.cpp] and [^mymodule/file2.cpp]. You
can then later do:

[pre >python pyste.py --module=mymodule file3.pyste]

and [^mymodule/file3.cpp] will be generated.

But compiling and linking this files won't be sufficient to generate your
extension. You have to also generate a file named [^main.cpp]; call pyste with
[*all] the Pyste files of your extension, and use the [^--generate-main] option:

[pre >python pyste.py --module=mymodule --generate-main file1.pyste file2.pyste file3.pyste]

Now compile and link all this files together and your extension is ready for
use.

[h2 Cache]

Pyste now supports a form of cache, which is a way to speed up the code
generation. Most of the time that Pyste takes to generate the code comes from
having to execute GCCXML (since being a front-end to GCC, it has to compile the
header files) and reading back the XML generated. 

When you use the [^--cache-dir=<dir>] option, Pyste will dump in the specified
directory the generated XMLs to a file named after the Pyste file, with the
extension [^.pystec].  The next time you run with this option, Pyste will use
the cache, instead of calling GCCXML again:

[pre >python pyste.py --module=mymodule --cache-dir=cache file1.pyste]

Will generate [^file1.cpp] and [^cache/file1.pystec]. Next time you execute
this command, the cache file will be used. Note that Pyste doesn't do any check
to ensure that the cache is up to date, but you can configure your build system to do that for you.

When you run Pyste with [^--only-create-cache], all the cache files will be
created again, but no code will be generated.

[page The Interface Files]

The interface files are the heart of Pyste. The user creates one or more
interface files declaring the classes and functions he wants to export, and then
invokes Pyste passing the interface files to it. Pyste then generates a single
cpp file with Boost.Python code, with all the classes and functions exported.

Besides declaring the classes and functions, the user has a number of other
options, like renaming e excluding classes and member functionis. Those are
explained later on.

[h2 Basics]

Suppose we have a class and some functions that we want to expose to Python
declared in the header [^hello.h]:

    struct World
    {
        World(std::string msg): msg(msg) {} 
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

    enum choice { red, blue };
    
    namespace test {
    
    void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
    
    }

We create a file named [^hello.pyste] and create instances of the classes
[^Function], [^Class] and [^Enum]:

    Function("test::show", "hello.h")
    Class("World", "hello.h")
    Enum("choice", "hello.h")

That will expose the class, the free function and the enum found in [^hello.h]. 

[h2 Inheritance]

Pyste automatically generates the correct code (specifying [^bases<>] in the
[^class_] declaration) [*if] the Class() function that exports the base classes
and their children are in the same Pyste file. If that's not the case, you have
to indicate that there's a relationship between the Pyste files using the
[^Import] function specifying the other Pyste file.

Suppose we have two classes, [^A] and [^B], and A is a base class for B. We
create two Pyste files:

[^A.pyste]:

    Class("A", "A.h")

[^B.pyste]:

    Import("A.pyste")
    Class("B", "B.h")

Note that we specify that [^B] needs to know about [^A] to be properly exported.

[page:1 Renaming and Excluding]

You can easily rename functions, classes, member functions, attributes, etc. Just use the
function [^rename], like this:

    World = Class("World", "hello.h")
    rename(World, "IWorld")
    show = Function("choice", "hello.h")
    rename(show, "Show")

You can rename member functions and attributes using this syntax:

    rename(World.greet, "Greet")
    rename(World.set, "Set")
    choice = Enum("choice", "hello.h")
    rename(choice.red, "Red")
    rename(choice.blue, "Blue")

You can exclude functions, classes, member functions, attributes, etc, in the same way,
with the function [^exclude]:

    exclude(World.greet)
    exclude(World.msg)

To access the operators of a class, access the member [^operator] like this
(supposing that [^C] is a class being exported):

    exclude(C.operator['+'])
    exclude(C.operator['*'])
    exclude(C.operator['<<'])

The string inside the brackets is the same as the name of the operator in C++.[br]

[h2 Virtual Member Functions]

Pyste automatically generates wrappers for virtual member functions, but you may
want to disable this behaviour (for performance reasons, for instance) if you do
not plan to override the functions in Python. To do this, use the function
[^final]:

    C = Class('C', 'C.h')
    final(C.foo) # C::foo is a virtual member function

No virtual wrapper code will be generated for the virtual member function
C::foo that way.

[page:1 Policies]

Even thought Pyste can identify various elements in the C++ code, like virtual
member functions, attributes, and so on, one thing that it can't do is to
guess the semantics of functions that return pointers or references. In this
case, the user must manually specify the policy. Policies are explained in the
[@../../doc/tutorial/doc/call_policies.html tutorial].

The policies in Pyste are named exactly as in Boost.Python, only the syntax is
slightly different. For instance, this policy:

    return_internal_reference<1, with_custodian_and_ward<1, 2> >()

becomes in Pyste:    

    return_internal_reference(1, with_custodian_and_ward(1, 2))

The user can specify policies for functions and virtual member functions with
the [^set_policy] function:

    set_policy(f, return_internal_reference())
    set_policy(C.foo, return_value_policy(manage_new_object))

[blurb 
[$theme/note.gif] [*What if a function or member function needs a policy and
the user doesn't set one?][br][br] If a function needs a policy and one
was not set, Pyste will issue a error.  The user should then go in the
interface file and set the policy for it, otherwise the generated cpp won't
compile.
]

[blurb
[$theme/note.gif] 
Note that for functions that return [^const T&], the policy
[^return_value_policy<copy_const_reference>()] wil be used by default, because
that's normally what you want. You can change it to something else if you need
to, though.
]

[page:1 Templates]

Template classes can easily be exported too, but you can't export the template
itself... you have to export instantiations of it! So, if you want to export a
[^std::vector], you will have to export vectors of int, doubles, etc.

Suppose we have this code:

    template <class T>
    struct Point
    {
        T x;
        T y;
    };

And we want to export [^Point]s of int and double:

    Point = Template("Point", "point.h")
    Point("int")
    Point("double")

Pyste will assign default names for each instantiation. In this example, those
would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to
rename the instantiations:

    Point("int", "IPoint")         // renames the instantiation
    double_inst = Point("double")  // another way to do the same
    rename(double_inst, "DPoint")

Note that you can rename, exclude, set policies, etc, in the [^Template] object
like you would do with a [^Function] or a [^Class]. This changes affect all
[*future] instantiations:

    Point = Template("Point", "point.h")
    Point("float", "FPoint")        // will have x and y as data members
    rename(Point.x, "X")
    rename(Point.y, "Y")
    Point("int", "IPoint")          // will have X and Y as data members
    Point("double", "DPoint")       // also will have X and Y as data member

If you want to change a option of a particular instantiation, you can do so:

    Point = Template("Point", "point.h")
    Point("int", "IPoint")          
    d_inst = Point("double", "DPoint")       
    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
    rename(d_inst.y, "Y")           // IPoint stays intact

[blurb [$theme/note.gif] [*What if my template accepts more than one type?]
[br][br]
When you want to instantiate a template with more than one type, you can pass
either a string with the types separated by whitespace, or a list of strings
'''("int double" or ["int", "double"]''' would both work).
]

[page:1 Wrappers]

Suppose you have this function:

    std::vector<std::string> names();

But you don't want to [@../../doc/v2/faq.html#question2 to export std::vector<std::string>], 
you want this function to return a python list of strings. Boost.Python has
excellent support for things like that:

    list names_wrapper()
    {
        list result;
        // call original function
        vector<string> v = names();
        // put all the strings inside the python list
        vector<string>::iterator it;
        for (it = v.begin(); it != v.end(); ++it){
            result.append(*it);    
        }
        return result;
    }
    
    BOOST_PYTHON_MODULE(test)
    {
        def("names", &names_wrapper);
    }

Nice heh? Pyste supports this mechanism too. You declare the [^names_wrapper]
function in a header named "[^test_wrappers.h]" and in the interface file:

    Include("test_wrappers.h")
    names = Function("names", "test.h")
    set_wrapper(names, "names_wrapper")

You can optionally declare the function in the interface file itself:

    names_wrapper = Wrapper("names_wrapper",
    """
    list names_wrapper()
    {
        // code to call name() and convert the vector to a list...
    }
    """)
    names = Function("names", "test.h")
    set_wrapper(names, names_wrapper)

The same mechanism can be used with member functions too. Just remember that
the first parameter of wrappers for member functions is a pointer to the
class, as in:

    struct C
    {
        std::vector<std::string> names();
    }

    list names_wrapper(C* c)
    {
        // same as before, calling c->names() and converting result to a list 
    }

And then in the interface file:

    C = Class("C", "test.h")
    set_wrapper(C.names, "names_wrapper")

[blurb 
[$theme/note.gif]Even though Boost.Python accepts either a pointer or a
reference to the class in wrappers for member functions as the first parameter,
Pyste expects them to be a [*pointer]. Doing otherwise will prevent your
code to compile when you set a wrapper for a virtual member function.
]

[page:1 Exporting An Entire Header]

Pyste also supports a mechanism to export all declarations found in a header
file. Suppose again our file, [^hello.h]:

    struct World
    {
        World(std::string msg): msg(msg) {} 
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

    enum choice { red, blue };
    
    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 

You can just use the [^AllFromHeader] construct:

    hello = AllFromHeader("hello.h")

this will export all the declarations found in [^hello.h], which is equivalent
to write:

    Class("World", "hello.h")
    Enum("choice", "hello.h")
    Function("show", "hello.h")

Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access
the members of the header object like this:

    rename(hello.World.greet, "Greet")
    exclude(hello.World.set, "Set")

[blurb    
[$theme/note.gif] [*AllFromHeader is broken] in some cases. Until it is fixed,
use at you own risk.
]


[page:1 Smart Pointers]

Pyste for now has manual support for smart pointers. Suppose:

    struct C
    {
        int value;
    };

    boost::shared_ptr<C> newC(int value)
    {
        boost::shared_ptr<C> c( new C() );
        c->value = value;
        return c;
    }

    void printC(boost::shared_ptr<C> c)
    {
        std::cout << c->value << std::endl;
    }

To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
convertor for [^boost::shared_ptr<C>] is needed.

    C = Class('C', 'C.h')
    use_shared_ptr(C)
    Function('newC', 'C.h')
    Function('printC', 'C.h')

For [^std::auto_ptr]'s, use the function [^use_auto_ptr].

This system is temporary, and in the future the converters will automatically be
exported if needed, without the need to tell Pyste about them explicitly.

[h2 Holders]

If only the converter for the smart pointers is not enough and you need to
specify the smart pointer as the holder for a class, use the functions
[^hold_with_shared_ptr] and [^hold_with_auto_ptr]:

    C = Class('C', 'C.h')
    hold_with_shared_ptr(C)
    Function('newC', 'C.h')
    Function('printC', 'C.h') 

[page:1 Global Variables]

To export global variables, use the [^Var] construct:

    Var("myglobal", "foo.h")

Beware of non-const global variables: changes in Python won't reflect in C++!
If you really must change them in Python, you will have to write some accessor
functions, and export those.


[page:1 Adding New Methods]

Suppose that you want to add a function to a class, turning it into a member
function:

    struct World
    {
        void set(std::string msg) { this->msg = msg; }
        std::string msg;
    };

    std::string greet(World& w)
    {
        return w.msg;
    }

Here, we want to make [^greet] work as a member function of the class [^World]. We do
that using the [^add_method] construct:

    W = Class("World", "hello.h")
    add_method(W, "greet")

Notice also that then you can rename it, set its policy, just like a regular
member function:

    rename(W.greet, 'Greet')

Now from Python:

    >>> import hello
    >>> w = hello.World()
    >>> w.set('Ni')
    >>> w.greet()
    'Ni'
    >>> print 'Oh no! The knights who say Ni!'
    Oh no! The knights who say Ni!


[page:1 Inserting Code]

You can insert arbitrary code in the generated cpps, just use the functions
[^declaration_code] and [^module_code]. This will insert the given string in the
respective sections. Example:

    # file A.pyste
    Class("A", "A.h")
    declaration_code("/* declaration_code() comes here */\n")
    module_code("/* module_code() comes here */\n")

Will generate:

    // Includes ====================================================================
    #include <boost/python.hpp>

    // Using =======================================================================
    using namespace boost::python;

    // Declarations ================================================================

    /* declaration_code() comes here */

    // Module ======================================================================
    BOOST_PYTHON_MODULE(A)
    {
        class_< A >("A", init<  >())
            .def(init< const A& >())
        ;

    /* module_code() comes here */
    }
