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

boost-ification

[SVN r8335]
This commit is contained in:
Dave Abrahams
2000-11-27 07:02:14 +00:00
parent 6691261130
commit 308f3acb46
12 changed files with 169 additions and 205 deletions

View File

@@ -1,21 +1,21 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
Building a Module with Py_cpp
Building an Extension Module
</title>
<div>
<h1>
<img width="277" height="86" id="_x0000_i1025" align="center"
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building a Module with Py_cpp
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building an Extension Module
</h1>
<p>
Right now, the only supported configuration is one in which the py_cpp
Right now, the only supported configuration is one in which the BPL
source files are statically linked with the source for your extension
module. You may first build them into a library and link it with your
extension module source, but the effect is the same as compiling all
the source files together. Some users have successfully built the
py_cpp sources into a shared library, and support for a shared library
build is planned, but not yet implemented. The py_cpp source files are:
sources into a shared library, and support for a shared library
build is planned, but not yet implemented. The BPL source files are:
<blockquote>
<pre>
<a href="../../../libs/python/src/extension_class.cpp">extclass.cpp</a>
@@ -29,6 +29,7 @@
</pre>
</blockquote>
<p>
Next: <a href="enums.html">Enums</a>
Previous: <a href="under-the-hood.html">A Peek Under the Hood</a>
Up: <a href="index.html">Top</a>
<p>

View File

@@ -12,14 +12,16 @@
<h2>CXX</h2>
<p>
Like py_cpp, <a href="http://cxx.sourceforge.net/">CXX</a> attempts to
provide a C++-oriented interface to Python. In most cases, like py_cpp,
it relieves the user from worrying about reference-counts. As far as I
can tell, there is no support for subclassing C++ extension types in
Python. An even more-significant difference is that a user's C++ code is
still basically &ldquo;dealing with Python objects&rdquo;, though they are wrapped
in C++ classes. This means such jobs as argument parsing and conversion
are still left to be done explicitly by the user.
Like BPL, <a href="http://cxx.sourceforge.net/">CXX</a> attempts to
provide a C++-oriented interface to Python. In most cases, as with the
boost library, it relieves the user from worrying about
reference-counts. Both libraries automatically convert thrown C++
exceptions into Python exceptions. As far as I can tell, CXX has no
support for subclassing C++ extension types in Python. An even
more significant difference is that a user's C++ code is still basically
&ldquo;dealing with Python objects&rdquo;, though they are wrapped in
C++ classes. This means such jobs as argument parsing and conversion are
still left to be done explicitly by the user.
<p>
CXX claims to interoperate well with the C++ Standard Library
@@ -38,11 +40,9 @@
<p>
As far as I can tell, CXX enables one to write what is essentially
idiomatic Python code in C++, manipulating Python objects through the
same fully-generic interfaces we use in Python. I think it would be fair
to say that while you're not programming directly to the &ldquo;bare
metal&rdquo; with CXX, in comparison to py_cpp, it presents a low-level
interface to Python. That use is also supported by the py_cpp object
wrappers.
same fully-generic interfaces we use in Python. While you're hardly programming directly to the &ldquo;bare
metal&rdquo; with CXX, it basically presents a &ldquo;C++-ized&rdquo;
version of the Python 'C' API.
<p>
<a href="mailto:dubois1@llnl.gov">Paul F. Dubois</a>, the original
@@ -65,7 +65,7 @@ that.&rdquo;<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
languages. Swig relies on a parser to read your source code and produce
additional source code files which can be compiled into a Python (or
Perl or Tcl) extension module. It has been successfully used to create
many Python extension modules. Like py_cpp, SWIG is trying to allow an
many Python extension modules. Like BPL, SWIG is trying to allow an
existing interface to be wrapped with little or no change to the
existing code. The documentation says &ldquo;SWIG parses a form of ANSI C
syntax that has been extended with a number of special directives. As a
@@ -78,15 +78,15 @@ that.&rdquo;<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
couldnt handle templates, didnt do func overloading properly etc. For
ANSI C libraries this was fine. But for usual C++ code this was a
problem. Simple things work. But for anything very complicated (or
realistic), one had to write code by hand. I believe py_cpp doesn't have
realistic), one had to write code by hand. I believe BPL doesn't have
this problem[<a href="#sic">sic</a>]... IMHO overloaded functions are very important to
wrap correctly.&rdquo;<br><i>-Prabhu Ramachandran</i>
</blockquote>
<p>
By contrast, py_cpp doesn't attempt to parse C++ - the problem is simply
By contrast, BPL doesn't attempt to parse C++ - the problem is simply
too complex to do correctly. <a name="sic">Technically</a>, one does
write code by hand to use py_cpp. The goal, however, has been to make
write code by hand to use BPL. The goal, however, has been to make
that code nearly as simple as listing the names of the classes and
member functions you want to expose in Python.
@@ -95,7 +95,7 @@ that.&rdquo;<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
<a
href="http://www.thekompany.com/projects/pykde/background.php3?dhtml_ok=1">SIP</a>
is a system similar to SWIG, though seemingly more
C++-oriented. The author says that like py_cpp, SIP supports overriding
C++-oriented. The author says that like BPL, SIP supports overriding
extension class member functions in Python subclasses. It appears to
have been designed specifically to directly support some features of
PyQt/PyKDE, which is its primary client. Documentation is almost
@@ -113,7 +113,7 @@ that.&rdquo;<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
to a wide range of computer languages, including Common Lisp, C++, C,
Modula-3, and Python. ILU can parse the ISL to generate a C++ language
header file describing the interface, of which the user is expected to
provide an implementation. Unlike py_cpp, this means that the system
provide an implementation. Unlike BPL, this means that the system
imposes implementation details on your C++ code at the deepest level. It
is worth noting that some of the C++ names generated by ILU are supposed
to be reserved to the C++ implementation. It is unclear from the
@@ -148,7 +148,7 @@ an inheritance relationship?
<h2>Zope ExtensionClasses</h2>
<p>
<a href="http:http://www.digicool.com/releases/ExtensionClass">
ExtensionClasses in Zope</a> use the same underlying mechanism as py_cpp
ExtensionClasses in Zope</a> use the same underlying mechanism as BPL
to support subclassing of extension types in Python, including
multiple-inheritance. Both systems support pickling/unpickling of
extension class instances in very similar ways. Both systems rely on the
@@ -159,30 +159,30 @@ an inheritance relationship?
The major differences are:
<ul>
<li>
py_cpp lifts the burden on the user to parse and convert function
BPL lifts the burden on the user to parse and convert function
argument types. Zope provides no such facility.
<li>
py_cpp lifts the burden on the user to maintain Python
BPL lifts the burden on the user to maintain Python
reference-counts.
<li>
py_cpp supports function overloading; Zope does not.
BPL supports function overloading; Zope does not.
<li>
py_cpp supplies a simple mechanism for exposing read-only and
BPL supplies a simple mechanism for exposing read-only and
read/write access to data members of the wrapped C++ type as Python
attributes.
<li>
Writing a Zope ExtensionClass is significantly more complex than
exposing a C++ class to python using py_cpp (mostly a summary of the
exposing a C++ class to python using BPL (mostly a summary of the
previous 4 items). <a href=
"http://www.digicool.com/releases/ExtensionClass/MultiMapping.html">A
Zope Example</a> illustrates the differences.
<li>
Zope's ExtensionClasses are specifically motivated by &ldquo;the need for a
C-based persistence mechanism&rdquo;. Py_cpp's are motivated by the desire
C-based persistence mechanism&rdquo;. BPL's are motivated by the desire
to simply reflect a C++ API into Python with as little modification as
possible.
<li>
The following Zope restriction does not apply to py_cpp: &ldquo;At most one
The following Zope restriction does not apply to BPL: &ldquo;At most one
base extension direct or indirect super class may define C data
members. If an extension subclass inherits from multiple base
extension classes, then all but one must be mix-in classes that
@@ -191,22 +191,22 @@ an inheritance relationship?
Zope requires use of the somewhat funky inheritedAttribute (search for
&ldquo;inheritedAttribute&rdquo; on <a
href="http://www.digicool.com/releases/ExtensionClass">this page</a>)
method to access base class methods. In py_cpp, base class methods can
method to access base class methods. In BPL, base class methods can
be accessed in the usual way by writing
&ldquo;<code>BaseClass.method</code>&rdquo;.
<li>
Zope supplies some creative but esoteric idioms such as <a href=
"http://www.digicool.com/releases/ExtensionClass/Acquisition.html">
Acquisition</a>. No specific support for this is built into py_cpp.
Acquisition</a>. No specific support for this is built into BPL.
<li>
Zope's ComputedAttribute support is designed to be used from Python.
<a href="special.html#getter_setter">The analogous feature of
py_cpp</a> can be used from C++ or Python. The feature is arguably
easier to use in py_cpp.
BPL</a> can be used from C++ or Python. The feature is arguably
easier to use in BPL.
</ul>
<p>
Next: <a href="example1.html">A Simple Example Using BPL</a>
Previous: <a href="extending.html">A Brief Introduction to writing Python Extension Modules</a>
Next: <a href="example1.html">A Simple Example Using py_cpp</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,

View File

@@ -8,31 +8,36 @@
<img width="277" height="86" id="_x0000_i1025" align="center"
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Wrapping enums
</h1>
<p>Because there is in general no way to deduce that a value of arbitrary type T
is an enumeration constant, py_cpp cannot automatically convert enum values to
and from Python. To handle this case, you need to decide how you want the enum
to show up in Python (since Python doesn't have enums). Once you have done that,
you can write some simple <code>from_python()</code> and
<code>to_python()</code> functions.
is an enumeration constant, the Boost Python Library cannot automatically
convert enum values to and from Python. To handle this case, you need to decide
how you want the enum to show up in Python (since Python doesn't have
enums). Once you have done that, you can write some simple
<code>from_python()</code> and <code>to_python()</code> functions.
<p>If you are satisfied with a Python int as a way to represent your enum
values, py_cpp provides a shorthand for these functions. You just need to
values, we provide a shorthand for these functions. You just need to
instantiate <code>boost::python::enum_as_int_converters&lt;EnumType&gt;</code> where
<code>EnumType</code> is your enumerated type. There are two convenient ways to do this:
<ol>
<li><blockquote>
<pre>
...
} // close my_namespace
// drop into namespace python and explicitly instantiate
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
template class enum_as_int_converters<extclass_demo::EnumOwner::enum_type>;
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace my_namespace { // re-open my_namespace
...
</pre>
</blockquote>
<li><blockquote><pre>
// instantiate as base class in any namespace
struct EnumTypeConverters
: boost::python::py_enum_as_int_converters<EnumType>
: boost::python::enum_as_int_converters&lt;EnumType&gt;
{
};
</blockquote></pre>
@@ -82,6 +87,10 @@ my_class.add(boost::python::to_python(enum_value_1), "enum_value_1");
my_class.add(boost::python::to_python(enum_value_2), "enum_value_2");
...
</pre></blockquote>
<p>
Next: <a href="pointers.html">Pointers</a>
Previous: <a href="building.html">Building an Extension Module</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
A Simple Example Using py_cpp
A Simple Example Using BPL
</title>
<div>
<h1>
@@ -9,7 +9,7 @@
"c++boost.gif (8819 bytes)">
</h1>
<h1>
A Simple Example Using py_cpp
A Simple Example Using BPL
</h1>
<p>
Suppose we have the following C++ API which we want to expose in
@@ -24,20 +24,20 @@ namespace hello {
   public:
      world(int);
      ~world();
      std::string get() const { return "hi, world"; }
      std::string greet() const { return "hi, world"; }
    ...
  };
  std::size_t length(const world&amp; x) { return std::strlen(x.get()); }
  std::size_t length(const world&amp; x) { return std::strlen(x.greet()); }
}
</pre>
</blockquote>
<p>
Here is the C++ code for a python module called <code>hello</code>
which exposes the API using py_cpp:
which exposes the API using BPL:
<blockquote>
<pre>
#include <boost/python/class_builder.hpp>
#include &lt;boost/python/class_builder.hpp&gt;
// Python requires an exported function called init&lt;module-name&gt; in every
// extension module. This is where we build the module contents.
extern "C"
@@ -49,15 +49,15 @@ void inithello()
    try
    {
       // create an object representing this extension module
       boost::python::module_builder hello("hello");
       boost::python::module_builder m("hello");
       // Create the Python type object for our extension class
       boost::python::class_builder&lt;hello::world&gt; world_class(hello, "world");
       boost::python::class_builder&lt;hello::world&gt; world_class(m, "world");
       // Add the __init__ function
       world_class.def(boost::python::constructor&lt;int&gt;());
       // Add a regular member function
       world_class.def(&amp;hello::world::get, "get");
       // Add a regular function to the module
       hello.def(hello::length, "length");
       m.def(hello::length, "length");
    }
    catch(...)
    {
@@ -82,7 +82,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
<pre>
&gt;&gt;&gt; import hello
&gt;&gt;&gt; hi_world = hello.world(3)
&gt;&gt;&gt; hi_world.get()
&gt;&gt;&gt; hi_world.greet()
'hi, world'
&gt;&gt;&gt; hello.length(hi_world)
9
@@ -93,11 +93,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
<blockquote>
<pre>
&gt;&gt;&gt; class my_subclass(hello.world):
...     def get(self):
...     def greet(self):
...         return 'hello, world'
...
&gt;&gt;&gt; y = my_subclass(4)
&gt;&gt;&gt; y.get()
&gt;&gt;&gt; y.greet()
'hello, world'
</pre>
</blockquote>
@@ -115,7 +115,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
to have a <code>length()</code> of <code>12</code>? If so, <a href=
"overriding.html">read on</a>...
<p>
Previous: <a href="comparisons.html">Comparisons with other systems</a> Next: <a href="overriding.html">Overridable virtual functions</a> Up:
Next: <a href="overriding.html">Overridable virtual functions</a>
Previous: <a href="comparisons.html">Comparisons with other systems</a> Up:
<a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,

View File

@@ -38,11 +38,11 @@
</ul>
This last item typically occupies a great deal of code in an extension
module. Remember that Python is a completely dynamic language. A callable
object receives its arguments in a tuple; it is up to that object to
extract those arguments from the tuple, check their types, and raise
appropriate exceptions. There are numerous other tedious details that need
to be managed; too many to mention here. Py_cpp is designed to lift most of
that burden.<br>
object receives its arguments in a tuple; it is up to that object to extract
those arguments from the tuple, check their types, and raise appropriate
exceptions. There are numerous other tedious details that need to be
managed; too many to mention here. The Boost Python Library is designed to
lift most of that burden.<br>
<br>
<p>
@@ -56,10 +56,10 @@
sublcassing the extension type. Aside from being tedious, it's not really
the same as having a true class, because there's no way for the user to
override a method of the extension type which is called from the
extension module. Py_cpp solves this problem by taking advantage of <a
extension module. BPL solves this problem by taking advantage of <a
href="http://www.python.org/doc/essays/metaclasses/">Python's metaclass
feature</a> to provide objects which look, walk, and hiss almost exactly
like regular Python classes. Py_cpp classes are actually cleaner than
like regular Python classes. BPL classes are actually cleaner than
Python classes in some subtle ways; a more detailed discussion will
follow (someday).</p>
<p>Next: <a href="comparisons.html">Comparisons with Other Systems</a> Up: <a

View File

@@ -2,26 +2,22 @@
"http://www.w3.org/TR/REC-html40/strict.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>
py_cpp Python/C++ binding documentation
The Boost Python Library (BPL)
</title>
<h1>
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277"
align="center" height="86"> py_cpp<a href="#naming_contest">*</a>
align="center" height="86">The Boost Python Library (BPL)
</h1>
<p>
The source code for py_cpp, including a MSVC demo project is available <a
href="py_cpp_20001106.zip">here</a>.
<h2>Synopsis</h2>
<p>
py_cpp is a system for quickly and easily interfacing C++ code with <a
href="http:www.python.org">Python</a> such that the Python interface is
Use the Boost Python Library to quickly and easily export a C++ library to <a
href="http://www.pythonlabs.com/pub/www.python.org">Python</a> such that the Python interface is
very similar to the C++ interface. It is designed to be minimally
intrusive on your C++ design. In most cases, you should not have to alter
your C++ classes in any way in order to use them with py_cpp. The system
your C++ classes in any way in order to use them with BPL. The system
<em>should</em> simply &ldquo;reflect&rdquo; your C++ classes and functions into
Python. The major features of py_cpp include support for:
Python. The major features of BPL include support for:
<ul>
<li><a href="inheritance.hml">Subclassing extension types in Python</a>
<li><a href="overriding.html">Overriding virtual functions in Python</a>
@@ -32,7 +28,7 @@ among others.
<h2>Supported Platforms</h2>
<p>py_cpp has been tested in the following configurations:
<p>BPL has been tested in the following configurations:
<ul>
<li>Against Python 1.5.2 using the following compiler/library:
@@ -56,7 +52,7 @@ among others.
href="mailto:rwgk@cci.lbl.gov">Ralf W. Grosse-Kunstleve</a>]
<li>An upcoming release of <a href="http://www.metrowerks.com/products/windows/">Metrowerks CodeWarrior
Pro6 for Windows</a> (the first release has a bug that's fatal to py_cpp)
Pro6 for Windows</a> (the first release has a bug that's fatal to BPL)
</ul>
<br>
<li>Against Python 2.0 using the following compiler/library combinations:
@@ -67,18 +63,13 @@ among others.
</ul>
</ul>
<p>Py_cpp requires the <a href="http://www.boost.org">boost</a> libraries, and is
has been accepted for inclusion into the boost libraries pending &ldquo;boostification&ldquo;
(completion of the documentation, change in some naming conventions and
resolution of some namespace issues).
<h2>Credits</h2>
<ul>
<li><a href="mailto:abrahams@mediaone.net">David Abrahams</a> originated
and wrote py_cpp.
<li><a href="../../../people/dave_abrahams.htm">David Abrahams</a> originated
and wrote the library.
<li><a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich Koethe</a>
had independently developed a similar system. When he discovered py_cpp,
had independently developed a similar system. When he discovered BPL,
he generously contributed countless hours of coding and much insight into
improving it. He is responsible for an early version of the support for <a
href="overloading.html">function overloading</a> and wrote the support for
@@ -88,13 +79,13 @@ among others.
exposing <a href="special.html#numeric">numeric operators</a>, including
a way to avoid explicit coercion by means of overloading.
<li>The members of the boost mailing list and the Python community supplied
invaluable early feedback. In particular, Ron Clarke, Mark Evans, Anton
Gluck, Ralf W. Grosse-Kunstleve, Prabhu Ramachandran, and Barry Scott took
the brave step of trying to use py_cpp while it was still in early stages
of development.
<li>The members of the boost mailing list and the Python community
supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans,
Anton Gluck, Ralf W. Grosse-Kunstleve, Chuck Ingold, Prabhu Ramachandran,
and Barry Scott took the brave step of trying to use BPL while it was
still in early stages of development.
<li>The development of py_cpp wouldn't have been
<li>The development of BPL wouldn't have been
possible without the generous support of <a href="http://www.dragonsys.com/">Dragon Systems/Lernout and
Hauspie, Inc</a> who supported its development as an open-source project.
</ul>
@@ -105,10 +96,10 @@ among others.
<li><a href="extending.html">A Brief Introduction to writing Python
extension modules</a>
<li><a href="comparisons.html">Comparisons between py_cpp and other
<li><a href="comparisons.html">Comparisons between BPL and other
systems for extending Python</a>
<li><a href="example1.html">A Simple Example Using py_cpp</a>
<li><a href="example1.html">A Simple Example Using BPL</a>
<li><a href="overriding.html">Overridable Virtual Functions</a>
@@ -120,11 +111,13 @@ among others.
<li><a href="under-the-hood.html">A Peek Under the Hood</a>
<li><a href="building.html">Building a Module with Py_cpp</a>
<li><a href="building.html">Building a Module with BPL</a>
<li>Advanced Topics
<ol>
<li>Pickling
<li>class_builder&lt;&gt;
<li><a href="enums.html">enums</a>
@@ -143,63 +136,17 @@ among others.
</ol>
<p>
More sophisticated examples are given in
<code>extclass_demo.cpp</code>, <code> extclass_demo.h</code>, and <code>
test_extclass.py</code> in the <a href="py_cpp.tgz">source code
archive</a>. There's much more here, and much more documentation to
come...
Documentation is a major ongoing project; assistance is greatly
appreciated! In the meantime, useful examples of every BPL feature should
be evident in the regression test files <code>test/comprehensive.[<a
href="../test/comprehensive.py">py</a>/<a
href="../test/comprehensive.hpp">hpp</a>/<a
href="../test/comprehensive.cpp">cpp</a>]</code>
<p>
Questions should be directed to <a href=
"http://www.egroups.com/list/boost">the boost mailing list</a>.
<h2>Naming Contest</h2>
<p>
Yes, I know py_cpp is a lousy name. Problem is, the best names my puny
imagination can muster (IDLE and GRAIL) are taken, so I'm holding a
naming contest. First prize? You get to pick the name&lt;0.2wink&gt; and
you will be credited in the documentation. Names that have been suggested
so far include:
<ul>
<li>
Py++
<li>
Python++
<li>
Coil
<li>
SnakeSkin
<li>
CCCP - <b>C</b>onvert <b>C</b>++ <b>
C</b>lasses to <b>P</b>ython
<li>
C<sup>3</sup>PO - <b>C</b>onvert <b>C</b>++
<b>C</b>lasses to <b>P</b>ython <b>
O</b>bjects
<li>
PALIN - <b>P</b>ython <b>
A</b>ugmented-<b>L</b>anguage <b>
IN</b>tegration
<li>
CLEESE - <b>C</b>++ <b>L</b>anguage <b>E</b>xtension <b>E</b>nvironment
<b>S</b>upremely <b>E</b>asy
<li>
JONES - <b>J</b>ust <b>O</b>bscenely <b>N</b>eat <b>E</b>xtension
<b>S</b>ystem
<li>
C-thru
<li>
SeamlessC
<li>
BorderCrossing
<li>
Perseus (because he solved a hairy problem involving snakes by using
reflection and was invisible most of the time).
</ul>
Please <a href="http://www.egroups.com/list/boost">post</a> or send <a
href="http:mailto:abrahams@mediaone.net">me</a> your suggestions!<br>
<br>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright

View File

@@ -12,11 +12,11 @@
<h2>Inheritance in Python</h2>
<p>
Py_cpp extension classes support single and multiple-inheritance in
Python, just like regular Python classes. You can mix built-in Python
classes with py_cpp extension classes in a derived class' tuple of
bases. Whenever a py_cpp extension class is among the bases for a new
class in Python, the result is an extension class:
BPL extension classes support single and multiple-inheritance in
Python, just like regular Python classes. You can arbitrarily mix
built-in Python classes with extension classes in a derived class'
tuple of bases. Whenever a BPL extension class is among the bases for a
new class in Python, the result is an extension class:
<blockquote>
<pre>
&gt;&gt;&gt; class MyPythonClass:
@@ -37,7 +37,7 @@
<h2><a name="implicit_conversion">Reflecting C++ Inheritance Relationships</a></h2>
<p>
Py_cpp also allows us to represent C++ inheritance relationships so that
BPL also allows us to represent C++ inheritance relationships so that
wrapped derived classes may be passed where values, pointers, or
references to a base class are expected as arguments. The
<code>declare_base</code> member function of
@@ -71,7 +71,11 @@ int get_derived_x(const Derived& d) {
return d.x;
}
<hr>
#include <boost/python/class_builder.hpp>
#include &lt;boost/python/class_builder.hpp&gt;
// namespace alias for code brevity
namespace python = boost::python;
extern "C"
#ifdef _WIN32
__declspec(dllexport)
@@ -80,13 +84,13 @@ void initmy_module()
{
    try
    {
       boost::python::module_builder my_module("my_module");
       python::module_builder my_module("my_module");
       boost::python::class_builder&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(boost::python::constructor&lt;void&gt;());
       python::class_builder&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(python::constructor&lt;void&gt;());
       boost::python::class_builder&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(boost::python::constructor&lt;void&gt;());
       python::class_builder&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(python::constructor&lt;void&gt;());
<b>// Establish the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);</b>
@@ -96,7 +100,7 @@ void initmy_module()
    }
    catch(...)
    {
       boost::python::handle_exception();    // Deal with the exception for Python
       python::handle_exception();    // Deal with the exception for Python
    }
}
</pre>
@@ -135,12 +139,12 @@ struct Base2 {};
struct Derived2 { int f(); };
<hr>
...
   boost::python::class_builder&lt;Base&gt; base2_class(my_module, "Base2");
   base2_class.def(boost::python::constructor&lt;void&gt;());
   python::class_builder&lt;Base&gt; base2_class(my_module, "Base2");
   base2_class.def(python::constructor&lt;void&gt;());
   boost::python::class_builder&lt;Derived2&gt; derived2_class(my_module, "Derived2");
   derived2_class.def(boost::python::constructor&lt;void&gt;());
derived_class.declare_base(base_class, <b>boost::python::without_downcast</b>);
   python::class_builder&lt;Derived2&gt; derived2_class(my_module, "Derived2");
   derived2_class.def(python::constructor&lt;void&gt;());
derived_class.declare_base(base_class, <b>python::without_downcast</b>);
</pre>
</blockquote>
@@ -150,8 +154,8 @@ struct Derived2 { int f(); };
references, or values.
<p>
Next: <a href="special.html">Special Method and Operator Support</a>
Previous: <a href="overloading.html">Function Overloading</a>
Next: <a href="special.html">Special Method Names</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,

View File

@@ -113,8 +113,7 @@ namespace scope as Python member functions.
<h2>Overload Resolution</h2>
<p>
The function overload resolution mechanism in py_cpp works as
follows:
The function overload resolution mechanism works as follows:
<ul>
@@ -141,8 +140,8 @@ namespace scope as Python member functions.
</ul>
<p>
Prev: <a href="overriding.html">Overridable Virtual Functions</a>
Next: <a href="inheritance.html">Special Method Names</a>
Next: <a href="inheritance.html">Inheritance</a>
Previous: <a href="overriding.html">Overridable Virtual Functions</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,

View File

@@ -17,7 +17,7 @@
<h2><a name="overriding_example">Example</a></h2>
<p>In this example, it is assumed that <code>world::get()</code> is a virtual
<p>In this example, it is assumed that <code>world::greet()</code> is a virtual
member function:
<blockquote><pre>
@@ -26,7 +26,7 @@ class world
public:
   world(int);
    virtual ~world();
    <b>virtual</b> std::string get() const { return "hi, world"; }
    <b>virtual</b> std::string greet() const { return "hi, world"; }
};
</pre></blockquote>
@@ -65,11 +65,11 @@ struct world_callback : world
: world(x),
m_self(self) {}
std::string get() const // <a href="#derived_3">3</a>
std::string greet() const // <a href="#derived_3">3</a>
{ return boost::python::callback&lt;std::string&gt;::call_method(m_self, "get"); }
static std::string <a name= "default_implementation">default_get</a>(const hello::world& self) const // <a href="#derived_4">4</a>
{ return self.world::get(); }
{ return self.world::greet(); }
private:
PyObject* m_self; // <a href="#derived_1">1</a>
};
@@ -94,7 +94,7 @@ world_class.def(&amp;world::get, "get", &amp;<b>world_callback::default_get</b>)
<blockquote><pre>
&gt;&gt;&gt; class my_subclass(hello.world):
... def get(self):
... def greet(self):
... return 'hello, world'
...
&gt;&gt;&gt; hello.length(my_subclass())
@@ -181,9 +181,9 @@ break the <a
href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR</a>).
<p>
Prev: <a href="example1.html">A Simple Example Using py_cpp</a> Next: <a
href="overloading.html">Function Overloading</a> Up: <a href=
"index.html">Top</a>
Next: <a href="overloading.html">Function Overloading</a>
Previous: <a href="example1.html">A Simple Example Using py_cpp</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright

View File

@@ -13,7 +13,7 @@
<p>
In general, raw pointers passed to or returned from functions are problematic
for py_cpp because pointers have too many potential meanings. Is it an iterator?
for BPL because pointers have too many potential meanings. Is it an iterator?
A pointer to a single element? An array? When used as a return value, is the
caller expected to manage (delete) the pointed-to object or is the pointer
really just a reference? If the latter, what happens to Python references to the
@@ -35,11 +35,9 @@ converted from/to Python strings.
<p>My first piece of advice to anyone with a case not covered above is
&ldquo;find a way to avoid the problem.&rdquo; For example, if you have just one
or two functions returning a pointer to a single (not an array of) <code>const
T*</code> for some wrapped <code>T</code>, you may be able to write a &ldquo;thin
converting wrapper&rdquo; over those two functions as follows (Since py_cpp
converts <code>const T&</code> values <code>to_python</code> by copying the T
into a new extension instance, Foo must have a public copy constructor):
or two functions that return a pointer to an individual <code>const
T</code>, and <code>T</code> is a wrapped class, you may be able to write a &ldquo;thin
converting wrapper&rdquo; over those two functions as follows:
<blockquote><pre>
const Foo* f(); // original function
@@ -47,6 +45,10 @@ const Foo& f_wrapper() { return *f(); }
...
my_module.def(f_wrapper, "f");
</pre></blockquote>
<p>
Foo must have a public copy constructor for this technique to work, since BPL
converts <code>const T&</code> values <code>to_python</code> by copying the <code>T</code>
value into a new extension instance.
<h2>Dealing with the problem</h2>
@@ -118,7 +120,7 @@ return value. You can handle this case by returning a Python tuple:
typedef unsigned ErrorCode;
const char* f(int* in_out_x); // original function
...
#include <boost/python/objects.hpp>
#include &lt;boost/python/objects.hpp&gt;
const boost::python::tuple f_wrapper(int in_x) {
const char* s = f(in_x);
return boost::python::tuple(s, in_x);
@@ -131,8 +133,9 @@ my_module.def(f_wrapper, "f");
&gt;&gt;&gt; str,out_x = f(3)
</pre></blockquote>
<p>
Previous: <a href="enums.html">Enums</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright

View File

@@ -13,7 +13,7 @@
Overview
</h2>
<p>
Py_cpp supports all of the standard <a href=
BPL supports all of the standard <a href=
"http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/specialnames.html">
special method names</a> supported by real Python class instances <em>
except</em> <code>__complex__</code> (more on the reasons <a href=
@@ -100,7 +100,7 @@ std::string to_string(Foo const&amp; f)
boost::python::class_builder&lt;Foo&gt; foo_class(my_module, "Foo");
foo_class.def(&amp;to_string, "__str__");
</pre></blockquote>
Note that py_cpp also supports <em>automatic wrapping</em> of
Note that BPL also supports <em>automatic wrapping</em> of
<code>__str__</code> and <code>__cmp__</code>. This is explained in the <a
href="#numeric">next section</a> and the <a href="#numeric_table">Table of
Automatically Wrapped Methods</a>.
@@ -113,7 +113,7 @@ foo_class.def(&amp;to_string, "__str__");
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/numeric-types.html">numeric
protocols</a>. This is the basic same technique used to expose
<code>to_string()</code> as <code>__str__()</code> above, and is <a
href="#numeric_manual">covered in detail below</a>. Py_cpp also supports
href="#numeric_manual">covered in detail below</a>. BPL also supports
<i>automatic wrapping</i> of numeric operators whenever they have already
been defined in C++.
@@ -170,7 +170,7 @@ a = i + b;
bignum_class.def(boost::python::operators&lt;boost::python::op_add&gt;(), boost::python::right_operand&lt;int&gt;());
bignum_class.def(boost::python::operators&lt;boost::python::op_add&gt;(), boost::python::left_operand&lt;int&gt;());
</pre></blockquote>
Py_cpp uses overloading to register several variants of the same
BPL uses overloading to register several variants of the same
operation (more on this in the context of <a href="#coercion">
coercion</a>). Again, several operators can be exported at once:
<blockquote><pre>
@@ -276,13 +276,13 @@ bignum_class.def(&amp;rmod, "__rmod__");
coercion functions can be difficult if many type combinations must be
supported.
<p>
Py_cpp solves this problem the same way that C++ does: with <em><a
BPL solves this problem the same way that C++ does: with <em><a
href="overloading.html">overloading</a></em>. This technique drastically
simplifies the code neccessary to support operators: you just register
operators for all desired type combinations, and py_cpp automatically
operators for all desired type combinations, and BPL automatically
ensures that the correct function is called in each case; there is no
need for user-defined coercion functions. To enable operator
overloading, py_cpp provides a standard coercion which is <em>implicitly
overloading, BPL provides a standard coercion which is <em>implicitly
registered</em> whenever automatic operator wrapping is used.
<p>
If you wrap all operator functions manually, but still want to use
@@ -354,7 +354,7 @@ bignum_class.def((ternary_function2)&amp;power, "__pow__");
In the second variant, however, <code>BigNum</code> appears only as second
argument, and in the last one it is the third argument. These functions
must be presented to py_cpp such that that the <code>BigNum</code>
must be presented to BPL such that that the <code>BigNum</code>
argument appears in first position:
<blockquote><pre>
@@ -381,7 +381,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<h2><a name="numeric_table">Table of Automatically Wrapped Methods</a></h2>
<p>
Py_cpp can automatically wrap the following <a href=
BPL can automatically wrap the following <a href=
"http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/specialnames.html">
special methods</a>:
@@ -755,13 +755,13 @@ KeyError: 2
<h2><a name="getter_setter">Customized Attribute Access</a></h2>
<p>
Just like built-in Python classes, py_cpp extension classes support <a
Just like built-in Python classes, BPL extension classes support <a
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/attribute-access.html">special
the usual attribute access methods</a> <code>__getattr__</code>,
<code>__setattr__</code>, and <code>__delattr__</code>.
Because writing these functions can
be tedious in the common case where the attributes being accessed are
known statically, py_cpp checks the special names
known statically, BPL checks the special names
<ul>
<li>
@@ -777,7 +777,7 @@ KeyError: 2
following shows how we can implement a &ldquo;computed attribute&rdquo; in Python:
<blockquote>
<pre>
&gt;&gt;&gt; class Range(AnyPy_cppExtensionClass):
&gt;&gt;&gt; class Range(AnyBPLExtensionClass):
... def __init__(self, start, end):
... self.start = start
... self.end = end
@@ -793,7 +793,7 @@ KeyError: 2
Direct Access to Data Members
</h4>
<p>
Py_cpp uses the special <code>
BPL uses the special <code>
__xxxattr__<em>&lt;name&gt;</em>__</code> functionality described above
to allow direct access to data members through the following special
functions on <code>class_builder&lt;&gt;</code> and <code>
@@ -873,9 +873,9 @@ if (PyInstance_Check(r)) { ...
</pre>
</blockquote>
<p>
Previous: <a href="inheritance.html">Inheritance</a> Next: <a href=
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
"index.html">Top</a>
Next: <a href="under-the-hood.html">A Peek Under the Hood</a>
Previous: <a href="inheritance.html">Inheritance</a>
Up: <a href= "index.html">Top</a>
<p>
&copy; Copyright David Abrahams and Ullrich K&ouml;the 2000.
Permission to copy, use, modify, sell and distribute this document is

View File

@@ -22,7 +22,7 @@
"example1.html#add_world_class">add it to the module</a> it goes into the
module's dictionary to be looked up under the name "world".
<p>
Py_cpp uses C++'s template argument deduction mechanism to determine the
BPL uses C++'s template argument deduction mechanism to determine the
types of arguments to functions (except constructors, for which we must
<a href="example1.html#Constructor_example">provide an argument list</a>
because they can't be named in C++). Then, it calls the appropriate
@@ -48,8 +48,8 @@
the top of your module's init function, then <code>def</code> the member
functions later to avoid problems with inter-class dependencies.
<p>
Previous: <a href="overriding.html">Function Overloading</a>
Next: <a href="building.html">Building a Module with Py_cpp</a>
Next: <a href="building.html">Building a Module with BPL</a>
Previous: <a href="special.html">Special Method and Operator Support</a>
Up: <a href="index.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,