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

Compare commits

...

40 Commits

Author SHA1 Message Date
nobody
9529ad16e9 This commit was manufactured by cvs2svn to create tag
'Version_1_30_0'.

[SVN r18026]
2003-03-20 02:53:48 +00:00
Dave Abrahams
955f716108 fix typo
[SVN r18025]
2003-03-20 02:53:47 +00:00
Ralf W. Grosse-Kunstleve
9178b9e6cc pyconfig.h included first only under Tru64/cxx
[SVN r18022]
2003-03-20 00:27:16 +00:00
Ralf W. Grosse-Kunstleve
6f0b083a51 restore Codewarrior builds
[SVN r17998]
2003-03-19 07:04:07 +00:00
Bruno da Silva de Oliveira
574e6b9e2c - Updated to reflect changes in declarations.py
[SVN r17997]
2003-03-19 05:55:28 +00:00
nobody
5bfc1e080d This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17996]
2003-03-19 05:54:27 +00:00
Bruno da Silva de Oliveira
d475fcaf7d - Fixed bug where the PointerDeclaration of functions and methods didn't have the & operator
[SVN r17994]
2003-03-19 05:03:49 +00:00
Bruno da Silva de Oliveira
85f324efb6 - Unit tests for the examples
[SVN r17992]
2003-03-19 03:08:53 +00:00
Bruno da Silva de Oliveira
08254b1fe7 - Fixed bug where an union that was a class member crashed pyste (unions are still not exported)
- Added support for int, double, float and long operators


[SVN r17991]
2003-03-19 02:57:31 +00:00
Bruno da Silva de Oliveira
d4b1b46e63 - Unit tests for the examples
[SVN r17990]
2003-03-19 02:55:30 +00:00
nobody
08f07b0cc6 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17988]
2003-03-19 02:47:30 +00:00
Ralf W. Grosse-Kunstleve
2d0e0759c7 special code only for gcc <= 2.96
[SVN r17986]
2003-03-19 02:40:15 +00:00
Ralf W. Grosse-Kunstleve
130de54f23 fix for Visual C++ >= 7.1 as per David Abrahams
[SVN r17978]
2003-03-18 22:31:12 +00:00
Ralf W. Grosse-Kunstleve
3068b4ae13 gcc 2.96 compatibility
[SVN r17977]
2003-03-18 20:57:46 +00:00
Dave Abrahams
5867b87b60 Add funcptr FAQ
[SVN r17974]
2003-03-18 14:40:09 +00:00
Bruno da Silva de Oliveira
87953ae423 - Fixed bugs in Linux
[SVN r17969]
2003-03-18 05:16:01 +00:00
Bruno da Silva de Oliveira
eb252c0395 - Fixed bug where the permission bits were being copied to the tmp file
[SVN r17934]
2003-03-15 02:51:51 +00:00
nobody
2c0ec733ca This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17932]
2003-03-14 23:39:05 +00:00
Bruno da Silva de Oliveira
13df532aca - Fixed definition of private default implementations
[SVN r17930]
2003-03-14 23:36:44 +00:00
Bruno da Silva de Oliveira
c8747f6893 - Now generating wrappers for protected and private virtual methods
[SVN r17927]
2003-03-14 21:43:33 +00:00
nobody
69b9094dfc This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17902]
2003-03-14 02:49:25 +00:00
Bruno da Silva de Oliveira
5788cc83f3 no message
[SVN r17874]
2003-03-13 00:58:17 +00:00
Ralf W. Grosse-Kunstleve
0262c3bba9 adjustment for MIPSpro
[SVN r17864]
2003-03-12 22:59:46 +00:00
nobody
d6dd4e48e2 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17843]
2003-03-12 13:51:19 +00:00
Dave Abrahams
b58503707f opaque pointer conversions from Gottfried.Ganssauge@haufe.de
Acknowledgements for all


[SVN r17839]
2003-03-12 13:38:18 +00:00
nobody
8c1a826ce8 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17837]
2003-03-12 13:29:13 +00:00
Bruno da Silva de Oliveira
cc76f068ee - first RC version
[SVN r17827]
2003-03-12 03:40:44 +00:00
nobody
4efab432ab This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17826]
2003-03-12 01:39:29 +00:00
Ralf W. Grosse-Kunstleve
13b1f434ad pyconfig.h must be included before any system header (as per Python docs; essential for Python 2.3 under Tru64 Unix)
[SVN r17799]
2003-03-10 17:25:52 +00:00
Ralf W. Grosse-Kunstleve
c29241d859 non-template function make_function1 must be inline
[SVN r17791]
2003-03-09 17:26:06 +00:00
Dave Abrahams
fbe3d080e8 Fix for older EDGs
[SVN r17786]
2003-03-08 12:36:18 +00:00
Dave Abrahams
be96a3c4d6 Remove flotsam
[SVN r17783]
2003-03-08 08:53:19 +00:00
Dave Abrahams
70a967bac5 Remove flotsam
[SVN r17782]
2003-03-08 08:51:45 +00:00
Ralf W. Grosse-Kunstleve
a7ce37effa missing raw_function.hpp added; struct is_reference_to_class definition moved up
[SVN r17781]
2003-03-08 08:44:38 +00:00
Dave Abrahams
87c92775c9 Fix for Python 2.3 long->int conversion behavior change
[SVN r17779]
2003-03-08 05:28:54 +00:00
nobody
a15f7d5bf3 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17778]
2003-03-08 03:53:20 +00:00
Dave Abrahams
a870ce20fc Added dangling_reference FAQ
Various idiomatic MPL cleanups in indirect_traits.hpp
raw_function support
Patches for CWPro7.2
Patches to pass tests under Python 2.3 with the new bool type.
Tests for member operators returning const objects
Fixes for testing Boost.Python under Cygwin


[SVN r17777]
2003-03-08 03:53:19 +00:00
Ralf W. Grosse-Kunstleve
e042228f45 MIPSpro compatibility
[SVN r17776]
2003-03-08 01:47:40 +00:00
Dave Abrahams
7c4cfe0589 Workaround for vc7 bug
[SVN r17709]
2003-03-03 17:24:07 +00:00
nobody
e24497a6cd This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17693]
2003-03-01 19:43:06 +00:00
72 changed files with 2449 additions and 281 deletions

1117
doc/PyConDC_2003/bpl.html Executable file

File diff suppressed because it is too large Load Diff

BIN
doc/PyConDC_2003/bpl.pdf Executable file

Binary file not shown.

View File

@@ -9,12 +9,10 @@
:Author: Ralf W. Grosse-Kunstleve
:status: Draft
:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
.. contents:: Table of Contents
.. _`Boost Consulting`: http://www.boost-consulting.com
==========
@@ -631,19 +629,22 @@ virtual functions. At least one very promising project has been
started to write a front-end which can generate these dispatchers (and
other wrapping code) automatically from C++ headers.
Pyste builds on GCC_XML_, which generates an XML version of GCC's
internal program representation. Since GCC is a highly-conformant C++
compiler, this ensures correct handling of the most-sophisticated
template code and full access to the underlying type system. In
keeping with the Boost.Python philosophy, a Pyste interface
description is neither intrusive on the code being wrapped, nor
expressed in some unfamiliar language: instead it is a 100% pure
Python script. If Pyste is successful it will mark a move away from
wrapping everything directly in C++ for many of our users. We expect
that soon, not only our users but the Boost.Python developers
themselves will be "thinking hybrid" about their own code.
Pyste_ is being developed by Bruno da Silva de Oliveira. It builds on
GCC_XML_, which generates an XML version of GCC's internal program
representation. Since GCC is a highly-conformant C++ compiler, this
ensures correct handling of the most-sophisticated template code and
full access to the underlying type system. In keeping with the
Boost.Python philosophy, a Pyste interface description is neither
intrusive on the code being wrapped, nor expressed in some unfamiliar
language: instead it is a 100% pure Python script. If Pyste is
successful it will mark a move away from wrapping everything directly
in C++ for many of our users. It will also allow us the choice to
shift some of the metaprogram code from C++ to Python. We expect that
soon, not only our users but the Boost.Python developers themselves
will be "thinking hybrid" about their own code.
.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
.. _`Pyste`: http://www.boost.org/libs/python/pyste
---------------
Serialization
@@ -770,15 +771,6 @@ This almost looks and works like regular Python code, but it is pure
C++. Of course we can wrap C++ functions which accept or return
``object`` instances.
.. =====================
Development history
=====================
XXX Outline of development history to illustrate that the
library is mature. XXX
This can be postponed for the PyConDC paper
=================
Thinking hybrid
=================
@@ -816,7 +808,7 @@ mainly concentrated on the C++ parts. However, as the toolbox is
becoming more complete, more and more newly added functionality can be
implemented in Python.
.. image:: python_cpp_mix.png
.. image:: python_cpp_mix.jpg
This figure shows the estimated ratio of newly added C++ and Python
code over time as new algorithms are implemented. We expect this
@@ -826,6 +818,87 @@ language is the return on our investment in Boost.Python. The ability
to access all of our code from Python allows a broader group of
developers to use it in the rapid development of new applications.
=====================
Development history
=====================
The first version of Boost.Python was developed in 2000 by Dave
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
as a guide to "The Zen of Python". One of Dave's jobs was to develop
a Python-based natural language processing system. Since it was
eventually going to be targeting embedded hardware, it was always
assumed that the compute-intensive core would be rewritten in C++ to
optimize speed and memory footprint [#1]_. The project also wanted to
test all of its C++ code using Python test scripts [#2]_. The only
tool we knew of for binding C++ and Python was SWIG_, and at the time
its handling of C++ was weak. It would be false to claim any deep
insight into the possible advantages of Boost.Python's approach at
this point. Dave's interest and expertise in fancy C++ template
tricks had just reached the point where he could do some real damage,
and Boost.Python emerged as it did because it filled a need and
because it seemed like a cool thing to try.
This early version was aimed at many of the same basic goals we've
described in this paper, differing most-noticeably by having a
slightly more cumbersome syntax and by lack of special support for
operator overloading, pickling, and component-based development.
These last three features were quickly added by Ullrich Koethe and
Ralf Grosse-Kunstleve [#3]_, and other enthusiastic contributors arrived
on the scene to contribute enhancements like support for nested
modules and static member functions.
By early 2001 development had stabilized and few new features were
being added, however a disturbing new fact came to light: Ralf had
begun testing Boost.Python on pre-release versions of a compiler using
the EDG_ front-end, and the mechanism at the core of Boost.Python
responsible for handling conversions between Python and C++ types was
failing to compile. As it turned out, we had been exploiting a very
common bug in the implementation of all the C++ compilers we had
tested. We knew that as C++ compilers rapidly became more
standards-compliant, the library would begin failing on more
platforms. Unfortunately, because the mechanism was so central to the
functioning of the library, fixing the problem looked very difficult.
Fortunately, later that year Lawrence Berkeley and later Lawrence
Livermore National labs contracted with `Boost Consulting`_ for support
and development of Boost.Python, and there was a new opportunity to
address fundamental issues and ensure a future for the library. A
redesign effort began with the low level type conversion architecture,
building in standards-compliance and support for component-based
development (in contrast to version 1 where conversions had to be
explicitly imported and exported across module boundaries). A new
analysis of the relationship between the Python and C++ objects was
done, resulting in more intuitive handling for C++ lvalues and
rvalues.
The emergence of a powerful new type system in Python 2.2 made the
choice of whether to maintain compatibility with Python 1.5.2 easy:
the opportunity to throw away a great deal of elaborate code for
emulating classic Python classes alone was too good to pass up. In
addition, Python iterators and descriptors provided crucial and
elegant tools for representing similar C++ constructs. The
development of the generalized ``object`` interface allowed us to
further shield C++ programmers from the dangers and syntactic burdens
of the Python 'C' API. A great number of other features including C++
exception translation, improved support for overloaded functions, and
most significantly, CallPolicies for handling pointers and
references, were added during this period.
In October 2002, version 2 of Boost.Python was released. Development
since then has concentrated on improved support for C++ runtime
polymorphism and smart pointers. Peter Dimov's ingenious
``boost::shared_ptr`` design in particular has allowed us to give the
hybrid developer a consistent interface for moving objects back and
forth across the language barrier without loss of information. At
first, we were concerned that the sophistication and complexity of the
Boost.Python v2 implementation might discourage contributors, but the
emergence of Pyste_ and several other significant feature
contributions have laid those fears to rest. Daily questions on the
Python C++-sig and a backlog of desired improvements show that the
library is getting used. To us, the future looks bright.
.. _`EDG`: http://www.edg.com
=============
Conclusions
=============
@@ -844,10 +917,21 @@ like serialization that are trivial in Python can be very difficult in
pure C++. Given the luxury of building a hybrid software system from
the ground up, we can approach design with new confidence and power.
===========
Citations
===========
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
Vol. 7 No. 5 June 1995, pp. 26-31.
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
.. [#1] In retrospect, it seems that "thinking hybrid" from the ground up
might have been better for the NLP system: the natural component
boundaries defined by the pure python prototype turned out to be
inappropriate for getting the desired performance and memory footprint
out of the C++ core, which eventually caused some redesign overhead on
the Python side when the core was moved to C++.
.. [#2] We also have some reservations about driving all C++ testing through a
Python interface, unless that's the only way it will be ultimately
used. Any transition across language boundaries with such different
object models can inevitably mask bugs.
.. [#3] These features were expressed very differently in v1 of
Boost.Python

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -357,7 +357,7 @@ bjam -sTOOLS=<i><a href=
(i.e. <code>c:/Python/Libs</code>. Make sure it is <code>Libs</code> with
an "<code>s</code>" and not just <code>Lib</code>).</p>
<h3>Using the IDE for you own projects</h3>
<h3>Using the IDE for your own projects</h3>
<p>Building your own projects using the IDE is slightly more complicated.
Firstly, you need to make sure that the project you create as the right

View File

@@ -31,6 +31,15 @@
<p><a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> is
the architect, designer, and implementor of <b>Boost.Python</b>.</p>
<p><a href="mailto:brett.calcott@paradise.net.nz">Brett Calcott</a>
contributed and maintains the Visual Studio project files and
documentation.</p>
<p><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Ganßauge</a> supplied support for opaque pointer conversions,
complete with documentation and a regression test (and I didn't
even have to ask him for those)!
<p>Joel de Guzman implemented the <a href="overloads.html">default
argument support</a> and wrote the excellent <a href=
"../tutorial/index.html">tutorial documentation</a>.</p>
@@ -63,6 +72,17 @@
use the new preproccessor metaprogramming constructs and helping us to
work around buggy and slow C++ preprocessors.</p>
<p><a href="nicodemus-at-globalite.com.br">Bruno da Silva de
Oliveira</a> contributed the ingenious <a
href="../../pyste/index.html">Pyste</a> (&quot;Pie-Steh&quot;)
code generator.
<p><a href="mailto:nickm@sitius.com">Nikolay Mladenov</a> contributed
<code>staticmethod</code> support.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p><a href="mailto:achim@procoders.net">Achim Domma</a> contributed some
of the <a href="reference.html#object_wrappers">Object Wrappers</a> and
HTML templates for this documentation. Dave Hawkes contributed
@@ -71,16 +91,6 @@
definition syntax. Pearu Pearson wrote some of the test cases that are in
the current test suite.</p>
<p><a href="mailto:brett.calcott@paradise.net.nz">Brett Calcott</a>
contributed and maintains the Visual Studio project files and
documentation.</p>
<p><a href="mailto:nickm@sitius.com">Nikolay Mladenov</a> contributed
<code>staticmethod</code> support.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p>The development of this version of Boost.Python was funded in part by
the <a href="http://www.llnl.gov/">Lawrence Livermore National
Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational

View File

@@ -29,6 +29,10 @@
<hr>
<dl class="page-index">
<dt><a href="#funcptr">How can I wrap a function which takes a
function pointer as an argument?</a><dd>
<dt><a href="#dangling">I'm getting the "attempt to return dangling
reference" error. What am I doing wrong?</a></dt>
@@ -56,6 +60,57 @@
</dl>
<hr>
<h2><a name="funcptr">How can I wrap a function which takes a
function pointer as an argument?</a></h2>
If what you're trying to do is something like this:
<pre>
typedef boost::function&lt;void (string s) &gt; funcptr;
void foo(funcptr fp)
{
fp(&quot;hello,world!&quot;);
}
BOOST_PYTHON_MODULE(test)
{
def(&quot;foo&quot;,foo) ;
}
</pre>
And then:
<pre>
&gt;&gt;&gt; def hello(s):
... print s
...
&gt;&gt;&gt; foo(hello)
hello, world!
</pre>
The short answer is: &quot;you can't&quot;. This is not a
Boost.Python limitation so much as a limitation of C++. The
problem is that a Python function is actually data, and the only
way of associating data with a C++ function pointer is to store it
in a static variable of the function. The problem with that is
that you can only associate one piece of data with every C++
function, and we have no way of compiling a new C++ function
on-the-fly for every Python function you decide to pass
to <code>foo</code>. In other words, this could work if the C++
function is always going to invoke the <em>same</em> Python
function, but you probably don't want that.
<p>If you have the luxury of changing the C++ code you're
wrapping, pass it an <code>object</code> instead and call that;
the overloaded function call operator will invoke the Python
function you pass it behind the <code>object</code>.
<p>For more perspective on the issue, see <a
href="http://aspn.activestate.com/ASPN/Mail/Message/1554837">this
posting</a>.
<hr>
<h2><a name="dangling">I'm getting the "attempt to return dangling
reference" error. What am I doing wrong?</a></h2>
That exception is protecting you from causing a nasty crash. It usually
@@ -492,7 +547,7 @@ void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
23 January, 2003
18 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -0,0 +1,142 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/opaque_pointer_converter.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/opaque_pointer_converter.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque_pointer_converter-spec">Class template
<code>opaque_pointer_converter&lt;P&gt;</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque_pointer_converter-spec-synopsis">Class template
<code>opaque_pointer_converter</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#macros">Macros</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">Macro
<code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
<dt><a href="#see-also">See Also</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="opaque_pointer_converter-spec"></a>Class template
<code>opaque_pointer_converter&lt;P&gt;</code></h3>
<p><code>opaque_pointer_converter&lt;&gt;</code> is derived from
<a href="to_python_converter.html#to_python_converter-spec">
<code>to_python_converter</code></a>
and registers itself as an
<a href="lvalue_from_pytype.html#lvalue_from_pytype-spec">
<code>lvalue_from_pytype</code></a> converter from Python objects
into pointers to undefined types.
Thus it may be used as a converter from opaque pointers into
Python objects and vice versa.</p>
<h4><a name="opaque_pointer_converter-spec-synopsis"></a>Class template
<code>opaque_pointer_converter</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template&lt;class Pointer&gt;
struct opaque_pointer_converter
: to_python_converter&lt;
Pointer, opaque_pointer_converter&lt;Pointer&gt; &gt;
{
explicit opaque_pointer_converter(char const* name);
};
}}
</pre>
<h4><a name="opaque_pointer_converter-spec-constructor"></a>Class template
<code>opaque_pointer_converter</code> constructor</h4>
<pre>
explicit opaque_pointer_converter(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<p>Registers the instance as a
<a href="lvalue_from_pytype.html#lvalue_from_pytype-spec">
<code>lvalue_from_pytype</code></a> converter from Python objects
into opaque pointers.</p>
<p>The name is used for the type of the Python Objects created;
it should be printable but needn't be an
<a href="definitions.html#ntbs">ntbs</a> because the object type is
not supposed to be user constructible within python scripts.</p>
</dt>
</dl>
<h2><a name="macros"></a>Macros</h2>
<h3><a name="BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec"></a>
Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)</h3>
<p>This macro must be used to define specializations of the
<a href="type_id.html#type_id-spec">type_id</a> function
which can't be instantiated for incomplete types.</p>
<h4>Note</h4>
<p>In order for this to work in a cross-module environment the macro must
be invoked in every translation unit which uses the
opaque_pointer_converter.</p>
<h2><a name="examples"></a>Example</h2>
please see example for <a href="return_opaque_pointer.html#example">
return_opaque_pointer</a>.
<h2><a name="see-also"></a>See Also</h2>
<p>
<a href="return_opaque_pointer.html">return_opaque_pointer</a>
</p>
<p>Revised
10 March, 2003
</p>
<p><i>&copy; Copyright 2003 Haufe Mediengruppe. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,116 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/raw_function.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/raw_function.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#raw_function-spec">raw_function</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code><a href="#raw_function-spec">raw_function</a>(...)</code>
is used to convert a function taking a <a
href="tuple.html#tuple-spec">tuple</a> and a <a
href="dict.html#dict-spec">dict</a> into a Python callable object
which accepts a variable number of arguments and arbitrary keyword
arguments.
<h2><a name="functions"></a>Functions</h2>
<a name="raw_function-spec"></a>raw_function
<pre>
template &lt;class F&gt;
object raw_function(F f, std::size_t min_args = 0);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>f(tuple(), dict())</code> is
well-formed.</dt>
<dt><b>Returns:</b> a <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a> object which requires at least <code>min_args</code> arguments. When called, the actual non-keyword arguments will be passed in a <a
href="tuple.html#tuple-spec">tuple</a> as the first argument to <code>f</code>, and the keyword arguments will be passed in a <a
href="dict.html#dict-spec">dict</a> as the second argument to <code>f</code>.
</dd>
</dl>
<h2><a name="examples"></a>Example</h2>
C++:
<pre>
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/tuple.hpp&gt;
#include &lt;boost/python/dict.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/raw_function.hpp&gt;
using namespace boost::python;
tuple raw(tuple args, dict kw)
{
return make_tuple(args, kw);
}
BOOST_PYTHON_MODULE(raw_test)
{
def("raw", raw_function(raw));
}
</pre>
Python:
<pre>
&gt;&gt;&gt; from raw_test import *
&gt;&gt;&gt; raw(3, 4, foo = 'bar', baz = 42)
((3, 4), {'foo': 'bar', 'baz': 42})
</pre>
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
7 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -749,6 +749,22 @@
</dd>
</dl>
</dd>
<dt><a href="return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="return_opaque_pointer.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="return_opaque_pointer.html#return_opaque_pointer-spec">
return_opaque_pointer</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
@@ -806,6 +822,29 @@
</dl>
</dd>
<dt><a href="opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="opaque_pointer_converter.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="opaque_pointer_converter.html#opaque_pointer_converter-spec">
opaque_pointer_converter</a></dt>
</dl>
</dd>
<dt><a href="opaque_pointer_converter.html#macros">Macros</a></dt>
<dd>
<dl class="index">
<dt><a href="opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="to_python_converter.html">to_python_converter.hpp</a></dt>
<dd>

View File

@@ -0,0 +1,189 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/return_opaque_pointer.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/return_opaque_pointer.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#return_opaque_pointer-spec">Class
<code>return_opaque_pointer</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#return_opaque_pointer-spec-synopsis">Class
<code>return_opaque_pointer</code> synopsis</a></dt>
<dt><a href="#return_opaque_pointer-spec-metafunctions">Class
<code>return_opaque_pointer</code> metafunctions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
<dt><a href="#see-also">See Also</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="return_opaque_pointer-spec"></a>Class
<code>return_opaque_pointer</code></h3>
<p><code>return_opaque_pointer</code> is a model of
<a href="ResultConverter.html#ResultConverterGenerator-concept">
ResultConverterGenerator</a>
which can be used to wrap C++ functions returning pointers to
undefined types such that the return value is copied into a
new Python object.</p>
<p>In addition to specifying the <code>return_opaque_pointer</code>
policy the <a href="opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
<code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a> macro must be
used to define specializations for the
<a href="type_id.html#type_id-spec">type_id</a> function
on the type pointed to by returned pointer.</p>
<h4><a name="return_opaque_pointer-spec-synopsis"></a>Class
<code>return_opaque_pointer</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct return_opaque_pointer
{
template &lt;class R&gt; struct apply;
};
}}
</pre>
<h4><a name="return_opaque_pointer-spec-metafunctions"></a>Class
<code>return_opaque_pointer</code> metafunctions</h4>
<pre>
template &lt;class R&gt; struct apply
</pre>
<dl class="metafunction-semantics">
<dt><b>Returns:</b> <code>typedef
detail::opaque_conversion_holder&lt;R&gt;
type;</code></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<h3>C++ Module Definition</h3>
<pre>
# include &lt;boost/python/return_opaque_pointer.hpp&gt;
# include &lt;boost/python/def.hpp&gt;
# include &lt;boost/python/module.hpp&gt;
# include &lt;boost/python/return_value_policy.hpp&gt;
typedef struct opaque_ *opaque;
opaque the_op = ((opaque) 0x47110815);
opaque get () { return the_op; }
void use (opaque op) {
if (op != the_op)
throw std::runtime_error (std::string ("failed"));
}
void failuse (opaque op) {
if (op == the_op)
throw std::runtime_error (std::string ("success"));
}
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
namespace bpl = boost::python;
BOOST_PYTHON_MODULE(opaque_ext)
{
bpl::def (
"get", &::get, bpl::return_value_policy&lt;bpl::return_opaque_pointer&gt;());
bpl::def ("use", &::use);
bpl::def ("failuse", &::failuse);
}
</pre>
<h3>Python Code</h3>
<pre>
"""
>>> from opaque_ext import *
>>> #
>>> # Check for correct conversion
>>> use(get())
>>> failuse(get())
Traceback (most recent call last):
...
RuntimeError: success
>>> #
>>> # Check that there is no conversion from integers ...
>>> use(0)
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> #
>>> # ... and from strings to opaque objects
>>> use("")
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])
</pre>
<h2><a name="see-also"></a>See Also</h2>
<p>
<a href="opaque_pointer_converter.html">
opaque_pointer_converter</a>
</p>
<p>Revised
28 January, 2003
</p>
<p><i>&copy; Copyright 2003 Haufe Mediengruppe. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -44,12 +44,14 @@
# include <boost/python/object_protocol.hpp>
# include <boost/python/object_protocol_core.hpp>
# include <boost/python/operators.hpp>
# include <boost/python/opaque_pointer_converter.hpp>
# include <boost/python/other.hpp>
# include <boost/python/overloads.hpp>
# include <boost/python/pointee.hpp>
# include <boost/python/ptr.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/scope.hpp>
# include <boost/python/self.hpp>

View File

@@ -12,6 +12,9 @@
#ifndef CONFIG_DWA052200_H_
# define CONFIG_DWA052200_H_
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
# include <boost/config.hpp>
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE

View File

@@ -0,0 +1,18 @@
// Copyright Gottfried Ganßauge 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef BOOST_PYTHON_DETAIL_DEALLOC_HPP_
# define BOOST_PYTHON_DETAIL_DEALLOC_HPP_
namespace boost { namespace python { namespace detail {
extern "C"
{
inline void dealloc(PyObject* self)
{
PyObject_Del(self);
}
}
}}} // namespace boost::python::detail
# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_

View File

@@ -1,18 +0,0 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef IS_SHARED_PTR_DWA2003224_HPP
# define IS_SHARED_PTR_DWA2003224_HPP
# include <boost/python/detail/is_xxx.hpp>
# include <boost/shared_ptr.hpp>
namespace boost { namespace python { namespace detail {
BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1)
}}} // namespace boost::python::detail
#endif // IS_SHARED_PTR_DWA2003224_HPP

View File

@@ -24,6 +24,9 @@
// Python's LongObject.h helpfully #defines ULONGLONG_MAX for us,
// which confuses Boost's config
//
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
#include <limits.h>
#ifndef ULONG_MAX
# define BOOST_PYTHON_ULONG_MAX_UNDEFINED

View File

@@ -6,6 +6,11 @@
#ifndef HAS_BACK_REFERENCE_DWA2002323_HPP
# define HAS_BACK_REFERENCE_DWA2002323_HPP
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
#include <boost/config.hpp>
namespace boost { namespace python {
// traits class which users can specialize to indicate that a class

View File

@@ -6,6 +6,9 @@
#ifndef OBJECT_CORE_DWA2002615_HPP
# define OBJECT_CORE_DWA2002615_HPP
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
# include <boost/type.hpp>
# include <boost/python/call.hpp>

View File

@@ -0,0 +1,145 @@
// Copyright Gottfried Ganßauge 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
/*
* Generic Conversion of opaque C++-pointers to a Python-Wrapper.
*/
# ifndef OPAQUE_POINTER_CONVERTER_HPP_
# define OPAQUE_POINTER_CONVERTER_HPP_
# include <boost/python/lvalue_from_pytype.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/python/detail/dealloc.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/type_traits/remove_pointer.hpp>
// opaque_pointer_converter --
//
// usage: opaque_pointer_converter<Pointer>("name")
//
// registers to- and from- python conversions for a type Pointer,
// and a corresponding Python type called "name".
//
// Note:
// In addition you need to define specializations for type_id
// on the type pointed to by Pointer using
// BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)
//
// For an example see libs/python/test/opaque.cpp
//
namespace boost { namespace python {
namespace detail {
template <class R>
struct opaque_pointer_converter_requires_a_pointer_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class Pointer>
struct opaque_pointer_converter
: to_python_converter<
Pointer, opaque_pointer_converter<Pointer> >
{
BOOST_STATIC_CONSTANT(
bool, ok = is_pointer<Pointer>::value);
typedef typename mpl::if_c<
ok
, Pointer
, detail::opaque_pointer_converter_requires_a_pointer_type<Pointer>
>::type ptr_type;
private:
struct instance;
public:
explicit opaque_pointer_converter(char const* name)
{
type_object.tp_name = const_cast<char *> (name);
lvalue_from_pytype<
opaque_pointer_converter<ptr_type>,
&opaque_pointer_converter<ptr_type>::type_object
>();
}
static PyObject* convert(ptr_type x)
{
PyObject *result = 0;
if (x != 0) {
instance *o = PyObject_New (instance, &type_object);
if (o != 0) {
o->x = x;
result = &o->base_;
}
} else {
result = detail::none();
}
return (result);
}
static typename ::boost::remove_pointer<ptr_type>::type&
execute(instance &p_)
{
return *p_.x;
}
private:
static PyTypeObject type_object;
// This is a POD so we can use PyObject_Del on it, for example.
struct instance
{
PyObject base_;
ptr_type x;
};
};
template <class Pointer>
PyTypeObject opaque_pointer_converter<Pointer>::type_object =
{
PyObject_HEAD_INIT(NULL)
0,
0,
sizeof(typename opaque_pointer_converter<Pointer>::instance),
0,
::boost::python::detail::dealloc
};
}} // namespace boost::python
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// MSC works without this workaround, but needs another one ...
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(Pointee)
# elif BOOST_WORKAROUND(__GNUC__, < 3)
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
namespace boost { namespace python { \
template<> \
inline type_info type_id<Pointee>() { \
return type_info (typeid (Pointee *)); \
} \
template<> \
inline type_info type_id<const volatile Pointee &>() { \
return type_info (typeid (Pointee *)); \
} \
}}
# else
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
namespace boost { namespace python { \
template<> \
inline type_info type_id(boost::type<Pointee>*) { \
return type_info (typeid (Pointee *)); \
} \
template<> \
inline type_info type_id( \
boost::type<const volatile Pointee &>*) { \
return type_info (typeid (Pointee *)); \
} \
}}
# endif
# endif // OPAQUE_POINTER_CONVERTER_HPP_

View File

@@ -14,6 +14,9 @@
# pragma once
# endif
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
# include <boost/config.hpp>
# include <boost/mpl/bool.hpp>

View File

@@ -0,0 +1,51 @@
// Copyright Gottfried Ganßauge 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
/*
* Generic Return value converter generator for opaque C++-pointers
*/
# ifndef RETURN_OPAQUE_POINTER_HPP_
# define RETURN_OPAQUE_POINTER_HPP_
# include <boost/python/opaque_pointer_converter.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/if.hpp>
namespace boost { namespace python {
namespace detail {
template <class Pointer>
struct opaque_conversion_holder {
inline PyObject *operator () (Pointer p) {
static opaque_pointer_converter<Pointer> converter (
typeid (Pointer).name());
return converter.convert(p);
}
};
template <class R>
struct return_opaque_pointer_requires_a_pointer_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
struct return_opaque_pointer
{
template <class R>
struct apply
{
BOOST_STATIC_CONSTANT(
bool, ok = is_pointer<R>::value);
typedef typename mpl::if_c<
ok
, detail::opaque_conversion_holder<R>
, detail::return_opaque_pointer_requires_a_pointer_type<R>
>::type type;
};
};
}} // namespace boost::python
# endif // RETURN_OPAQUE_POINTER_HPP_

View File

@@ -1,4 +1,4 @@
To use this examples, just execute in the command-line:
To use this examples, just execute the command-line:
pyste --module=<example> <example>.pyste

View File

@@ -1,3 +1,5 @@
namespace basic {
struct C
{
virtual int f(int x = 10)
@@ -19,3 +21,5 @@ int call_f(C& c, int x)
{
return c.f(x);
}
}

View File

@@ -1,2 +1,2 @@
Class('C', 'basic.h')
Function('call_f', 'basic.h')
Class('basic::C', 'basic.h')
Function('basic::call_f', 'basic.h')

View File

@@ -1,4 +1,5 @@
namespace test {
namespace enums {
enum color { red, blue };
struct X

View File

@@ -1,7 +1,7 @@
color = Enum('test::color', 'enums.h')
color = Enum('enums::color', 'enums.h')
rename(color.red, 'Red')
rename(color.blue, 'Blue')
X = Class('test::X', 'enums.h')
X = Class('enums::X', 'enums.h')
rename(X.choices.bad, 'Bad')
rename(X.choices.good, 'Good')
rename(X.choices, 'Choices')

View File

@@ -1,23 +1,26 @@
#include <iostream>
#include <map>
#include <string>
namespace header_test {
enum choice { red, blue };
void print_choice(choice c)
std::string choice_str(choice c)
{
std::map<choice, std::string> choice_map;
choice_map[red] = "red";
choice_map[blue] = "blue";
std::cout << "You chose: " << choice_map[c] << std::endl;
return choice_map[c];
}
struct C
{
choice c;
void print_()
std::string get()
{
print_choice(c);
return choice_str(c);
}
};
}

View File

@@ -1,4 +1,5 @@
namespace nested {
struct X
{
struct Y
@@ -19,3 +20,5 @@ int X::staticXValue = 10;
int X::Y::staticYValue = 20;
typedef X Root;
}

View File

@@ -1 +1 @@
Class('Root', 'nested.h')
Class('nested::Root', 'nested.h')

View File

@@ -1,12 +0,0 @@
Include('iostream')
test = Wrapper('sum',
'''
const C sum(const C&, const C&)
{
std::cout << "sum!" << std::endl;
return C();
}
'''
)
C = Class('C', 'operator.h')
set_wrapper(C.operator['+'], test)

View File

@@ -1,5 +1,6 @@
#include <iostream>
namespace operators {
struct C
{
@@ -16,14 +17,15 @@ struct C
{
return value;
}
double operator()()
{
return x;
return C::x;
}
double operator()(double other)
{
return x + other;
return C::x + other;
}
@@ -38,10 +40,4 @@ const C operator*(const C& lhs, const C& rhs)
return c;
}
std::ostream& operator <<( std::ostream& s, const C& c)
{
std::cout << "here";
s << "C instance: ";
return s;
}
}

View File

@@ -0,0 +1 @@
Class('operators::C', 'operators.h')

View File

@@ -1,4 +1,5 @@
namespace templates {
template <class X, class Y>
struct Point
{
@@ -6,3 +7,4 @@ struct Point
Y y;
};
}

View File

@@ -1,8 +1,9 @@
Point = Template('Point', 'templates.h')
Point = Template('templates::Point', 'templates.h')
rename(Point.x, 'i')
rename(Point.y, 'j')
IPoint = Point('int double')
FPoint = Point('double int')
FPoint = Point('double int', 'FPoint')
rename(IPoint, 'IPoint')
rename(IPoint.x, '_x_')
rename(IPoint.x, 'x')
rename(IPoint.y, 'y')

16
pyste/example/unions.h Normal file
View File

@@ -0,0 +1,16 @@
namespace unions {
class UnionTest
{
public:
union // unions are not supported for now
{
int i;
short s1;
short s2;
} mBad;
int mGood;
};
}

View File

@@ -0,0 +1,2 @@
UnionTest = Class('unions::UnionTest', 'unions.h')
exclude(UnionTest.mBad)

23
pyste/example/virtual.h Normal file
View File

@@ -0,0 +1,23 @@
struct C
{
public:
virtual int f()
{
return f_abs();
}
const char* get_name()
{
return name();
}
protected:
virtual int f_abs() = 0;
private:
virtual const char* name() { return "C"; }
};
int call_f(C& c) { return c.f(); }

View File

@@ -0,0 +1 @@
Class('C', 'virtual.h')

View File

@@ -4,6 +4,8 @@
#include <vector>
namespace wrappertest {
std::vector<int> Range(int count)
{
std::vector<int> v;
@@ -32,4 +34,6 @@ struct C
}
};
}
#endif

View File

@@ -1,15 +1,15 @@
Include('wrappertest_wrappers.h')
f = Function('Range', 'wrappertest.h')
f = Function('wrappertest::Range', 'wrappertest.h')
set_wrapper(f, 'RangeWrapper')
mul = Wrapper('MulWrapper',
'''
list MulWrapper(C& c, int value){
list MulWrapper(wrappertest::C& c, int value){
return VectorToList(c.Mul(value));
}
'''
)
C = Class('C', 'wrappertest.h')
C = Class('wrappertest::C', 'wrappertest.h')
set_wrapper(C.Mul, mul)

View File

@@ -20,7 +20,7 @@ list VectorToList(const std::vector<T> & v)
}
list RangeWrapper(int count){
return VectorToList(Range(count));
return VectorToList(wrappertest::Range(count));
}
#endif

View File

@@ -53,7 +53,7 @@ class ClassExporter(Exporter):
Exporter.SetDeclarations(self, declarations)
decl = self.GetDeclaration(self.info.name)
if isinstance(decl, Typedef):
self.class_ = decl.type
self.class_ = self.GetDeclaration(decl.type.name)
if not self.info.rename:
self.info.rename = decl.name
else:
@@ -195,6 +195,12 @@ class ClassExporter(Exporter):
constructors = [x for x in self.public_members if isinstance(x, Constructor)]
self.constructors = constructors[:]
# don't export the copy constructor if the class is abstract
if self.class_.abstract:
for cons in constructors:
if cons.IsCopy():
constructors.remove(cons)
break
if not constructors:
# declare no_init
self.Add('constructor', py_ns + 'no_init')
@@ -360,10 +366,11 @@ class ClassExporter(Exporter):
}
# converters which has a special name in python
SPECIAL_CONVETERS = {
SPECIAL_CONVERTERS = {
'double' : '__float__',
'float' : '__float__',
'int' : '__int__',
'long' : '__long__',
}
@@ -474,12 +481,15 @@ class ClassExporter(Exporter):
# export them as simple functions with a pre-determined name
converters = [x for x in self.public_members if type(x) == ConverterOperator]
def ConverterMethodName(converter):
result_fullname = converter.result.name
# extract the last name from the full name
result_name = _ID(result_fullname.split('::')[-1])
return 'to_' + result_name
if result_fullname in self.SPECIAL_CONVERTERS:
return self.SPECIAL_CONVERTERS[result_fullname]
else:
# extract the last name from the full name
result_name = _ID(result_fullname.split('::')[-1])
return 'to_' + result_name
for converter in converters:
info = self.info['operator'][converter.result.name]
@@ -605,12 +615,13 @@ class _VirtualWrapperGenerator(object):
param_names_str = ', '.join(param_names)
if param_names_str:
param_names_str = ', ' + param_names_str
decl += indent*2 + '%s%scall_method<%s>(self, "%s"%s);\n' %\
decl += indent*2 + '%s%scall_method< %s >(self, "%s"%s);\n' %\
(return_str, python, result, rename, param_names_str)
decl += indent + '}\n'
# default implementations (with overloading)
if not method.abstract:
# only for classes that are not abstract, and public methods
if not method.abstract and method.visibility == Scope.public:
minArgs = method.minArgs
maxArgs = method.maxArgs
impl_names = self.DefaultImplementationNames(method)
@@ -628,8 +639,6 @@ class _VirtualWrapperGenerator(object):
'''Returns a list of lines, which should be put inside the class_
statement to export this method.'''
# dont define abstract methods
if method.abstract:
return []
pyste = namespaces.pyste
rename = self.info[method.name].rename or method.name
default_names = self.DefaultImplementationNames(method)
@@ -675,18 +684,25 @@ class _VirtualWrapperGenerator(object):
def VirtualMethods(self):
return [m for m in self.class_.members if type(m) == Method and m.virtual]
def IsVirtual(m):
return type(m) == Method and m.virtual
return [m for m in self.class_.members if IsVirtual(m)]
def Constructors(self):
return [m for m in self.class_.members if isinstance(m, Constructor)]
def IsValid(m):
return isinstance(m, Constructor) and m.visibility == Scope.public
return [m for m in self.class_.members if IsValid(m)]
def GenerateDefinitions(self):
defs = []
for method in self.VirtualMethods():
if not self.info[method.name].exclude:
defs.extend(self.MethodDefinition(method))
exclude = self.info[method.name].exclude
# generate definitions only for public methods and non-abstract methods
if method.visibility == Scope.public and not method.abstract and not exclude:
defs.extend(self.MethodDefinition(method))
return defs
@@ -698,7 +714,7 @@ class _VirtualWrapperGenerator(object):
code = 'struct %s: %s\n' % (self.wrapper_name, class_name)
code += '{\n'
# generate constructors (with the overloads for each one)
for cons in self.Constructors():
for cons in self.Constructors(): # only public constructors
minArgs = cons.minArgs
maxArgs = cons.maxArgs
# from the min number of arguments to the max number, generate

View File

@@ -59,7 +59,7 @@ class CppParser:
if tail:
tempfilename = tempfile.mktemp('.h')
infilename = tempfilename
shutil.copy(filename, infilename)
shutil.copyfile(filename, infilename)
f = file(infilename, 'a')
f.write('\n\n'+tail)
f.close()

View File

@@ -221,14 +221,14 @@ class GCCXMLParser(object):
bases = self.GetBases(element.get('bases'))
location = self.GetLocation(element.get('location'))
context = self.GetDecl(element.get('context'))
if isinstance(context, Class): # a nested class
if isinstance(context, str):
class_ = Class(name, context, [], abstract, bases)
self.AddDecl(class_)
else:
# a nested class
visib = element.get('access', Scope.public)
class_ = NestedClass(
name, context.FullName(), visib, [], abstract, bases)
else:
assert isinstance(context, str)
class_ = Class(name, context, [], abstract, bases)
self.AddDecl(class_)
# we have to add the declaration of the class before trying
# to parse its members, to avoid recursion.
class_.location = location
@@ -251,10 +251,6 @@ class GCCXMLParser(object):
type_ = self.GetType(element.get('type'))
min = element.get('min')
max = element.get('max')
if min:
min = int(min)
if max:
max = int(max)
array = ArrayType(type_.name, min, max, type_.const)
self.Update(id, array)
@@ -349,7 +345,7 @@ class GCCXMLParser(object):
def ParseTypedef(self, id, element):
name = element.get('name')
type = self.GetDecl(element.get('type'))
type = self.GetType(element.get('type'))
context = self.GetDecl(element.get('context'))
if isinstance(context, Class):
context = context.FullName()
@@ -362,12 +358,13 @@ class GCCXMLParser(object):
name = element.get('name')
location = self.GetLocation(element.get('location'))
context = self.GetDecl(element.get('context'))
if isinstance(context, Class):
if isinstance(context, str):
enum = Enumeration(name, context)
self.AddDecl(enum) # in this case, is a top level decl
else:
visib = element.get('access', Scope.public)
enum = ClassEnumeration(name, context.FullName(), visib)
else:
enum = Enumeration(name, context)
self.AddDecl(enum) # in this case, is a top level decl
enum.location = location
for child in element:
if child.tag == 'EnumValue':
@@ -383,7 +380,18 @@ class GCCXMLParser(object):
def ParseUnion(self, id, element):
self.Update(id, Declaration(element.get('name'), ''))
name = element.get('name')
context = self.GetDecl(element.get('context'))
location = self.GetLocation(element.get('location'))
if isinstance(context, str):
# a free union
union = Union(name, context)
self.AddDecl(union)
else:
visib = element.get('access', Scope.public)
union = ClassUnion(name, context.FullName(), visib)
union.location = location
self.Update(id, union)

View File

@@ -157,7 +157,7 @@ class Function(Declaration):
'returns a declaration of a pointer to this function'
result = self.result.FullName()
params = ', '.join([x.FullName() for x in self.parameters])
return '(%s (*)(%s))%s' % (result, params, self.FullName())
return '(%s (*)(%s))&%s' % (result, params, self.FullName())
def _MinArgs(self):
@@ -211,7 +211,7 @@ class Method(Function):
const = ''
if self.const:
const = 'const'
return '(%s (%s::*)(%s) %s)%s' %\
return '(%s (%s::*)(%s) %s)&%s' %\
(result, self.class_, params, const, self.FullName())
@@ -445,8 +445,20 @@ class Typedef(Declaration):
self.visibility = Scope.public
class Union(Declaration):
'Shallow declaration, because Unions are not supported yet'
def __init__(self, name, namespace):
Declaration.__init__(self, name, namespace)
class ClassUnion(Union):
def __init__(self, name, class_, visib):
Union.__init__(self, name, None)
self.class_ = class_
self.visibility = visib
def FullName(self):
return '%s::%s' % (self.class_, self.name)

3
pyste/tests/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
*.pyc
*.dll
*.cpp

View File

@@ -72,7 +72,7 @@ class ClassBaseTest(Tester):
self.TestType(param, FundamentalType, 'int', 'int', False)
self.assertEqual(foo.namespace, None)
self.assertEqual(
foo.PointerDeclaration(), '(void (test::Base::*)(int) )test::Base::foo')
foo.PointerDeclaration(), '(void (test::Base::*)(int) )&test::Base::foo')
def testX(self):
'test the member x in class Base'
@@ -109,7 +109,7 @@ class ClassBaseTest(Tester):
self.TestType(simple.result, FundamentalType, 'bool', 'bool', False)
self.assertEqual(
simple.PointerDeclaration(),
'(bool (test::Base::*)(const std::string &) )test::Base::simple')
'(bool (test::Base::*)(const std::string &) )&test::Base::simple')
def testZ(self):
@@ -181,7 +181,7 @@ class FreeFuncTest(Tester):
self.assertEqual(self.func.namespace, 'test')
self.assertEqual(
self.func.PointerDeclaration(),
'(const test::Base & (*)(const std::string &, int))test::FreeFunc')
'(const test::Base & (*)(const std::string &, int))&test::FreeFunc')
def testResult(self):

View File

@@ -0,0 +1,19 @@
@echo off
setlocal
set MODULE_NAME=%1
set PYSTE_FILE=%2
set BOOST_ROOT=d:/programming/libraries/boost-cvs
set PYTHON_ROOT=c:/python
set STLPORT_ROOT=d:/programming/libraries/stlport-4.5.3
set PYSTE_FILE_DIR=%@PATH[%PYSTE_FILE]
python ../src/pyste.py -I%PYSTE_FILE_DIR --out=%MODULE_NAME.cpp --module=%MODULE_NAME %PYSTE_FILE
icl /nologo /LD /GR /GX -I%PYSTE_FILE_DIR -I%STLPORT_ROOT/stlport -I%BOOST_ROOT/boost -I%PYTHON_ROOT/include %MODULE_NAME.cpp /link /libpath:%PYTHON_ROOT/libs /libpath:%BOOST_ROOT/lib /libpath:%STLPORT_ROOT/lib boost_python.lib
rm %MODULE_NAME.cpp
rm %MODULE_NAME.exp
rm %MODULE_NAME.lib
rm %MODULE_NAME.obj
endlocal

View File

@@ -0,0 +1,27 @@
import unittest
import os
class BasicExampleTest(unittest.TestCase):
def testIt(self):
from basic import C, call_f
class D(C):
def f(self, x=10):
return x+1
d = D()
c = C()
self.assertEqual(c.f(), 20)
self.assertEqual(c.f(3), 6)
self.assertEqual(d.f(), 11)
self.assertEqual(d.f(3), 4)
self.assertEqual(call_f(c), 20)
self.assertEqual(call_f(c, 4), 8)
self.assertEqual(call_f(d), 11)
self.assertEqual(call_f(d, 3), 4)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,18 @@
import unittest
from enums import *
class EnumsTest(unittest.TestCase):
def testIt(self):
self.assertEqual(int(color.Red), 0)
self.assertEqual(int(color.Blue), 1)
self.assertEqual(int(X.Choices.Good), 1)
self.assertEqual(int(X.Choices.Bad), 2)
x = X()
self.assertEqual(x.set(x.Choices.Good), 1)
self.assertEqual(x.set(x.Choices.Bad), 2)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,15 @@
import unittest
from header_test import *
class HeaderTest(unittest.TestCase):
def testIt(self):
self.assertEqual(choice.red, 0)
self.assertEqual(choice.blue, 1)
self.assertEqual(choice_str(choice.blue), 'blue')
self.assertEqual(choice_str(choice.red), 'red')
c = C()
c.c = choice.blue
self.assertEqual(c.get(), 'blue')
c.c = choice.red
self.assertEqual(c.get(), 'red')

View File

@@ -0,0 +1,15 @@
import unittest
from nested import *
class NestedTest(unittest.TestCase):
def testIt(self):
self.assertEqual(Root.staticXValue, 10)
self.assertEqual(Root.Y.staticYValue, 20)
z = Root.Y.Z()
z.valueZ = 3
self.assertEqual(z.valueZ, 3)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,25 @@
import unittest
from operators import *
class OperatorTest(unittest.TestCase):
def testIt(self):
c = C()
c.value = 3.0
d = C()
d.value = 2.0
self.assertEqual(c.x, 10)
self.assertEqual(C.x, 10)
self.assertEqual(C.x, 10)
self.assertEqual((c * d).value, 6.0)
self.assertEqual((c + d).value, 5.0)
self.assertEqual(int(c), 3)
self.assertEqual(int(d), 2)
self.assertEqual(c(), 10)
self.assertEqual(d(), 10)
self.assertEqual(c(3.0), 13.0)
self.assertEqual(d(6.0), 16.0)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,26 @@
import unittest
from templates import *
class TemplatesTest(unittest.TestCase):
def testIt(self):
fp = FPoint()
fp.i = 3.0
fp.j = 4
ip = IPoint()
ip.x = 10
ip.y = 3.0
self.assertEqual(fp.i, 3.0)
self.assertEqual(fp.j, 4)
self.assertEqual(ip.x, 10)
self.assertEqual(ip.y, 3.0)
self.assertEqual(type(fp.i), float)
self.assertEqual(type(fp.j), int)
self.assertEqual(type(ip.x), int)
self.assertEqual(type(ip.y), float)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,31 @@
import unittest
from virtual import *
class VirtualTest(unittest.TestCase):
def testIt(self):
class D(C):
def f_abs(self):
return 3
class E(C):
def f(self):
return 10
def name(self):
return 'E'
d = D()
e = E()
self.assertEqual(d.f(), 3)
self.assertEqual(call_f(d), 3)
self.assertEqual(e.f(), 10)
self.assertEqual(call_f(e), 10)
self.assertEqual(d.get_name(), 'C')
self.assertEqual(e.get_name(), 'E')
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,11 @@
import unittest
from wrappertest import *
class WrapperTest(unittest.TestCase):
def testIt(self):
self.assertEqual(Range(10), range(10))
self.assertEqual(C().Mul(10), [x*10 for x in range(10)])
if __name__ == '__main__':
unittest.main()

View File

@@ -11,4 +11,5 @@ if __name__ == '__main__':
module = __import__(os.path.splitext(name)[0])
tests.append(loader.loadTestsFromModule(module))
runner = unittest.TextTestRunner()
runner.run(unittest.TestSuite(tests))
result = runner.run(unittest.TestSuite(tests))
sys.exit(not result.wasSuccessful())

20
pyste/tests/test_all.bat Normal file
View File

@@ -0,0 +1,20 @@
@echo off
call build_pyste_nt basic ../example/basic.pyste
call build_pyste_nt enums ../example/enums.pyste
call build_pyste_nt header_test ../example/header_test.pyste
call build_pyste_nt nested ../example/nested.pyste
call build_pyste_nt operators ../example/operators.pyste
call build_pyste_nt templates ../example/templates.pyste
call build_pyste_nt virtual ../example/virtual.pyste
call build_pyste_nt wrappertest ../example/wrappertest.pyste
call build_pyste_nt unions ../example/unions.pyste
runtests.py
if errorlevel != 0 goto end
rm *.dll
rm *.pyc
:end

View File

@@ -124,6 +124,8 @@ bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ;
bpl-test extract ;
bpl-test opaque ;
bpl-test pickle1 ;
bpl-test pickle2 ;
bpl-test pickle3 ;

View File

@@ -3,13 +3,13 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <string>
#include <boost/python/operators.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/manage_new_object.hpp>
#include <string>
#include "test_class.hpp"
// Just use math.h here; trying to use std::pow() causes too much

View File

@@ -7,10 +7,10 @@
// embedded_hello -- A simple Boost.Python embedding example -- by
// Dirk Gerrits
#include <iostream>
#include <stdexcept>
#include <boost/python.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
#include <stdexcept>
namespace python = boost::python;

View File

@@ -4,7 +4,6 @@
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include "test_class.hpp"
#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
#include <boost/python/module.hpp>
@@ -15,6 +14,7 @@
#include <boost/python/implicit.hpp>
#include <string>
#include <boost/lexical_cast.hpp>
#include "test_class.hpp"
#include <cassert>
using namespace boost::python;

View File

@@ -20,18 +20,8 @@ int x_value(X const& x)
X make_x(int n) { return X(n); }
// foo/bar -- a regression for a vc7 bug workaround
struct bar {};
struct foo
{
virtual void f() = 0;
operator bar() const { return bar(); }
};
BOOST_PYTHON_MODULE(implicit_ext)
{
implicitly_convertible<foo,bar>();
implicitly_convertible<int,X>();
def("x_value", x_value);

View File

@@ -5,8 +5,6 @@
// to its suitability for any purpose.
#include "simple_type.hpp"
#include "complicated.hpp"
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
@@ -17,6 +15,8 @@
#include <boost/python/errors.hpp>
#include <boost/python/manage_new_object.hpp>
#include <string.h>
#include "simple_type.hpp"
#include "complicated.hpp"
// Declare some straightforward extension types
extern "C" void

75
test/opaque.cpp Normal file
View File

@@ -0,0 +1,75 @@
// Copyright David Abrahams and Gottfried Ganssauge 2003. Permission
// to copy, use, modify, sell and distribute this software is granted
// provided this copyright notice appears in all copies. This software
// is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/def.hpp>
# include <boost/python/module.hpp>
# include <boost/python/return_value_policy.hpp>
typedef struct opaque_ *opaque;
typedef struct opaque2_ *opaque2;
opaque the_op = ((opaque) 0x47110815);
opaque2 the_op2 = ((opaque2) 0x08154711);
opaque get() { return the_op; }
void use(opaque op)
{
if (op != the_op)
throw std::runtime_error (std::string ("failed"));
}
int useany(opaque op)
{
return op ? 1 : 0;
}
opaque getnull()
{
return 0;
}
void failuse (opaque op)
{
if (op == the_op)
throw std::runtime_error (std::string ("success"));
}
opaque2 get2 () { return the_op2; }
void use2 (opaque2 op)
{
if (op != the_op2)
throw std::runtime_error (std::string ("failed"));
}
void failuse2 (opaque2 op)
{
if (op == the_op2)
throw std::runtime_error (std::string ("success"));
}
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque2_)
namespace bpl = boost::python;
BOOST_PYTHON_MODULE(opaque_ext)
{
bpl::def (
"get", &::get, bpl::return_value_policy<bpl::return_opaque_pointer>());
bpl::def ("use", &::use);
bpl::def ("useany", &::useany);
bpl::def ("getnull", &::getnull, bpl::return_value_policy<bpl::return_opaque_pointer>());
bpl::def ("failuse", &::failuse);
bpl::def (
"get2",
&::get2,
bpl::return_value_policy<bpl::return_opaque_pointer>());
bpl::def ("use2", &::use2);
bpl::def ("failuse2", &::failuse2);
}

77
test/opaque.py Normal file
View File

@@ -0,0 +1,77 @@
# Copyright Gottfried Ganßauge 2003. Permission to copy, use,
# modify, sell and distribute this software is granted provided this
# copyright notice appears in all copies. This software is provided
# "as is" without express or implied warranty, and with no claim as
# to its suitability for any purpose.
"""
>>> from opaque_ext import *
>>> #
>>> # Check for correct conversion
>>> use(get())
# Check that None is converted to a NULL opaque pointer
>>> useany(get())
1
>>> useany(None)
0
# check that we don't lose type information by converting NULL opaque
# pointers to None
>>> assert getnull() is None
>>> useany(getnull())
0
>>> failuse(get())
Traceback (most recent call last):
...
RuntimeError: success
>>> #
>>> # Check that there is no conversion from integers ...
>>> use(0)
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> #
>>> # ... and from strings to opaque objects
>>> use("")
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> #
>>> # Now check the same for another opaque pointer type
>>> use2(get2())
>>> failuse2(get2())
Traceback (most recent call last):
...
RuntimeError: success
>>> use2(0)
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> use2("")
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> #
>>> # Check that opaque types are distinct
>>> use(get2())
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
>>> use2(get())
Traceback (most recent call last):
...
TypeError: bad argument type for built-in operation
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -3,11 +3,11 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <string>
#include <boost/python/operators.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <string>
#include "test_class.hpp"
#if __GNUC__ != 2
# include <ostream>

View File

@@ -15,9 +15,6 @@
>>> (-y).value()
39
>>> (x + y).value()
3
>>> abs(y).value()
39

View File

@@ -20,8 +20,6 @@
For more information refer to boost/libs/python/doc/pickle.html.
*/
#include <string>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
@@ -29,6 +27,8 @@
#include <boost/python/extract.hpp>
#include <boost/python/detail/api_placeholder.hpp>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A friendly class.

View File

@@ -15,8 +15,6 @@
For more information refer to boost/libs/python/doc/pickle.html.
*/
#include <string>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
@@ -26,6 +24,8 @@
#include <boost/python/detail/api_placeholder.hpp>
#include <boost/python/back_reference.hpp>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A friendly class.

View File

@@ -3,11 +3,11 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/static_assert.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <boost/python/object/select_holder.hpp>
#include <boost/python/has_back_reference.hpp>
#include <boost/python/detail/not_specified.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <boost/function/function0.hpp>
#include <memory>

View File

@@ -3,9 +3,9 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <string>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <string>
#include <complex>
#include <boost/python/handle.hpp>
#include <boost/python/cast.hpp>