From 445b0438a2da659c6bff6c1ca29771345d639365 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 Nov 2000 04:42:46 +0000 Subject: [PATCH 001/279] bug fix [SVN r8345] --- example/rwgk1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/rwgk1.cpp b/example/rwgk1.cpp index 0577aded..b21ae4d1 100644 --- a/example/rwgk1.cpp +++ b/example/rwgk1.cpp @@ -17,7 +17,7 @@ extern "C" #ifdef _WIN32 __declspec(dllexport) #endif -initrwgk1() +void initrwgk1() { try { From 4e27f8de274fd8f76ea227200b6c2a0d3352ec21 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 Nov 2000 05:17:07 +0000 Subject: [PATCH 002/279] boost-ification [SVN r8347] --- build/como.mak | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ build/gcc.mak | 39 +++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 build/como.mak diff --git a/build/como.mak b/build/como.mak new file mode 100644 index 00000000..5a9920d8 --- /dev/null +++ b/build/como.mak @@ -0,0 +1,51 @@ +LIBSRC = \ + classes.cpp \ + conversions.cpp \ + extension_class.cpp \ + functions.cpp \ + init_function.cpp \ + module_builder.cpp \ + objects.cpp \ + types.cpp + +LIBOBJ = $(LIBSRC:.cpp=.o) +OBJ = $(LIBOBJ) + + +ifeq "$(OS)" "Windows_NT" +PYTHON_LIB=c:/tools/python/libs/python15.lib +INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include +MODULE_EXTENSION=dll +else +INC = -I/usr/local/include/python1.5 +MODULE_EXTENSION=so +endif + +%.o: ../src/%.cpp + como --pic $(INC) -o $*.o -c $< + +%.d: ../src/%.cpp + @echo creating $@ + @set -e; como -M $(INC) -c $< \ + | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ + [ -s $@ ] || rm -f $@ + +example1: example1.o libpycpp.a + como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lpycpp + python ../example/test_example1.py + +example1.o: ../example/example1.cpp + como --pic $(INC) -o $*.o -c $< + +clean: + rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out + +libpycpp.a: $(LIBOBJ) + rm -f libpycpp.a + ar cq libpycpp.a $(LIBOBJ) + +DEP = $(OBJ:.o=.d) + +ifneq "$(MAKECMDGOALS)" "clean" +include $(DEP) +endif diff --git a/build/gcc.mak b/build/gcc.mak index cec872cf..d0b42548 100644 --- a/build/gcc.mak +++ b/build/gcc.mak @@ -1,15 +1,15 @@ LIBSRC = \ - extclass.cpp \ - init_function.cpp \ - py.cpp \ - module.cpp \ - subclass.cpp \ + classes.cpp \ + conversions.cpp \ + extension_class.cpp \ functions.cpp \ - newtypes.cpp \ - objects.cpp - + init_function.cpp \ + module_builder.cpp \ + objects.cpp \ + types.cpp + LIBOBJ = $(LIBSRC:.cpp=.o) -OBJ = $(LIBOBJ) extclass_demo.o +OBJ = $(LIBOBJ) ifeq "$(OS)" "Windows_NT" @@ -17,22 +17,27 @@ PYTHON_LIB=c:/tools/python/libs/python15.lib INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include MODULE_EXTENSION=dll else -INC = -I/home/koethe/include -I/home/koethe/C++/boost -I/home/koethe/python/include/python1.5 +INC = -I/usr/local/include/python1.5 MODULE_EXTENSION=so endif -%.o: %.cpp - g++ -fPIC $(INC) -c $*.cpp +%.o: ../src/%.cpp + g++ -fPIC -Wall -W $(INC) -o $*.o -c $< -%.d: %.cpp +%.d: ../src/%.cpp @echo creating $@ - @set -e; g++ -M $(INC) -c $*.cpp \ + @set -e; g++ -M $(INC) -c $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ -demo: extclass_demo.o libpycpp.a - g++ -shared -o demomodule.$(MODULE_EXTENSION) $(PYTHON_LIB) extclass_demo.o -L. -lpycpp - python test_extclass.py + +example1: example1.o libpycpp.a + g++ -shared -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lpycpp + python ../example/test_example1.py + +example1.o: ../example/example1.cpp + g++ -fPIC -Wall -W $(INC) -o $*.o -c $< + clean: rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out From 7f58e66754067b1852b7a66aa515d83afc7c25a5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 Nov 2000 05:17:55 +0000 Subject: [PATCH 003/279] removed non-portable but beautiful “/” [SVN r8349] --- doc/building.html | 4 +- doc/comparisons.html | 38 ++++---- doc/data_structures.txt | 192 ++++++++++++++++++++++++++++++++++++++++ doc/enums.html | 4 +- doc/example1.html | 6 +- doc/index.html | 10 ++- doc/overloading.html | 14 +-- doc/pointers.html | 6 +- doc/special.html | 20 ++--- 9 files changed, 244 insertions(+), 50 deletions(-) create mode 100644 doc/data_structures.txt diff --git a/doc/building.html b/doc/building.html index 84657b7a..4ac2343c 100644 --- a/doc/building.html +++ b/doc/building.html @@ -35,8 +35,8 @@

© Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided “as - is” without express or implied warranty, and with no claim as to + notice appears in all copies. This document is provided ``as + is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

Updated: Nov 26, 2000 diff --git a/doc/comparisons.html b/doc/comparisons.html index 2590dae2..336220fb 100644 --- a/doc/comparisons.html +++ b/doc/comparisons.html @@ -19,7 +19,7 @@ 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 - “dealing with Python objects”, though they are wrapped in + ``dealing with Python objects'', 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. @@ -40,8 +40,8 @@

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. While you're hardly programming directly to the “bare - metal” with CXX, it basically presents a “C++-ized” + same fully-generic interfaces we use in Python. While you're hardly programming directly to the ``bare + metal'' with CXX, it basically presents a ``C++-ized'' version of the Python 'C' API.

@@ -51,11 +51,11 @@ fill in the other half. Here is his response to the commentary above:

-“My intention with CXX was not to do what you are doing. It was to enable a +``My intention with CXX was not to do what you are doing. It was to enable a person to write an extension directly in C++ rather than C. I figured others had the wrapping business covered. I thought maybe CXX would provide an easier target language for those making wrappers, but I never explored -that.”
-Paul Dubois +that.''
-Paul Dubois

SWIG

@@ -67,20 +67,20 @@ that.”
-Paul Dubois Perl or Tcl) extension module. It has been successfully used to create 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 “SWIG parses a form of ANSI C + existing code. The documentation says ``SWIG parses a form of ANSI C syntax that has been extended with a number of special directives. As a result, interfaces are usually built by grabbing a header file and - tweaking it a little bit.” For C++ interfaces, the tweaking has often + tweaking it a little bit.'' For C++ interfaces, the tweaking has often proven to amount to more than just a little bit. One user writes: -
“The problem with swig (when I used it) is that it +
``The problem with swig (when I used it) is that it 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 BPL doesn't have this problem[sic]... IMHO overloaded functions are very important to - wrap correctly.”
-Prabhu Ramachandran + wrap correctly.''
-Prabhu Ramachandran

@@ -124,7 +124,7 @@ that.”
-Paul Dubois GRAD is another very ambitious project aimed at generating Python wrappers for - interfaces written in “legacy languages”, among which C++ is the first one + interfaces written in ``legacy languages'', among which C++ is the first one implemented. Like SWIG, it aims to parse source code and automatically generate wrappers, though it appears to take a more sophisticated approach to parsing in general and C++ in particular, so it should do a much better @@ -152,9 +152,9 @@ an inheritance relationship? 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 - same “Don - Beaudry Hack” that also inspired Don's MESS System. + Beaudry Hack'' that also inspired Don's MESS System.

The major differences are:

Here is the C++ code for a python module called hello - which exposes the API using BPL: + which exposes the API using:

 #include <boost/python/class_builder.hpp>
diff --git a/doc/index.html b/doc/index.html
index 43a971bf..1167f637 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -16,7 +16,7 @@
       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 BPL. The system
-      should simply “reflect” your C++ classes and functions into
+      should simply ``reflect'' your C++ classes and functions into
       Python. The major features of BPL include support for:
 
  • Subclassing extension types in Python @@ -99,7 +99,7 @@ among others.
  • Comparisons between BPL and other systems for extending Python -
  • A Simple Example Using BPL +
  • A Simple Example
  • Overridable Virtual Functions @@ -111,7 +111,7 @@ among others.
  • A Peek Under the Hood -
  • Building a Module with BPL +
  • Building an Extension Module
  • Advanced Topics @@ -131,6 +131,8 @@ among others.
  • Other Extension Types
  • Templates + +
  • Internal Data Structures @@ -150,7 +152,7 @@ among others.

    © Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided “as is” without + notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

    diff --git a/doc/overloading.html b/doc/overloading.html index 5c2c236d..995b3a40 100644 --- a/doc/overloading.html +++ b/doc/overloading.html @@ -123,7 +123,7 @@ namespace scope as Python member functions. class is found which has a matching attribute, only functions overloaded in the context of that class are candidates for overload resolution. In this sense, overload resolution mirrors the C++ mechanism, where a name - in a derived class “hides” all functions with the same name from a base + in a derived class ``hides'' all functions with the same name from a base class.

    @@ -132,11 +132,11 @@ namespace scope as Python member functions. def()ed. The first function whose signature can be made to match each argument passed is the one which is ultimately called. This means in particular that you cannot overload the same function on - both “int” and “float” because Python + both ``int'' and ``float'' because Python automatically converts either of the two types into the other one. - If the “float” overload is found first, it is used - also used for arguments of type “int” as well, and the - “int” version of the function is never invoked. + If the ``float'' overload is found first, it is used + also used for arguments of type ``int'' as well, and the + ``int'' version of the function is never invoked.

@@ -146,8 +146,8 @@ namespace scope as Python member functions.

© Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided “as - is” without express or implied warranty, and with no claim as to + notice appears in all copies. This document is provided ``as + is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

Updated: Nov 26, 2000 diff --git a/doc/pointers.html b/doc/pointers.html index 0d0a92dc..26f96f0d 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -34,10 +34,10 @@ converted from/to Python strings.

Can you avoid the problem?

My first piece of advice to anyone with a case not covered above is -“find a way to avoid the problem.” For example, if you have just one +``find a way to avoid the problem.'' For example, if you have just one or two functions that return a pointer to an individual const -T, and T is a wrapped class, you may be able to write a “thin -converting wrapper” over those two functions as follows: +T, and T is a wrapped class, you may be able to write a ``thin +converting wrapper'' over those two functions as follows:

 const Foo* f(); // original function
diff --git a/doc/special.html b/doc/special.html
index 7dd210ba..286dc396 100644
--- a/doc/special.html
+++ b/doc/special.html
@@ -78,7 +78,7 @@
         
__call__ (self[, args...])
-Called when the instance is “called” as a function; if this method +Called when the instance is ``called'' as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...). @@ -143,7 +143,7 @@ bignum_class.def(boost::python::operators<boost::python::op_add>()); Since BigNum also supports subtraction, multiplication, and division, we want to export those also. This can be done in a single command by - “or”ing the operator identifiers together (a complete list of these + ``or''ing the operator identifiers together (a complete list of these identifiers and the corresponding operators can be found in the Table of Automatically Wrapped Methods):
@@ -181,7 +181,7 @@ bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::pyt
 
The type of the operand not mentioned is taken from the class being wrapped. In our example, the class object is bignum_class, and thus the - other operand's type is “BigNum const&”. You can override + other operand's type is ``BigNum const&''. You can override this default by explicitly specifying a type in the operators template:
@@ -189,7 +189,7 @@ bignum_class.def(boost::python::operators<boost::python::op_add, BigNum>()
 

Note that automatic wrapping uses the expression - “left + right” and can be used uniformly + ``left + right'' and can be used uniformly regardless of whether the C++ operators are supplied as free functions

 BigNum operator+(BigNum, BigNum)
@@ -261,9 +261,9 @@ bignum_class.def(&rmod,  "__rmod__");
       

Automatic and manual wrapping can be mixed arbitrarily. Note that you cannot overload the same operator for a given extension class on both - “int” and “float”, because Python implicitly + ``int'' and ``float'', because Python implicitly converts these types into each other. Thus, the overloaded variant - found first (be it “int“ or “float”) will be + found first (be it ``int`` or ``float'') will be used for either of the two types.

Coercion

@@ -315,7 +315,7 @@ some_class.def(&custom_coerce, "__coerce__"); Note that the later use of automatic operator wrapping on a class_builder or a call to - “some_class.def_standard_coerce()” will cause any + ``some_class.def_standard_coerce()'' will cause any custom coercion function to be replaced by the standard one.

The Ternary pow() Operator

@@ -689,7 +689,7 @@ void throw_key_error_if_end( // Define some simple wrapper functions which match the Python protocol // for __getitem__, __setitem__, and __delitem__. Just as in Python, a -// free function with a “self” first parameter makes a fine class method. +// free function with a ``self'' first parameter makes a fine class method. const std::string& get_item(const StringMap& self, std::size_t key) { @@ -774,7 +774,7 @@ KeyError: 2 to provide functional access to the attribute <name>. This facility can be used from C++ or entirely from Python. For example, the - following shows how we can implement a “computed attribute” in Python: + following shows how we can implement a ``computed attribute'' in Python:
 >>> class Range(AnyBPLExtensionClass):
@@ -880,7 +880,7 @@ Up: Top
          © Copyright David Abrahams and Ullrich Köthe 2000.
         Permission to copy, use, modify, sell and distribute this document is
         granted provided this copyright notice appears in all copies. This
-        document is provided “as is” without express or implied
+        document is provided ``as is'' without express or implied
         warranty, and with no claim as to its suitability for any purpose.
       

Updated: Nov 26, 2000 From c278310d1b6b2bbe25d6a2fec944bde3ce07c231 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 Nov 2000 05:19:10 +0000 Subject: [PATCH 004/279] Fix for compatibility with STLport using native iostreams [SVN r8351] --- include/boost/python/operators.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index d0c06895..e76943e8 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -2,7 +2,9 @@ #define OPERATORS_UK112000_H_ #include -#if !defined(__GNUC__) || defined(__SGI_STL_PORT) +// When STLport is used with native streams, _STL::ostringstream().str() is not +// _STL::string, but std::string. +#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) # include #else # include @@ -473,17 +475,15 @@ namespace detail { tuple args(ref(arguments, ref::increment_count)); -#if !defined(__GNUC__) || defined(__SGI_STL_PORT) +// When STLport is used with native streams, _STL::ostringstream().str() is not +// _STL::string, but std::string. +#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) std::ostringstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); + return BOOST_PYTHON_CONVERSION::to_python(s.str()); #else std::ostrstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) << char(); -#endif - -#if !defined(__GNUC__) || defined(__SGI_STL_PORT) - return BOOST_PYTHON_CONVERSION::to_python(s.str()); -#else return BOOST_PYTHON_CONVERSION::to_python(const_cast(s.str())); #endif } From 8637e270a90a8cbb60e674375d67b6dd09356910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20K=C3=B6the?= Date: Tue, 28 Nov 2000 21:22:21 +0000 Subject: [PATCH 005/279] minor improvements, fix of typos [SVN r8352] --- doc/special.html | 62 +++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/doc/special.html b/doc/special.html index 286dc396..525b0a56 100644 --- a/doc/special.html +++ b/doc/special.html @@ -41,12 +41,17 @@ __init__(self)

Initialize the class instance. For extension classes not subclassed in - Python, this is provided by the - boost::python::constructor<...>() construct and should not be explicitly defed. + Python, __init__ is defined by + +
    my_class.def(boost::python::constructor<...>())
+ + (see section "A Simple Example Using BPL").

__del__(self)
- Called when the extension instance is about to be destroyed. + Called when the extension instance is about to be destroyed. For extension classes + not subclassed in Python, __del__ is always defined automatically by + means of the class' destructor.
__repr__(self)
@@ -111,7 +116,7 @@ foo_class.def(&to_string, "__str__"); Numeric operators can be exposed manually, by defing C++ [member] functions that support the standard Python numeric - protocols. This is the basic same technique used to expose + protocols. This is the same basic technique used to expose to_string() as __str__() above, and is covered in detail below. BPL also supports automatic wrapping of numeric operators whenever they have already @@ -121,7 +126,7 @@ foo_class.def(&to_string, "__str__");

Supose we wanted to expose a C++ class - BigNum which supports addition, so that we can write (in C++): + BigNum which supports addition. That is, in C++ we can write:

 BigNum a, b, c;
 ...
@@ -196,7 +201,7 @@ BigNum operator+(BigNum, BigNum)
 
or as member functions
-BigNum::operator+(BigNum).
+BigNum BigNum::operator+(BigNum).
 

@@ -218,8 +223,7 @@ namespace boost { namespace python {

In some cases, automatic wrapping of operators may be impossible or undesirable. Suppose, for example, that the modulo operation for BigNums - is defined by a set of functions mod() (for automatic - wrapping, we would need operator%()): + is defined by a set of functions called mod():

 BigNum mod(BigNum const& left, BigNum const& right);
@@ -228,8 +232,9 @@ BigNum mod(int left, BigNum const& right);
 

- In order to create the Python operator "__mod__" from these functions, we - have to wrap them manually: + For automatic wrapping of the modulo function, operator%() would be needed. + Therefore, the mod()-functions must be wrapped manually. That is, we have + to export them explicitly with the Python special name "__mod__":

 bignum_class.def((BigNum (*)(BigNum const&, BigNum const&))&mod, "__mod__");
@@ -237,8 +242,8 @@ bignum_class.def((BigNum (*)(BigNum const&, int))&mod, "__mod__");
 

- The third form (with int as left operand) cannot be wrapped - this way. We must first create a function rmod() with the + The third form of mod() (with int as left operand) cannot + be wrapped directly. We must first create a function rmod() with the operands reversed:

@@ -248,7 +253,7 @@ BigNum rmod(BigNum const& right, int left)
 }
 
- This function must be wrapped under the name "__rmod__": + This function must be wrapped under the name "__rmod__" (standing for "reverse mod"):
 bignum_class.def(&rmod,  "__rmod__");
@@ -271,7 +276,7 @@ bignum_class.def(&rmod,  "__rmod__");
 
       Plain Python can only execute operators with identical types on the left
       and right hand side. If it encounters an expression where the types of
-      the left and right operand differ, it tries to coerce these type to a
+      the left and right operand differ, it tries to coerce these types to a
       common type before invoking the actual operator. Implementing good
       coercion functions can be difficult if many type combinations must be
       supported. 
@@ -295,7 +300,7 @@ bignum_class.def_standard_coerce();
 
If you encounter a situation where you absolutely need a customized - coercion, you can overload the "__coerce__" operator itself. The signature + coercion, you can still define the "__coerce__" operator manually. The signature of a coercion function should look like one of the following (the first is the safest): @@ -310,13 +315,22 @@ PyObject* custom_coerce(PyObject* left, PyObject* right); converted to the same type. Such a function is wrapped as usual:
+// this must be called before any use of automatic operator  
+// wrapping or a call to some_class.def_standard_coerce()
 some_class.def(&custom_coerce, "__coerce__");
 
- Note that the later use of automatic operator wrapping on a + Note that the standard coercion (defined by use of automatic operator wrapping on a class_builder or a call to - ``some_class.def_standard_coerce()'' will cause any - custom coercion function to be replaced by the standard one. + “some_class.def_standard_coerce()”) will never be applied + if a custom coercion function has been registered. Therefore, in your coercion function + you should call + +
+boost::python::detail::extension_class_coerce(left, right);
+
+ + for all cases that you don't want to handle yourself.

The Ternary pow() Operator

@@ -330,7 +344,7 @@ some_class.def(&custom_coerce, "__coerce__"); this is done as usual:
-BigNum power(BigNum const& first, BigNum const& second, BigNum const& module);
+BigNum power(BigNum const& first, BigNum const& second, BigNum const& modulus);
 typedef BigNum (ternary_function1)(const BigNum&, const BigNum&, const BigNum&);
 ...
 bignum_class.def((ternary_function1)&power,  "__pow__");
@@ -353,19 +367,19 @@ bignum_class.def((ternary_function2)&power,  "__pow__");
 
In the second variant, however, BigNum appears only as second - argument, and in the last one it is the third argument. These functions + argument, and in the last one it's the third argument. These functions must be presented to BPL such that that the BigNum argument appears in first position:
 BigNum rpower(BigNum const& second, int first, int modulus)
 {
-    return power(first, second, third);
+    return power(first, second, modulus);
 }
 
-BigNum rrpower(BigNum const& third, int first, int second)
+BigNum rrpower(BigNum const& modulus, int first, int second)
 {
-    return power(first, second, third);
+    return power(first, second, modulus);
 }
 
@@ -637,7 +651,7 @@ for i in S: while in C++ one writes
-for (iterator i = S.begin(), end = S.end(); i != end)
+for (iterator i = S.begin(), end = S.end(); i != end; ++i)
 

One could try to wrap C++ iterators in order to carry the C++ idiom into From 8a5de60b33218a6c66354945f43bbff65e4ab176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20K=C3=B6the?= Date: Tue, 28 Nov 2000 21:38:21 +0000 Subject: [PATCH 006/279] fixed html bugs recovered by "validator.w3.org" [SVN r8353] --- doc/special.html | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/special.html b/doc/special.html index 525b0a56..1f35b01d 100644 --- a/doc/special.html +++ b/doc/special.html @@ -1,11 +1,10 @@ - + Special Method and Operator Support

- c++boost.gif (8819 bytes)Special Method and Operator Support

@@ -202,7 +201,7 @@ BigNum operator+(BigNum, BigNum) or as member functions
 BigNum BigNum::operator+(BigNum).
-
+

For the Python built-in functions pow() and @@ -646,13 +645,13 @@ Note that "__rrpow__" is an extension not present in plain Python. iteration idiom looks like

 for i in S:
-
+ while in C++ one writes
 for (iterator i = S.begin(), end = S.end(); i != end; ++i)
-
+

One could try to wrap C++ iterators in order to carry the C++ idiom into Python. However, this does not work very well because From ecdf8e1591508c33e1c303aa145d94918a260369 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 Nov 2000 13:41:18 +0000 Subject: [PATCH 007/279] changed name of extension_class_coerce to standard_coerce, applied Ullrich's documentation fix for standard_coerce. [SVN r8356] --- doc/special.html | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/special.html b/doc/special.html index 1f35b01d..7debc7c1 100644 --- a/doc/special.html +++ b/doc/special.html @@ -195,12 +195,15 @@ bignum_class.def(boost::python::operators<boost::python::op_add, BigNum>() Note that automatic wrapping uses the expression ``left + right'' and can be used uniformly regardless of whether the C++ operators are supplied as free functions -

+
+ 
 BigNum operator+(BigNum, BigNum)
 
- or as member - functions
-BigNum BigNum::operator+(BigNum).
+
+        or as member functions
+
+
+BigNum::operator+(BigNum).
 

@@ -319,17 +322,17 @@ PyObject* custom_coerce(PyObject* left, PyObject* right); some_class.def(&custom_coerce, "__coerce__");

- Note that the standard coercion (defined by use of automatic operator wrapping on a - class_builder or a call to - “some_class.def_standard_coerce()”) will never be applied - if a custom coercion function has been registered. Therefore, in your coercion function - you should call + Note that the standard coercion (defined by use of automatic + operator wrapping on a class_builder or a call to + class_builder::def_standard_coerce()) will never be applied if + a custom coercion function has been registered. Therefore, in + your coercion function you should call
-boost::python::detail::extension_class_coerce(left, right);
+boost::python::standard_coerce(left, right);
 
- for all cases that you don't want to handle yourself. + for all cases that you don't want to handle yourself.

The Ternary pow() Operator

@@ -643,11 +646,12 @@ Note that "__rrpow__" is an extension not present in plain Python. to Python's iteration and access protocols. These protocols differ considerably from the ones found in C++. For example, Python's typical iteration idiom looks like +
 for i in S:
 
-while in C++ one writes + while in C++ one writes
 for (iterator i = S.begin(), end = S.end(); i != end; ++i)

From 0f43a2fe9bd01b818db9519c754476572f3f5ae1 Mon Sep 17 00:00:00 2001
From: Dave Abrahams 
Date: Wed, 29 Nov 2000 13:42:45 +0000
Subject: [PATCH 008/279] changed name of extension_class_coerce to
 standard_coerce.

[SVN r8357]
---
 .../boost/python/detail/extension_class.hpp   |  4 +--
 include/boost/python/operators.hpp            | 19 +++++++-----
 src/extension_class.cpp                       | 29 ++++++++-----------
 3 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp
index 20d48796..0e2e3427 100644
--- a/include/boost/python/detail/extension_class.hpp
+++ b/include/boost/python/detail/extension_class.hpp
@@ -721,8 +721,6 @@ class extension_instance : public instance
 // Template function implementations
 //
 
-tuple extension_class_coerce(ref l, ref r);
-
 template 
 extension_class::extension_class()
     : extension_class_base(typeid(T).name())
@@ -743,7 +741,7 @@ void extension_class::def_standard_coerce()
     ref coerce_fct = dict().get_item(string("__coerce__"));
     
     if(coerce_fct.get() == 0) // not yet defined
-        this->def(&extension_class_coerce, "__coerce__");
+        this->def(&standard_coerce, "__coerce__");
 }
 
 template 
diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp
index e76943e8..40400f47 100644
--- a/include/boost/python/operators.hpp
+++ b/include/boost/python/operators.hpp
@@ -1,17 +1,22 @@
 #ifndef OPERATORS_UK112000_H_
 #define OPERATORS_UK112000_H_
 
-#include 
+# include 
+# include 
+
 // When STLport is used with native streams, _STL::ostringstream().str() is not
-// _STL::string, but std::string.
-#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__)
-# include 
-#else
-# include 
-#endif
+// _STL::string, but std::string. This confuses to_python(), so we'll use
+// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
+# if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) || __GNUC__ > 2
+#  include 
+# else
+#  include 
+# endif
 
 namespace boost { namespace python {
 
+tuple standard_coerce(ref l, ref r);
+
 namespace detail {
   
   // helper class for automatic operand type detection
diff --git a/src/extension_class.cpp b/src/extension_class.cpp
index cde3d836..c15e538b 100644
--- a/src/extension_class.cpp
+++ b/src/extension_class.cpp
@@ -46,24 +46,19 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
 
 namespace boost { namespace python { 
 
-namespace detail {
+tuple standard_coerce(ref l, ref r)
+{
+    // Introduced sequence points for exception-safety.
+    ref first(detail::operator_dispatcher::create(l, l));
+    
+    ref second(r->ob_type == &detail::operator_dispatcher::type_obj
+               ? r
+               : ref(detail::operator_dispatcher::create(r, ref())));
 
-  tuple extension_class_coerce(ref l, ref r)
-  {
-      // Introduced sequence points for exception-safety.
-      ref first(operator_dispatcher::create(l, l));
-      ref second;
-      
-      if(r->ob_type == &operator_dispatcher::type_obj)
-      {
-           second = r;
-      }
-      else
-      {
-           second = ref(operator_dispatcher::create(r, ref()));
-      }
-      return boost::python::tuple(first, second);
-  }
+    return tuple(first, second);
+}
+
+namespace detail {
 
   enum { unwrap_exception_code = -1000 };
 

From 9dca983e3336107c5865149821f5fbbc953dd2d6 Mon Sep 17 00:00:00 2001
From: Dave Abrahams 
Date: Wed, 29 Nov 2000 14:18:37 +0000
Subject: [PATCH 009/279] changed name of extension_class_coerce to
 standard_coerce.

[SVN r8358]
---
 src/gen_extclass.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/gen_extclass.py b/src/gen_extclass.py
index 5180a3de..f8906970 100644
--- a/src/gen_extclass.py
+++ b/src/gen_extclass.py
@@ -707,8 +707,6 @@ class extension_instance : public instance
 // Template function implementations
 //
 
-tuple extension_class_coerce(ref l, ref r);
-
 template 
 extension_class::extension_class()
     : extension_class_base(typeid(T).name())
@@ -729,7 +727,7 @@ void extension_class::def_standard_coerce()
     ref coerce_fct = dict().get_item(string("__coerce__"));
     
     if(coerce_fct.get() == 0) // not yet defined
-        this->def(&extension_class_coerce, "__coerce__");
+        this->def(&standard_coerce, "__coerce__");
 }
 
 template 

From 81cf5333c3318e45b40318435e9159582f7f8261 Mon Sep 17 00:00:00 2001
From: Dave Abrahams 
Date: Thu, 30 Nov 2000 04:51:05 +0000
Subject: [PATCH 010/279] Added module() function to get the module being built
 Added initializing() function to distinguish whether a module is initializing
 Changed logic so that multiple non-overlapping module_builders() may be
 constructed. This fixes a bug when BPL is built as a shared lib.

[SVN r8361]
---
 include/boost/python/module_builder.hpp | 21 ++++++++++++++++++---
 src/module_builder.cpp                  | 12 +++++++++++-
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp
index 57507e59..6a8a9b4b 100644
--- a/include/boost/python/module_builder.hpp
+++ b/include/boost/python/module_builder.hpp
@@ -18,11 +18,10 @@ namespace boost { namespace python {
 
 class module_builder
 {
-    typedef PyObject * (*raw_function_ptr)(boost::python::tuple const &, boost::python::dictionary const &);
-    
  public:
     // Create a module. REQUIRES: only one module_builder is created per module.
     module_builder(const char* name);
+    ~module_builder();
 
     // Add elements to the module
     void add(detail::function* x, const char* name);
@@ -41,13 +40,29 @@ class module_builder
         add(detail::new_wrapped_function(fn), name);
     }
 
-    static string name();
+    // Return true iff a module is currently being built.
+    static bool initializing();
     
+    // Return the name of the module currently being built.
+    // REQUIRES: initializing() == true
+    static string name();
+
+    // Return a pointer to the Python module object being built
+    PyObject* module() const;
+
  private:
     PyObject* m_module;
     static PyMethodDef initial_methods[1];
 };
 
+//
+// inline implementations
+//
+inline PyObject* module_builder::module() const
+{
+    return m_module;
+}
+
 }} // namespace boost::python
 
 #endif
diff --git a/src/module_builder.cpp b/src/module_builder.cpp
index ea00b71c..57eec75f 100644
--- a/src/module_builder.cpp
+++ b/src/module_builder.cpp
@@ -14,10 +14,15 @@ namespace {
   ref name_holder;
 }
 
+bool module_builder::initializing()
+{
+    return name_holder.get() != 0;
+}
+
 string module_builder::name()
 {
     // If this fails, you haven't created a module_builder object
-    assert(name_holder.get() != 0);
+    assert(initializing());
     return string(name_holder);
 }
 
@@ -29,6 +34,11 @@ module_builder::module_builder(const char* name)
     name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__")));
 }
 
+module_builder::~module_builder()
+{
+    name_holder.reset();
+}
+
 void
 module_builder::add(detail::function* x, const char* name)
 {

From ff31b16285688a7852382fee42041e69f37f8f80 Mon Sep 17 00:00:00 2001
From: Dave Abrahams 
Date: Thu, 30 Nov 2000 04:53:31 +0000
Subject: [PATCH 011/279] Fixed __module__ name extraction logic so that when a
 module is not initializing the module name comes from the global __name__.

[SVN r8362]
---
 src/classes.cpp | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/classes.cpp b/src/classes.cpp
index 34b42c22..2901aa81 100644
--- a/src/classes.cpp
+++ b/src/classes.cpp
@@ -840,7 +840,27 @@ namespace {
   void add_current_module_name(dictionary& name_space)
   {
       static string module_key("__module__", string::interned);
-      name_space.set_item(module_key, module_builder::name());
+
+      // If the user didn't specify a __module__ attribute already
+      if (name_space.get_item(module_key).get() == 0)
+      {
+          if (module_builder::initializing())
+          {
+              // The global __name__ is not properly set in this case
+              name_space.set_item(module_key, module_builder::name());
+          }
+          else
+          {
+              // Get the module name from the global __name__
+              PyObject *globals = PyEval_GetGlobals();
+              if (globals != NULL)
+              {
+                  PyObject *module_name = PyDict_GetItemString(globals, "__name__");
+                  if (module_name != NULL)
+                      name_space.set_item(module_key, module_name);
+              }
+          }
+      }
   }
 }
 

From b91d11431d1af462023bbd7623514e7cdb656e4c Mon Sep 17 00:00:00 2001
From: Dave Abrahams 
Date: Fri, 1 Dec 2000 02:27:06 +0000
Subject: [PATCH 012/279] Applied fixes for como courtesy of Jens Maurer.

[SVN r8375]
---
 include/boost/python/operators.hpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp
index 40400f47..100c62aa 100644
--- a/include/boost/python/operators.hpp
+++ b/include/boost/python/operators.hpp
@@ -7,7 +7,7 @@
 // When STLport is used with native streams, _STL::ostringstream().str() is not
 // _STL::string, but std::string. This confuses to_python(), so we'll use
 // strstream instead. Also, GCC 2.95.2 doesn't have sstream.
-# if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) || __GNUC__ > 2
+# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
 #  include 
 # else
 #  include 
@@ -482,7 +482,7 @@ namespace detail
 
 // When STLport is used with native streams, _STL::ostringstream().str() is not
 // _STL::string, but std::string.
-#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__)
+#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
               std::ostringstream s;
               s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type());
               return BOOST_PYTHON_CONVERSION::to_python(s.str()); 

From 7ea7f87a9fd9dbc96b1c942257a9076aa057640c Mon Sep 17 00:00:00 2001
From: Beman Dawes 
Date: Fri, 8 Dec 2000 15:12:31 +0000
Subject: [PATCH 013/279] Fixed broken link

[SVN r8401]
---
 doc/index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/index.html b/doc/index.html
index 1167f637..0f5f3e04 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -19,7 +19,7 @@
       should simply ``reflect'' your C++ classes and functions into
       Python. The major features of BPL include support for:
 
    -
  • Subclassing extension types in Python +
  • Subclassing extension types in Python
  • Overriding virtual functions in Python
  • [Member] function Overloading
  • Automatic wrapping of numeric operators From 826c1bd894280d6980aa540662b60eebf6939434 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Dec 2000 03:41:32 +0000 Subject: [PATCH 014/279] Correct asynchrony with python generator [SVN r8442] --- .../boost/python/detail/extension_class.hpp | 39 ++++++++++++++++--- include/boost/python/detail/init_function.hpp | 30 +++++++------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 0e2e3427..94d9bf6b 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -6,7 +6,7 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. // -// This file automatically generated for 5-argument constructors by +// This file automatically generated for 10-argument constructors by // gen_extclass.python #ifndef EXTENSION_CLASS_DWA052000_H_ @@ -363,8 +363,8 @@ class extension_class ~extension_class(); // define constructors - template - inline void def(constructor) + template + inline void def(constructor) // The following incantation builds a signature1, signature2,... object. It // should _all_ get optimized away. { add_constructor( @@ -373,7 +373,12 @@ class extension_class prepend(type::id(), prepend(type::id(), prepend(type::id(), - signature0())))))); + prepend(type::id(), + prepend(type::id(), + prepend(type::id(), + prepend(type::id(), + prepend(type::id(), + signature0()))))))))))); } @@ -625,6 +630,16 @@ public: held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : T(a1, a2, a3, a4) {} template held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {} + template + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : T(a1, a2, a3, a4, a5, a6) {} + template + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : T(a1, a2, a3, a4, a5, a6, a7) {} + template + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : T(a1, a2, a3, a4, a5, a6, a7, a8) {} + template + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + template + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} }; // Abstract base class for all obj holders. Base for template class @@ -676,6 +691,21 @@ public: template instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_held(p, a1, a2, a3, a4, a5) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : + m_held(p, a1, a2, a3, a4, a5, a6) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : + m_held(p, a1, a2, a3, a4, a5, a6, a7) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} public: // implementation of instance_holder_base required interface bool held_by_value() { return true; } @@ -829,4 +859,3 @@ std::vector class_registry::static_derived_class_info; }}} // namespace boost::python::detail #endif // EXTENSION_CLASS_DWA052000_H_ - diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index e53f8aa9..f4b24fa6 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -110,11 +110,11 @@ template struct init2; template struct init3; template struct init4; template struct init5; -template struct Init6; -template struct Init7; -template struct Init8; -template struct Init9; -template struct Init10; +template struct init6; +template struct init7; +template struct init8; +template struct init9; +template struct init10; template struct init_function @@ -165,7 +165,7 @@ struct init_function template static init* create(signature6) { - return new Init6::const_reference, detail::parameter_traits::const_reference, detail::parameter_traits::const_reference, @@ -176,7 +176,7 @@ struct init_function template static init* create(signature7) { - return new Init7::const_reference, detail::parameter_traits::const_reference, detail::parameter_traits::const_reference, @@ -188,7 +188,7 @@ struct init_function template static init* create(signature8) { - return new Init8::const_reference, detail::parameter_traits::const_reference, detail::parameter_traits::const_reference, @@ -201,7 +201,7 @@ struct init_function template static init* create(signature9) { - return new Init9::const_reference, detail::parameter_traits::const_reference, detail::parameter_traits::const_reference, @@ -215,7 +215,7 @@ struct init_function template static init* create(signature10) { - return new Init10::const_reference, detail::parameter_traits::const_reference, detail::parameter_traits::const_reference, @@ -353,7 +353,7 @@ struct init5 : init }; template -struct Init6 : init +struct init6 : init { virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { @@ -379,7 +379,7 @@ struct Init6 : init }; template -struct Init7 : init +struct init7 : init { virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { @@ -407,7 +407,7 @@ struct Init7 : init }; template -struct Init8 : init +struct init8 : init { virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { @@ -437,7 +437,7 @@ struct Init8 : init }; template -struct Init9 : init +struct init9 : init { virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { @@ -469,7 +469,7 @@ struct Init9 : init }; template -struct Init10 : init +struct init10 : init { virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { From e5670d5e3c625f5e5a850fa4a706e89536594995 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Dec 2000 03:42:28 +0000 Subject: [PATCH 015/279] Correct the generated filenames [SVN r8444] --- src/gen_all.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gen_all.py b/src/gen_all.py index fd8d78cc..416c66f1 100644 --- a/src/gen_all.py +++ b/src/gen_all.py @@ -6,12 +6,12 @@ from gen_singleton import * from gen_extclass import * def gen_all(args): - open('callback.h', 'w').write(gen_callback(args)) - open('caller.h', 'w').write(gen_caller(args)) - open('init_function.h', 'w').write(gen_init_function(args)) - open('signatures.h', 'w').write(gen_signatures(args)) - open('instance.h', 'w').write(gen_singleton(args)) - open('extclass.h', 'w').write(gen_extclass(args)) + open('callback.hpp', 'w').write(gen_callback(args)) + open('caller.hpp', 'w').write(gen_caller(args)) + open('init_function.hpp', 'w').write(gen_init_function(args)) + open('signatures.hpp', 'w').write(gen_signatures(args)) + open('instance.hpp', 'w').write(gen_singleton(args)) + open('extension_class.hpp', 'w').write(gen_extclass(args)) if __name__ == '__main__': import sys From 7ca17b7bd9deff152b80f5571f1ba45805e2d346 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Dec 2000 03:37:33 +0000 Subject: [PATCH 016/279] Fixed links to avoid www.pythonlabs.com [SVN r8455] --- doc/index.html | 2 +- doc/overloading.html | 2 +- doc/special.html | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/index.html b/doc/index.html index 0f5f3e04..9ddd65d3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -12,7 +12,7 @@

    Synopsis

    Use the Boost Python Library to quickly and easily export a C++ library to Python such that the Python interface is + href="http://www.python.org">Python 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 BPL. The system diff --git a/doc/overloading.html b/doc/overloading.html index 995b3a40..6979efd0 100644 --- a/doc/overloading.html +++ b/doc/overloading.html @@ -118,7 +118,7 @@ namespace scope as Python member functions.

    • Attribute lookup for extension classes proceeds in the + href="http://www.python.org/doc/current/tut/node11.html#SECTION0011510000000000000000">the usual Python way using a depth-first, left-to-right search. When a class is found which has a matching attribute, only functions overloaded in the context of that class are candidates for overload resolution. In diff --git a/doc/special.html b/doc/special.html index 7debc7c1..50cee505 100644 --- a/doc/special.html +++ b/doc/special.html @@ -13,7 +13,7 @@

      BPL supports all of the standard + "http://www.python.org/doc/current/ref/specialnames.html"> special method names supported by real Python class instances except __complex__ (more on the reasons below). In addition, it can quickly and easily expose @@ -33,7 +33,7 @@ Python provides a number of special operators for basic customization of a class. Only a brief description is provided below; more complete documentation can be found here. + href="http://www.python.org/doc/current/ref/customization.html">here.

      @@ -114,7 +114,7 @@ foo_class.def(&to_string, "__str__");

      Numeric operators can be exposed manually, by defing C++ [member] functions that support the standard Python numeric + href="http://www.python.org/doc/current/ref/numeric-types.html">numeric protocols. This is the same basic technique used to expose to_string() as __str__() above, and is covered in detail below. BPL also supports @@ -398,7 +398,7 @@ Note that "__rrpow__" is an extension not present in plain Python.

      Table of Automatically Wrapped Methods

      BPL can automatically wrap the following + "http://www.python.org/doc/current/ref/specialnames.html"> special methods:

      @@ -672,12 +672,12 @@ for (iterator i = S.begin(), end = S.end(); i != end; ++i)

      It is a better idea to support the standard Python + href="http://www.python.org/doc/current/ref/sequence-types.html">Python sequence and mapping protocols for your wrapped containers. These operators have to be wrapped manually because there are no corresponding C++ operators that could be used for automatic wrapping. The Python documentation lists the relevant + "http://www.python.org/doc/current/ref/sequence-types.html"> container operators. In particular, expose __getitem__, __setitem__ and remember to raise the appropriate Python exceptions (PyExc_IndexError for sequences, @@ -773,7 +773,7 @@ KeyError: 2

      Just like built-in Python classes, BPL extension classes support special + href="http://www.python.org/doc/current/ref/attribute-access.html">special the usual attribute access methods __getattr__, __setattr__, and __delattr__. Because writing these functions can From 7d9332e94f2ae6980527fe29f064ce1dfff5e97d Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sat, 30 Dec 2000 11:28:30 +0000 Subject: [PATCH 017/279] added directure structure proposal [SVN r8504] --- build/bpl_static.dsp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp index 60f56070..701dd309 100644 --- a/build/bpl_static.dsp +++ b/build/bpl_static.dsp @@ -63,8 +63,8 @@ LIB32=link.exe -lib # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /ZI /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /ZI /Od /I "d:\boost\type_traits" /I "..\..\.." /I "c:\progra~1\python20\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe From a8641c69cc3cad4d3b662c85396b0ef925740b5e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 21 Jan 2001 05:29:26 +0000 Subject: [PATCH 018/279] A bug fix that I failed to check in long ago for the use of strstream [SVN r8666] --- include/boost/python/operators.hpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 100c62aa..41b1bf5c 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -8,6 +8,10 @@ // _STL::string, but std::string. This confuses to_python(), so we'll use // strstream instead. Also, GCC 2.95.2 doesn't have sstream. # if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) +# define BOOST_PYTHON_USE_SSTREAM +# endif + +#if BOOST_PYTHON_USE_SSTREAM # include # else # include @@ -468,6 +472,16 @@ namespace detail static const char * rname() { return "__rcmp__"; } }; +# ifndef BOOST_PYTHON_USE_SSTREAM + class unfreezer { + public: + unfreezer(std::ostrstream& s) : m_stream(s) {} + ~unfreezer() { m_stream.freeze(false); } + private: + std::ostrstream& m_stream; + }; +# endif + // str(): Manual specialization needed because the string conversion does not follow // the standard pattern relized by the macros. template <> @@ -482,15 +496,16 @@ namespace detail // When STLport is used with native streams, _STL::ostringstream().str() is not // _STL::string, but std::string. -#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) +# ifdef BOOST_PYTHON_USE_SSTREAM std::ostringstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); return BOOST_PYTHON_CONVERSION::to_python(s.str()); -#else +# else std::ostrstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) << char(); + auto unfreezer unfreeze(s); return BOOST_PYTHON_CONVERSION::to_python(const_cast(s.str())); -#endif +# endif } const char* description() const @@ -506,4 +521,5 @@ namespace detail }} // namespace boost::python +# undef BOOST_PYTHON_USE_SSTREAM #endif /* OPERATORS_UK112000_H_ */ From 6238770324f697c5d2256b32f591c4584b2df5ff Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 22 Jan 2001 22:58:37 +0000 Subject: [PATCH 019/279] Added a fix from Ralf W. Grosse-Kunstleve [SVN r8724] --- include/boost/python/operators.hpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 41b1bf5c..f7017355 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -1,3 +1,14 @@ +// (C) Copyright Ullrich Koethe and David Abrahams 2000-2001. 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. +// +// The authors gratefully acknowlege the support of Dragon Systems, Inc., in +// producing this work. +// +// Revision History: +// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams) #ifndef OPERATORS_UK112000_H_ #define OPERATORS_UK112000_H_ @@ -9,9 +20,9 @@ // strstream instead. Also, GCC 2.95.2 doesn't have sstream. # if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) # define BOOST_PYTHON_USE_SSTREAM -# endif +# endi -#if BOOST_PYTHON_USE_SSTREAM +#if defined(BOOST_PYTHON_USE_SSTREAM) # include # else # include From b0d9bbc0b15b787d15aeaf378d2614b0eeae5365 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 23 Jan 2001 22:41:46 +0000 Subject: [PATCH 020/279] Another stupid typo fix by Ralf W. Grosse-Kunstleve [SVN r8745] --- include/boost/python/operators.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index f7017355..da88ec6c 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -8,6 +8,7 @@ // producing this work. // // Revision History: +// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams) // 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams) #ifndef OPERATORS_UK112000_H_ #define OPERATORS_UK112000_H_ @@ -20,7 +21,7 @@ // strstream instead. Also, GCC 2.95.2 doesn't have sstream. # if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) # define BOOST_PYTHON_USE_SSTREAM -# endi +# endif #if defined(BOOST_PYTHON_USE_SSTREAM) # include From e508842da672b5f8865fb93718b4e6048fa0d02d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 27 Jan 2001 17:35:02 +0000 Subject: [PATCH 021/279] BPL support for exporting/importing class wrappers. [SVN r8788] --- example/abstract.cpp | 34 ++++++ example/dvect.cpp | 69 +++++++++++ example/dvect.h | 32 +++++ example/example1.cpp | 54 --------- example/{rwgk1.cpp => getting_started1.cpp} | 15 +-- example/getting_started2.cpp | 51 ++++++++ example/getting_started3.cpp | 122 +++++++++++++++++++ example/getting_started4.cpp | 104 ++++++++++++++++ example/getting_started5.cpp | 127 ++++++++++++++++++++ example/ivect.cpp | 69 +++++++++++ example/ivect.h | 32 +++++ example/noncopyable_export.cpp | 24 ++++ example/noncopyable_import.cpp | 42 +++++++ example/store.h | 14 +++ example/test_abstract.py | 23 ++++ example/test_example1.py | 50 -------- example/test_getting_started1.py | 17 +++ example/test_getting_started2.py | 19 +++ example/test_getting_started3.py | 56 +++++++++ example/test_getting_started4.py | 35 ++++++ example/test_getting_started5.py | 22 ++++ example/test_rwgk1.py | 17 --- example/tst_dvect.py | 16 +++ example/tst_ivect.py | 16 +++ example/tst_noncopyable.py | 8 ++ 25 files changed, 935 insertions(+), 133 deletions(-) create mode 100644 example/abstract.cpp create mode 100644 example/dvect.cpp create mode 100644 example/dvect.h delete mode 100644 example/example1.cpp rename example/{rwgk1.cpp => getting_started1.cpp} (74%) create mode 100644 example/getting_started2.cpp create mode 100644 example/getting_started3.cpp create mode 100644 example/getting_started4.cpp create mode 100644 example/getting_started5.cpp create mode 100644 example/ivect.cpp create mode 100644 example/ivect.h create mode 100644 example/noncopyable_export.cpp create mode 100644 example/noncopyable_import.cpp create mode 100644 example/store.h create mode 100644 example/test_abstract.py delete mode 100644 example/test_example1.py create mode 100644 example/test_getting_started1.py create mode 100644 example/test_getting_started2.py create mode 100644 example/test_getting_started3.py create mode 100644 example/test_getting_started4.py create mode 100644 example/test_getting_started5.py delete mode 100644 example/test_rwgk1.py create mode 100644 example/tst_dvect.py create mode 100644 example/tst_ivect.py create mode 100644 example/tst_noncopyable.py diff --git a/example/abstract.cpp b/example/abstract.cpp new file mode 100644 index 00000000..41d34def --- /dev/null +++ b/example/abstract.cpp @@ -0,0 +1,34 @@ +// Example by Ullrich Koethe +#include "boost/python/class_builder.hpp" +#include + +struct Abstract +{ + virtual std::string test() = 0; +}; + +struct Abstract_callback: Abstract +{ + Abstract_callback(PyObject * self) + : m_self(self) + {} + + std::string test() + { + return boost::python::callback::call_method(m_self, "test"); + } + + PyObject * m_self; +}; + +extern "C" +DL_EXPORT(void) +initabstract() +{ + boost::python::module_builder a("abstract"); + + boost::python::class_builder + a_class(a, "Abstract"); + a_class.def(boost::python::constructor<>()); // wrap a constructor + a_class.def(&Abstract::test, "test"); +} diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..3228010c --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,69 @@ +#include "ivect.h" +#include "dvect.h" +#include +#include +namespace python = boost::python; + +namespace { + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } + + boost::python::tuple ivect_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) + { + return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) + { + return iv->as_tuple(); + } + + boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) + { + return iv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initdvect() +{ + try + { + python::module_builder this_module("dvect"); + + python::x_class_builder dvect_class(this_module, "dvect"); + + python::import_class_builder ivect_class("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + + this_module.def(ivect_as_tuple, "ivect_as_tuple"); + dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); + dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); + this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); + this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.h b/example/dvect.h new file mode 100644 index 00000000..8ffe7b50 --- /dev/null +++ b/example/dvect.h @@ -0,0 +1,32 @@ +#ifndef DVECT_H +#define DVECT_H + +#include +#include + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // DVECT_H diff --git a/example/example1.cpp b/example/example1.cpp deleted file mode 100644 index 467ac0dc..00000000 --- a/example/example1.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include - -namespace hello { - class world - { - public: - world(int) {} - ~world() {} - const char* get() const { return "hi, world"; } - }; - - size_t length(const world& x) { return strlen(x.get()); } -} - -#include - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void inithello() -{ - try - { - // create an object representing this extension module - boost::python::module_builder hello("hello"); - - // Create the Python type object for our extension class - boost::python::class_builder world_class(hello, "world"); - - // Add the __init__ function - world_class.def(boost::python::constructor()); - // Add a regular member function - world_class.def(&hello::world::get, "get"); - - // Add a regular function to the module - hello.def(hello::length, "length"); - } - catch(...) - { - boost::python::handle_exception(); // Deal with the exception for Python - } -} - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) -{ - return 1; -} -#endif // _WIN32 diff --git a/example/rwgk1.cpp b/example/getting_started1.cpp similarity index 74% rename from example/rwgk1.cpp rename to example/getting_started1.cpp index b21ae4d1..9679a2a4 100644 --- a/example/rwgk1.cpp +++ b/example/getting_started1.cpp @@ -8,21 +8,18 @@ namespace { // Avoid cluttering the global namespace. } #include - namespace python = boost::python; // Python requires an exported function called init in every // extension module. This is where we build the module contents. extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void initrwgk1() +DL_EXPORT(void) +initgetting_started1() { try { // Create an object representing this extension module. - python::module_builder this_module("rwgk1"); + python::module_builder this_module("getting_started1"); // Add regular functions to the module. this_module.def(greet, "greet"); @@ -33,9 +30,3 @@ void initrwgk1() python::handle_exception(); // Deal with the exception for Python } } - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } -#endif // _WIN32 diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp new file mode 100644 index 00000000..82b4a6df --- /dev/null +++ b/example/getting_started2.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + public: + world(const std::string& country) { this->country = country; } + std::string greet() const { return "Hello from " + country + "!"; } + }; + + // A function taking a world object as an argument. + std::string invite(const world& w) { + return w.greet() + " Please come soon!"; + } +} + +extern "C" +DL_EXPORT(void) +initgetting_started2() +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("getting_started2"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + + // Add invite() as a regular function to the module. + this_module.def(invite, "invite"); + + // Even better, invite() can also be made a member of world_class!!! + world_class.def(invite, "invite"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/getting_started3.cpp b/example/getting_started3.cpp new file mode 100644 index 00000000..7e827249 --- /dev/null +++ b/example/getting_started3.cpp @@ -0,0 +1,122 @@ +/* + This example shows how to make an Extension Class "pickleable". + + Python's pickle module implements a basic but powerful algorithm + for "pickling" (a.k.a. serializing, marshalling or flattening) + nearly arbitrary Python objects. + + The user can influence how an Extension Class instance is pickled + by defining three special methods: __getinitargs__(), + __getstate__(), and __setstate(). This interface is similar to + that for regular Python classes as described in detail in the + Python Library Reference for pickle: + + http://www.python.org/doc/current/lib/module-pickle.html + + When an Extension Class instance is pickled, __getinitargs__() is + called, if implemented. This method should return a tuple + containing the arguments to be passed to the class constructor when + the object is restored. + + If there is no __getstate__() method, the instance's __dict__ is + pickled if it is not empty. If __getstate__() is defined, it should + return an object representing the state of the instance. + + If there is no __setstate__() method, __getstate__() must return a + dictionary. When the instance is restored, the items in this dictionary + are added to the instance's __dict__. + + If the Extension Class defines __setstate__(), the pickle loader + calls it with the result of __getstate__() as arguments. In this + case, the state object need not be a dictionary. The + __getstate__() and __setstate__() methods can do what they want. + + If both __getinitargs__() and __getstate__() are defined, the + instance is restored by first calling the constructor with + the result of __getinitargs__() as argument. After the instance + is reconstructed, the __dict__ is updated or __setstate__() is + called if implemented. + + The mechanism described here is an exact replication of that one + implemented by Jim Fulton's ExtensionClass (included in Zope 2.2.2). + */ + +#include +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + int secret_number; + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + }; + + // Support for pickle. + python::tuple world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result; + } + + python::tuple world_getstate(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_secret_number()); + return result; + } + + void world_setstate(world& w, python::tuple state) { + if (state.size() != 1) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), + python::type()); + if (number != 42) + w.set_secret_number(number); + } +} + +extern "C" +DL_EXPORT(void) +initgetting_started3() +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("getting_started3"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def(world_getstate, "__getstate__"); + world_class.def(world_setstate, "__setstate__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/getting_started4.cpp b/example/getting_started4.cpp new file mode 100644 index 00000000..0c7bd7ee --- /dev/null +++ b/example/getting_started4.cpp @@ -0,0 +1,104 @@ +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A wrapper is used to define additional constructors. + // + struct vector_double_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_double_wrapper(PyObject*, const std::vector& vd) + : std::vector(vd) {} + + vector_double_wrapper(PyObject* self) + : std::vector() {} + + vector_double_wrapper(PyObject* self, const int n) + : std::vector(n) {} + + vector_double_wrapper(PyObject* self, python::tuple tuple) + : std::vector(tuple.size()) + { + std::vector::iterator vd = begin(); + for (int i = 0; i < tuple.size(); i++) + vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + python::type()); + } + }; + + double getitem(const std::vector& vd, const std::size_t key) { + return vd[key]; + } + + void setitem(std::vector& vd, const std::size_t key, + const double &d) { + std::vector::iterator vditer = vd.begin(); + vditer[key] = d; + } + + void delitem(std::vector& vd, const std::size_t key) { + std::vector::iterator vditer = vd.begin(); + vd.erase(&vditer[key]); + } + + // Convert vector_double to a regular Python tuple. + // + python::tuple as_tuple(const std::vector& vd) + { + python::tuple t(vd.size()); + for (int i = 0; i < vd.size(); i++) t.set_item(i, + python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); + return t; + } + + // Function returning a vector_double object to Python. + // + std::vector foo(const int n) + { + std::vector vd(n); + std::vector::iterator vditer = vd.begin(); + for (int i = 0; i < n; i++) vditer[i] = double(i); + return vd; + } + + // Same as foo(), but avoid copying on return. + // + std::auto_ptr > bar(const int n) + { + std::auto_ptr > vdptr(new std::vector(n)); + std::vector::iterator vditer = vdptr->begin(); + for (int i = 0; i < n; i++) vditer[i] = double(10 * i); + return vdptr; + } +} + +extern "C" +DL_EXPORT(void) +initgetting_started4() +{ + try + { + python::module_builder this_module("getting_started4"); + + python::class_builder, vector_double_wrapper> + vector_double(this_module, "vector_double"); + + vector_double.def(python::constructor<>()); + vector_double.def(python::constructor()); + vector_double.def(python::constructor()); + vector_double.def(&std::vector::size, "__len__"); + vector_double.def(getitem, "__getitem__"); + vector_double.def(setitem, "__setitem__"); + vector_double.def(delitem, "__delitem__"); + vector_double.def(as_tuple, "as_tuple"); + + this_module.def(foo, "foo"); + this_module.def(bar, "bar"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp new file mode 100644 index 00000000..e82fec30 --- /dev/null +++ b/example/getting_started5.cpp @@ -0,0 +1,127 @@ +/* + This example shows how to convert a class from and to native + Python objects, such as tuples. + + We do not want to expose the helper class MillerIndex as an + Extension Class. However, in order to simplify the wrapper code, + we want to define from_python() and to_python() functions for + class MillerIndex. + + Consider the alternatives: + + - Expose MillerIndex as an Extension Class. + We need a constructor MillerIndex(python::tuple). + Python function calls become more complex: + foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) + We need a method such as MillerIndex().as_tuple(). + + - Define a wrapper function for each function that we + want to expose, e.g.: + void add(const IndexingSet& ixset, const python::tuple PyMIx) + + The first alternative introduces a new type that the user has to + deal with. Other modules using Miller indices might organize them in + different ways, for example to increase runtime efficiency for + important procedures. This means, the user has to know how to + convert between the different kinds of Miller index representations. + This can quickly become a nuisance. Relying on native Python data + structures minimizes the number of special types the user has to + learn and convert. Of course, this argument is only valid for + small and relatively simply classes. + + If there are many member functions with MillerIndex arguments, the + second alternative is impractical, and concentrating the conversion + mechanism in one central place is essential for code + maintainability. An added benefit is that more convenient (smarter) + conversion functions can be provided without cluttering the rest of + the wrapper code. + + */ + +#include +#include +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // The helper class. + // + class MillerIndex { + public: + int v[3]; + }; + + // The main class. Imagine that there are MANY member functions + // like add() and get(). + // + class IndexingSet { + private: + std::vector VMIx; + public: + void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } + MillerIndex get(const std::size_t i) const { return VMIx[i]; } + }; +} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + + // Convert a Python tuple to a MillerIndex object. + // + MillerIndex from_python(PyObject* p, python::type) + { + python::tuple tup = python::tuple(python::ref(p)); + if (tup.size() != 3) { + PyErr_SetString(PyExc_ValueError, + "expecting exactly 3 values in tuple."); + throw python::error_already_set(); + } + MillerIndex result; + for (int i = 0; i < 3; i++) + result.v[i] = from_python(tup[i].get(), python::type()); + return result; + } + + // Similar conversion for MillerIndex objects passed by value. + // Not actually used, but included to show the principle. + // + MillerIndex from_python(PyObject* p, python::type) + { + return from_python(p, python::type()); + } + + // Convert a MillerIndex object to a Python tuple. + // + PyObject* to_python(const MillerIndex& hkl) + { + python::tuple result(3); + for (int i = 0; i < 3; i++) + result.set_item(i, to_python(hkl.v[i])); + return result.reference().release(); + } + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +extern "C" +DL_EXPORT(void) +initgetting_started5() +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("getting_started5"); + + // Create the Python type object for our extension class. + python::class_builder ixset_class(this_module, "IndexingSet"); + + // Add the __init__ function. + ixset_class.def(python::constructor<>()); + // Add the member functions. + ixset_class.def(&IndexingSet::add, "add"); + ixset_class.def(&IndexingSet::get, "get"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..f8ca8707 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,69 @@ +#include "ivect.h" +#include "dvect.h" +#include +#include +namespace python = boost::python; + +namespace { + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } + + boost::python::tuple dvect_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) + { + return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) + { + return dv->as_tuple(); + } + + boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) + { + return dv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initivect() +{ + try + { + python::module_builder this_module("ivect"); + + python::x_class_builder ivect_class(this_module, "ivect"); + + python::import_class_builder dvect_class("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + + this_module.def(dvect_as_tuple, "dvect_as_tuple"); + ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); + ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); + this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); + this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.h b/example/ivect.h new file mode 100644 index 00000000..a0187307 --- /dev/null +++ b/example/ivect.h @@ -0,0 +1,32 @@ +#ifndef IVECT_H +#define IVECT_H + +#include +#include + +namespace vects { + + struct ivect : public std::vector + { + ivect() : std::vector() {} + ivect(size_t n) : std::vector(n) {} + ivect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // IVECT_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..82c3f049 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,24 @@ +#include +#include +namespace python = boost::python; + +#include "store.h" + +extern "C" +DL_EXPORT(void) +initnoncopyable_export() +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::xptr_class_builder store_class(this_module, "store"); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..529c9f42 --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,42 @@ +#include +#include +namespace python = boost::python; + +#include "store.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +extern "C" +DL_EXPORT(void) +initnoncopyable_import() +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_class_builder + dvect_class("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/store.h b/example/store.h new file mode 100644 index 00000000..74ef0477 --- /dev/null +++ b/example/store.h @@ -0,0 +1,14 @@ +#ifndef STORE_H +#define STORE_H + +class store +{ + private: + store(const store&) { } // Disable the copy constructor. + int number; + public: + store(const int i) : number(i) { } + int recall() const { return number; } +}; + +#endif // STORE_H diff --git a/example/test_abstract.py b/example/test_abstract.py new file mode 100644 index 00000000..dda8aaa7 --- /dev/null +++ b/example/test_abstract.py @@ -0,0 +1,23 @@ +# Example by Ullrich Koethe +r'''>>> from abstract import * + >>> class A(Abstract): + ... def __init__(self, text): + ... Abstract.__init__(self) # call the base class constructor + ... self.text = text + ... def test(self): # implement abstract function + ... return self.text + ... + >>> a = A("Hello") + >>> a.test() + 'Hello' +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_abstract + doctest.testmod(test_abstract) + +if __name__ == '__main__': + run() diff --git a/example/test_example1.py b/example/test_example1.py deleted file mode 100644 index 0e3a9a18..00000000 --- a/example/test_example1.py +++ /dev/null @@ -1,50 +0,0 @@ -r''' -// (C) Copyright David Abrahams 2000. 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. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -That's it! If we build this shared library and put it on our PYTHONPATH we can -now access our C++ class and function from Python. - - >>> import hello - >>> hi_world = hello.world(3) - >>> hi_world.get() - 'hi, world' - >>> hello.length(hi_world) - 9 - -We can even make a subclass of hello.world: - - - >>> class my_subclass(hello.world): - ... def get(self): - ... return 'hello, world' - ... - >>> y = my_subclass(2) - >>> y.get() - 'hello, world' - -Pretty cool! You can't do that with an ordinary Python extension type! - - >>> hello.length(y) - 9 - -Of course, you may now have a slightly empty feeling in the pit of your little -pythonic stomach. Perhaps you feel your subclass deserves to have a length() of -12? If so, read on... -''' -from hello import * - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_example1 - doctest.testmod(test_example1) - -if __name__ == '__main__': - run() diff --git a/example/test_getting_started1.py b/example/test_getting_started1.py new file mode 100644 index 00000000..7daf65af --- /dev/null +++ b/example/test_getting_started1.py @@ -0,0 +1,17 @@ +r'''>>> import getting_started1 + >>> print getting_started1.greet() + hello, world + >>> number = 11 + >>> print number, '*', number, '=', getting_started1.square(number) + 11 * 11 = 121 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_getting_started1 + doctest.testmod(test_getting_started1) + +if __name__ == '__main__': + run() diff --git a/example/test_getting_started2.py b/example/test_getting_started2.py new file mode 100644 index 00000000..09215816 --- /dev/null +++ b/example/test_getting_started2.py @@ -0,0 +1,19 @@ +r'''>>> import getting_started2 + >>> w = getting_started2.world('California') + >>> print w.greet() + Hello from California! + >>> print getting_started2.invite(w) + Hello from California! Please come soon! + >>> print w.invite() + Hello from California! Please come soon! +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_getting_started2 + doctest.testmod(test_getting_started2) + +if __name__ == '__main__': + run() diff --git a/example/test_getting_started3.py b/example/test_getting_started3.py new file mode 100644 index 00000000..d62cf5a2 --- /dev/null +++ b/example/test_getting_started3.py @@ -0,0 +1,56 @@ +r'''>>> import getting_started3 + >>> import re + >>> import pickle + >>> getting_started3.world.__module__ + 'getting_started3' + >>> getting_started3.world.__safe_for_unpickling__ + 1 + >>> getting_started3.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\), \(0,\)\)", + ... repr(getting_started3.world('Hello').__reduce__())) + >>> + >>> for number in (24, 42): + ... wd = getting_started3.world('California') + ... wd.set_secret_number(number) + ... pstr = pickle.dumps(wd) + ... print pstr + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number() + ... print wl.greet(), wl.get_secret_number() + cgetting_started3 + world + p0 + (S'California' + p1 + tp2 + R(I24 + tp3 + bp4 + . + Hello from California! 24 + Hello from California! 24 + cgetting_started3 + world + p0 + (S'California' + p1 + tp2 + R(I42 + tp3 + bp4 + . + Hello from California! 42 + Hello from California! 0 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_getting_started3 + doctest.testmod(test_getting_started3) + +if __name__ == '__main__': + run() diff --git a/example/test_getting_started4.py b/example/test_getting_started4.py new file mode 100644 index 00000000..82b5c794 --- /dev/null +++ b/example/test_getting_started4.py @@ -0,0 +1,35 @@ +r'''>>> import getting_started4 + >>> v=getting_started4.vector_double() + >>> print v.as_tuple() + () + >>> v=getting_started4.vector_double(5) + >>> print v.as_tuple() + (0.0, 0.0, 0.0, 0.0, 0.0) + >>> print len(v) + 5 + >>> v=getting_started4.vector_double((3,4,5)) + >>> print v.as_tuple() + (3.0, 4.0, 5.0) + >>> print v[1] + 4.0 + >>> v[1] = 40 + >>> print v.as_tuple() + (3.0, 40.0, 5.0) + >>> del v[1] + >>> print v.as_tuple() + (3.0, 5.0) + >>> print getting_started4.foo(11).as_tuple() + (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) + >>> print getting_started4.bar(12).as_tuple() + (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_getting_started4 + doctest.testmod(test_getting_started4) + +if __name__ == '__main__': + run() diff --git a/example/test_getting_started5.py b/example/test_getting_started5.py new file mode 100644 index 00000000..8eeba1e2 --- /dev/null +++ b/example/test_getting_started5.py @@ -0,0 +1,22 @@ +r'''>>> import getting_started5 + >>> ixset = getting_started5.IndexingSet() + >>> ixset.add((1,2,3)) + >>> ixset.add((4,5,6)) + >>> ixset.add((7,8,9)) + >>> print ixset.get(0) + (1, 2, 3) + >>> print ixset.get(1) + (4, 5, 6) + >>> print ixset.get(2) + (7, 8, 9) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_getting_started5 + doctest.testmod(test_getting_started5) + +if __name__ == '__main__': + run() diff --git a/example/test_rwgk1.py b/example/test_rwgk1.py deleted file mode 100644 index 87298875..00000000 --- a/example/test_rwgk1.py +++ /dev/null @@ -1,17 +0,0 @@ -r'''>>> import rwgk1 - >>> print rwgk1.greet() - hello, world - >>> number = 11 - >>> print number, '*', number, '=', rwgk1.square(number) - 11 * 11 = 121 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_rwgk1 - doctest.testmod(test_rwgk1) - -if __name__ == '__main__': - run() diff --git a/example/tst_dvect.py b/example/tst_dvect.py new file mode 100644 index 00000000..563f0ad5 --- /dev/null +++ b/example/tst_dvect.py @@ -0,0 +1,16 @@ +import dvect +print dvect.dvect.__converters__ +dv = dvect.dvect((1,2,3,4,5)) +print dv +print dv.as_tuple() +iv = dv.as_ivect() +print iv +print iv.as_tuple() +print dvect.ivect_as_tuple(iv) +aiv = dv.auto_ptr_ivect() +print aiv +siv = dv.shared_ptr_ivect() +print dvect.auto_ptr_ivect_as_tuple(aiv) +print dvect.ivect_as_tuple(aiv) +print dvect.shared_ptr_ivect_as_tuple(siv) +print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py new file mode 100644 index 00000000..58bc323f --- /dev/null +++ b/example/tst_ivect.py @@ -0,0 +1,16 @@ +import ivect +print ivect.ivect.__converters__ +iv = ivect.ivect((1,2,3,4,5)) +print iv +print iv.as_tuple() +dv = iv.as_dvect() +print dv +print dv.as_tuple() +print ivect.dvect_as_tuple(dv) +adv = iv.auto_ptr_dvect() +print adv +sdv = iv.shared_ptr_dvect() +print ivect.auto_ptr_dvect_as_tuple(adv) +print ivect.dvect_as_tuple(adv) +print ivect.shared_ptr_dvect_as_tuple(sdv) +print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..913df039 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,8 @@ +import noncopyable_export +import noncopyable_import +s1 = noncopyable_export.store(1) +print s1.recall() +s2 = noncopyable_export.store(2) +print s2.recall() +s3 = noncopyable_import.add_stores(s1, s2) +print s3.recall() From f24a95c9172769d78a3695392464cfab08b4e7cd Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 31 Jan 2001 19:27:17 +0000 Subject: [PATCH 022/279] fix for reference count bug. [SVN r8835] --- example/getting_started5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index e82fec30..bbe4725a 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -70,7 +70,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // MillerIndex from_python(PyObject* p, python::type) { - python::tuple tup = python::tuple(python::ref(p)); + python::tuple tup = python::tuple(python::ref(p, ref::increment_count)); if (tup.size() != 3) { PyErr_SetString(PyExc_ValueError, "expecting exactly 3 values in tuple."); From 1d4dfdf271155f94ed4684b92bf426de8445aa4c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Feb 2001 23:28:01 +0000 Subject: [PATCH 023/279] converted <> to <> [SVN r8954] --- doc/pointers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pointers.html b/doc/pointers.html index 26f96f0d..bf8ec8ae 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -90,7 +90,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround PyObject* to_python(const Foo* p) { - return to_python(const_cast(p)); + return to_python(const_cast<Foo*>(p)); } BOOST_PYTHON_END_CONVERSION_NAMESPACE

From 4d19be8ea477d05df16c979032326175d088d299 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Feb 2001 03:08:00 +0000 Subject: [PATCH 024/279] PyExtensionClassConverters -> python_extension_class_converters<Foo> [SVN r8968] --- doc/pointers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pointers.html b/doc/pointers.html index bf8ec8ae..e26cea02 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -85,7 +85,7 @@ code before the last Python reference to it disappears: BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround PyObject* to_python(Foo* p) { - return boost::python::PyExtensionClassConverters::ptr_to_python(p); + return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); } PyObject* to_python(const Foo* p) From 1d17690f694f72b7b663f048f93b4f356905a404 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 7 Feb 2001 23:50:41 +0000 Subject: [PATCH 025/279] Add back old example files that were accidentally removed from the main branch. [SVN r9016] --- example/example1.cpp | 54 ++++++++++++++++++++++++++++++++++++++++ example/rwgk1.cpp | 41 ++++++++++++++++++++++++++++++ example/test_example1.py | 50 +++++++++++++++++++++++++++++++++++++ example/test_rwgk1.py | 17 +++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 example/example1.cpp create mode 100644 example/rwgk1.cpp create mode 100644 example/test_example1.py create mode 100644 example/test_rwgk1.py diff --git a/example/example1.cpp b/example/example1.cpp new file mode 100644 index 00000000..467ac0dc --- /dev/null +++ b/example/example1.cpp @@ -0,0 +1,54 @@ +#include + +namespace hello { + class world + { + public: + world(int) {} + ~world() {} + const char* get() const { return "hi, world"; } + }; + + size_t length(const world& x) { return strlen(x.get()); } +} + +#include + +// Python requires an exported function called init in every +// extension module. This is where we build the module contents. +extern "C" +#ifdef _WIN32 +__declspec(dllexport) +#endif +void inithello() +{ + try + { + // create an object representing this extension module + boost::python::module_builder hello("hello"); + + // Create the Python type object for our extension class + boost::python::class_builder world_class(hello, "world"); + + // Add the __init__ function + world_class.def(boost::python::constructor()); + // Add a regular member function + world_class.def(&hello::world::get, "get"); + + // Add a regular function to the module + hello.def(hello::length, "length"); + } + catch(...) + { + boost::python::handle_exception(); // Deal with the exception for Python + } +} + +// Win32 DLL boilerplate +#if defined(_WIN32) +#include +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) +{ + return 1; +} +#endif // _WIN32 diff --git a/example/rwgk1.cpp b/example/rwgk1.cpp new file mode 100644 index 00000000..b21ae4d1 --- /dev/null +++ b/example/rwgk1.cpp @@ -0,0 +1,41 @@ +#include + +namespace { // Avoid cluttering the global namespace. + + // A couple of simple C++ functions that we want to expose to Python. + std::string greet() { return "hello, world"; } + int square(int number) { return number * number; } +} + +#include + +namespace python = boost::python; + +// Python requires an exported function called init in every +// extension module. This is where we build the module contents. +extern "C" +#ifdef _WIN32 +__declspec(dllexport) +#endif +void initrwgk1() +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("rwgk1"); + + // Add regular functions to the module. + this_module.def(greet, "greet"); + this_module.def(square, "square"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} + +// Win32 DLL boilerplate +#if defined(_WIN32) +#include +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } +#endif // _WIN32 diff --git a/example/test_example1.py b/example/test_example1.py new file mode 100644 index 00000000..0e3a9a18 --- /dev/null +++ b/example/test_example1.py @@ -0,0 +1,50 @@ +r''' +// (C) Copyright David Abrahams 2000. 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. +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +That's it! If we build this shared library and put it on our PYTHONPATH we can +now access our C++ class and function from Python. + + >>> import hello + >>> hi_world = hello.world(3) + >>> hi_world.get() + 'hi, world' + >>> hello.length(hi_world) + 9 + +We can even make a subclass of hello.world: + + + >>> class my_subclass(hello.world): + ... def get(self): + ... return 'hello, world' + ... + >>> y = my_subclass(2) + >>> y.get() + 'hello, world' + +Pretty cool! You can't do that with an ordinary Python extension type! + + >>> hello.length(y) + 9 + +Of course, you may now have a slightly empty feeling in the pit of your little +pythonic stomach. Perhaps you feel your subclass deserves to have a length() of +12? If so, read on... +''' +from hello import * + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_example1 + doctest.testmod(test_example1) + +if __name__ == '__main__': + run() diff --git a/example/test_rwgk1.py b/example/test_rwgk1.py new file mode 100644 index 00000000..87298875 --- /dev/null +++ b/example/test_rwgk1.py @@ -0,0 +1,17 @@ +r'''>>> import rwgk1 + >>> print rwgk1.greet() + hello, world + >>> number = 11 + >>> print number, '*', number, '=', rwgk1.square(number) + 11 * 11 = 121 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_rwgk1 + doctest.testmod(test_rwgk1) + +if __name__ == '__main__': + run() From 0d04bf8e34031d7413bce85c4eeabf73e5024445 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 7 Feb 2001 23:58:44 +0000 Subject: [PATCH 026/279] Remove example files that were accidentally added to the main branch. [SVN r9017] --- example/README | 6 +++ example/dvect.cpp | 69 ---------------------------------- example/dvect.h | 32 ---------------- example/ivect.cpp | 69 ---------------------------------- example/ivect.h | 32 ---------------- example/noncopyable_export.cpp | 24 ------------ example/noncopyable_import.cpp | 42 --------------------- example/store.h | 14 ------- example/tst_dvect.py | 16 -------- example/tst_ivect.py | 16 -------- example/tst_noncopyable.py | 8 ---- 11 files changed, 6 insertions(+), 322 deletions(-) create mode 100644 example/README delete mode 100644 example/dvect.cpp delete mode 100644 example/dvect.h delete mode 100644 example/ivect.cpp delete mode 100644 example/ivect.h delete mode 100644 example/noncopyable_export.cpp delete mode 100644 example/noncopyable_import.cpp delete mode 100644 example/store.h delete mode 100644 example/tst_dvect.py delete mode 100644 example/tst_ivect.py delete mode 100644 example/tst_noncopyable.py diff --git a/example/README b/example/README new file mode 100644 index 00000000..34b50d61 --- /dev/null +++ b/example/README @@ -0,0 +1,6 @@ +To get started with the Boost Python Library, use the examples +getting_started?.cpp and abstract.cpp. + +The files example1.cpp and rwgk1.cpp are obsolete. They are only +included because the makefiles in the build directory still refer to +them. This will be fixed later. diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index 3228010c..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -#include -namespace python = boost::python; - -namespace { - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } - - boost::python::tuple ivect_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) - { - return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) - { - return iv->as_tuple(); - } - - boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) - { - return iv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initdvect() -{ - try - { - python::module_builder this_module("dvect"); - - python::x_class_builder dvect_class(this_module, "dvect"); - - python::import_class_builder ivect_class("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - - this_module.def(ivect_as_tuple, "ivect_as_tuple"); - dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); - dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); - this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); - this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/dvect.h b/example/dvect.h deleted file mode 100644 index 8ffe7b50..00000000 --- a/example/dvect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DVECT_H -#define DVECT_H - -#include -#include - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // DVECT_H diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index f8ca8707..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -#include -namespace python = boost::python; - -namespace { - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } - - boost::python::tuple dvect_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) - { - return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) - { - return dv->as_tuple(); - } - - boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) - { - return dv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initivect() -{ - try - { - python::module_builder this_module("ivect"); - - python::x_class_builder ivect_class(this_module, "ivect"); - - python::import_class_builder dvect_class("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - - this_module.def(dvect_as_tuple, "dvect_as_tuple"); - ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); - ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); - this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); - this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/ivect.h b/example/ivect.h deleted file mode 100644 index a0187307..00000000 --- a/example/ivect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IVECT_H -#define IVECT_H - -#include -#include - -namespace vects { - - struct ivect : public std::vector - { - ivect() : std::vector() {} - ivect(size_t n) : std::vector(n) {} - ivect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // IVECT_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 82c3f049..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -namespace python = boost::python; - -#include "store.h" - -extern "C" -DL_EXPORT(void) -initnoncopyable_export() -{ - try - { - python::module_builder this_module("noncopyable_export"); - - python::xptr_class_builder store_class(this_module, "store"); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index 529c9f42..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -namespace python = boost::python; - -#include "store.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -extern "C" -DL_EXPORT(void) -initnoncopyable_import() -{ - try - { - python::module_builder this_module("noncopyable_import"); - - python::import_class_builder - dvect_class("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/store.h b/example/store.h deleted file mode 100644 index 74ef0477..00000000 --- a/example/store.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef STORE_H -#define STORE_H - -class store -{ - private: - store(const store&) { } // Disable the copy constructor. - int number; - public: - store(const int i) : number(i) { } - int recall() const { return number; } -}; - -#endif // STORE_H diff --git a/example/tst_dvect.py b/example/tst_dvect.py deleted file mode 100644 index 563f0ad5..00000000 --- a/example/tst_dvect.py +++ /dev/null @@ -1,16 +0,0 @@ -import dvect -print dvect.dvect.__converters__ -dv = dvect.dvect((1,2,3,4,5)) -print dv -print dv.as_tuple() -iv = dv.as_ivect() -print iv -print iv.as_tuple() -print dvect.ivect_as_tuple(iv) -aiv = dv.auto_ptr_ivect() -print aiv -siv = dv.shared_ptr_ivect() -print dvect.auto_ptr_ivect_as_tuple(aiv) -print dvect.ivect_as_tuple(aiv) -print dvect.shared_ptr_ivect_as_tuple(siv) -print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py deleted file mode 100644 index 58bc323f..00000000 --- a/example/tst_ivect.py +++ /dev/null @@ -1,16 +0,0 @@ -import ivect -print ivect.ivect.__converters__ -iv = ivect.ivect((1,2,3,4,5)) -print iv -print iv.as_tuple() -dv = iv.as_dvect() -print dv -print dv.as_tuple() -print ivect.dvect_as_tuple(dv) -adv = iv.auto_ptr_dvect() -print adv -sdv = iv.shared_ptr_dvect() -print ivect.auto_ptr_dvect_as_tuple(adv) -print ivect.dvect_as_tuple(adv) -print ivect.shared_ptr_dvect_as_tuple(sdv) -print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 913df039..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,8 +0,0 @@ -import noncopyable_export -import noncopyable_import -s1 = noncopyable_export.store(1) -print s1.recall() -s2 = noncopyable_export.store(2) -print s2.recall() -s3 = noncopyable_import.add_stores(s1, s2) -print s3.recall() From f3d9193743d8635a46b53c7d36a3c77d8c61c83c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 8 Feb 2001 01:54:59 +0000 Subject: [PATCH 027/279] Fix for linux gcc-2.95.2 [SVN r9023] --- example/getting_started5.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index bbe4725a..4b64e4b8 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -70,7 +70,8 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // MillerIndex from_python(PyObject* p, python::type) { - python::tuple tup = python::tuple(python::ref(p, ref::increment_count)); + python::tuple tup + = python::tuple(python::ref(p, python::ref::increment_count)); if (tup.size() != 3) { PyErr_SetString(PyExc_ValueError, "expecting exactly 3 values in tuple."); From b000c759477dc3cdaaa6ced47accf92e890fc7f3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 23 Feb 2001 08:58:32 +0000 Subject: [PATCH 028/279] Fix for python::tuple.set_item() memory leak. [SVN r9316] --- example/getting_started5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index 4b64e4b8..c9f1ce36 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -97,7 +97,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE { python::tuple result(3); for (int i = 0; i < 3; i++) - result.set_item(i, to_python(hkl.v[i])); + result.set_item(i, python::ref(to_python(hkl.v[i]))); return result.reference().release(); } From 977841a7f383115244b27fdf58a4af6429852ff8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 2 Mar 2001 01:48:30 +0000 Subject: [PATCH 029/279] Use PyObject_INIT() instead of hand-initializing objects [SVN r9375] --- include/boost/python/detail/base_object.hpp | 6 ++-- include/boost/python/detail/wrap_python.hpp | 7 +++++ src/extension_class.cpp | 7 +++-- src/functions.cpp | 31 ++++++++++++--------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp index f8ed665b..bf0faa7b 100644 --- a/include/boost/python/detail/base_object.hpp +++ b/include/boost/python/detail/base_object.hpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #ifndef BASE_OBJECT_DWA051600_H_ # define BASE_OBJECT_DWA051600_H_ @@ -46,9 +49,8 @@ base_object::base_object(PyTypeObject* type_obj) std:: #endif memset(bp, 0, sizeof(base_python_type)); - ob_refcnt = 1; - ob_type = type_obj; Py_INCREF(type_obj); + PyObject_INIT(bp, type_obj); } template diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index eb831b68..9e57c287 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -15,6 +15,9 @@ // To use the Python debugging library, #define BOOST_DEBUG_PYTHON on the // compiler command-line. +// Revision History: +// 01 Mar 01 define PyObject_INIT() for Python 1.x + #ifdef _DEBUG # ifndef BOOST_DEBUG_PYTHON # undef _DEBUG // Don't let Python force the debug library just because we're debugging. @@ -76,3 +79,7 @@ typedef int pid_t; # define _DEBUG #endif +#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 +# define PyObject_INIT(op, typeobj) \ + ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#endif diff --git a/src/extension_class.cpp b/src/extension_class.cpp index c15e538b..47862ec7 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #include #include @@ -446,8 +449,8 @@ operator_dispatcher::operator_dispatcher(const ref& o, const ref& s) : m_object(o), m_self(s), m_free_list_link(0) { - ob_refcnt = 1; - ob_type = &type_obj; + PyObject* self = this; + PyObject_INIT(self, &type_obj); } operator_dispatcher* diff --git a/src/functions.cpp b/src/functions.cpp index e166c91c..71b59136 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #include #include @@ -97,19 +100,6 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const return 0; } -bound_function* bound_function::create(const ref& target, const ref& fn) -{ - bound_function* const result = free_list; - if (result == 0) - return new bound_function(target, fn); - - free_list = result->m_free_list_link; - result->m_target = target; - result->m_unbound_function = fn; - Py_INCREF(result); - return result; -} - // The instance class whose obj represents the type of bound_function // objects in Python. bound_functions must be GetAttrable so the __doc__ // attribute of built-in Python functions can be accessed when bound. @@ -123,6 +113,21 @@ private: // type_object hook override void dealloc(bound_function*) const; }; +bound_function* bound_function::create(const ref& target, const ref& fn) +{ + bound_function* const result = free_list; + if (result == 0) + return new bound_function(target, fn); + + free_list = result->m_free_list_link; + result->m_target = target; + result->m_unbound_function = fn; + + PyObject* self = result; + PyObject_INIT(self, type_object::instance()); + return result; +} + bound_function::bound_function(const ref& target, const ref& fn) : python_object(type_object::instance()), m_target(target), From f5fa4a460a27afdfb53b5054c6a9550c009b1817 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 10:22:35 +0000 Subject: [PATCH 030/279] Wrong file name replaced (instance.hpp -> singleton.hpp). [SVN r9390] --- src/gen_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gen_all.py b/src/gen_all.py index 416c66f1..3877d181 100644 --- a/src/gen_all.py +++ b/src/gen_all.py @@ -10,7 +10,7 @@ def gen_all(args): open('caller.hpp', 'w').write(gen_caller(args)) open('init_function.hpp', 'w').write(gen_init_function(args)) open('signatures.hpp', 'w').write(gen_signatures(args)) - open('instance.hpp', 'w').write(gen_singleton(args)) + open('singleton.hpp', 'w').write(gen_singleton(args)) open('extension_class.hpp', 'w').write(gen_extclass(args)) if __name__ == '__main__': From 51d60a603590d559647283bbf3d9c33ebf866002 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 11:48:52 +0000 Subject: [PATCH 031/279] added: converters for [plain] char and std::complex [SVN r9397] --- include/boost/python/conversions.hpp | 39 ++++++++++++++++++++++++++++ src/conversions.cpp | 21 +++++++++++++++ test/comprehensive.cpp | 34 ++++++++++++++++++++++++ test/comprehensive.py | 33 +++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index d11f7f14..b633c0ee 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 03 01 added: converters for [plain] char and std::complex (Ralf W. Grosse-Kunstleve) #ifndef METHOD_DWA122899_H_ # define METHOD_DWA122899_H_ @@ -16,6 +19,7 @@ # include # include # include +# include BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround @@ -100,6 +104,10 @@ PyObject* to_python(unsigned short); unsigned short from_python(PyObject*, boost::python::type); unsigned short from_python(PyObject*, boost::python::type); +PyObject* to_python(char); +char from_python(PyObject*, boost::python::type); +char from_python(PyObject*, boost::python::type); + PyObject* to_python(signed char); signed char from_python(PyObject*, boost::python::type); signed char from_python(PyObject*, boost::python::type); @@ -130,6 +138,32 @@ PyObject* to_python(const std::string& s); std::string from_python(PyObject*, boost::python::type); std::string from_python(PyObject*, boost::python::type); +template +PyObject* to_python(const std::complex& sc) { + Py_complex pcc; + pcc.real = sc.real(); + pcc.imag = sc.imag(); + return PyComplex_FromCComplex(pcc); +} + +template +std::complex from_python(PyObject* p, + boost::python::type&>) { + if (! PyComplex_Check(p)) { + PyErr_SetString(PyExc_TypeError, "expected a complex number"); + throw boost::python::argument_error(); + } + return std::complex( + static_cast(PyComplex_RealAsDouble(p)), + static_cast(PyComplex_ImagAsDouble(p))); +} + +template +inline std::complex from_python(PyObject* p, + boost::python::type >) { + return from_python(p, boost::python::type&>()); +} + // For when your C++ function really wants to pass/return a PyObject* PyObject* to_python(PyObject*); PyObject* from_python(PyObject*, boost::python::type); @@ -304,6 +338,11 @@ inline unsigned short from_python(PyObject* p, boost::python::type()); } +inline char from_python(PyObject* p, boost::python::type) +{ + return from_python(p, boost::python::type()); +} + inline signed char from_python(PyObject* p, boost::python::type) { return from_python(p, boost::python::type()); diff --git a/src/conversions.cpp b/src/conversions.cpp index ded01e0e..369f197a 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 03 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) #include #include @@ -160,6 +163,24 @@ unsigned short from_python(PyObject* p, boost::python::type type return integer_from_python(p, type); } +PyObject* to_python(char c) +{ + if (c == '\0') return PyString_FromString(""); + return PyString_FromStringAndSize(&c, 1); +} + +char from_python(PyObject* p, boost::python::type) +{ + int l = -1; + if (PyString_Check(p)) l = PyString_Size(p); + if (l < 0 || l > 1) { + PyErr_SetString(PyExc_TypeError, "expected string of length 0 or 1"); + throw boost::python::argument_error(); + } + if (l == 0) return '\0'; + return PyString_AsString(p)[0]; +} + PyObject* to_python(unsigned char i) { return integer_to_python(i); diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 7fad74bb..592b0ebd 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -815,6 +815,25 @@ namespace bpl_test { w.set_secret_number(number); } + // Test plain char converters. + char get_plain_char() { return 'x'; } + std::string use_plain_char(char c) { return std::string(3, c); } + std::string use_const_plain_char(const char c) { return std::string(5, c); } + + // Test std::complex converters. + std::complex dpolar(double rho, double theta) { + return std::polar(rho, theta); + } + double dreal(const std::complex& c) { return c.real(); } + double dimag(std::complex c) { return c.imag(); } + + // Test std::complex converters. + std::complex fpolar(float rho, float theta) { + return std::polar(rho, theta); + } + double freal(const std::complex& c) { return c.real(); } + double fimag(std::complex c) { return c.imag(); } + /************************************************************/ /* */ /* init the module */ @@ -1036,6 +1055,21 @@ void init_module(boost::python::module_builder& m) world_class.def(world_getinitargs, "__getinitargs__"); world_class.def(world_getstate, "__getstate__"); world_class.def(world_setstate, "__setstate__"); + + // Test plain char converters. + m.def(get_plain_char, "get_plain_char"); + m.def(use_plain_char, "use_plain_char"); + m.def(use_const_plain_char, "use_const_plain_char"); + + // Test std::complex converters. + m.def(dpolar, "dpolar"); + m.def(dreal, "dreal"); + m.def(dimag, "dimag"); + + // Test std::complex converters. + m.def(fpolar, "fpolar"); + m.def(freal, "freal"); + m.def(fimag, "fimag"); } PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) diff --git a/test/comprehensive.py b/test/comprehensive.py index a8e181d2..8bc8021c 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1070,6 +1070,39 @@ test methodologies for wrapping functions that return a pointer 3 >>> eo.second 1 + +======== test [plain] char converters ============== + >>> get_plain_char() + 'x' + >>> use_plain_char('a') + 'aaa' + >>> use_const_plain_char('b') + 'bbbbb' + +======== test std::complex converters ============== + >>> c = dpolar(3, 5) + >>> type(c) + + >>> '%.3g' % (dreal(c)) + '0.851' + >>> '%.3g' % (dimag(c)) + '-2.88' + >>> '%.3g' % (freal(c)) + '0.851' + >>> '%.3g' % (fimag(c)) + '-2.88' + >>> c = fpolar(7, 13) + >>> type(c) + + >>> '%.3g' % (fimag(c)) + '2.94' + >>> '%.3g' % (freal(c)) + '6.35' + >>> '%.3g' % (dimag(c)) + '2.94' + >>> '%.3g' % (dreal(c)) + '6.35' + ''' from test import * From 1d4427c056ef90b36aaaecc9babc86a778b82e95 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 12:05:15 +0000 Subject: [PATCH 032/279] "T" replaced by "Held" to reduce chances of name clashes. [SVN r9398] --- .../boost/python/detail/extension_class.hpp | 30 +++++++++---------- src/gen_extclass.py | 10 +++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 94d9bf6b..bf43ec5c 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -61,7 +61,7 @@ T* check_non_null(T* p) return p; } -template class held_instance; +template class held_instance; typedef void* (*conversion_function_ptr)(void*); @@ -613,33 +613,33 @@ class extension_class // A simple wrapper over a T which allows us to use extension_class with a // single template parameter only. See extension_class, above. -template -class held_instance : public T +template +class held_instance : public Held { // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in T. + // any virtual functions in Held. public: - held_instance(PyObject*) : T() {} + held_instance(PyObject*) : Held() {} template - held_instance(PyObject*, A1 a1) : T(a1) {} + held_instance(PyObject*, A1 a1) : Held(a1) {} template - held_instance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {} + held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : T(a1, a2, a3, a4) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : T(a1, a2, a3, a4, a5, a6) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : T(a1, a2, a3, a4, a5, a6, a7) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : T(a1, a2, a3, a4, a5, a6, a7, a8) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} }; // Abstract base class for all obj holders. Base for template class diff --git a/src/gen_extclass.py b/src/gen_extclass.py index f8906970..7c378d45 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -66,7 +66,7 @@ T* check_non_null(T* p) return p; } -template class held_instance; +template class held_instance; typedef void* (*conversion_function_ptr)(void*); @@ -613,15 +613,15 @@ class extension_class // A simple wrapper over a T which allows us to use extension_class with a // single template parameter only. See extension_class, above. -template -class held_instance : public T +template +class held_instance : public Held { // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in T. + // any virtual functions in Held. public:""" + gen_functions("""%{ template <%(class A%n%:, %)>%} - held_instance(PyObject*%(, A%n% a%n%)) : T(%(a%n%:, %)) {}""", args) + held_instance(PyObject*%(, A%n% a%n%)) : Held(%(a%n%:, %)) {}""", args) + """ }; From b06d9e50ebf64969d198ab03430d21eb40cb8442 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 12:55:53 +0000 Subject: [PATCH 033/279] added: pickle safety measures; bug fix: use bound_function::create() [SVN r9399] --- include/boost/python/class_builder.hpp | 10 ++++++ src/classes.cpp | 46 ++++++++++++++++++++------ test/comprehensive.py | 41 +++++++++++++++++++++++ 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/include/boost/python/class_builder.hpp b/include/boost/python/class_builder.hpp index 7ef843c4..4a9ec1b2 100644 --- a/include/boost/python/class_builder.hpp +++ b/include/boost/python/class_builder.hpp @@ -1,3 +1,6 @@ +// Revision History: +// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) + #ifndef CLASS_WRAPPER_DWA101000_H_ # define CLASS_WRAPPER_DWA101000_H_ @@ -24,6 +27,13 @@ class class_builder ~class_builder() {} + + inline void dict_defines_state() { + add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__dict_defines_state__"); + } + inline void getstate_manages_dict() { + add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__getstate_manages_dict__"); + } // define constructors template diff --git a/src/classes.cpp b/src/classes.cpp index 2901aa81..625d67b7 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -5,6 +5,10 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) +// Mar 03 01 bug fix: use bound_function::create() (instead of new bound_function) #include #include @@ -67,8 +71,7 @@ namespace { ref global_class_reduce() { - static ref result(detail::new_wrapped_function(class_reduce)); - return result; + return ref(detail::new_wrapped_function(class_reduce)); } @@ -93,17 +96,41 @@ namespace { ref getstate(PyObject_GetAttrString(obj, const_cast("__getstate__")), ref::null_ok); PyErr_Clear(); + + ref dict(PyObject_GetAttrString(obj, const_cast("__dict__")), ref::null_ok); + PyErr_Clear(); + if (getstate.get() != 0) { + if (dict.get() != 0 && dictionary(dict).size() > 0) + { + ref getstate_manages_dict(PyObject_GetAttrString(instance_class.get(), const_cast("__getstate_manages_dict__")), ref::null_ok); + PyErr_Clear(); + if (getstate_manages_dict.get() == 0) + { + PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__getstate_manages_dict__ not set)"); + throw error_already_set(); + } + } + ref state = ref(PyEval_CallObject(getstate.get(), NULL)); return tuple(instance_class, initargs, state); } - ref state(PyObject_GetAttrString(obj, const_cast("__dict__")), ref::null_ok); - PyErr_Clear(); - if (state.get() != 0 && dictionary(state).size() > 0) + if (getinitargs.get() == 0) { - return tuple(instance_class, initargs, state); + ref dict_defines_state(PyObject_GetAttrString(instance_class.get(), const_cast("__dict_defines_state__")), ref::null_ok); + PyErr_Clear(); + if (dict_defines_state.get() == 0) + { + PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__dict_defines_state__ not set)"); + throw error_already_set(); + } + } + + if (dict.get() != 0 && dictionary(dict).size() > 0) + { + return tuple(instance_class, initargs, dict); } return tuple(instance_class, initargs); @@ -111,8 +138,7 @@ namespace { ref global_instance_reduce() { - static ref result(detail::new_wrapped_function(instance_reduce)); - return result; + return ref(detail::new_wrapped_function(instance_reduce)); } } @@ -177,7 +203,7 @@ namespace detail { if (!BOOST_CSTD_::strcmp(name, "__reduce__")) { ref target(as_object(this), ref::increment_count); - return new bound_function(target, global_class_reduce()); + return bound_function::create(target, global_class_reduce()); } ref local_attribute = m_name_space.get_item(string(name).reference()); @@ -348,7 +374,7 @@ PyObject* instance::getattr(const char* name, bool use_special_function) if (!BOOST_CSTD_::strcmp(name, "__reduce__")) { - return new detail::bound_function(ref(this, ref::increment_count), global_instance_reduce()); + return detail::bound_function::create(ref(this, ref::increment_count), global_instance_reduce()); } ref local_attribute = m_name_space.get_item(string(name).reference()); diff --git a/test/comprehensive.py b/test/comprehensive.py index 8bc8021c..3c7f3c61 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -239,6 +239,47 @@ Pickling tests: Hello from California! 42 Hello from California! 0 +Pickle safety measures: + >>> r=Rational(3, 4) + >>> r + Rational(3, 4) + >>> try: s=pickle.dumps(r) + ... except RuntimeError, err: print err[0] + ... + Incomplete pickle support (__dict_defines_state__ not set) + >>> class myrational(Rational): + ... __dict_defines_state__ = 1 # this is a lie but good enough for testing. + ... + >>> r=myrational(3, 4) + >>> r + Rational(3, 4) + >>> s=pickle.dumps(r) + + >>> class myworld(world): + ... def __init__(self): + ... world.__init__(self, 'anywhere') + ... self.x = 1 + ... + >>> w = myworld() + >>> w.greet() + 'Hello from anywhere!' + >>> w.__dict__ + {'x': 1} + >>> try: s=pickle.dumps(w) + ... except RuntimeError, err: print err[0] + ... + Incomplete pickle support (__getstate_manages_dict__ not set) + + >>> class myunsafeworld(myworld): + ... __getstate_manages_dict__ = 1 # this is a lie but good enough for testing. + ... + >>> w = myunsafeworld() + >>> w.greet() + 'Hello from anywhere!' + >>> w.__dict__ + {'x': 1} + >>> s=pickle.dumps(w) + Special member attributes. Tests courtesy of Barry Scott >>> class DerivedFromFoo(Foo): From fc62d3b44ec404cb470746c3c681764b846b88a8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 14:46:26 +0000 Subject: [PATCH 034/279] New Makefiles for tru64_cxx, linux_gcc, mingw32. [SVN r9400] --- build/Makefile.linux_gcc | 166 +++++++++++++++++++++++++++++++ build/Makefile.mingw32 | 210 +++++++++++++++++++++++++++++++++++++++ build/Makefile.tru64_cxx | 170 +++++++++++++++++++++++++++++++ build/tru64.mak | 51 ---------- 4 files changed, 546 insertions(+), 51 deletions(-) create mode 100644 build/Makefile.linux_gcc create mode 100644 build/Makefile.mingw32 create mode 100644 build/Makefile.tru64_cxx delete mode 100644 build/tru64.mak diff --git a/build/Makefile.linux_gcc b/build/Makefile.linux_gcc new file mode 100644 index 00000000..3e8f1041 --- /dev/null +++ b/build/Makefile.linux_gcc @@ -0,0 +1,166 @@ +# Usage: +# +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Set the BOOST pathname below. +# +# make softlinks Create softlinks to source code and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make unlink Remove softlinks + +BOOST= /net/cci/rwgk/boost + +PYEXE= /usr/local/Python-1.5.2/bin/python +PYINC= -I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE= /usr/local/Python-2.0/bin/python +#PYINC= -I/usr/local/Python-2.0/include/python2.0 +#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport +#STLPORTOPTS= \ +# -D__USE_STD_IOSTREAM \ +# -D__STL_NO_SGI_IOSTREAMS \ +# -D__STL_USE_NATIVE_STRING \ +# -D__STL_NO_NEW_C_HEADERS \ +# -D_RWSTD_COMPILE_INSTANTIATE=1 +#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport +#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS +#STLPORTINC= -I/net/cci/xp/C++_C_headers + +STDOPTS= -ftemplate-depth-21 +WARNOPTS= +# use -msg_display_number to obtain integer tags for -msg_disable + +CPP= g++ +CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) -g +MAKEDEP= -M + +LD= g++ +LDOPTS= -shared + +#HIDDEN= -hidden + +BPL_SRC = $(BOOST)/libs/python/src +BPL_TST = $(BOOST)/libs/python/test +BPL_EXA = $(BOOST)/libs/python/example +SOFTLINKS = \ +$(BPL_SRC)/classes.cpp \ +$(BPL_SRC)/conversions.cpp \ +$(BPL_SRC)/extension_class.cpp \ +$(BPL_SRC)/functions.cpp \ +$(BPL_SRC)/init_function.cpp \ +$(BPL_SRC)/module_builder.cpp \ +$(BPL_SRC)/objects.cpp \ +$(BPL_SRC)/types.cpp \ +$(BPL_TST)/comprehensive.cpp \ +$(BPL_TST)/comprehensive.hpp \ +$(BPL_TST)/comprehensive.py \ +$(BPL_TST)/doctest.py \ +$(BPL_EXA)/abstract.cpp \ +$(BPL_EXA)/getting_started1.cpp \ +$(BPL_EXA)/getting_started2.cpp \ +$(BPL_EXA)/getting_started3.cpp \ +$(BPL_EXA)/getting_started4.cpp \ +$(BPL_EXA)/getting_started5.cpp \ +$(BPL_EXA)/test_abstract.py \ +$(BPL_EXA)/test_getting_started1.py \ +$(BPL_EXA)/test_getting_started2.py \ +$(BPL_EXA)/test_getting_started3.py \ +$(BPL_EXA)/test_getting_started4.py \ +$(BPL_EXA)/test_getting_started5.py + +OBJ = classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o +DEPOBJ= $(OBJ) comprehensive.o abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + getting_started4.o getting_started5.o + +.SUFFIXES: .o .cpp + +all: libbpl.a test.so abstract.so \ + getting_started1.so getting_started2.so getting_started3.so \ + getting_started4.so getting_started5.so + +softlinks: + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ ! -e "$$bn" ]; then \ + echo "ln -s $$pn ."; \ + ln -s "$$pn" .; \ + else \ + echo "info: no softlink created (file exists): $$bn"; \ + fi; \ + done + +unlink: + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ -L "$$bn" ]; then \ + echo "rm $$bn"; \ + rm "$$bn"; \ + elif [ -e "$$bn" ]; then \ + echo "info: not a softlink: $$bn"; \ + fi; \ + done + +libbpl.a: $(OBJ) + rm -f libbpl.a + ar r libbpl.a $(OBJ) + +test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o test.so -lm + +abstract.so: $(OBJ) abstract.o + $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so + +getting_started1.so: $(OBJ) getting_started1.o + $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so + +getting_started2.so: $(OBJ) getting_started2.o + $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so + +getting_started3.so: $(OBJ) getting_started3.o + $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so + +getting_started4.so: $(OBJ) getting_started4.o + $(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so + +getting_started5.so: $(OBJ) getting_started5.o + $(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so + +.cpp.o: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_getting_started4.py + $(PYEXE) test_getting_started5.py + +clean: + rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f comprehensive.o test.so + rm -f abstract.o abstract.so + rm -f getting_started1.o getting_started1.so + rm -f getting_started2.o getting_started2.so + rm -f getting_started3.o getting_started3.so + rm -f getting_started4.o getting_started4.so + rm -f getting_started5.o getting_started5.so + rm -f so_locations *.pyc + rm -rf cxx_repository + +depend: + @ cat Makefile.nodepend; \ + for obj in $(DEPOBJ); \ + do \ + bn=`echo "$$obj" | cut -d. -f1`; \ + $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ + done + diff --git a/build/Makefile.mingw32 b/build/Makefile.mingw32 new file mode 100644 index 00000000..2d86efcd --- /dev/null +++ b/build/Makefile.mingw32 @@ -0,0 +1,210 @@ +# Usage: +# +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Set the BOOST_* pathnames below. +# +# The idea is that the build directory is on a Unix filesystem that +# is mounted on a PC using SAMBA. Use this makefile under both Unix +# and Windows: +# +# Unix: make softlinks Create softlinks to source code and tests +# Win: make Compile all sources +# Win: make test Run doctest tests +# Unix: make clean Remove all object files +# Unix: make unlink Remove softlinks + +# To install mingw32, follow instructions at: +# http://starship.python.net/crew/kernr/mingw32/Notes.html +# In particular, install: +# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/gcc-2.95.2-msvcrt.exe +# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/fixes/quote-fix-msvcrt.exe +# http://starship.python.net/crew/kernr/mingw32/Python-1.5.2-mingw32.zip +# Unpack the first two archives in the default locations and update your PATH. +# Unpack the third archive in \usr. + +# Note: comprehensive.cpp generates compiler errors and later crashes. +# L:\boost\boost\python\detail\extension_class.hpp:643: warning: +# alignment of `vtable for class +# boost::python::detail::held_instance' +# is greater than maximum object file alignment. Using 16. +# Could this be fixed with compiler options? +# -fhuge-objects looks interesting, but requires recompiling the C++ library. +# (what exactly does that mean?) +# -fvtable-thunks eliminates the compiler warning, but "import test" still +# causes a crash. + +BOOST_UNIX= /net/cci/rwgk/boost +BOOST_WIN= "L:\boost" + +PYEXE= "C:\Program files\Python\python.exe" +PYINC= -I"C:\usr\include\python1.5" +PYLIB= "C:\usr\lib\libpython15.a" + +STDOPTS= -ftemplate-depth-21 +WARNOPTS= + +CPP= g++ +CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) -g + +LD= g++ +LDOPTS= -shared + +BPL_SRC = $(BOOST_UNIX)/libs/python/src +BPL_TST = $(BOOST_UNIX)/libs/python/test +BPL_EXA = $(BOOST_UNIX)/libs/python/example +SOFTLINKS = \ +$(BPL_SRC)/classes.cpp \ +$(BPL_SRC)/conversions.cpp \ +$(BPL_SRC)/extension_class.cpp \ +$(BPL_SRC)/functions.cpp \ +$(BPL_SRC)/init_function.cpp \ +$(BPL_SRC)/module_builder.cpp \ +$(BPL_SRC)/objects.cpp \ +$(BPL_SRC)/types.cpp \ +$(BPL_TST)/comprehensive.cpp \ +$(BPL_TST)/comprehensive.hpp \ +$(BPL_TST)/comprehensive.py \ +$(BPL_TST)/doctest.py \ +$(BPL_EXA)/abstract.cpp \ +$(BPL_EXA)/getting_started1.cpp \ +$(BPL_EXA)/getting_started2.cpp \ +$(BPL_EXA)/getting_started3.cpp \ +$(BPL_EXA)/getting_started4.cpp \ +$(BPL_EXA)/getting_started5.cpp \ +$(BPL_EXA)/passing_char.cpp \ +$(BPL_EXA)/test_abstract.py \ +$(BPL_EXA)/test_getting_started1.py \ +$(BPL_EXA)/test_getting_started2.py \ +$(BPL_EXA)/test_getting_started3.py \ +$(BPL_EXA)/test_getting_started4.py \ +$(BPL_EXA)/test_getting_started5.py + +DEFS= \ +test \ +abstract \ +getting_started1 \ +getting_started2 \ +getting_started3 \ +getting_started4 \ +getting_started5 + +OBJ = classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o + +.SUFFIXES: .o .cpp + +all: libbpl.a test.pyd abstract.pyd \ + getting_started1.pyd getting_started2.pyd getting_started3.pyd \ + getting_started4.pyd getting_started5.pyd + +softlinks: defs + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ ! -e "$$bn" ]; then \ + echo "ln -s $$pn ."; \ + ln -s "$$pn" .; \ + else \ + echo "info: no softlink created (file exists): $$bn"; \ + fi; \ + done + +unlink: rmdefs + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ -L "$$bn" ]; then \ + echo "rm $$bn"; \ + rm "$$bn"; \ + elif [ -e "$$bn" ]; then \ + echo "info: not a softlink: $$bn"; \ + fi; \ + done + +defs: + @ for def in $(DEFS); \ + do \ + echo "EXPORTS\n\tinit$$def" > $$def.def; \ + done + +rmdefs: + @ for def in $(DEFS); \ + do \ + rm $$def.def; \ + done + +libbpl.a: $(OBJ) + del libbpl.a + ar r libbpl.a $(OBJ) + +DLLWRAPOPTS= -s --driver-name g++ -s + --entry _DllMainCRTStartup@12 --target=i386-mingw32 + +test.pyd: $(OBJ) comprehensive.o + dllwrap $(DLLWRAPOPTS) \ + --dllname test.pyd \ + --def test.def \ + $(OBJ) comprehensive.o $(PYLIB) + +abstract.pyd: $(OBJ) abstract.o + dllwrap $(DLLWRAPOPTS) \ + --dllname abstract.pyd \ + --def abstract.def \ + $(OBJ) abstract.o $(PYLIB) + +getting_started1.pyd: $(OBJ) getting_started1.o + dllwrap $(DLLWRAPOPTS) \ + --dllname getting_started1.pyd \ + --def getting_started1.def \ + $(OBJ) getting_started1.o $(PYLIB) + +getting_started2.pyd: $(OBJ) getting_started2.o + dllwrap $(DLLWRAPOPTS) \ + --dllname getting_started2.pyd \ + --def getting_started2.def \ + $(OBJ) getting_started2.o $(PYLIB) + +getting_started3.pyd: $(OBJ) getting_started3.o + dllwrap $(DLLWRAPOPTS) \ + --dllname getting_started3.pyd \ + --def getting_started3.def \ + $(OBJ) getting_started3.o $(PYLIB) + +getting_started4.pyd: $(OBJ) getting_started4.o + dllwrap $(DLLWRAPOPTS) \ + --dllname getting_started4.pyd \ + --def getting_started4.def \ + $(OBJ) getting_started4.o $(PYLIB) + +getting_started5.pyd: $(OBJ) getting_started5.o + dllwrap $(DLLWRAPOPTS) \ + --dllname getting_started5.pyd \ + --def getting_started5.def \ + $(OBJ) getting_started5.o $(PYLIB) + +.cpp.o: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_getting_started4.py + $(PYEXE) test_getting_started5.py + +clean: + rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f comprehensive.o test.pyd + rm -f abstract.o abstract.pyd + rm -f getting_started1.o getting_started1.pyd + rm -f getting_started2.o getting_started2.pyd + rm -f getting_started3.o getting_started3.pyd + rm -f getting_started4.o getting_started4.pyd + rm -f getting_started5.o getting_started5.pyd + rm -f so_locations *.pyc + rm -rf cxx_repository diff --git a/build/Makefile.tru64_cxx b/build/Makefile.tru64_cxx new file mode 100644 index 00000000..7b932bd3 --- /dev/null +++ b/build/Makefile.tru64_cxx @@ -0,0 +1,170 @@ +# Usage: +# +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Set the BOOST pathname below. +# +# make softlinks Create softlinks to source code and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make unlink Remove softlinks + +BOOST= /net/cci/rwgk/boost + +PYEXE= /usr/local/Python-1.5.2/bin/python +PYINC= -I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE= /usr/local/Python-2.0/bin/python +#PYINC= -I/usr/local/Python-2.0/include/python2.0 +#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport +#STLPORTOPTS= \ +# -D__USE_STD_IOSTREAM \ +# -D__STL_NO_SGI_IOSTREAMS \ +# -D__STL_USE_NATIVE_STRING \ +# -D__STL_NO_NEW_C_HEADERS \ +# -D_RWSTD_COMPILE_INSTANTIATE=1 +#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport +#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS +STLPORTINC= -I/net/cci/xp/C++_C_headers + +STDOPTS= -std strict_ansi +WARNOPTS= -msg_disable 186,450,1115 +# use -msg_display_number to obtain integer tags for -msg_disable + +CPP= cxx +CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) -g +MAKEDEP= -Em + +LD= cxx +LDOPTS= -shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' + +#HIDDEN= -hidden + +BPL_SRC = $(BOOST)/libs/python/src +BPL_TST = $(BOOST)/libs/python/test +BPL_EXA = $(BOOST)/libs/python/example +SOFTLINKS = \ +$(BPL_SRC)/classes.cpp \ +$(BPL_SRC)/conversions.cpp \ +$(BPL_SRC)/extension_class.cpp \ +$(BPL_SRC)/functions.cpp \ +$(BPL_SRC)/init_function.cpp \ +$(BPL_SRC)/module_builder.cpp \ +$(BPL_SRC)/objects.cpp \ +$(BPL_SRC)/types.cpp \ +$(BPL_TST)/comprehensive.cpp \ +$(BPL_TST)/comprehensive.hpp \ +$(BPL_TST)/comprehensive.py \ +$(BPL_TST)/doctest.py \ +$(BPL_EXA)/abstract.cpp \ +$(BPL_EXA)/getting_started1.cpp \ +$(BPL_EXA)/getting_started2.cpp \ +$(BPL_EXA)/getting_started3.cpp \ +$(BPL_EXA)/getting_started4.cpp \ +$(BPL_EXA)/getting_started5.cpp \ +$(BPL_EXA)/test_abstract.py \ +$(BPL_EXA)/test_getting_started1.py \ +$(BPL_EXA)/test_getting_started2.py \ +$(BPL_EXA)/test_getting_started3.py \ +$(BPL_EXA)/test_getting_started4.py \ +$(BPL_EXA)/test_getting_started5.py + +OBJ = classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o +DEPOBJ= $(OBJ) comprehensive.o abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + getting_started4.o getting_started5.o + +.SUFFIXES: .o .cpp + +all: libbpl.a test.so abstract.so \ + getting_started1.so getting_started2.so getting_started3.so \ + getting_started4.so getting_started5.so + +softlinks: + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ ! -e "$$bn" ]; then \ + echo "ln -s $$pn ."; \ + ln -s "$$pn" .; \ + else \ + echo "info: no softlink created (file exists): $$bn"; \ + fi; \ + done + +unlink: + @ for pn in $(SOFTLINKS); \ + do \ + bn=`basename "$$pn"`; \ + if [ -L "$$bn" ]; then \ + echo "rm $$bn"; \ + rm "$$bn"; \ + elif [ -e "$$bn" ]; then \ + echo "info: not a softlink: $$bn"; \ + fi; \ + done + +libbpl.a: $(OBJ) + rm -f libbpl.a + cd cxx_repository; \ + ls -1 > ../libbpl.a.input; \ + ar r ../libbpl.a -input ../libbpl.a.input + rm -f libbpl.a.input + ar r libbpl.a $(OBJ) + +test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o test.so -lm + +abstract.so: $(OBJ) abstract.o + $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so + +getting_started1.so: $(OBJ) getting_started1.o + $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so + +getting_started2.so: $(OBJ) getting_started2.o + $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so + +getting_started3.so: $(OBJ) getting_started3.o + $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so + +getting_started4.so: $(OBJ) getting_started4.o + $(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so + +getting_started5.so: $(OBJ) getting_started5.o + $(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so + +.cpp.o: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_getting_started4.py + $(PYEXE) test_getting_started5.py + +clean: + rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f comprehensive.o test.so + rm -f abstract.o abstract.so + rm -f getting_started1.o getting_started1.so + rm -f getting_started2.o getting_started2.so + rm -f getting_started3.o getting_started3.so + rm -f getting_started4.o getting_started4.so + rm -f getting_started5.o getting_started5.so + rm -f so_locations *.pyc + rm -rf cxx_repository + +depend: + @ cat Makefile.nodepend; \ + for obj in $(DEPOBJ); \ + do \ + bn=`echo "$$obj" | cut -d. -f1`; \ + $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ + done + diff --git a/build/tru64.mak b/build/tru64.mak deleted file mode 100644 index 6631615c..00000000 --- a/build/tru64.mak +++ /dev/null @@ -1,51 +0,0 @@ -# -# Tested with: -# Compaq C++ V6.2-024 for Digital UNIX V5.0 (Rev. 910) -# -# Python 1.5.2 was installed without any customizations. -# boost_all.zip vers. 1.18.1 was unpacked using unzip -aa and not modified. -# STLport-4.1b3 was unpacked using unzip -aa and not modified. -# -# Initial version 2000-10-20: Ralf W. Grosse-Kunstleve, rwgk@cci.lbl.gov -# - -PYINC= /usr/local/include/python1.5 -BOOSTINC= /usr/local/boost_1_18_1 -STLPORTINC= /usr/local/STLport-4.1b3/stlport -STLPORTOPTS= \ - -D__USE_STD_IOSTREAM \ - -D__STL_NO_SGI_IOSTREAMS \ - -D__STL_NO_NEW_C_HEADERS \ - -D_RWSTD_COMPILE_INSTANTIATE=1 - -STDOPTS= -std strict_ansi -WARNOPTS= -msg_disable 186,450,1115 -# use -msg_display_number to obtain integer tags for -msg_disable - -CPP= cxx -CPPOPTS= -I$(STLPORTINC) $(STLPORTOPTS) -I$(BOOSTINC) -I$(PYINC) \ - $(STDOPTS) $(WARNOPTS) - -LD= cxx -LDOPTS= -shared -expect_unresolved '*' - -OBJ = extclass.o functions.o init_function.o module.o newtypes.o \ - objects.o py.o subclass.o - -.SUFFIXES: .o .cpp - -all: demo.so hello.so - -demo.so: $(OBJ) extclass_demo.o - $(LD) $(LDOPTS) $(OBJ) extclass_demo.o -o demo.so - -hello.so: $(OBJ) example1.o - $(LD) $(LDOPTS) $(OBJ) example1.o -o hello.so - -.cpp.o: - -$(CPP) $(CPPOPTS) $(INC) -c $*.cpp - -clean: - rm -f $(OBJ) extclass_demo.o example1.o demo.so hello.so so_locations - rm -rf cxx_repository - rm -f *.pyc From 28e6a84acbf5c2fe893d5ca74b49dc78764588e9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:10:16 +0000 Subject: [PATCH 035/279] Fixed std::complex<> stuff to work with MSVC [SVN r9408] --- include/boost/python/conversions.hpp | 82 +++++++++++++++++++++------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index b633c0ee..47f80989 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -7,7 +7,9 @@ // producing this work. // // Revision History: -// Mar 03 01 added: converters for [plain] char and std::complex (Ralf W. Grosse-Kunstleve) +// 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams) +// 03 Mar 01 added: converters for [plain] char and std::complex +// (Ralf W. Grosse-Kunstleve) #ifndef METHOD_DWA122899_H_ # define METHOD_DWA122899_H_ @@ -19,8 +21,18 @@ # include # include # include + +# ifdef BOOST_MSVC6_OR_EARLIER +# pragma warning(push) +# pragma warning(disable:4275) // disable a bogus warning caused by +# endif + # include +# ifdef BOOST_MSVC6_OR_EARLIER +# pragma warning(pop) +# endif + BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround // This can be instantiated on an enum to provide the to_python/from_python @@ -74,6 +86,30 @@ inline void xdecref(T* p) xdecref_impl(reinterpret_cast(p_base)); } +namespace detail { + + void expect_complex(PyObject*); + + template + std::complex complex_from_python(PyObject* p, boost::python::type) + { + expect_complex(p); + + return std::complex( + static_cast(PyComplex_RealAsDouble(p)), + static_cast(PyComplex_ImagAsDouble(p))); + } + + template + PyObject* complex_to_python(const std::complex& sc) { + Py_complex pcc; + pcc.real = sc.real(); + pcc.imag = sc.imag(); + return PyComplex_FromCComplex(pcc); + } + +} + }} // namespace boost::python BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -138,30 +174,34 @@ PyObject* to_python(const std::string& s); std::string from_python(PyObject*, boost::python::type); std::string from_python(PyObject*, boost::python::type); -template -PyObject* to_python(const std::complex& sc) { - Py_complex pcc; - pcc.real = sc.real(); - pcc.imag = sc.imag(); - return PyComplex_FromCComplex(pcc); +inline PyObject* to_python(const std::complex& x) +{ + return boost::python::detail::complex_to_python(x); } -template -std::complex from_python(PyObject* p, - boost::python::type&>) { - if (! PyComplex_Check(p)) { - PyErr_SetString(PyExc_TypeError, "expected a complex number"); - throw boost::python::argument_error(); - } - return std::complex( - static_cast(PyComplex_RealAsDouble(p)), - static_cast(PyComplex_ImagAsDouble(p))); +inline PyObject* to_python(const std::complex& x) +{ + return boost::python::detail::complex_to_python(x); } -template -inline std::complex from_python(PyObject* p, - boost::python::type >) { - return from_python(p, boost::python::type&>()); +inline std::complex from_python(PyObject* p, + boost::python::type >) { + return boost::python::detail::complex_from_python(p, boost::python::type()); +} + +inline std::complex from_python(PyObject* p, + boost::python::type&>) { + return boost::python::detail::complex_from_python(p, boost::python::type()); +} + +inline std::complex from_python(PyObject* p, + boost::python::type >) { + return boost::python::detail::complex_from_python(p, boost::python::type()); +} + +inline std::complex from_python(PyObject* p, + boost::python::type&>) { + return boost::python::detail::complex_from_python(p, boost::python::type()); } // For when your C++ function really wants to pass/return a PyObject* From 0b97d9bae58d79e4c834f9e5a809a4fe36116368 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:12:30 +0000 Subject: [PATCH 036/279] Some fixes so it will compile with Intel C++ [SVN r9409] --- include/boost/python/detail/config.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index faf52ee4..3207f7c6 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -6,6 +6,9 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// Revision History: +// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams) + #ifndef CONFIG_DWA052200_H_ # define CONFIG_DWA052200_H_ @@ -46,8 +49,9 @@ # endif // The STLport puts all of the standard 'C' library names in std (as far as the -// user is concerned), but without it you need a fix if you're using MSVC. -# if defined(BOOST_MSVC6_OR_EARLIER) && !defined(__STLPORT) +// user is concerned), but without it you need a fix if you're using MSVC or +// Intel C++ +# if defined(BOOST_MSVC_STD_ITERATOR) # define BOOST_CSTD_ # else # define BOOST_CSTD_ std From a40daca9ef899a340608ee22b729a53160bb46b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:14:04 +0000 Subject: [PATCH 037/279] *** empty log message *** [SVN r9410] --- include/boost/python/detail/wrap_python.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 9e57c287..d5b75374 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -16,7 +16,8 @@ // compiler command-line. // Revision History: -// 01 Mar 01 define PyObject_INIT() for Python 1.x +// 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) +// 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) #ifdef _DEBUG # ifndef BOOST_DEBUG_PYTHON @@ -64,6 +65,8 @@ typedef int pid_t; # define _MSC_VER 900 # endif +# elif defined(_MSC_VER) +# include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX # endif #endif // _WIN32 From 71aff9f0e8fce2dda850f08f861dc9fcbbc3f39b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:41:47 +0000 Subject: [PATCH 038/279] Changed library name to libboost_python.a [SVN r9411] --- build/como.mak | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build/como.mak b/build/como.mak index 5a9920d8..c6f340a5 100644 --- a/build/como.mak +++ b/build/como.mak @@ -1,3 +1,5 @@ +# Revision History: +# 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) LIBSRC = \ classes.cpp \ conversions.cpp \ @@ -30,8 +32,8 @@ endif | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ -example1: example1.o libpycpp.a - como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lpycpp +example1: example1.o libboost_python.a + como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lboost_python python ../example/test_example1.py example1.o: ../example/example1.cpp @@ -40,9 +42,9 @@ example1.o: ../example/example1.cpp clean: rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out -libpycpp.a: $(LIBOBJ) - rm -f libpycpp.a - ar cq libpycpp.a $(LIBOBJ) +libboost_python.a: $(LIBOBJ) + rm -f libboost_python.a + ar cq libboost_python.a $(LIBOBJ) DEP = $(OBJ:.o=.d) From 4aa4f1c3b3b625450c1875548a49731db8bd6f3d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:45:02 +0000 Subject: [PATCH 039/279] Added DebugPython target; cleaned up some mess introduced by others [SVN r9412] --- build/bpl_static.dsp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp index 701dd309..92af59c7 100644 --- a/build/bpl_static.dsp +++ b/build/bpl_static.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Static Library" 0x0104 -CFG=bpl_static - Win32 Debug +CFG=bpl_static - Win32 DebugPython !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,13 @@ CFG=bpl_static - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "bpl_static.mak" CFG="bpl_static - Win32 Debug" +!MESSAGE NMAKE /f "bpl_static.mak" CFG="bpl_static - Win32 DebugPython" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "bpl_static - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "bpl_static - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "bpl_static - Win32 DebugPython" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project @@ -64,7 +65,30 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /ZI /Od /I "d:\boost\type_traits" /I "..\..\.." /I "c:\progra~1\python20\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "bpl_static - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "bpl_static___Win32_DebugPython" +# PROP BASE Intermediate_Dir "bpl_static___Win32_DebugPython" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPython" +# PROP Intermediate_Dir "DebugPython" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -80,6 +104,7 @@ LIB32=link.exe -lib # Name "bpl_static - Win32 Release" # Name "bpl_static - Win32 Debug" +# Name "bpl_static - Win32 DebugPython" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" From 4b926b7c7fa3aaf563745281034ed2405cf8b36b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:48:50 +0000 Subject: [PATCH 040/279] Changed library name to libboost_python.a, various cleanups, attempted Cygwin compatibility. Still needs testing on Linux. [SVN r9413] --- build/gcc.mak | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/build/gcc.mak b/build/gcc.mak index d0b42548..f71185e0 100644 --- a/build/gcc.mak +++ b/build/gcc.mak @@ -1,3 +1,10 @@ +# Revision History + +# 04 Mar 01 Changed library name to libboost_python.a, various cleanups, +# attempted Cygwin compatibility. Still needs testing on Linux +# (David Abrahams) + + LIBSRC = \ classes.cpp \ conversions.cpp \ @@ -11,13 +18,16 @@ LIBSRC = \ LIBOBJ = $(LIBSRC:.cpp=.o) OBJ = $(LIBOBJ) +PYTHON_INC=$(ROOT)/usr/local/include/python2.0 +# libpython2.0.dll ifeq "$(OS)" "Windows_NT" -PYTHON_LIB=c:/tools/python/libs/python15.lib -INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include +ROOT=c:/cygnus +INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC) MODULE_EXTENSION=dll +PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a else -INC = -I/usr/local/include/python1.5 +INC = -I$(PYTHON_INC) MODULE_EXTENSION=so endif @@ -31,20 +41,30 @@ endif [ -s $@ ] || rm -f $@ -example1: example1.o libpycpp.a - g++ -shared -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lpycpp - python ../example/test_example1.py +PYTHON = python + +test: comprehensive.o libboost_python.a + g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB) + $(PYTHON) ../test/comprehensive.py + +comprehensive.o: ../test/comprehensive.cpp + g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< + + +example1: example1.o libboost_python.a + g++ $(CXXFLAGS) -shared -o ../example/hellomodule.$(MODULE_EXTENSION) example1.o -L. -lboost_python $(PYTHON_LIB) + $(PYTHON) ../example/test_example1.py example1.o: ../example/example1.cpp - g++ -fPIC -Wall -W $(INC) -o $*.o -c $< + g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< clean: rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out -libpycpp.a: $(LIBOBJ) - rm -f libpycpp.a - ar cq libpycpp.a $(LIBOBJ) +libboost_python.a: $(LIBOBJ) + rm -f libboost_python.a + ar cq libboost_python.a $(LIBOBJ) DEP = $(OBJ:.o=.d) From f82151f925a3481ea05dd1b095069d5b5401f3ab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:48:55 +0000 Subject: [PATCH 041/279] no message [SVN r9414] --- build/build.opt | Bin 84480 -> 80384 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/build.opt b/build/build.opt index a650cf1f83e6ca05cbe1a0fccd96f89b59f47f31..9cdea95b7eef30bf876fd69fc7e9971cd8f4a6f9 100644 GIT binary patch literal 80384 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 literal 84480 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;!F$-42&?o00YCn|NsAkxG);TZeU(z@W##z@X2-z+k|@z+lM0z+l9{z+lY4z+l3_z+lS2z+lF}z+le6z+l0^z+lP1 zz+lC|z+lb5z+l6`z+lV3z+eY8&w+t~!I6Q1!HI!^!I^=9!G(c=!Igo5!Ht1|!JUDD z!GnQ;!IOc3!Ha=`!JC1B!H0o?!Iy!7!HA_D_M5(5K6 zG6Mrc3RM4e1_p+71_p)<1_p*q1_p*K1_p*~1_p*41_p*)1_p*a1_p+F1_p)#1_p*g z1_p*A1_p*=1_p)_1_p*ws2Sx93=9-r@+9(2uib{v&|p z81fm)8HyQF!Qn_qFS@({0}~@C?|{llV(sSv83M{I;PjTlkjYR24h4`fshE#}i4l}X zL3V>MG5WaGA%G0wAwVZL=1y&FPCSjU5QY#X33vyBo z4e;0nQxgMYz;x@y=pmt!{QMla?=tg}b4pWEW0G?ci;MGv^fHuUc)2*0koD;4 z#bDP)juwzdD#+28mzJ4MitAD`lS@dqCoMB4l?+`u`HAFMR+^Vgx@DQU1^GoJMO0=U z8IH@$D=A9ONKMWrCD3y+i^;GmCqFNp^l->cEy>7FAwyq&N^xlcsbQF#pHfOr(#WmM zP0Y#3PbMW4b1Msq@=Nkb(L#DKtz%aU{+&LW%-bb1h`R!VpKx|Hz~0=H6B*T5%eWgQ*vT)3BE9fdKIRc zV9G#MpIT9png{YmJh=TtyhUlHdC4WDc|S8Rvm_p-k9eE%^7B%OS6!T$o|jlsT0~SV zLIbThGcP?SwIn}}cxynJgoKzcFG?(khlD&4cEIWlf=L8Ybdiw2A&HL|hm(?Zi&E24 zi&FEF@kUc|ZemeMd_f7`d4 zYCsrf9!w30KEc4iFbz8G08#_OXP6imG{9rCAQcb{QwK5@qy~g>nFrDV(hgDs!uZsI z)Pl^+iy0mN!x#!39sh$RiqY{u(8vuuk3jkhkWK(810JK}e+8rCf1~4nuu^4o{I9qq zW_0{-bo_60{14|4J!G&i20FqxI{p_kI{pXhvy9@=5Eu=C(GVC7fzc44N(gW;Ff;i2 zc=<3faE7E7mpGRem8B}WSj7|U6fOpG9VVHm$^h^#h<0v#>@-roiwhEyQx(*~+o{y8 z6igHfit<6*tu=}@A*Rt^6~taN$C9+In2f#4pxq-msiXV9A^Yw@8@fmz3LoA74GF!` z{onbBCETPZqtWr-(eYpK=^vxxzu?`C@X?mh@n6tv8Mv)8I{u3?Gk`iUIlBKlGbd(r z|2MesKpD6m-Tw{hWR2p{5Eu=C(GVC7fzc2coFS0#3Ua2e1kwu=K#pS9Zo$`2t5ig!-7(CQWJ|)!DE%6LxLGVtXHg{aZ3>EH<$$qBb=s! zlriGf%EloQ9PAXtz{tSO;2e@zl%87RS(2KI$2oW{1W7`TOmQt{rY=>;;e$=5VXvEPxFu;8w$n zGMSG@9m=6+xYhBa4XNT*$%ndy8Mi`iq?6rntKtWpI)-%M5N?&+NSi+Ks6tw$idz*2 zY#}giCA=u@Z`|s5kQajDR>lcGjS;sR9^`W`aVrzTTvLWyF%R*}o{Svn#KGe}~+zQ!~Q_B)_^fGX(0HsQzeZhl#Kn89zIpL$r zxYh6_m8PYo77-3(uEeBbP!Ups≶XgBEaG$pNWX@R`G#hJ2PUZlkzh1yMl(Zbclh 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 From bf5eec727e06ee5fbeaa19a2a8ff9870f66c2ff0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:53:00 +0000 Subject: [PATCH 042/279] Added DebugPython target [SVN r9415] --- build/example1/example1.dsp | 39 +++++++++++++++++++++++++++----- build/rwgk1/rwgk1.dsp | 38 +++++++++++++++++++++++++++---- build/test/test.dsp | 45 ++++++++++++++++++++++++++++++++----- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/build/example1/example1.dsp b/build/example1/example1.dsp index 78d1f0d8..dcff3f55 100644 --- a/build/example1/example1.dsp +++ b/build/example1/example1.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 -CFG=example1 - Win32 Debug +CFG=example1 - Win32 DebugPython !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,13 @@ CFG=example1 - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "example1.mak" CFG="example1 - Win32 Debug" +!MESSAGE NMAKE /f "example1.mak" CFG="example1 - Win32 DebugPython" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "example1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "example1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project @@ -68,8 +69,8 @@ LINK32=link.exe # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -79,7 +80,34 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "example1 - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example1___Win32_DebugPython" +# PROP BASE Intermediate_Dir "example1___Win32_DebugPython" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPython" +# PROP Intermediate_Dir "DebugPython" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/hello_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" !ENDIF @@ -87,6 +115,7 @@ LINK32=link.exe # Name "example1 - Win32 Release" # Name "example1 - Win32 Debug" +# Name "example1 - Win32 DebugPython" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" diff --git a/build/rwgk1/rwgk1.dsp b/build/rwgk1/rwgk1.dsp index 18526979..daf736b3 100644 --- a/build/rwgk1/rwgk1.dsp +++ b/build/rwgk1/rwgk1.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 -CFG=rwgk1 - Win32 Debug +CFG=rwgk1 - Win32 DebugPython !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,13 @@ CFG=rwgk1 - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "rwgk1.mak" CFG="rwgk1 - Win32 Debug" +!MESSAGE NMAKE /f "rwgk1.mak" CFG="rwgk1 - Win32 DebugPython" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "rwgk1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "rwgk1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "rwgk1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project @@ -65,9 +66,10 @@ LINK32=link.exe # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -77,7 +79,34 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "rwgk1 - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "rwgk1___Win32_DebugPython" +# PROP BASE Intermediate_Dir "rwgk1___Win32_DebugPython" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPython" +# PROP Intermediate_Dir "DebugPython" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/rwgk1_d.dll" /pdbtype:sept /libpath:"C:\tools\python\src\PCbuild" !ENDIF @@ -85,6 +114,7 @@ LINK32=link.exe # Name "rwgk1 - Win32 Release" # Name "rwgk1 - Win32 Debug" +# Name "rwgk1 - Win32 DebugPython" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" diff --git a/build/test/test.dsp b/build/test/test.dsp index a29d011a..0816bf1e 100644 --- a/build/test/test.dsp +++ b/build/test/test.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 -CFG=test - Win32 Debug +CFG=test - Win32 DebugPython !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,13 @@ CFG=test - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug" +!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 DebugPython" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "test - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project @@ -44,6 +45,7 @@ RSC=rc.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /Zm200 /c +# SUBTRACT CPP /Fr # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" @@ -53,7 +55,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/boost_python_test.dll" /libpath:"c:\tools\python\libs" !ELSEIF "$(CFG)" == "test - Win32 Debug" @@ -68,8 +70,9 @@ LINK32=link.exe # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c +# SUBTRACT CPP /Fr # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -79,7 +82,36 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/boost_python_test.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "test - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "test___Win32_DebugPython" +# PROP BASE Intermediate_Dir "test___Win32_DebugPython" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPython" +# PROP Intermediate_Dir "DebugPython" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/boost_python_test_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" # SUBTRACT LINK32 /pdb:none !ENDIF @@ -88,6 +120,7 @@ LINK32=link.exe # Name "test - Win32 Release" # Name "test - Win32 Debug" +# Name "test - Win32 DebugPython" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" From afdaa4d0d848ec7242cf5b5f1d4d8a00e1639e20 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:55:35 +0000 Subject: [PATCH 043/279] Rolled in const_cast from Dragon fork [SVN r9416] --- src/classes.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/classes.cpp b/src/classes.cpp index 625d67b7..c609eeef 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -7,8 +7,9 @@ // producing this work. // // Revision History: -// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) -// Mar 03 01 bug fix: use bound_function::create() (instead of new bound_function) +// 04 Mar 01 Rolled in const_cast from Dragon fork (Dave Abrahams) +// 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) +// 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) #include #include @@ -881,7 +882,7 @@ namespace { PyObject *globals = PyEval_GetGlobals(); if (globals != NULL) { - PyObject *module_name = PyDict_GetItemString(globals, "__name__"); + PyObject *module_name = PyDict_GetItemString(globals, const_cast("__name__")); if (module_name != NULL) name_space.set_item(module_key, module_name); } From a3f822b7d3b24fa9d179e68bfe7cc93093fe368d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 4 Mar 2001 15:56:07 +0000 Subject: [PATCH 044/279] Documentation for pickle support. [SVN r9417] --- doc/index.html | 2 +- doc/pickle.html | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 doc/pickle.html diff --git a/doc/index.html b/doc/index.html index 9ddd65d3..4550be5c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -116,7 +116,7 @@ among others.
  • Advanced Topics
      -
    1. Pickling +
    2. Pickle Support
    3. class_builder<> diff --git a/doc/pickle.html b/doc/pickle.html new file mode 100644 index 00000000..0e64d6fc --- /dev/null +++ b/doc/pickle.html @@ -0,0 +1,223 @@ + + + BPL Pickle Support + + + +c++boost.gif (8819 bytes) + + +
      +

      BPL Pickle Support

      + +Pickle is a Python module for object serialization, also known +as persistence, marshalling, or flattening. + +

      +It is often necessary to save and restore the contents of an object to +a file. One approach to this problem is to write a pair of functions +that read and write data from a file in a special format. A powerful +alternative approach is to use Python's pickle module. Exploiting +Python's ability for introspection, the pickle module recursively +converts nearly arbitrary Python objects into a stream of bytes that +can be written to a file. + +

      +The Boost Python Library supports the pickle module by emulating the +interface implemented by Jim Fulton's ExtensionClass module that is +included in the ZOPE distribution +(http://www.zope.org/). +This interface is similar to that for regular Python classes as +described in detail in the Python Library Reference for pickle: + +

      + http://www.python.org/doc/current/lib/module-pickle.html +
      + +
      +

      The BPL Pickle Interface

      + +At the user level, the BPL pickle interface involves three special +methods: + +
      +
      +__getinitargs__ +
      + When an instance of a BPL extension class is pickled, the pickler + tests if the instance has a __getinitargs__ method. This method must + return a Python tuple. When the instance is restored by the + unpickler, the contents of this tuple are used as the arguments for + the class constructor. + +

      + If __getinitargs__ is not defined, the class constructor will be + called without arguments. + +

      +

      +__getstate__ + +
      + When an instance of a BPL extension class is pickled, the pickler + tests if the instance has a __getstate__ method. This method should + return a Python object representing the state of the instance. + +

      + If __getstate__ is not defined, the instance's __dict__ is pickled + (if it is not empty). + +

      +

      +__setstate__ + +
      + When an instance of a BPL extension class is restored by the + unpickler, it is first constructed using the result of + __getinitargs__ as arguments (see above). Subsequently the unpickler + tests if the new instance has a __setstate__ method. If so, this + method is called with the result of __getstate__ (a Python object) as + the argument. + +

      + If __setstate__ is not defined, the result of __getstate__ must be + a Python dictionary. The items of this dictionary are added to + the instance's __dict__. +

      + +If both __getstate__ and __setstate__ are defined, the Python object +returned by __getstate__ need not be a dictionary. The __getstate__ and +__setstate__ methods can do what they want. + +
      +

      Pitfalls and Safety Guards

      + +In BPL extension modules with many extension classes, providing +complete pickle support for all classes would be a significant +overhead. In general complete pickle support should only be implemented +for extension classes that will eventually be pickled. However, the +author of a BPL extension module might not anticipate correctly which +classes need support for pickle. Unfortunately, the pickle protocol +described above has two important pitfalls that the end user of a BPL +extension module might not be aware of: + +
      +
      +Pitfall 1: +Both __getinitargs__ and __getstate__ are not defined. + +
      + In this situation the unpickler calls the class constructor without + arguments and then adds the __dict__ that was pickled by default to + that of the new instance. + +

      + However, most C++ classes wrapped with the BPL will have member data + that are not restored correctly by this procedure. To alert the user + to this problem, a safety guard is provided. If both __getinitargs__ + and __getstate__ are not defined, the BPL tests if the class has an + attribute __dict_defines_state__. An exception is raised if this + attribute is not defined: + +

      +    RuntimeError: Incomplete pickle support (__dict_defines_state__ not set)
      +
      + + In the rare cases where this is not the desired behavior, the safety + guard can deliberately be disabled. The corresponding C++ code for + this is, e.g.: + +
      +    class_builder py_your_class(your_module, "your_class");
      +    py_your_class.dict_defines_state();
      +
      + + It is also possible to override the safety guard at the Python level. + E.g.: + +
      +    import your_bpl_module
      +    class your_class(your_bpl_module.your_class):
      +      __dict_defines_state__ = 1
      +
      + +

      +

      +Pitfall 2: +__getstate__ is defined and the instance's __dict__ is not empty. + +
      + The author of a BPL extension class might provide a __getstate__ + method without considering the possibilities that: + +

      +

        +
      • + his class is used as a base class. Most likely the __dict__ of + instances of the derived class needs to be pickled in order to + restore the instances correctly. + +

        +

      • + the user adds items to the instance's __dict__ directly. Again, + the __dict__ of the instance then needs to be pickled. +
      +

      + + To alert the user to this highly unobvious problem, a safety guard is + provided. If __getstate__ is defined and the instance's __dict__ is + not empty, the BPL tests if the class has an attribute + __getstate_manages_dict__. An exception is raised if this attribute + is not defined: + +

      +    RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
      +
      + + To resolve this problem, it should first be established that the + __getstate__ and __setstate__ methods manage the instances's __dict__ + correctly. Note that this can be done both at the C++ and the Python + level. Finally, the safety guard should intentionally be overridden. + E.g. in C++: + +
      +    class_builder py_your_class(your_module, "your_class");
      +    py_your_class.getstate_manages_dict();
      +
      + + In Python: + +
      +    import your_bpl_module
      +    class your_class(your_bpl_module.your_class):
      +      __getstate_manages_dict__ = 1
      +      def __getstate__(self):
      +        # your code here
      +      def __setstate__(self, state):
      +        # your code here
      +
      +
      + +
      +

      Practical Advice

      + +
        +
      • + Avoid using __getstate__ if the instance can also be reconstructed + by way of __getinitargs__. This automatically avoids Pitfall 2. + +

        +

      • + If __getstate__ is required, include the instance's __dict__ in the + Python object that is returned. +
      + +
      +
      +Author: Ralf W. Grosse-Kunstleve, March 2001 +
      + From af6cfd0ea8b5c854e66ecc8540f8c3fb54860e54 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:56:38 +0000 Subject: [PATCH 045/279] std::complex<> fixes for MSVC [SVN r9418] --- src/conversions.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index 369f197a..88e30048 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -7,7 +7,8 @@ // producing this work. // // Revision History: -// Mar 03 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) +// 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) +// 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) #include #include @@ -47,6 +48,19 @@ void handle_exception() } } +namespace detail { + + void expect_complex(PyObject* p) + { + if (!PyComplex_Check(p)) + { + PyErr_SetString(PyExc_TypeError, "expected a complex number"); + throw boost::python::argument_error(); + } + } + +} // namespace boost::python::detail + }} // namespace boost::python BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE From f6ba5a41da56aabcd0c337b1bd3fcaf36923d889 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:57:47 +0000 Subject: [PATCH 046/279] Use PyObject_INIT() instead of trying to hand-initialize [SVN r9419] --- src/extension_class.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/extension_class.cpp b/src/extension_class.cpp index 47862ec7..f71976b9 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -7,7 +7,7 @@ // producing this work. // // Revision History: -// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) +// 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #include #include @@ -463,7 +463,9 @@ operator_dispatcher::create(const ref& object, const ref& self) free_list = result->m_free_list_link; result->m_object = object; result->m_self = self; - Py_INCREF(result); + + PyObject* result_as_pyobject = result; + PyObject_INIT(result_as_pyobject, &type_obj); return result; } From 405710e635cce91ce42a0bd82ba4925cc82dc4dc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 15:59:52 +0000 Subject: [PATCH 047/279] Changed name of extension module so it would work with DebugPython, eliminated useless test that aggravated MSVC [SVN r9420] --- test/comprehensive.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 592b0ebd..57edd687 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -5,6 +5,10 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. + +// Revision History: +// 04 Mar 01 Changed name of extension module so it would work with DebugPython, +// eliminated useless test that aggravated MSVC (David Abrahams) #include "comprehensive.hpp" #include #include // used for portability on broken compilers @@ -818,7 +822,14 @@ namespace bpl_test { // Test plain char converters. char get_plain_char() { return 'x'; } std::string use_plain_char(char c) { return std::string(3, c); } - std::string use_const_plain_char(const char c) { return std::string(5, c); } + + // This doesn't test anything but the compiler, since it has the same signature as the above. + // Since MSVC is broken and gets the signature wrong, we'll skip it. + std::string use_const_plain_char( +#ifndef BOOST_MSVC6_OR_EARLIER + const +#endif + char c) { return std::string(5, c); } // Test std::complex converters. std::complex dpolar(double rho, double theta) { @@ -1091,18 +1102,18 @@ PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& void init_module() { - boost::python::module_builder test("test"); - init_module(test); + boost::python::module_builder boost_python_test("boost_python_test"); + init_module(boost_python_test); // Just for giggles, add a raw metaclass. - test.add(new boost::python::meta_class); + boost_python_test.add(new boost::python::meta_class); } extern "C" #ifdef _WIN32 __declspec(dllexport) #endif -void inittest() +void initboost_python_test() { try { bpl_test::init_module(); From 7208104122237e24eafd16f471ebc6eedf289e6b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 4 Mar 2001 16:02:46 +0000 Subject: [PATCH 048/279] Changed name of extension module so it would work with DebugPython, fixed exception message checking to work with Python 2.0 [SVN r9421] --- test/comprehensive.py | 44 ++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 3c7f3c61..c8033575 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -7,6 +7,15 @@ r''' // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// Revision History: +// 04 Mar 01 Changed name of extension module so it would work with DebugPython, +// fixed exception message checking to work with Python 2.0 +// (Dave Abrahams) + +Load up the extension module + + >>> from boost_python_test import * + Automatic checking of the number and type of arguments. Foo's constructor takes a single long parameter. @@ -17,9 +26,9 @@ a single long parameter. >>> try: ext = Foo('foo') ... except TypeError, err: - ... assert re.match( - ... '(illegal argument type for built-in operation)|(an integer is required)', str(err)) - ... else: print 'no exception' + ... assert_integer_expected(err) + ... else: + ... print 'no exception' >>> ext = Foo(1) @@ -209,7 +218,7 @@ Polymorphism also works: Pickling tests: >>> world.__module__ - 'test' + 'boost_python_test' >>> world.__safe_for_unpickling__ 1 >>> world.__reduce__() @@ -697,10 +706,11 @@ Testing interaction between callbacks, base declarations, and overloading >>> c = CallbackTest() >>> c.testCallback(1) 2 - >>> c.testCallback('foo') - Traceback (innermost last): - File "", line 1, in ? - TypeError: illegal argument type for built-in operation + + >>> try: c.testCallback('foo') + ... except TypeError, err: assert_integer_expected(err) + ... else: print 'no exception' + >>> c.callback(1) 2 >>> c.callback('foo') @@ -719,10 +729,11 @@ Testing interaction between callbacks, base declarations, and overloading -1 >>> r.callback('foo') 'foo 1' - >>> r.testCallback('foo') - Traceback (innermost last): - File "", line 1, in ? - TypeError: illegal argument type for built-in operation + + >>> try: r.testCallback('foo') + ... except TypeError, err: assert_integer_expected(err) + ... else: print 'no exception' + >>> r.testCallback(1) -1 >>> testCallback(r, 1) @@ -1145,8 +1156,15 @@ test methodologies for wrapping functions that return a pointer '6.35' ''' +#' + +def assert_integer_expected(err): + """Handle a common error report which appears differently in Python 1.5.x and 2.0""" + assert isinstance(err, TypeError) + message = str(err) + assert (message == "illegal argument type for built-in operation" + or message == "an integer is required") -from test import * import string import re import sys From 03dd2883f71fd8753148a3493ff4a70f909bd4f4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 4 Mar 2001 17:39:14 +0000 Subject: [PATCH 049/279] file name change: test.so -> boost_python_test.so [SVN r9426] --- build/Makefile.linux_gcc | 8 ++++---- build/Makefile.mingw32 | 16 ++++++++-------- build/Makefile.tru64_cxx | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/build/Makefile.linux_gcc b/build/Makefile.linux_gcc index 3e8f1041..7021e221 100644 --- a/build/Makefile.linux_gcc +++ b/build/Makefile.linux_gcc @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a test.so abstract.so \ +all: libbpl.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -111,8 +111,8 @@ libbpl.a: $(OBJ) rm -f libbpl.a ar r libbpl.a $(OBJ) -test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o test.so -lm +boost_python_test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm abstract.so: $(OBJ) abstract.o $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so @@ -146,7 +146,7 @@ test: clean: rm -f $(OBJ) libbpl.a libbpl.a.input - rm -f comprehensive.o test.so + rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so diff --git a/build/Makefile.mingw32 b/build/Makefile.mingw32 index 2d86efcd..7c5f2c52 100644 --- a/build/Makefile.mingw32 +++ b/build/Makefile.mingw32 @@ -31,8 +31,8 @@ # Could this be fixed with compiler options? # -fhuge-objects looks interesting, but requires recompiling the C++ library. # (what exactly does that mean?) -# -fvtable-thunks eliminates the compiler warning, but "import test" still -# causes a crash. +# -fvtable-thunks eliminates the compiler warning, +# but "import boost_python_test" still causes a crash. BOOST_UNIX= /net/cci/rwgk/boost BOOST_WIN= "L:\boost" @@ -82,7 +82,7 @@ $(BPL_EXA)/test_getting_started4.py \ $(BPL_EXA)/test_getting_started5.py DEFS= \ -test \ +boost_python_test \ abstract \ getting_started1 \ getting_started2 \ @@ -96,7 +96,7 @@ OBJ = classes.o conversions.o extension_class.o functions.o \ .SUFFIXES: .o .cpp -all: libbpl.a test.pyd abstract.pyd \ +all: libbpl.a boost_python_test.pyd abstract.pyd \ getting_started1.pyd getting_started2.pyd getting_started3.pyd \ getting_started4.pyd getting_started5.pyd @@ -143,10 +143,10 @@ libbpl.a: $(OBJ) DLLWRAPOPTS= -s --driver-name g++ -s --entry _DllMainCRTStartup@12 --target=i386-mingw32 -test.pyd: $(OBJ) comprehensive.o +boost_python_test.pyd: $(OBJ) comprehensive.o dllwrap $(DLLWRAPOPTS) \ - --dllname test.pyd \ - --def test.def \ + --dllname boost_python_test.pyd \ + --def boost_python_test.def \ $(OBJ) comprehensive.o $(PYLIB) abstract.pyd: $(OBJ) abstract.o @@ -199,7 +199,7 @@ test: clean: rm -f $(OBJ) libbpl.a libbpl.a.input - rm -f comprehensive.o test.pyd + rm -f comprehensive.o boost_python_test.pyd rm -f abstract.o abstract.pyd rm -f getting_started1.o getting_started1.pyd rm -f getting_started2.o getting_started2.pyd diff --git a/build/Makefile.tru64_cxx b/build/Makefile.tru64_cxx index 7b932bd3..2b417944 100644 --- a/build/Makefile.tru64_cxx +++ b/build/Makefile.tru64_cxx @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a test.so abstract.so \ +all: libbpl.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -115,8 +115,8 @@ libbpl.a: $(OBJ) rm -f libbpl.a.input ar r libbpl.a $(OBJ) -test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o test.so -lm +boost_python_test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm abstract.so: $(OBJ) abstract.o $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so @@ -150,7 +150,7 @@ test: clean: rm -f $(OBJ) libbpl.a libbpl.a.input - rm -f comprehensive.o test.so + rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so From 5ad51c36fb5bc0d3055977409512e099a0e79a38 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:43:10 +0000 Subject: [PATCH 050/279] Turned off "enable minimal rebuild", which causes INTERNAL COMPILER ERRORs [SVN r9437] --- build/bpl_static.dsp | 4 ++-- build/example1/example1.dsp | 4 ++-- build/rwgk1/rwgk1.dsp | 4 ++-- build/test/test.dsp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp index 92af59c7..ca70236d 100644 --- a/build/bpl_static.dsp +++ b/build/bpl_static.dsp @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -88,7 +88,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "DebugPython" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c +# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe diff --git a/build/example1/example1.dsp b/build/example1/example1.dsp index dcff3f55..4d95aa97 100644 --- a/build/example1/example1.dsp +++ b/build/example1/example1.dsp @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -97,7 +97,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/build/rwgk1/rwgk1.dsp b/build/rwgk1/rwgk1.dsp index daf736b3..67476984 100644 --- a/build/rwgk1/rwgk1.dsp +++ b/build/rwgk1/rwgk1.dsp @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -96,7 +96,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/build/test/test.dsp b/build/test/test.dsp index 0816bf1e..4bd2822a 100644 --- a/build/test/test.dsp +++ b/build/test/test.dsp @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c # SUBTRACT CPP /Fr # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -100,7 +100,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" From 7d29c6a0f79680e5a0512b396dc4c0691a2a5482 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:44:46 +0000 Subject: [PATCH 051/279] tests for null pointer <=> None conversions [SVN r9438] --- test/comprehensive.cpp | 24 +++++++++++++++++++++++- test/comprehensive.py | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 57edd687..3d173310 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -242,6 +242,23 @@ boost::shared_ptr Baz::create_foo() return boost::shared_ptr(new DerivedFromFoo(0)); } +// Used to check conversion to None +boost::shared_ptr foo_factory(bool create) +{ + return boost::shared_ptr(create ? new DerivedFromFoo(0) : 0); +} + +// Used to check conversion from None +bool foo_ptr_is_null(Foo* p) +{ + return p == 0; +} + +bool foo_shared_ptr_is_null(boost::shared_ptr p) +{ + return p.get() == 0; +} + // We can accept smart pointer parameters int Baz::get_foo_value(boost::shared_ptr foo) { @@ -408,7 +425,7 @@ static int testUpcast(Base* b) static std::auto_ptr derived1Factory(int i) { - return std::auto_ptr(new Derived1(i)); + return std::auto_ptr(i < 0 ? 0 : new Derived1(i)); } static std::auto_ptr derived2Factory(int i) @@ -1081,6 +1098,11 @@ void init_module(boost::python::module_builder& m) m.def(fpolar, "fpolar"); m.def(freal, "freal"); m.def(fimag, "fimag"); + + // Test new null-pointer<->None conversions + m.def(foo_factory, "foo_factory"); + m.def(foo_ptr_is_null, "foo_ptr_is_null"); + m.def(foo_shared_ptr_is_null, "foo_shared_ptr_is_null"); } PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) diff --git a/test/comprehensive.py b/test/comprehensive.py index c8033575..c1424d25 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -73,6 +73,21 @@ We can subclass Foo. >>> b.call_pure() 'not pure anymore!' +None corresponds to a NULL pointer or smart pointer + >>> f = foo_factory(1) + >>> f.add_len('xxx') + 1000 + >>> foo_factory(0) is None + 1 + >>> foo_ptr_is_null(None) + 1 + >>> foo_ptr_is_null(f) + 0 + >>> foo_shared_ptr_is_null(None) + 1 + >>> foo_shared_ptr_is_null(f) + 0 + If no __init__ function is defined, the one from the base class takes effect, just like in a Python class. From a559a371b1c839e7189afa3aa7c8b8da9890d17e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:48:38 +0000 Subject: [PATCH 052/279] enable null pointer <=> None conversions [SVN r9439] --- .../boost/python/detail/extension_class.hpp | 82 +++++++++++++++---- src/gen_extclass.py | 82 +++++++++++++++---- 2 files changed, 130 insertions(+), 34 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index bf43ec5c..987d753e 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -22,6 +22,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -133,6 +134,26 @@ class class_registry static std::vector static_derived_class_info; }; +template +struct is_null_helper +{ + template + static bool test(Ptr x) { return x == 0; } +}; + +template <> +struct is_null_helper +{ + template + static bool test(const Ptr& x) { return x.get() == 0; } +}; + +template +bool is_null(const Ptr& x) +{ + return is_null_helper<(is_pointer::value)>::test(x); +}; + }}} // namespace boost::python::detail BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -178,9 +199,9 @@ class python_extension_class_converters new boost::python::detail::instance_value_holder(result.get(), x))); return result.release(); } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) + + friend + T* non_null_from_python(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -201,9 +222,18 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Convert to PtrType, where PtrType can be dereferenced to obtain a T. + // Convert to T* + friend T* from_python(PyObject* obj, boost::python::type) + { + if (obj == Py_None) + return 0; + else + return non_null_from_python(obj, boost::python::type()); + } + + // Extract from obj a mutable reference to the PtrType object which is holding a T. template - static PtrType& ptr_from_python(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -220,9 +250,27 @@ class python_extension_class_converters throw boost::python::argument_error(); } + // Extract from obj a constant reference to the PtrType object which is holding a T. + // If obj is None, the reference denotes a default-constructed PtrType template - static PyObject* ptr_to_python(PtrType x) + static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { + if (obj == Py_None) + { + static PtrType null_ptr; + return null_ptr; + } + return smart_ptr_reference(obj, boost::python::type()); + } + + template + static PyObject* smart_ptr_to_python(PtrType x) + { + if (boost::python::detail::is_null(x)) + { + return boost::python::detail::none(); + } + boost::python::reference result(create_instance()); result->add_implementation( std::auto_ptr( @@ -254,7 +302,7 @@ class python_extension_class_converters // Convert to T& friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } // Convert to const T& friend const T& from_python(PyObject* p, boost::python::type) @@ -265,28 +313,28 @@ class python_extension_class_converters { return from_python(p, boost::python::type()); } friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(std::auto_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(boost::shared_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } }; // Convert T to_python, instantiated on demand and only if there isn't a diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 7c378d45..2d261289 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -27,6 +27,7 @@ def gen_extclass(args): # include # include # include +# include namespace boost { namespace python { @@ -138,6 +139,26 @@ class class_registry static std::vector static_derived_class_info; }; +template +struct is_null_helper +{ + template + static bool test(Ptr x) { return x == 0; } +}; + +template <> +struct is_null_helper +{ + template + static bool test(const Ptr& x) { return x.get() == 0; } +}; + +template +bool is_null(const Ptr& x) +{ + return is_null_helper<(is_pointer::value)>::test(x); +}; + }}} // namespace boost::python::detail BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -183,9 +204,9 @@ class python_extension_class_converters new boost::python::detail::instance_value_holder(result.get(), x))); return result.release(); } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) + + friend + T* non_null_from_python(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -206,9 +227,18 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Convert to PtrType, where PtrType can be dereferenced to obtain a T. + // Convert to T* + friend T* from_python(PyObject* obj, boost::python::type) + { + if (obj == Py_None) + return 0; + else + return non_null_from_python(obj, boost::python::type()); + } + + // Extract from obj a mutable reference to the PtrType object which is holding a T. template - static PtrType& ptr_from_python(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -225,9 +255,27 @@ class python_extension_class_converters throw boost::python::argument_error(); } + // Extract from obj a constant reference to the PtrType object which is holding a T. + // If obj is None, the reference denotes a default-constructed PtrType template - static PyObject* ptr_to_python(PtrType x) + static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { + if (obj == Py_None) + { + static PtrType null_ptr; + return null_ptr; + } + return smart_ptr_reference(obj, boost::python::type()); + } + + template + static PyObject* smart_ptr_to_python(PtrType x) + { + if (boost::python::detail::is_null(x)) + { + return boost::python::detail::none(); + } + boost::python::reference result(create_instance()); result->add_implementation( std::auto_ptr( @@ -259,7 +307,7 @@ class python_extension_class_converters // Convert to T& friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } // Convert to const T& friend const T& from_python(PyObject* p, boost::python::type) @@ -270,28 +318,28 @@ class python_extension_class_converters { return from_python(p, boost::python::type()); } friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(std::auto_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(boost::shared_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } }; // Convert T to_python, instantiated on demand and only if there isn't a From 1edec9ff89141b4624e8824f7b806369d70c8fe1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 14:41:57 +0000 Subject: [PATCH 053/279] no message [SVN r9443] --- build/build.opt | Bin 80384 -> 86528 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/build.opt b/build/build.opt index 9cdea95b7eef30bf876fd69fc7e9971cd8f4a6f9..5086795feff7997de1d0b50d82b2404da330c819 100644 GIT binary patch literal 86528 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 literal 80384 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 From 2e145ea9163340ef7f4ab94cf7bb3ddbc74d511d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 5 Mar 2001 23:41:37 +0000 Subject: [PATCH 054/279] Use file name "libboost_python.a"; rename makefiles. [SVN r9449] --- build/{Makefile.linux_gcc => linux_gcc.mak} | 10 +++++----- build/{Makefile.mingw32 => mingw32.mak} | 10 +++++----- build/{Makefile.tru64_cxx => tru64_cxx.mak} | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) rename build/{Makefile.linux_gcc => linux_gcc.mak} (96%) rename build/{Makefile.mingw32 => mingw32.mak} (96%) rename build/{Makefile.tru64_cxx => tru64_cxx.mak} (93%) diff --git a/build/Makefile.linux_gcc b/build/linux_gcc.mak similarity index 96% rename from build/Makefile.linux_gcc rename to build/linux_gcc.mak index 7021e221..a07bb5da 100644 --- a/build/Makefile.linux_gcc +++ b/build/linux_gcc.mak @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.so abstract.so \ +all: libboost_python.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -107,9 +107,9 @@ unlink: fi; \ done -libbpl.a: $(OBJ) - rm -f libbpl.a - ar r libbpl.a $(OBJ) +libboost_python.a: $(OBJ) + rm -f libboost_python.a + ar r libboost_python.a $(OBJ) boost_python_test.so: $(OBJ) comprehensive.o $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm @@ -145,7 +145,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so diff --git a/build/Makefile.mingw32 b/build/mingw32.mak similarity index 96% rename from build/Makefile.mingw32 rename to build/mingw32.mak index 7c5f2c52..014af132 100644 --- a/build/Makefile.mingw32 +++ b/build/mingw32.mak @@ -96,7 +96,7 @@ OBJ = classes.o conversions.o extension_class.o functions.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.pyd abstract.pyd \ +all: libboost_python.a boost_python_test.pyd abstract.pyd \ getting_started1.pyd getting_started2.pyd getting_started3.pyd \ getting_started4.pyd getting_started5.pyd @@ -136,9 +136,9 @@ rmdefs: rm $$def.def; \ done -libbpl.a: $(OBJ) - del libbpl.a - ar r libbpl.a $(OBJ) +libboost_python.a: $(OBJ) + del libboost_python.a + ar r libboost_python.a $(OBJ) DLLWRAPOPTS= -s --driver-name g++ -s --entry _DllMainCRTStartup@12 --target=i386-mingw32 @@ -198,7 +198,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.pyd rm -f abstract.o abstract.pyd rm -f getting_started1.o getting_started1.pyd diff --git a/build/Makefile.tru64_cxx b/build/tru64_cxx.mak similarity index 93% rename from build/Makefile.tru64_cxx rename to build/tru64_cxx.mak index 2b417944..3fd584b7 100644 --- a/build/Makefile.tru64_cxx +++ b/build/tru64_cxx.mak @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.so abstract.so \ +all: libboost_python.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -107,13 +107,13 @@ unlink: fi; \ done -libbpl.a: $(OBJ) - rm -f libbpl.a +libboost_python.a: $(OBJ) + rm -f libboost_python.a cd cxx_repository; \ - ls -1 > ../libbpl.a.input; \ - ar r ../libbpl.a -input ../libbpl.a.input - rm -f libbpl.a.input - ar r libbpl.a $(OBJ) + ls -1 > ../libboost_python.a.input; \ + ar r ../libboost_python.a -input ../libboost_python.a.input + rm -f libboost_python.a.input + ar r libboost_python.a $(OBJ) boost_python_test.so: $(OBJ) comprehensive.o $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm @@ -149,7 +149,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so From 149cc499ede69475159d5a120c3213597c9d410a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 5 Mar 2001 23:46:43 +0000 Subject: [PATCH 055/279] Remove spurious ";" [SVN r9450] --- include/boost/python/detail/extension_class.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 987d753e..4afffcae 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -152,7 +152,7 @@ template bool is_null(const Ptr& x) { return is_null_helper<(is_pointer::value)>::test(x); -}; +} }}} // namespace boost::python::detail From fdff5e33b3745a4768caf0145d57d3cce7f1a668 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:02:01 +0000 Subject: [PATCH 056/279] temp file for branching [SVN r9451] --- src/x_class_builder.cpp | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/x_class_builder.cpp diff --git a/src/x_class_builder.cpp b/src/x_class_builder.cpp new file mode 100644 index 00000000..cf81a3f7 --- /dev/null +++ b/src/x_class_builder.cpp @@ -0,0 +1,118 @@ +# include +namespace python = boost::python; +# include // MSVC6.0SP4 does not know std::fprintf +# include // MSVC6.0SP4 does not know std::strcmp + +namespace { + + PyObject *get_module_dict(const char *module_name) + { + python::ref module_obj(PyImport_ImportModule((char*) module_name)); + PyObject *module_dict = PyModule_GetDict(module_obj.get()); + if (module_dict == 0) throw python::import_error(); + return module_dict; + } +} + +namespace boost { namespace python { namespace detail { + +#ifndef SPECIAL_PYCVTSOBJECT + +void *import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject *module_dict + = get_module_dict(const_cast(module_name.c_str())); + PyObject *klass + = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); + if (klass == 0) { + err = std::string("module ") + module_name + " has no attribute " + + klass_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref c_obj(PyObject_GetAttrString(klass, + const_cast(attribute_name.c_str())), ref::null_ok); + if (c_obj.get() == 0) { + err = std::string("object ") + module_name + "." + klass_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + if (! PyCObject_Check(c_obj.get())) { + err = std::string("object ") + module_name + "." + klass_name + "." + + attribute_name + " is not a PyCObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return PyCObject_AsVoidPtr(c_obj.get()); +} + +#else + +PyObject *new_import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject *module_dict + = get_module_dict(const_cast(module_name.c_str())); + PyObject *klass + = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); + if (klass == 0) { + err = std::string("module ") + module_name + " has no attribute " + + klass_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref cvts_obj(PyObject_GetAttrString(klass, + const_cast(attribute_name.c_str())), ref::null_ok); + if (cvts_obj.get() == 0) { + err = std::string("object ") + module_name + "." + klass_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + // Weak point: direct access to ob_type->tp_name + if (strcmp(cvts_obj->ob_type->tp_name, "PyCvtsObject") != 0) { + err = std::string("object ") + module_name + "." + klass_name + "." + + attribute_name + " is not a PyCvtsObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return cvts_obj.release(); +} + +#endif // SPECIAL_PYCVTSOBJECT + +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor) +{ + if (importing_major != imported_major) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Fatal: EXPORT_CONVERTERS_API mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + PyErr_SetString(PyExc_RuntimeError, + "Fatal: EXPORT_CONVERTERS_API mismatch"); + throw import_error(); + } + if (importing_minor != imported_minor) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Warning: EXPORT_CONVERTERS_API mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + } +} + +}}} // namespace boost::python::detail From f49141f71ede423a1ae6f52f85f3a5b054c869e9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:04:28 +0000 Subject: [PATCH 057/279] temp file removed after branching [SVN r9452] --- src/x_class_builder.cpp | 118 ---------------------------------------- 1 file changed, 118 deletions(-) delete mode 100644 src/x_class_builder.cpp diff --git a/src/x_class_builder.cpp b/src/x_class_builder.cpp deleted file mode 100644 index cf81a3f7..00000000 --- a/src/x_class_builder.cpp +++ /dev/null @@ -1,118 +0,0 @@ -# include -namespace python = boost::python; -# include // MSVC6.0SP4 does not know std::fprintf -# include // MSVC6.0SP4 does not know std::strcmp - -namespace { - - PyObject *get_module_dict(const char *module_name) - { - python::ref module_obj(PyImport_ImportModule((char*) module_name)); - PyObject *module_dict = PyModule_GetDict(module_obj.get()); - if (module_dict == 0) throw python::import_error(); - return module_dict; - } -} - -namespace boost { namespace python { namespace detail { - -#ifndef SPECIAL_PYCVTSOBJECT - -void *import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name) -{ - static std::string err; - PyObject *module_dict - = get_module_dict(const_cast(module_name.c_str())); - PyObject *klass - = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); - if (klass == 0) { - err = std::string("module ") + module_name + " has no attribute " - + klass_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref c_obj(PyObject_GetAttrString(klass, - const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + klass_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + klass_name + "." - + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); -} - -#else - -PyObject *new_import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name) -{ - static std::string err; - PyObject *module_dict - = get_module_dict(const_cast(module_name.c_str())); - PyObject *klass - = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); - if (klass == 0) { - err = std::string("module ") + module_name + " has no attribute " - + klass_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref cvts_obj(PyObject_GetAttrString(klass, - const_cast(attribute_name.c_str())), ref::null_ok); - if (cvts_obj.get() == 0) { - err = std::string("object ") + module_name + "." + klass_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - // Weak point: direct access to ob_type->tp_name - if (strcmp(cvts_obj->ob_type->tp_name, "PyCvtsObject") != 0) { - err = std::string("object ") + module_name + "." + klass_name + "." - + attribute_name + " is not a PyCvtsObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return cvts_obj.release(); -} - -#endif // SPECIAL_PYCVTSOBJECT - -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) -{ - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: EXPORT_CONVERTERS_API mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: EXPORT_CONVERTERS_API mismatch"); - throw import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: EXPORT_CONVERTERS_API mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } -} - -}}} // namespace boost::python::detail From 23725680c9b8ab8068e26b46512936d260fb95df Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:05:41 +0000 Subject: [PATCH 058/279] temp file before branching [SVN r9453] --- include/boost/python/x_class_builder.hpp | 361 +++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 include/boost/python/x_class_builder.hpp diff --git a/include/boost/python/x_class_builder.hpp b/include/boost/python/x_class_builder.hpp new file mode 100644 index 00000000..4b3da600 --- /dev/null +++ b/include/boost/python/x_class_builder.hpp @@ -0,0 +1,361 @@ +#ifndef X_CLASS_BUILDER_HPP +# define X_CLASS_BUILDER_HPP + +# include + +//QUESTIONMARK +// Do we really need the special PyCvtsObject? +// Is there a better way of creating the special PyCvtsObject? +// My solution adds a lot of code including several reinterpret_cast. +//#define SPECIAL_PYCVTSOBJECT + +namespace boost { namespace python { + struct import_error : error_already_set {}; + struct export_error : error_already_set {}; +}} + +namespace boost { namespace python { namespace detail { + +// Concept: throw exception if api_major is changed +// show warning on stderr if api_minor is changed +const int EXPORT_CONVERTERS_API_MAJOR = 1; +const int EXPORT_CONVERTERS_API_MINOR = 1; +const std::string converters_attribute_name = "__converters__"; +#ifndef SPECIAL_PYCVTSOBJECT +void *import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name); +#else +PyObject *new_import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name); +#endif +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor); + +}}} + +// forward declaration +namespace boost { namespace python { namespace detail { +template class import_extension_class; +}}} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + +//QUESTIONMARK +// This class is a look-alike of class python_extension_class_converters. +// Is there a way to ensure that the siblings stay in sync? +template +class python_import_extension_class_converters +{ + public: + + friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) + { + return python_import_extension_class_converters(); + } + + PyObject* to_python(const T& x) const + { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend T* from_python(PyObject* obj, boost::python::type) + { + return boost::python::detail::import_extension_class::get_converters()->Tptr_from_python(obj); + } + + // Convert to const T* + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to const T* const& + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T* const& + friend T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T& + friend T& from_python(PyObject* p, boost::python::type) + { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + + // Convert to const T& + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend PyObject* to_python(std::auto_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend PyObject* to_python(boost::shared_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } +}; + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +namespace boost { namespace python { + +BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); + +// A pointer to this class is exported/imported via the Python API. +// All functions are virtual. This is, what we really export/import +// is essentially just a pointer to a vtbl. +template +struct export_converters_base +{ + virtual const int get_api_major() const { + return detail::EXPORT_CONVERTERS_API_MAJOR; } + virtual const int get_api_minor() const { + return detail::EXPORT_CONVERTERS_API_MINOR; } + virtual PyObject *to_python(const T& x) = 0; + virtual PyObject *to_python(std::auto_ptr x) = 0; + virtual PyObject *to_python(boost::shared_ptr x) = 0; + virtual T* Tptr_from_python(PyObject* obj) = 0; + virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) = 0; + virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) = 0; +}; + +// Converters to be used if T is not copyable. +template +struct export_ptr_converters : export_converters_base +{ + virtual PyObject *to_python(const T& x) { + PyErr_SetString(PyExc_RuntimeError, + "to_python(const T&) converter not exported"); + throw import_error(); + } + virtual PyObject *to_python(std::auto_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual PyObject *to_python(boost::shared_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual T* Tptr_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); + } + virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); + } + virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); + } +}; + +// The addditional to_python() converter that can be used if T is copyable. +template +struct export_converters : export_ptr_converters +{ + virtual PyObject *to_python(const T& x) { + BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; + return cv.to_python(x); + } +}; + +namespace detail { + +//QUESTIONMARK +// A stripped-down, modified version of class extension_class. +// Would it make sense to establish a formal relationship +// between the two classes? +template +class import_extension_class + : public python_import_extension_class_converters +{ + public: + inline import_extension_class(const char *module, const char* klass) { + m_module = module; + m_klass = klass; + } + + static boost::python::export_converters_base* get_converters(); + + private: + static std::string m_module; + static std::string m_klass; + static boost::python::export_converters_base* imported_converters; +}; + +template std::string import_extension_class::m_module; +template std::string import_extension_class::m_klass; +template +boost::python::export_converters_base* +import_extension_class::imported_converters = 0; + +#ifdef SPECIAL_PYCVTSOBJECT + +// A special PyObject for passing pointers to export_converters_base +template +struct PyCvtsObject { + PyObject_HEAD + export_converters_base* cvts; +}; + +template +void DEL_PyCvtsObject(PyCvtsObject* self) { PyMem_DEL(self); } + +template +PyObject *create_PyCvtsObject(export_converters_base* cvts) +{ + static char PyCvtsObject_Type__doc__[] = + "Boost Python Library (BPL) converters objects to be exported from\n" + "one extension module to another."; + + static PyTypeObject PyCvtsObject_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "PyCvtsObject", /*tp_name*/ + sizeof(PyCvtsObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)(static_cast*)> + (DEL_PyCvtsObject)), /*tp_dealloc*/ + (printfunc)0, /*tp_print*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ + (cmpfunc)0, /*tp_compare*/ + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ + + /* Space for future expansion */ + 0L,0L,0L,0L, + PyCvtsObject_Type__doc__ /* Documentation string */ + }; + + PyCvtsObject* self = PyObject_NEW(PyCvtsObject, &PyCvtsObject_Type); + if (self == 0) throw export_error(); + self->cvts = cvts; + return reinterpret_cast(self); +} + +#endif // SPECIAL_PYCVTSOBJECT + +template +boost::python::export_converters_base* +import_extension_class::get_converters() { + if (imported_converters == 0) { +#ifndef SPECIAL_PYCVTSOBJECT + void *cobject + = import_converters(m_module, m_klass, converters_attribute_name); + imported_converters + = static_cast*>(cobject); +#else + ref cvts_obj( + new_import_converters(m_module, m_klass, converters_attribute_name)); + PyCvtsObject* cvts = reinterpret_cast*>(cvts_obj.get()); + imported_converters = cvts->cvts; +#endif + check_export_converters_api( + EXPORT_CONVERTERS_API_MAJOR, + EXPORT_CONVERTERS_API_MINOR, + imported_converters->get_api_major(), + imported_converters->get_api_minor()); + } + return imported_converters; +} + +}}} // namespace boost::python::detail + +namespace boost { namespace python { + +//QUESTIONMARK +// A stripped-down, modified version of class class_builder. +// Would it make sense to establish a formal relationship +// between the two classes? +template +class import_class_builder + : python_import_extension_class_converters +{ + public: + import_class_builder(const char *module, const char* klass) + : m_class(new detail::import_extension_class(module, klass)) + { } + private: + + //QUESTIONMARK + //reference > m_class; + boost::shared_ptr > m_class; +}; + +}} // namespace boost::python + +namespace boost { namespace python { + +// A class_builder that exports the converter functions. +template , + class C = export_converters > +class x_class_builder + : public class_builder +{ + private: + static C export_cvts; + + public: + x_class_builder(module_builder& module, const char* name) + : class_builder(module, name) { +#ifndef SPECIAL_PYCVTSOBJECT + add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + const_cast(detail::converters_attribute_name.c_str())); +#else + add(ref(detail::create_PyCvtsObject(&export_cvts)), + const_cast(detail::converters_attribute_name.c_str())); +#endif + } +}; + +template +C x_class_builder::export_cvts; + +//QUESTIONMARK +// Is there a better way of making it easy for the end-user +// to choose between x_class_builder and xptr_class_builder? +template , + class C = export_ptr_converters > +class xptr_class_builder : public x_class_builder +{ + public: + xptr_class_builder(module_builder& module, const char* name) + : x_class_builder(module, name) { } +}; + +}} // namespace boost::python + +#endif // X_CLASS_BUILDER_HPP From 5b13e75fa585d73753627a2f4df1cb2c8fa2128e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:06:55 +0000 Subject: [PATCH 059/279] temp file removed after branching. [SVN r9454] --- include/boost/python/x_class_builder.hpp | 361 ----------------------- 1 file changed, 361 deletions(-) delete mode 100644 include/boost/python/x_class_builder.hpp diff --git a/include/boost/python/x_class_builder.hpp b/include/boost/python/x_class_builder.hpp deleted file mode 100644 index 4b3da600..00000000 --- a/include/boost/python/x_class_builder.hpp +++ /dev/null @@ -1,361 +0,0 @@ -#ifndef X_CLASS_BUILDER_HPP -# define X_CLASS_BUILDER_HPP - -# include - -//QUESTIONMARK -// Do we really need the special PyCvtsObject? -// Is there a better way of creating the special PyCvtsObject? -// My solution adds a lot of code including several reinterpret_cast. -//#define SPECIAL_PYCVTSOBJECT - -namespace boost { namespace python { - struct import_error : error_already_set {}; - struct export_error : error_already_set {}; -}} - -namespace boost { namespace python { namespace detail { - -// Concept: throw exception if api_major is changed -// show warning on stderr if api_minor is changed -const int EXPORT_CONVERTERS_API_MAJOR = 1; -const int EXPORT_CONVERTERS_API_MINOR = 1; -const std::string converters_attribute_name = "__converters__"; -#ifndef SPECIAL_PYCVTSOBJECT -void *import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name); -#else -PyObject *new_import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name); -#endif -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); - -}}} - -// forward declaration -namespace boost { namespace python { namespace detail { -template class import_extension_class; -}}} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -//QUESTIONMARK -// This class is a look-alike of class python_extension_class_converters. -// Is there a way to ensure that the siblings stay in sync? -template -class python_import_extension_class_converters -{ - public: - - friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_import_extension_class_converters(); - } - - PyObject* to_python(const T& x) const - { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend T* from_python(PyObject* obj, boost::python::type) - { - return boost::python::detail::import_extension_class::get_converters()->Tptr_from_python(obj); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend PyObject* to_python(std::auto_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend PyObject* to_python(boost::shared_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); - -// A pointer to this class is exported/imported via the Python API. -// All functions are virtual. This is, what we really export/import -// is essentially just a pointer to a vtbl. -template -struct export_converters_base -{ - virtual const int get_api_major() const { - return detail::EXPORT_CONVERTERS_API_MAJOR; } - virtual const int get_api_minor() const { - return detail::EXPORT_CONVERTERS_API_MINOR; } - virtual PyObject *to_python(const T& x) = 0; - virtual PyObject *to_python(std::auto_ptr x) = 0; - virtual PyObject *to_python(boost::shared_ptr x) = 0; - virtual T* Tptr_from_python(PyObject* obj) = 0; - virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) = 0; - virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) = 0; -}; - -// Converters to be used if T is not copyable. -template -struct export_ptr_converters : export_converters_base -{ - virtual PyObject *to_python(const T& x) { - PyErr_SetString(PyExc_RuntimeError, - "to_python(const T&) converter not exported"); - throw import_error(); - } - virtual PyObject *to_python(std::auto_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual PyObject *to_python(boost::shared_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual T* Tptr_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); - } - virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); - } - virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); - } -}; - -// The addditional to_python() converter that can be used if T is copyable. -template -struct export_converters : export_ptr_converters -{ - virtual PyObject *to_python(const T& x) { - BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; - return cv.to_python(x); - } -}; - -namespace detail { - -//QUESTIONMARK -// A stripped-down, modified version of class extension_class. -// Would it make sense to establish a formal relationship -// between the two classes? -template -class import_extension_class - : public python_import_extension_class_converters -{ - public: - inline import_extension_class(const char *module, const char* klass) { - m_module = module; - m_klass = klass; - } - - static boost::python::export_converters_base* get_converters(); - - private: - static std::string m_module; - static std::string m_klass; - static boost::python::export_converters_base* imported_converters; -}; - -template std::string import_extension_class::m_module; -template std::string import_extension_class::m_klass; -template -boost::python::export_converters_base* -import_extension_class::imported_converters = 0; - -#ifdef SPECIAL_PYCVTSOBJECT - -// A special PyObject for passing pointers to export_converters_base -template -struct PyCvtsObject { - PyObject_HEAD - export_converters_base* cvts; -}; - -template -void DEL_PyCvtsObject(PyCvtsObject* self) { PyMem_DEL(self); } - -template -PyObject *create_PyCvtsObject(export_converters_base* cvts) -{ - static char PyCvtsObject_Type__doc__[] = - "Boost Python Library (BPL) converters objects to be exported from\n" - "one extension module to another."; - - static PyTypeObject PyCvtsObject_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "PyCvtsObject", /*tp_name*/ - sizeof(PyCvtsObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)(static_cast*)> - (DEL_PyCvtsObject)), /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - (cmpfunc)0, /*tp_compare*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - - /* Space for future expansion */ - 0L,0L,0L,0L, - PyCvtsObject_Type__doc__ /* Documentation string */ - }; - - PyCvtsObject* self = PyObject_NEW(PyCvtsObject, &PyCvtsObject_Type); - if (self == 0) throw export_error(); - self->cvts = cvts; - return reinterpret_cast(self); -} - -#endif // SPECIAL_PYCVTSOBJECT - -template -boost::python::export_converters_base* -import_extension_class::get_converters() { - if (imported_converters == 0) { -#ifndef SPECIAL_PYCVTSOBJECT - void *cobject - = import_converters(m_module, m_klass, converters_attribute_name); - imported_converters - = static_cast*>(cobject); -#else - ref cvts_obj( - new_import_converters(m_module, m_klass, converters_attribute_name)); - PyCvtsObject* cvts = reinterpret_cast*>(cvts_obj.get()); - imported_converters = cvts->cvts; -#endif - check_export_converters_api( - EXPORT_CONVERTERS_API_MAJOR, - EXPORT_CONVERTERS_API_MINOR, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); - } - return imported_converters; -} - -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -//QUESTIONMARK -// A stripped-down, modified version of class class_builder. -// Would it make sense to establish a formal relationship -// between the two classes? -template -class import_class_builder - : python_import_extension_class_converters -{ - public: - import_class_builder(const char *module, const char* klass) - : m_class(new detail::import_extension_class(module, klass)) - { } - private: - - //QUESTIONMARK - //reference > m_class; - boost::shared_ptr > m_class; -}; - -}} // namespace boost::python - -namespace boost { namespace python { - -// A class_builder that exports the converter functions. -template , - class C = export_converters > -class x_class_builder - : public class_builder -{ - private: - static C export_cvts; - - public: - x_class_builder(module_builder& module, const char* name) - : class_builder(module, name) { -#ifndef SPECIAL_PYCVTSOBJECT - add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - const_cast(detail::converters_attribute_name.c_str())); -#else - add(ref(detail::create_PyCvtsObject(&export_cvts)), - const_cast(detail::converters_attribute_name.c_str())); -#endif - } -}; - -template -C x_class_builder::export_cvts; - -//QUESTIONMARK -// Is there a better way of making it easy for the end-user -// to choose between x_class_builder and xptr_class_builder? -template , - class C = export_ptr_converters > -class xptr_class_builder : public x_class_builder -{ - public: - xptr_class_builder(module_builder& module, const char* name) - : x_class_builder(module, name) { } -}; - -}} // namespace boost::python - -#endif // X_CLASS_BUILDER_HPP From 2d568b1c0fd9b786d93b10e5f96a9118ce865274 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 01:13:35 +0000 Subject: [PATCH 060/279] Fixed a bug which prevented auto_ptr values from being converted to_python [SVN r9455] --- include/boost/python/detail/extension_class.hpp | 14 ++++++++++---- src/gen_extclass.py | 16 +++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 4afffcae..125f1eed 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -9,6 +9,10 @@ // This file automatically generated for 10-argument constructors by // gen_extclass.python +// Revision History: +// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted +// to_python (Dave Abrahams) + #ifndef EXTENSION_CLASS_DWA052000_H_ # define EXTENSION_CLASS_DWA052000_H_ @@ -250,10 +254,12 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Extract from obj a constant reference to the PtrType object which is holding a T. - // If obj is None, the reference denotes a default-constructed PtrType + // Extract from obj a reference to the PtrType object which is holding a + // T. If it weren't for auto_ptr, it would be a constant reference. Do not + // modify the referent except by copying an auto_ptr! If obj is None, the + // reference denotes a default-constructed PtrType template - static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { if (obj == Py_None) { @@ -315,7 +321,7 @@ class python_extension_class_converters friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { return smart_ptr_reference(p, boost::python::type >()); } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + friend std::auto_ptr from_python(PyObject* p, boost::python::type >) { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 2d261289..8de8a1ae 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -14,6 +14,10 @@ def gen_extclass(args): // This file automatically generated for %d-argument constructors by // gen_extclass.python +// Revision History: +// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted +// to_python (Dave Abrahams) + #ifndef EXTENSION_CLASS_DWA052000_H_ # define EXTENSION_CLASS_DWA052000_H_ @@ -157,7 +161,7 @@ template bool is_null(const Ptr& x) { return is_null_helper<(is_pointer::value)>::test(x); -}; +} }}} // namespace boost::python::detail @@ -255,10 +259,12 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Extract from obj a constant reference to the PtrType object which is holding a T. - // If obj is None, the reference denotes a default-constructed PtrType + // Extract from obj a reference to the PtrType object which is holding a + // T. If it weren't for auto_ptr, it would be a constant reference. Do not + // modify the referent except by copying an auto_ptr! If obj is None, the + // reference denotes a default-constructed PtrType template - static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { if (obj == Py_None) { @@ -320,7 +326,7 @@ class python_extension_class_converters friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { return smart_ptr_reference(p, boost::python::type >()); } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + friend std::auto_ptr from_python(PyObject* p, boost::python::type >) { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) From b0d6d40c2a800159cacbe796f96c069ec503fc2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 01:14:47 +0000 Subject: [PATCH 061/279] Suppress warnings under Cygwin with Python 2.0 [SVN r9456] --- include/boost/python/detail/wrap_python.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index d5b75374..b7a47513 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -16,9 +16,13 @@ // compiler command-line. // Revision History: +// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams) // 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) // 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) + +#include + #ifdef _DEBUG # ifndef BOOST_DEBUG_PYTHON # undef _DEBUG // Don't let Python force the debug library just because we're debugging. @@ -37,9 +41,11 @@ typedef int pid_t; # define WORD_BIT 32 # define hypot _hypot # include -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR +# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 +# define HAVE_CLOCK +# define HAVE_STRFTIME +# define HAVE_STRERROR +# endif # define NT_THREADS # define WITH_THREAD # ifndef NETSCAPE_PI From dd0e42cf7252e41d3c3e1c5d5854d614c446d57a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 02:44:32 +0000 Subject: [PATCH 062/279] temp files before branching [SVN r9457] --- example/dvect.cpp | 68 ++++++++++++++++++++++++++++++++++ example/dvect.h | 32 ++++++++++++++++ example/ivect.cpp | 68 ++++++++++++++++++++++++++++++++++ example/ivect.h | 32 ++++++++++++++++ example/noncopyable.h | 14 +++++++ example/noncopyable_export.cpp | 23 ++++++++++++ example/noncopyable_import.cpp | 41 ++++++++++++++++++++ example/tst_dvect.py | 16 ++++++++ example/tst_ivect.py | 16 ++++++++ example/tst_noncopyable.py | 8 ++++ 10 files changed, 318 insertions(+) create mode 100644 example/dvect.cpp create mode 100644 example/dvect.h create mode 100644 example/ivect.cpp create mode 100644 example/ivect.h create mode 100644 example/noncopyable.h create mode 100644 example/noncopyable_export.cpp create mode 100644 example/noncopyable_import.cpp create mode 100644 example/tst_dvect.py create mode 100644 example/tst_ivect.py create mode 100644 example/tst_noncopyable.py diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..47f70d3b --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,68 @@ +#include "ivect.h" +#include "dvect.h" +#include +namespace python = boost::python; + +namespace { + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } + + boost::python::tuple ivect_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) + { + return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) + { + return iv->as_tuple(); + } + + boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) + { + return iv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initdvect() +{ + try + { + python::module_builder this_module("dvect"); + + python::x_class_builder dvect_class(this_module, "dvect"); + + python::import_class_builder ivect_class("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + + this_module.def(ivect_as_tuple, "ivect_as_tuple"); + dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); + dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); + this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); + this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.h b/example/dvect.h new file mode 100644 index 00000000..8ffe7b50 --- /dev/null +++ b/example/dvect.h @@ -0,0 +1,32 @@ +#ifndef DVECT_H +#define DVECT_H + +#include +#include + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // DVECT_H diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..dfd90fc9 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,68 @@ +#include "ivect.h" +#include "dvect.h" +#include +namespace python = boost::python; + +namespace { + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } + + boost::python::tuple dvect_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) + { + return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) + { + return dv->as_tuple(); + } + + boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) + { + return dv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initivect() +{ + try + { + python::module_builder this_module("ivect"); + + python::x_class_builder ivect_class(this_module, "ivect"); + + python::import_class_builder dvect_class("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + + this_module.def(dvect_as_tuple, "dvect_as_tuple"); + ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); + ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); + this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); + this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.h b/example/ivect.h new file mode 100644 index 00000000..a0187307 --- /dev/null +++ b/example/ivect.h @@ -0,0 +1,32 @@ +#ifndef IVECT_H +#define IVECT_H + +#include +#include + +namespace vects { + + struct ivect : public std::vector + { + ivect() : std::vector() {} + ivect(size_t n) : std::vector(n) {} + ivect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // IVECT_H diff --git a/example/noncopyable.h b/example/noncopyable.h new file mode 100644 index 00000000..de7b3672 --- /dev/null +++ b/example/noncopyable.h @@ -0,0 +1,14 @@ +#ifndef NONCOPYABLE_H +#define NONCOPYABLE_H + +class store +{ + private: + store(const store&) { } // Disable the copy constructor. + int number; + public: + store(const int i) : number(i) { } + int recall() const { return number; } +}; + +#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..31cbe7c8 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,23 @@ +#include +namespace python = boost::python; + +#include "noncopyable.h" + +extern "C" +DL_EXPORT(void) +initnoncopyable_export() +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::xptr_class_builder store_class(this_module, "store"); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..f2b2c6d0 --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,41 @@ +#include +namespace python = boost::python; + +#include "noncopyable.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +extern "C" +DL_EXPORT(void) +initnoncopyable_import() +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_class_builder + dvect_class("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/tst_dvect.py b/example/tst_dvect.py new file mode 100644 index 00000000..563f0ad5 --- /dev/null +++ b/example/tst_dvect.py @@ -0,0 +1,16 @@ +import dvect +print dvect.dvect.__converters__ +dv = dvect.dvect((1,2,3,4,5)) +print dv +print dv.as_tuple() +iv = dv.as_ivect() +print iv +print iv.as_tuple() +print dvect.ivect_as_tuple(iv) +aiv = dv.auto_ptr_ivect() +print aiv +siv = dv.shared_ptr_ivect() +print dvect.auto_ptr_ivect_as_tuple(aiv) +print dvect.ivect_as_tuple(aiv) +print dvect.shared_ptr_ivect_as_tuple(siv) +print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py new file mode 100644 index 00000000..58bc323f --- /dev/null +++ b/example/tst_ivect.py @@ -0,0 +1,16 @@ +import ivect +print ivect.ivect.__converters__ +iv = ivect.ivect((1,2,3,4,5)) +print iv +print iv.as_tuple() +dv = iv.as_dvect() +print dv +print dv.as_tuple() +print ivect.dvect_as_tuple(dv) +adv = iv.auto_ptr_dvect() +print adv +sdv = iv.shared_ptr_dvect() +print ivect.auto_ptr_dvect_as_tuple(adv) +print ivect.dvect_as_tuple(adv) +print ivect.shared_ptr_dvect_as_tuple(sdv) +print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..913df039 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,8 @@ +import noncopyable_export +import noncopyable_import +s1 = noncopyable_export.store(1) +print s1.recall() +s2 = noncopyable_export.store(2) +print s2.recall() +s3 = noncopyable_import.add_stores(s1, s2) +print s3.recall() From 53d2398e0654b67463c4326b7dc8ba134d925711 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 02:45:39 +0000 Subject: [PATCH 063/279] remove temp files after branching. [SVN r9459] --- example/dvect.cpp | 68 ---------------------------------- example/dvect.h | 32 ---------------- example/ivect.cpp | 68 ---------------------------------- example/ivect.h | 32 ---------------- example/noncopyable.h | 14 ------- example/noncopyable_export.cpp | 23 ------------ example/noncopyable_import.cpp | 41 -------------------- example/tst_dvect.py | 16 -------- example/tst_ivect.py | 16 -------- example/tst_noncopyable.py | 8 ---- 10 files changed, 318 deletions(-) delete mode 100644 example/dvect.cpp delete mode 100644 example/dvect.h delete mode 100644 example/ivect.cpp delete mode 100644 example/ivect.h delete mode 100644 example/noncopyable.h delete mode 100644 example/noncopyable_export.cpp delete mode 100644 example/noncopyable_import.cpp delete mode 100644 example/tst_dvect.py delete mode 100644 example/tst_ivect.py delete mode 100644 example/tst_noncopyable.py diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index 47f70d3b..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -namespace python = boost::python; - -namespace { - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } - - boost::python::tuple ivect_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) - { - return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) - { - return iv->as_tuple(); - } - - boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) - { - return iv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initdvect() -{ - try - { - python::module_builder this_module("dvect"); - - python::x_class_builder dvect_class(this_module, "dvect"); - - python::import_class_builder ivect_class("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - - this_module.def(ivect_as_tuple, "ivect_as_tuple"); - dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); - dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); - this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); - this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/dvect.h b/example/dvect.h deleted file mode 100644 index 8ffe7b50..00000000 --- a/example/dvect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DVECT_H -#define DVECT_H - -#include -#include - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // DVECT_H diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index dfd90fc9..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -namespace python = boost::python; - -namespace { - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } - - boost::python::tuple dvect_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) - { - return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) - { - return dv->as_tuple(); - } - - boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) - { - return dv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initivect() -{ - try - { - python::module_builder this_module("ivect"); - - python::x_class_builder ivect_class(this_module, "ivect"); - - python::import_class_builder dvect_class("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - - this_module.def(dvect_as_tuple, "dvect_as_tuple"); - ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); - ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); - this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); - this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/ivect.h b/example/ivect.h deleted file mode 100644 index a0187307..00000000 --- a/example/ivect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IVECT_H -#define IVECT_H - -#include -#include - -namespace vects { - - struct ivect : public std::vector - { - ivect() : std::vector() {} - ivect(size_t n) : std::vector(n) {} - ivect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // IVECT_H diff --git a/example/noncopyable.h b/example/noncopyable.h deleted file mode 100644 index de7b3672..00000000 --- a/example/noncopyable.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NONCOPYABLE_H -#define NONCOPYABLE_H - -class store -{ - private: - store(const store&) { } // Disable the copy constructor. - int number; - public: - store(const int i) : number(i) { } - int recall() const { return number; } -}; - -#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 31cbe7c8..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -namespace python = boost::python; - -#include "noncopyable.h" - -extern "C" -DL_EXPORT(void) -initnoncopyable_export() -{ - try - { - python::module_builder this_module("noncopyable_export"); - - python::xptr_class_builder store_class(this_module, "store"); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index f2b2c6d0..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -namespace python = boost::python; - -#include "noncopyable.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -extern "C" -DL_EXPORT(void) -initnoncopyable_import() -{ - try - { - python::module_builder this_module("noncopyable_import"); - - python::import_class_builder - dvect_class("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/tst_dvect.py b/example/tst_dvect.py deleted file mode 100644 index 563f0ad5..00000000 --- a/example/tst_dvect.py +++ /dev/null @@ -1,16 +0,0 @@ -import dvect -print dvect.dvect.__converters__ -dv = dvect.dvect((1,2,3,4,5)) -print dv -print dv.as_tuple() -iv = dv.as_ivect() -print iv -print iv.as_tuple() -print dvect.ivect_as_tuple(iv) -aiv = dv.auto_ptr_ivect() -print aiv -siv = dv.shared_ptr_ivect() -print dvect.auto_ptr_ivect_as_tuple(aiv) -print dvect.ivect_as_tuple(aiv) -print dvect.shared_ptr_ivect_as_tuple(siv) -print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py deleted file mode 100644 index 58bc323f..00000000 --- a/example/tst_ivect.py +++ /dev/null @@ -1,16 +0,0 @@ -import ivect -print ivect.ivect.__converters__ -iv = ivect.ivect((1,2,3,4,5)) -print iv -print iv.as_tuple() -dv = iv.as_dvect() -print dv -print dv.as_tuple() -print ivect.dvect_as_tuple(dv) -adv = iv.auto_ptr_dvect() -print adv -sdv = iv.shared_ptr_dvect() -print ivect.auto_ptr_dvect_as_tuple(adv) -print ivect.dvect_as_tuple(adv) -print ivect.shared_ptr_dvect_as_tuple(sdv) -print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 913df039..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,8 +0,0 @@ -import noncopyable_export -import noncopyable_import -s1 = noncopyable_export.store(1) -print s1.recall() -s2 = noncopyable_export.store(2) -print s2.recall() -s3 = noncopyable_import.add_stores(s1, s2) -print s3.recall() From 116b3db1d1b6ebbaab7aca99401b6a8dd332d613 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 20:55:09 +0000 Subject: [PATCH 064/279] Fixed typo in use of "PYTHON_LIB" [SVN r9467] --- build/como.mak | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/como.mak b/build/como.mak index c6f340a5..581eefea 100644 --- a/build/como.mak +++ b/build/como.mak @@ -1,5 +1,7 @@ # Revision History: +# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams) # 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) + LIBSRC = \ classes.cpp \ conversions.cpp \ @@ -33,7 +35,7 @@ endif [ -s $@ ] || rm -f $@ example1: example1.o libboost_python.a - como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lboost_python + como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYTHON_LIB) example1.o -L. -lboost_python python ../example/test_example1.py example1.o: ../example/example1.cpp From 617bcdac9f81d1486c585158b9c7694f2f5c48fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:39:31 +0000 Subject: [PATCH 065/279] Major doc updates [SVN r9470] --- doc/building.html | 195 +++++++++++++++++++++++++++++-------- doc/comparisons.html | 61 +++++++----- doc/enums.html | 43 +++++--- doc/example1.html | 112 ++++++--------------- doc/exporting_classes.html | 144 +++++++++++++++++++++++++++ doc/extending.html | 4 +- doc/index.html | 91 +++++++++-------- doc/inheritance.html | 26 ++--- doc/overloading.html | 6 +- doc/overriding.html | 98 +++++++++++-------- doc/pickle.html | 28 +++--- doc/pointers.html | 4 +- doc/special.html | 28 +++--- doc/under-the-hood.html | 4 +- 14 files changed, 551 insertions(+), 293 deletions(-) create mode 100644 doc/exporting_classes.html diff --git a/doc/building.html b/doc/building.html index 4ac2343c..6627bbe8 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1,44 +1,157 @@ - - - Building an Extension Module - + + + + + Building an Extension Module +
      -

      - c++boost.gif (8819 bytes)Building an Extension Module -

      -

      - 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 - sources into a shared library, and support for a shared library - build is planned, but not yet implemented. The BPL source files are: -

      -
      -extclass.cpp
      -functions.cpp
      -init_function.cpp
      -module.cpp
      -newtypes.cpp
      -objects.cpp
      -py.cpp
      -subclass.cpp
      -         
      -
      -

      - Next: Enums - Previous: A Peek Under the Hood - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

      - Updated: Nov 26, 2000 +

      c++boost.gif (8819 bytes)Building an + Extension Module

      + +

      The build process for Boost is currently undergoing some evolution, + and, it is to be hoped, improvement. The following facts may help: + +

        +
      • + Makefiles for various platforms reside in the Boost subdirectory + libs/python/build: + +
          +
        • como.mak (Comeau C++ on Linux) + +
        • linux_gcc.mak (GCC on + Linux/Unix) + +
        • gcc.mak (older makefile for GCC + on Linux/Unix. Deprecated.) + +
        • mingw32.mak + (highly-specialized makefile for mingw32 (Win32-targeted) GCC. Read + the header comment). + +
        • tru64_cxx.mak (Compaq + Alpha). +
        +
        + +
      • + A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The + include paths for this project may need to be changed for your + installation. They currently assume that python has been installed at + c:\tools\python. Three configurations of all targets are + supported: + +
          +
        • Release (optimization, -DNDEBUG) + +
        • Debug (no optimization -D_DEBUG) + +
        • DebugPython (no optimization, -D_DEBUG + -DBOOST_DEBUG_PYTHON) +
        + +

        When extension modules are built with Visual C++ using + -D_DEBUG, Python defaults to force linking with a + special debugging version of the Python DLL. Since this debug DLL + isn't supplied with the default Python installation for Windows, + Boost.Python uses boost/python/detail/wrap_python.hpp + to temporarily undefine _DEBUG when Python.h is + #included. + +

        If you want the extra runtime checks available with the debugging + version of the library, #define BOOST_DEBUG_PYTHON to + re-enable library forcing, and link with the DebugPython version of + boost_python.lib. You'll need to get the debugging version + of the Python executable (python_d.exe) and DLL + (python20_d.dll or python15_d.dll). The Python + sources include project files for building these. If you download them, change the name of the + top-level directory to src, and install it under + c:\tools\python, the workspace supplied by Boost.Python will + be able to use it without modification. Just open + c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build + all" to generate all the debugging targets. + +

        If you do not #define BOOST_DEBUG_PYTHON, be sure that + any source files #include <boost/python/detail/wrap_python.hpp> + instead of the usual Python.h, or you will have link + incompatibilities.
        +
        + + +

      • + The makefiles and Visual Studio project can all build at least the + following: + +
          +
        • The boost_python library for static linking with your + extension module. On the various Unices, this library will be + called libboost_python.a. On Win32 platforms, the library + will be called boost_python.lib. + +
        • A comprehensive test of Boost.Python features. This test builds + a Boost.Python extension module, then runs Python to import the + module, and runs a series of tests on it using doctest. Source code for the module + and tests is available in the Boost subdirectory + libs/python/test.
          + + +
        • Various examples from the Boost subdirectory + libs/python/example. Which examples are built currently + depends on the platform. The most up-to-date examples are + getting_startedn.cpp from Ralf W. + Grosse-Kunstleve. All these examples include a doctest modeled + on the comprehensive test above.
          +
          + +
        + +
      • + If your platform isn't directly supported, you can build a static + library from the following source files (in the Boost subdirectory + libs/python/src), or compile them directly and link the + resulting objects into your extension module: + + +
      + +

      Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top + +

      © Copyright David Abrahams 2000. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright + notice appears in all copies. This document is provided ``as is'' without + express or implied warranty, and with no claim as to its suitability for + any purpose. + +

      Updated: Mar 6, 2001

      diff --git a/doc/comparisons.html b/doc/comparisons.html index 336220fb..6f082d51 100644 --- a/doc/comparisons.html +++ b/doc/comparisons.html @@ -6,13 +6,14 @@

      c++boost.gif (8819 bytes)Comparisons with + src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">
      + Comparisons with Other Systems

      CXX

      - Like BPL, CXX attempts to + Like Boost.Python, CXX 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++ @@ -40,9 +41,15 @@

      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. While you're hardly programming directly to the ``bare - metal'' with CXX, it basically presents a ``C++-ized'' - version of the Python 'C' API. + same fully-generic interfaces we use in Python. While you're hardly + programming directly to the ``bare metal'' with CXX, it basically + presents a ``C++-ized'' version of the Python 'C' API. Some fraction of + that capability is available in Boost.Python through boost/python/objects.hpp, + which provides C++ objects corresponding to Python lists, tuples, + strings, and dictionaries, and through boost/python/callback.hpp, + which allows you to call back into python with C++ arguments.

      Paul F. Dubois, the original @@ -65,7 +72,7 @@ that.''
      -Paul Dubois 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 BPL, SWIG is trying to allow an + many Python extension modules. Like Boost.Python, SWIG is trying to allow an existing interface to be wrapped with little or no change to the existing code. The documentation says ``SWIG parses a form of ANSI C syntax that has been extended with a number of special directives. As a @@ -78,15 +85,15 @@ that.''
      -Paul Dubois 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 BPL doesn't have + realistic), one had to write code by hand. I believe Boost.Python doesn't have this problem[sic]... IMHO overloaded functions are very important to wrap correctly.''
      -Prabhu Ramachandran

  • - By contrast, BPL doesn't attempt to parse C++ - the problem is simply + By contrast, Boost.Python doesn't attempt to parse C++ - the problem is simply too complex to do correctly. Technically, one does - write code by hand to use BPL. The goal, however, has been to make + write code by hand to use Boost.Python. 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 +102,7 @@ that.''
    -Paul Dubois SIP is a system similar to SWIG, though seemingly more - C++-oriented. The author says that like BPL, SIP supports overriding + C++-oriented. The author says that like Boost.Python, 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 +120,7 @@ that.''
    -Paul Dubois 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 BPL, this means that the system + provide an implementation. Unlike Boost.Python, 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 +155,7 @@ an inheritance relationship?

    Zope ExtensionClasses

    - ExtensionClasses in Zope use the same underlying mechanism as BPL + ExtensionClasses in Zope use the same underlying mechanism as Boost.Python 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 @@ -158,31 +165,35 @@ an inheritance relationship?

    The major differences are:

      +
    • Zope is entirely 'C' language-based. It doesn't require a C++ + compiler, so it's much more portable than Boost.Python, which stresses + the limits of even some modern C++ implementations. +
    • - BPL lifts the burden on the user to parse and convert function + Boost.Python lifts the burden on the user to parse and convert function argument types. Zope provides no such facility.
    • - BPL lifts the burden on the user to maintain Python + Boost.Python lifts the burden on the user to maintain Python reference-counts.
    • - BPL supports function overloading; Zope does not. + Boost.Python supports function overloading; Zope does not.
    • - BPL supplies a simple mechanism for exposing read-only and + Boost.Python supplies a simple mechanism for exposing read-only and read/write access to data members of the wrapped C++ type as Python attributes.
    • Writing a Zope ExtensionClass is significantly more complex than - exposing a C++ class to python using BPL (mostly a summary of the + exposing a C++ class to python using Boost.Python (mostly a summary of the previous 4 items). A Zope Example illustrates the differences.
    • Zope's ExtensionClasses are specifically motivated by ``the need for a - C-based persistence mechanism''. BPL's are motivated by the desire + C-based persistence mechanism''. Boost.Python's are motivated by the desire to simply reflect a C++ API into Python with as little modification as possible.
    • - The following Zope restriction does not apply to BPL: ``At most one + The following Zope restriction does not apply to Boost.Python: ``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,21 +202,21 @@ an inheritance relationship? Zope requires use of the somewhat funky inheritedAttribute (search for ``inheritedAttribute'' on this page) - method to access base class methods. In BPL, base class methods can + method to access base class methods. In Boost.Python, base class methods can be accessed in the usual way by writing ``BaseClass.method''.
    • Zope supplies some creative but esoteric idioms such as - Acquisition. No specific support for this is built into BPL. + Acquisition. No specific support for this is built into Boost.Python.
    • Zope's ComputedAttribute support is designed to be used from Python. The analogous feature of - BPL can be used from C++ or Python. The feature is arguably - easier to use in BPL. + Boost.Python can be used from C++ or Python. The feature is arguably + easier to use in Boost.Python.

    - Next: A Simple Example Using BPL + Next: A Simple Example Using Boost.Python Previous: A Brief Introduction to writing Python Extension Modules Up: Top

    @@ -215,6 +226,6 @@ an inheritance relationship? express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2001 diff --git a/doc/enums.html b/doc/enums.html index 04138ff1..32d61447 100644 --- a/doc/enums.html +++ b/doc/enums.html @@ -6,7 +6,8 @@

    c++boost.gif (8819 bytes)Wrapping enums + src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">
    + Wrapping enums

    Because there is in general no way to deduce that a value of arbitrary type T @@ -17,24 +18,39 @@ enums). Once you have done that, you can write some simple from_python() and to_python() functions.

    If you are satisfied with a Python int as a way to represent your enum -values, we provide a shorthand for these functions. You just need to -instantiate boost::python::enum_as_int_converters<EnumType> where +values, we provide a shorthand for these functions. You just need to cause +boost::python::enum_as_int_converters<EnumType> to be +instantiated, where EnumType is your enumerated type. There are two convenient ways to do this:

      -
    1. +
    2. Explicit instantiation: + +
      +  template class boost::python::enum_as_int_converters<my_enum>;
      +
      + +Some buggy C++ implementations require a class to be instantiated in the same +namespace in which it is defined. In that case, the simple incantation above becomes: + +
          ...
       } // 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;
      -BOOST_PYTHON_END_CONVERSION_NAMESPACE
      +namespace boost { namespace python {
      +  template class enum_as_int_converters<my_enum_type>;
      +}} // namespace boost::python
      +
       namespace my_namespace { // re-open my_namespace
          ...
       
      -
    3. +
      +
      +
    4. If you have such an implementation, you may find this technique more convenient +
       // instantiate as base class in any namespace
       struct EnumTypeConverters
           : boost::python::enum_as_int_converters<EnumType>
      @@ -71,7 +87,8 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
        long type.
       
       You may also want to add a bunch of lines like this to your module
      -initialization:
      +initialization. These bind the corresponding enum values to the appropriate
      +names so they can be used from Python:
       
       
       mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
      @@ -83,12 +100,12 @@ You can also add these to an extension class definition, if your enum happens to
       be local to a class and you want the analogous interface in Python:
       
       
      -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");
      +my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
      +my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
       ...
       

      - Next: Pointers + Next: Pointers and Smart Pointers Previous: Building an Extension Module Up: Top

      @@ -98,6 +115,6 @@ my_class.add(boost::python::to_python(enum_value_2), "enum_value_2"); is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

      - Updated: Nov 26, 2000 + Updated: Mar 6, 2001

    diff --git a/doc/example1.html b/doc/example1.html index 655f3d6a..402cc7a6 100644 --- a/doc/example1.html +++ b/doc/example1.html @@ -18,104 +18,56 @@
     #include <string>
     
    -namespace hello {
    -  class world
    -  {
    -   public:
    -      world(int);
    -      ~world();
    -      std::string greet() const { return "hi, world"; }
    -    ...
    -  };
    -  std::size_t length(const world& x) { return std::strlen(x.greet()); }
    +namespace { // Avoid cluttering the global namespace.
    +
    +  // A couple of simple C++ functions that we want to expose to Python.
    +  std::string greet() { return "hello, world"; }
    +  int square(int number) { return number * number; }
     }
     
     

    - Here is the C++ code for a python module called hello - which exposes the API using: + Here is the C++ code for a python module called getting_started1 + which exposes the API.

     #include <boost/python/class_builder.hpp>
    -// Python requires an exported function called init<module-name> in every
    -// extension module. This is where we build the module contents.
    -extern "C"
    -#ifdef _WIN32
    -__declspec(dllexport)
    -#endif
    -void inithello()
    +namespace python = boost::python;
    +
    +BOOST_PYTHON_MODULE_INIT(getting_started1)
     {
    -    try
    -    {
    -       // create an object representing this extension module
    -       boost::python::module_builder m("hello");
    -       // Create the Python type object for our extension class
    -       boost::python::class_builder<hello::world> world_class(m, "world");
    -       // Add the __init__ function
    -       world_class.def(boost::python::constructor<int>());
    -       // Add a regular member function
    -       world_class.def(&hello::world::get, "get");
    -       // Add a regular function to the module
    -       m.def(hello::length, "length");
    -    }
    -    catch(...)
    -    {
    -       boost::python::handle_exception();    // Deal with the exception for Python
    -    }
    +  try
    +  {
    +    // Create an object representing this extension module.
    +    python::module_builder this_module("getting_started1");
    +
    +    // Add regular functions to the module.
    +    this_module.def(greet, "greet");
    +    this_module.def(square, "square");
    +  }
    +  catch(...)
    +  {
    +    python::handle_exception(); // Deal with the exception for Python
    +  }
     }
    -// Win32 DLL boilerplate
    -#if defined(_WIN32)
    -#include <windows.h>
    -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
    -{
    -    return 1;
    -}
    -#endif // _WIN32
     

    That's it! If we build this shared library and put it on our - PYTHONPATH we can now access our C++ class and function from + PYTHONPATH we can now access our C++ functions from Python.

    ->>> import hello
    ->>> hi_world = hello.world(3)
    ->>> hi_world.greet()
    -'hi, world'
    ->>> hello.length(hi_world)
    -9
    +>>> import getting_started1
    +>>> print getting_started1.greet()
    +hello, world
    +>>> number = 11
    +>>> print number, '*', number, '=', getting_started1.square(number)
    +11 * 11 = 121
     
    -

    - We can even make a subclass of hello.world: -

    -
    ->>> class my_subclass(hello.world):
    -...     def greet(self):
    -...         return 'hello, world'
    -...
    ->>> y = my_subclass(4)
    ->>> y.greet()
    -'hello, world'
    -
    -
    -

    - Pretty cool! You can't do that with an ordinary Python extension type! -

    -
    ->>> hello.length(y)
    -9
    -
    -
    -

    - Of course, you may now have a slightly empty feeling in the pit of - your little pythonic stomach. Perhaps you feel your subclass deserves - to have a length() of 12? If so, read on... -

    - Next: Overridable virtual functions + Next: Exporting Classes Previous: Comparisons with other systems Up: Top

    @@ -125,6 +77,6 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2000 diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html new file mode 100644 index 00000000..e5932e70 --- /dev/null +++ b/doc/exporting_classes.html @@ -0,0 +1,144 @@ + + + Exporting Classes + +

    +

    + + +

    +

    + Exporting Classes +

    +

    + Now let's expose a C++ class to Python: + +

    +#include <iostream>
    +#include <string>
    +
    +namespace { // Avoid cluttering the global namespace.
    +
    +  // A friendly class.
    +  class hello
    +  {
    +    public:
    +      hello(const std::string& country) { this->country = country; }
    +      std::string greet() const { return "Hello from " + country; }
    +    private:
    +      std::string country;
    +  };
    +
    +  // A function taking a hello object as an argument.
    +  std::string invite(const hello& w) {
    +    return w.greet() + "! Please come soon!";
    +  }
    +}
    +
    +

    + To expose the class, we use a class_builder in addition to the + module_builder from the previous example. Class member functions + are exposed by using the def() member function on the + class_builder: +

    +#include <boost/python/class_builder.hpp>
    +namespace python = boost::python;
    +
    +BOOST_PYTHON_MODULE_INIT(getting_started2)
    +{
    +  try
    +  {
    +    // Create an object representing this extension module.
    +    python::module_builder this_module("getting_started2");
    +
    +    // Create the Python type object for our extension class.
    +    python::class_builder<hello> hello_class(this_module, "hello");
    +
    +    // Add the __init__ function.
    +    hello_class.def(python::constructor<std::string>());
    +    // Add a regular member function.
    +    hello_class.def(&hello::greet, "greet");
    +
    +    // Add invite() as a regular function to the module.
    +    this_module.def(invite, "invite");
    +
    +    // Even better, invite() can also be made a member of hello_class!!!
    +    hello_class.def(invite, "invite");
    +  }
    +  catch(...)
    +  {
    +    python::handle_exception(); // Deal with the exception for Python
    +  }
    +}
    +
    +

    +Now we can use the class normally from Python: + +

    +>>> from getting_started2 import *
    +>>> hi = hello('California')
    +>>> hi.greet()
    +'Hello from California'
    +>>> invite(hi)
    +'Hello from California! Please come soon!'
    +>>> hi.invite()
    +'Hello from California! Please come soon!'
    +
    + +Notes:
      +
    • We expose the class' constructor by calling def() on the + class_builder with an argument whose type is + constructor<params>, where params + matches the list of constructor argument types: + + +
    • Regular member functions are defined by calling def() with a + member function pointer and its Python name: + +
    • Any function added to a class whose initial argument matches the class (or +any base) will act like a member function in Python. +
    +

    + We can even make a subclass of hello.world: + +

    +>>> class wordy(hello):
    +...     def greet(self):
    +...         return hello.greet(self) + ', where the weather is fine'
    +...
    +>>> hi2 = wordy('Florida')
    +>>> hi2.greet()
    +'Hello from Florida, where the weather is fine'
    +>>> invite(hi2)
    +'Hello from Florida! Please come soon!'
    +
    +

    + Pretty cool! You can't do that with an ordinary Python extension type! + + Of course, you may now have a slightly empty feeling in the pit of + your little pythonic stomach. Perhaps you wanted to see the following + wordy invitation: + +

    +'Hello from Florida, where the weather is fine! Please come soon!'
    +
    + + After all, invite calls hello::greet(), and you + reimplemented that in your Python subclass, wordy. If so, read on... + +

    + Next: Overridable virtual functions + Previous: A Simple Example Up: + Top +

    + © Copyright David Abrahams 2000. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright + notice appears in all copies. This document is provided "as is" without + express or implied warranty, and with no claim as to its suitability + for any purpose. +

    + Updated: Mar 6, 2001 +

    + diff --git a/doc/extending.html b/doc/extending.html index c4a3a5e4..8839ab43 100644 --- a/doc/extending.html +++ b/doc/extending.html @@ -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. BPL solves this problem by taking advantage of Python's metaclass feature to provide objects which look, walk, and hiss almost exactly - like regular Python classes. BPL classes are actually cleaner than + like regular Python classes. Boost.Python classes are actually cleaner than Python classes in some subtle ways; a more detailed discussion will follow (someday).

    Next: Comparisons with Other Systems Up: - The Boost Python Library (BPL) + The Boost Python Library (Boost.Python)

    c++boost.gif (8819 bytes)The Boost Python Library (BPL) + align="center" height="86">
    The Boost Python Library (Boost.Python)

    Synopsis

    @@ -15,9 +15,9 @@ href="http://www.python.org">Python
    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 BPL. The system + your C++ classes in any way in order to use them with Boost.Python. The system should simply ``reflect'' your C++ classes and functions into - Python. The major features of BPL include support for: + Python. The major features of Boost.Python include support for: