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

- Lots of fixes in the documentation

- Fixed support for return_opaque_pointer policy


[SVN r18199]
This commit is contained in:
Bruno da Silva de Oliveira
2003-04-08 01:01:32 +00:00
parent f7f089d2d4
commit c7ea0aacd6
38 changed files with 294 additions and 114 deletions

View File

@@ -1,6 +1,12 @@
07 Apr 2003
Removed the warnings about forward declarations: it was not accurate enough.
Another strategy must be thought of.
- Removed the warnings about forward declarations: it was not accurate enough.
Another strategy must be thought of.
- Fixed bug in the --multiple mode, where the order of the class instantiations
could end up wrong.
- Lots of fixes in the documentation, pointed out by Dirk Gerrits. Thanks Dirk!
- Fixed support for the return_opaque_pointer policy (the support macro was not
being declared).
06 Apr 2003
Support for the improved static data members support of Boost.Python.

View File

@@ -51,7 +51,7 @@ Here's the interface file for it, named <tt>world.pyste</tt>:</p>
<p>
and that's it!</p>
<p>
The next step is invoke pyste in the command-line:</p>
The next step is invoke Pyste in the command-line:</p>
<code><pre>python pyste.py --module=hello world.pyste</pre></code><p>
this will create a file &quot;<tt>hello.cpp</tt>&quot; in the directory where the command was
run. </p>

View File

@@ -69,7 +69,7 @@ and set the policy for it, otherwise the generated cpp won't compile.
Note that, for functions/methods that return <tt>const T&amp;</tt>, the policy
<tt>return_value_policy&lt;copy_const_reference&gt;()</tt> wil be used by default, because
that's normally what you want. You can change it to something else if you need
to, thought.
to, though.
</td>
</tr>
</table>

View File

@@ -30,7 +30,7 @@ Here's the interface file for it, named [^world.pyste]:
and that's it!
The next step is invoke pyste in the command-line:
The next step is invoke Pyste in the command-line:
[pre python pyste.py --module=hello world.pyste]
@@ -51,17 +51,17 @@ Pyste supports the following features:
[page Running Pyste]
To run pyste, you will need:
To run Pyste, you will need:
* Python 2.2, avaiable at [@http://www.python.org python's website].
* 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 avaiable in their respective webpages.
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.
that Pyste can call it. How to do this varies from platform to platform.
]
[h2 Ok, now what?]
@@ -87,7 +87,7 @@ where options are:
--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 "pyste"
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
@@ -97,11 +97,11 @@ where options are:
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
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.
[^--multiple] tells pyste to generate multiple cpps for this module (one for
[^--multiple] tells Pyste to generate multiple cpps for this module (one for
each header parsed) in the directory named by [^--out], instead of the usual
single cpp file. This mode is useful during development of a binding, because
you are constantly changing source files, re-generating the bindings and
@@ -110,7 +110,7 @@ recompiling. This saves a lot of time in compiling.
[^--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
[^--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.
@@ -118,7 +118,7 @@ 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
[^--debug] will write in the current directory a xml file as outputted by GCCXML
for each header parsed. Useful for bug reports.
[^-h, --help, -v, --version] are self-explaining, I believe. ;)
@@ -160,7 +160,7 @@ Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to use
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
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
@@ -265,12 +265,12 @@ and set the policy for it, otherwise the generated cpp won't compile.
Note that, for functions/methods 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, thought.
to, though.
]
[page:1 Templates]
Template Classes can easily exported too, but you can't export the "Template"
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.
@@ -297,7 +297,7 @@ rename the instantiations:
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] class
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:
@@ -318,7 +318,7 @@ If you want to change a option of a particular instantiation, you can do so:
[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
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).
]
@@ -329,8 +329,8 @@ Suppose you have this function:
std::vector<std::string> names();
But you don't want to export [^std::vector<string>], you want this function
to return a python list of strings. Boost.Python has an excellent support for
But you don't want to export [^std::vector<std::string>], you want this function
to return a python list of strings. Boost.Python has excellent support for
that:
list names_wrapper()
@@ -338,7 +338,11 @@ that:
list result;
// call original function
vector<string> v = names();
// put each string from the vector in the list
// 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;
}
@@ -360,13 +364,13 @@ You can optionally declare the function in the interface file itself:
"""
list names_wrapper()
{
// call name() and convert the vector to a list...
// 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 done with methods too. Just remember that the first
The same mechanism can be used with methods too. Just remember that the first
parameter of wrappers for methods is a pointer to the class, like in
Boost.Python:
@@ -449,7 +453,7 @@ Pyste for now has manual support for smart pointers. Suppose:
}
To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
conversor for [^boost::shared_ptr<C>] is needed.
convertor for [^boost::shared_ptr<C>] is needed.
C = Class('C', 'C.h')
use_shared_ptr(C)
@@ -458,6 +462,6 @@ conversor for [^boost::shared_ptr<C>] is needed.
For [^std::auto_ptr]'s, use the function [^use_auto_ptr].
This system is temporary, and in the future the conversors will automatically be
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.

View File

@@ -25,19 +25,19 @@
</tr>
</table>
<p>
To run pyste, you will need:</p>
<ul><li>Python 2.2, avaiable at <a href="http://www.python.org">
To run Pyste, you will need:</p>
<ul><li>Python 2.2, available at <a href="http://www.python.org">
python's website</a>.</li><li>The great <a href="http://effbot.org">
elementtree</a> library, from Fredrik Lundh.</li><li>The excellent <a href="http://www.gccxml.org">
GCCXML</a>, from Brad King.</li></ul><p>
Installation for the tools is avaiable in their respective webpages.</p>
Installation for the tools is available in their respective webpages.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <a href="http://www.gccxml.org">
GCCXML</a> must be accessible in the PATH environment variable, so
that pyste can call it. How to do this varies from platform to platform.
that Pyste can call it. How to do this varies from platform to platform.
</td>
</tr>
</table>
@@ -62,7 +62,7 @@ where options are:
--no-using do not declare &quot;using namespace boost&quot;;
use explicit declarations instead
--pyste-ns=&lt;name&gt; set the namespace where new types will be declared;
default is &quot;pyste&quot;
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
@@ -71,11 +71,12 @@ where options are:
</pre></code><p>
Options explained:</p>
<p>
The <tt>-I</tt> and <tt>-D</tt> 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
The <tt>-I</tt> and <tt>-D</tt> are preprocessor flags, which are needed by <a href="http://www.gccxml.org">
GCCXML</a> to parse
the header files correctly and by Pyste to find the header files declared in the
interface files.</p>
<p>
<tt>--multiple</tt> tells pyste to generate multiple cpps for this module (one for
<tt>--multiple</tt> tells Pyste to generate multiple cpps for this module (one for
each header parsed) in the directory named by <tt>--out</tt>, instead of the usual
single cpp file. This mode is useful during development of a binding, because
you are constantly changing source files, re-generating the bindings and
@@ -84,7 +85,7 @@ recompiling. This saves a lot of time in compiling.</p>
<tt>--out</tt> names the output file (default: <tt>&lt;module&gt;.cpp</tt>), or in multiple mode,
names a output directory for the files (default: <tt>&lt;module&gt;</tt>).</p>
<p>
<tt>--no-using</tt> tells pyste to don't declare &quot;<tt>using namespace boost;</tt>&quot; in the
<tt>--no-using</tt> tells Pyste to don't declare &quot;<tt>using namespace boost;</tt>&quot; 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.</p>
<p>
@@ -92,7 +93,8 @@ Use <tt>--pyste-ns</tt> to change the namespace where new types are declared (fo
instance, the virtual wrappers). Use only if you are having any problems. By
default, Pyste uses the empty namespace.</p>
<p>
<tt>--debug</tt> will write in the current directory a xml file as outputted by gccxml
<tt>--debug</tt> will write in the current directory a xml file as outputted by <a href="http://www.gccxml.org">
GCCXML</a>
for each header parsed. Useful for bug reports.</p>
<p>
<tt>-h, --help, -v, --version</tt> are self-explaining, I believe. ;)</p>

View File

@@ -45,7 +45,7 @@ Pyste for now has manual support for smart pointers. Suppose:</p>
</span></pre></code>
<p>
To make <tt>newC</tt> and <tt>printC</tt> work correctly, you have to tell Pyste that a
conversor for <tt>boost::shared_ptr&lt;C&gt;</tt> is needed.</p>
convertor for <tt>boost::shared_ptr&lt;C&gt;</tt> is needed.</p>
<code><pre>
<span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
</span><span class=identifier>use_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
@@ -55,7 +55,7 @@ conversor for <tt>boost::shared_ptr&lt;C&gt;</tt> is needed.</p>
<p>
For <tt>std::auto_ptr</tt>'s, use the function <tt>use_auto_ptr</tt>.</p>
<p>
This system is temporary, and in the future the conversors will automatically be
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.</p>
<table border="0">
<tr>

View File

@@ -25,7 +25,7 @@
</tr>
</table>
<p>
Template Classes can easily exported too, but you can't export the &quot;Template&quot;
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
<tt>std::vector</tt>, you will have to export vectors of int, doubles, etc.</p>
<p>
@@ -55,7 +55,7 @@ rename the instantiations:</p>
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>double_inst</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>)
</span></pre></code>
<p>
Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> class
Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> object
like you would do with a <tt>Function</tt> or a <tt>Class</tt>. This changes affect all
<b>future</b> instantiations:</p>
<code><pre>
@@ -80,7 +80,7 @@ If you want to change a option of a particular instantiation, you can do so:</p>
<td class="note_box">
<img src="theme/note.gif"></img> <b>What if my template accepts more than one type?</b>
<br><br>
When you want to instantiate a Template with more than one type, you can pass
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
(&quot;int double&quot; or [&quot;int&quot;, &quot;double&quot;] would both work).
</td>

View File

@@ -27,7 +27,7 @@
<p>
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
invokes Pyste passing the interface files to it. Pyste then generates a single
cpp file with <a href="../../index.html">
Boost.Python</a> code, with all the classes and functions exported.</p>
<p>

View File

@@ -30,9 +30,9 @@ Suppose you have this function:</p>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>names</span><span class=special>();
</span></pre></code>
<p>
But you don't want to export <tt>std::vector&lt;string&gt;</tt>, you want this function
But you don't want to export <tt>std::vector&lt;std::string&gt;</tt>, you want this function
to return a python list of strings. <a href="../../index.html">
Boost.Python</a> has an excellent support for
Boost.Python</a> has excellent support for
that:</p>
<code><pre>
<span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>()
@@ -40,7 +40,11 @@ that:</p>
</span><span class=identifier>list </span><span class=identifier>result</span><span class=special>;
// </span><span class=identifier>call </span><span class=identifier>original </span><span class=identifier>function
</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>names</span><span class=special>();
// </span><span class=identifier>put </span><span class=identifier>each </span><span class=identifier>string </span><span class=identifier>from </span><span class=identifier>the </span><span class=identifier>vector </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>list
// </span><span class=identifier>put </span><span class=identifier>all </span><span class=identifier>the </span><span class=identifier>strings </span><span class=identifier>inside </span><span class=identifier>the </span><span class=identifier>python </span><span class=identifier>list
</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt;::</span><span class=identifier>iterator </span><span class=identifier>it</span><span class=special>;
</span><span class=keyword>for </span><span class=special>(</span><span class=identifier>it </span><span class=special>= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(); </span><span class=identifier>it </span><span class=special>!= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(); ++</span><span class=identifier>it</span><span class=special>){
</span><span class=identifier>result</span><span class=special>.</span><span class=identifier>append</span><span class=special>(*</span><span class=identifier>it</span><span class=special>);
}
</span><span class=keyword>return </span><span class=identifier>result</span><span class=special>;
}
@@ -64,14 +68,14 @@ You can optionally declare the function in the interface file itself:</p>
</span><span class=string>&quot;&quot;</span><span class=string>&quot;
list names_wrapper()
{
// call name() and convert the vector to a list...
// code to call name() and convert the vector to a list...
}
&quot;</span><span class=string>&quot;&quot;</span><span class=special>)
</span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
</span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=identifier>names_wrapper</span><span class=special>)
</span></pre></code>
<p>
The same mechanism can be done with methods too. Just remember that the first
The same mechanism can be used with methods too. Just remember that the first
parameter of wrappers for methods is a pointer to the class, like in
<a href="../../index.html">
Boost.Python</a>:</p>

View File

@@ -1,2 +1,2 @@
*.cpp
.sconsign
*.obj

8
pyste/example/basic.cpp Normal file
View File

@@ -0,0 +1,8 @@
#include "basic.h"
namespace basic {
int C::static_value = 3;
const int C::const_static_value = 100;
}

View File

@@ -1,3 +1,7 @@
#ifndef BASIC_H
#define BASIC_H
#include <string>
namespace basic {
@@ -24,27 +28,26 @@ struct C
const int const_value;
};
int C::static_value = 3;
const int C::const_static_value = 100;
int call_f(C& c)
inline int call_f(C& c)
{
return c.f();
}
int call_f(C& c, int x)
inline int call_f(C& c, int x)
{
return c.f(x);
}
int get_static()
inline int get_static()
{
return C::static_value;
}
int get_value(C& c)
inline int get_value(C& c)
{
return c.value;
}
}
#endif

View File

@@ -1,3 +1,6 @@
#ifndef ENUMS_H
#define ENUMS_H
namespace enums {
enum color { red, blue };
@@ -17,3 +20,5 @@ struct X
};
}
#endif

View File

@@ -1,3 +1,6 @@
#ifndef HEADER_TEST_H
#define HEADER_TEST_H
#include <map>
#include <string>
@@ -5,7 +8,7 @@ namespace header_test {
enum choice { red, blue };
std::string choice_str(choice c)
inline std::string choice_str(choice c)
{
std::map<choice, std::string> choice_map;
choice_map[red] = "red";
@@ -24,3 +27,5 @@ struct C
};
}
#endif

4
pyste/example/nested.cpp Normal file
View File

@@ -0,0 +1,4 @@
#include "nested.h"
int nested::X::staticXValue = 10;
int nested::X::Y::staticYValue = 20;

View File

@@ -1,3 +1,6 @@
#ifndef NESTED_H
#define NESTED_H
namespace nested {
struct X
@@ -16,9 +19,8 @@ struct X
int valueX;
};
int X::staticXValue = 10;
int X::Y::staticYValue = 20;
typedef X Root;
}
#endif

47
pyste/example/opaque.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef OPAQUE_H
#define OPAQUE_H
#include <iostream>
namespace opaque {
struct C {
C(int v): value(v) {}
int value;
};
inline C* new_C()
{
return new C(10);
}
inline int get(C* c)
{
return c->value;
}
struct D {
D(double v): value(v) {}
double value;
};
struct A
{
D* new_handle()
{
return new D(3.0);
}
double get(D* d)
{
return d->value;
}
int f(int x=0) { return x; }
};
}
#endif

View File

@@ -0,0 +1,5 @@
foo = Function('opaque::new_C', 'opaque.h')
set_policy(foo, return_value_policy(return_opaque_pointer))
Function('opaque::get', 'opaque.h' )
A = Class('opaque::A', 'opaque.h')
set_policy(A.new_handle, return_value_policy(return_opaque_pointer))

View File

@@ -0,0 +1,3 @@
#include "operators.h"
double operators::C::x = 10;

View File

@@ -1,3 +1,7 @@
#ifndef OPERATORS_H
#define OPERATORS_H
#include <iostream>
namespace operators {
@@ -31,9 +35,7 @@ struct C
operator const char*() { return "C"; }
};
double C::x = 10;
const C operator*(const C& lhs, const C& rhs)
inline const C operator*(const C& lhs, const C& rhs)
{
C c;
c.value = lhs.value * rhs.value;
@@ -42,3 +44,6 @@ const C operator*(const C& lhs, const C& rhs)
}
#endif

View File

@@ -1,3 +1,7 @@
#ifndef SMART_PTR_H
#define SMART_PTR_H
#include <memory>
#include <boost/shared_ptr.hpp>
@@ -8,7 +12,7 @@ struct C
int value;
};
boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
inline boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
struct D
{
@@ -18,5 +22,8 @@ private:
boost::shared_ptr<C> ptr;
};
std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
inline std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
}
#endif

View File

@@ -20,6 +20,6 @@ private:
virtual const char* name() { return "C"; }
};
int call_f(C& c) { return c.f(); }
inline int call_f(C& c) { return c.f(); }
}

View File

@@ -13,14 +13,14 @@ struct B: A
virtual int f2() { return 20; }
};
int call_fs(A*a)
inline int call_fs(A*a)
{
int r = a->f1();
B* b = dynamic_cast<B*>(a);
return r + b->f2();
}
int call_f(A* a)
inline int call_f(A* a)
{
return a->f();
}

View File

@@ -6,7 +6,7 @@
namespace wrappertest {
std::vector<int> Range(int count)
inline std::vector<int> Range(int count)
{
std::vector<int> v;
v.reserve(count);
@@ -40,7 +40,7 @@ struct A
virtual int f() { return 1; };
};
int call_foo(A* a){ return a->f(); }
inline int call_foo(A* a){ return a->f(); }
}
#endif

View File

@@ -19,10 +19,10 @@ list VectorToList(const std::vector<T> & v)
return res;
}
list RangeWrapper(int count){
inline list RangeWrapper(int count){
return VectorToList(wrappertest::Range(count));
}
int f_wrapper(wrappertest::A*) { return 10; }
inline int f_wrapper(wrappertest::A*) { return 10; }
#endif

View File

@@ -2,6 +2,7 @@ import exporters
from Exporter import Exporter
from declarations import *
from settings import *
from policies import *
from SingleCodeUnit import SingleCodeUnit
from EnumExporter import EnumExporter
from utils import makeid, enumerate
@@ -35,12 +36,14 @@ class ClassExporter(Exporter):
self.sections['scope'] = []
# declarations: outside the BOOST_PYTHON_MODULE macro
self.sections['declaration'] = []
self.sections['declaration-outside'] = []
self.sections['include'] = []
# a list of Constructor instances
self.constructors = []
self.wrapper_generator = None
# a list of code units, generated by nested declarations
self.nested_codeunits = []
self._exported_opaque_pointers = {}
def ScopeName(self):
@@ -96,6 +99,7 @@ class ClassExporter(Exporter):
self.ExportNestedClasses(exported_names)
self.ExportNestedEnums()
self.ExportSmartPointer()
self.ExportOpaquePointerPolicies()
self.Write(codeunit)
@@ -149,6 +153,9 @@ class ClassExporter(Exporter):
declarations += nested_unit.Section('declaration')
if declarations:
codeunit.Write('declaration', declarations + '\n')
declarations_outside = '\n'.join(self.sections['declaration-outside'])
if declarations_outside:
codeunit.Write('declaration-outside', declarations_outside + '\n')
# write the includes to the codeunit
includes = '\n'.join(self.sections['include'])
@@ -546,6 +553,19 @@ class ClassExporter(Exporter):
smart_ptr = self.info.smart_ptr
if smart_ptr:
self.Add('template', smart_ptr % self.class_.FullName())
def ExportOpaquePointerPolicies(self):
# check all methods for 'return_opaque_pointer' policies
methods = [x for x in self.public_members if isinstance(x, Method)]
for method in methods:
return_opaque_policy = return_value_policy(return_opaque_pointer)
if self.info[method.name].policy == return_opaque_policy:
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method.result.name
if macro not in self._exported_opaque_pointers:
self.Add('declaration-outside', macro)
self._exported_opaque_pointers[macro] = 1
#==============================================================================

View File

@@ -14,6 +14,7 @@ class FunctionExporter(Exporter):
def __init__(self, info, tail=None):
Exporter.__init__(self, info, tail)
self._exported_opaque_pointers = {}
def Export(self, codeunit, exported_names):
@@ -22,7 +23,8 @@ class FunctionExporter(Exporter):
self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
exporterutils.WarnForwardDeclarations(decl)
self.ExportDeclaration(decl, len(decls) == 1, codeunit)
self.GenerateOverloads(decls, codeunit)
self.ExportOpaquePointer(decl, codeunit)
self.GenerateOverloads(decls, codeunit)
def ExportDeclaration(self, decl, unique, codeunit):
@@ -75,6 +77,15 @@ class FunctionExporter(Exporter):
return ''
def ExportOpaquePointer(self, function, codeunit):
if self.info.policy == return_value_policy(return_opaque_pointer):
type = function.result.name
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % type
if macro not in self._exported_opaque_pointers:
codeunit.Write('declaration-outside', macro)
self._exported_opaque_pointers[macro] = 1
def Order(self):
return self.info.name

View File

@@ -65,7 +65,7 @@ class HeaderExporter(Exporter):
def Unit(self):
return self.info.include
return None # doesn't write anything by himself
def Order(self):

View File

@@ -34,7 +34,10 @@ class MultipleCodeUnit(object):
def SetCurrent(self, code_unit_name):
'Changes the current code unit'
try:
codeunit = self.codeunits[code_unit_name]
if code_unit_name is not None:
codeunit = self.codeunits[code_unit_name]
else:
codeunit = None
except KeyError:
filename = self._FileName(code_unit_name)
function_name = self._FunctionName(code_unit_name)
@@ -52,19 +55,14 @@ class MultipleCodeUnit(object):
current = property(Current, SetCurrent)
def _CheckCurrent(self):
if self.current is None:
raise RuntimeError, "No current code unit to write to!"
def Write(self, section, code):
self._CheckCurrent()
self.current.Write(section, code)
if self._current is not None:
self.current.Write(section, code)
def Section(self, section):
self._CheckCurrent()
return self.current.Section(section)
if self._current is not None:
return self.current.Section(section)
def _CreateOutputDir(self):

View File

@@ -22,8 +22,13 @@ class SingleCodeUnit:
self.filename = filename
# define the avaiable sections
self.code = {}
# include section
self.code['include'] = ''
# declaration section (inside namespace)
self.code['declaration'] = ''
# declaration (outside namespace)
self.code['declaration-outside'] = ''
# inside BOOST_PYTHON_MACRO
self.code['module'] = ''
# create the default module definition
self.module_definition = 'BOOST_PYTHON_MODULE(%s)' % modulename
@@ -37,7 +42,7 @@ class SingleCodeUnit:
def Merge(self, other):
for section in ('include', 'declaration', 'module'):
for section in ('include', 'declaration', 'declaration-outside', 'module'):
self.code[section] = self.code[section] + other.code[section]
@@ -60,21 +65,20 @@ class SingleCodeUnit:
fout.write(left_equals('Using'))
fout.write('using namespace boost::python;\n\n')
# declarations
if self.code['declaration']:
pyste_namespace = namespaces.pyste[:-2]
declaration = self.code['declaration']
declaration_outside = self.code['declaration-outside']
if declaration_outside or declaration:
fout.write(left_equals('Declarations'))
fout.write('namespace %s {\n\n\n' % pyste_namespace)
fout.write(self.code['declaration'])
fout.write('\n\n}// namespace %s\n' % pyste_namespace)
fout.write(space)
fout.write(declaration_outside + '\n\n')
if declaration:
pyste_namespace = namespaces.pyste[:-2]
fout.write('namespace %s {\n\n\n' % pyste_namespace)
fout.write(declaration)
fout.write('\n\n}// namespace %s\n' % pyste_namespace)
fout.write(space)
# module
fout.write(left_equals('Module'))
fout.write(self.module_definition + '\n')
fout.write('{\n')
fout.write(self.code['module'])
fout.write('}\n')
def _leftEquals(self, s):
s = '// %s ' % s
return s + ('='*(80-len(s))) + '\n'

View File

@@ -19,6 +19,13 @@ class Policy:
return ' >'
def __eq__(self, other):
try:
return self.Code() == other.Code()
except AttributeError:
return False
class return_internal_reference(Policy):
'Ties the return value to one of the parameters.'

View File

@@ -14,7 +14,7 @@ where options are:
--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 "pyste"
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
@@ -34,7 +34,7 @@ from policies import *
from CppParser import CppParser, CppParserError
import time
__VERSION__ = '0.7.1'
__VERSION__ = '0.7.2'
def RecursiveIncludes(include):
'Return a list containg the include dir and all its subdirectories'

View File

@@ -1,4 +1,8 @@
*.pyc
*.exp
*.lib
*.obj
*.arg
*.dll
*.cpp
.sconsign

View File

@@ -47,8 +47,13 @@ env = Environment(
modules = [os.path.splitext(os.path.basename(x))[0] for x in glob.glob('../example/*.pyste')]
for module in modules:
multiple = ARGUMENTS.get('multiple', '')
if multiple:
env.SharedLibrary(target=module, source=glob.glob(module+'/*.cpp'))
example_cpp = '../example/%s.cpp' % module
if os.path.isfile(example_cpp):
sources = [example_cpp]
else:
env.SharedLibrary(target=module, source=module + '.cpp')
sources = []
if multiple:
env.SharedLibrary(target=module, source=sources + glob.glob('_%s/*.cpp'%module))
else:
env.SharedLibrary(target=module, source=sources + ['_%s.cpp' % module])

View File

@@ -0,0 +1,18 @@
import unittest
from opaque import *
class OpaqueTest(unittest.TestCase):
def testIt(self):
c = new_C()
self.assertEqual(get(c), 10)
a = A()
d = a.new_handle()
self.assertEqual(a.get(d), 3.0)
self.assertEqual(a.f(), 0)
self.assertEqual(a.f(3), 3)
if __name__ == '__main__':
unittest.main()

View File

@@ -11,3 +11,4 @@ call nt_build_pyste.bat unions %1
call nt_build_pyste.bat virtual %1
call nt_build_pyste.bat virtual2 %1
call nt_build_pyste.bat wrappertest %1
call nt_build_pyste.bat opaque %1

View File

@@ -1,7 +1,7 @@
@echo off
set BOOST_INCLUDE=D:\Programming\Libraries\boost-cvs\boost
set out=%1.cpp
if "%2" == "--multiple" set out=%1
set out=_%1.cpp
if "%2" == "--multiple" set out=_%1
rem python ../src/pyste.py %2 -I%BOOST_INCLUDE -I../example --module=%1 --out=%out ../example/%1.pyste
pyste %2 -I%BOOST_INCLUDE -I../example --module=%1 --out=%out ../example/%1.pyste

View File

@@ -1,16 +1,17 @@
@echo off
rm -Rf basic
rm -Rf enums
rm -Rf header_test
rm -Rf nested
rm -Rf operators
rm -Rf smart_ptr
rm -Rf templates
rm -Rf unions
rm -Rf virtual
rm -Rf virtual2
rm -Rf wrappertest
rm -Rf _basic
rm -Rf _enums
rm -Rf _header_test
rm -Rf _nested
rm -Rf _operators
rm -Rf _smart_ptr
rm -Rf _templates
rm -Rf _unions
rm -Rf _virtual
rm -Rf _virtual2
rm -Rf _wrappertest
rm -Rf _opaque
rm -f *.cpp
rm -f *.obj
@@ -19,3 +20,4 @@ rm -f *.arg
rm -f *.dll
rm -f *.pyc
rm -f *.lib
rm -f ../example/*.obj