From qinlj at solidshare.com Fri Aug 1 01:53:44 2003 From: qinlj at solidshare.com (Lijun Qin) Date: Thu, 31 Jul 2003 16:53:44 -0700 Subject: [C++-sig] Automatic PyUnicode to 'const char*' Message-ID: <000d01c357be$feffb700$0200a8c0@barrack> Hi all, I'm using boost.python to wrap the WTL (Windows Template Libaray), using VC 7.1 and porting some old code previously use win32ui.pyd. Basically it is easy to do, though gccxml failed to parse the ATL/WTL code so I can not use Pyste. But there is a trouble, does anybody know how to automaticly convert PyUnicode to 'const char *'? Without this, I have to change lot of code lines to explictly use str() function. Lijun Qin http://www.solidshare.com From qinlj at solidshare.com Sat Aug 2 02:10:30 2003 From: qinlj at solidshare.com (Lijun Qin) Date: Fri, 1 Aug 2003 17:10:30 -0700 Subject: [C++-sig] Re: Automatic PyUnicode to 'const char*' References: <20030731174424.7728.63710.Mailman@mail.python.org> Message-ID: <005001c3588a$805b8b00$0200a8c0@barrack> > To: c++-sig at python.org > From: David Abrahams > Date: Thu, 31 Jul 2003 12:18:34 -0400 > Subject: [C++-sig] Re: Automatic PyUnicode to 'const char*' > Reply-To: c++-sig at python.org > > Stefan Seefeld writes: > > > David Abrahams wrote: > >> "Lijun Qin" writes: > >> > >>>Hi all, > >>> > >>>I'm using boost.python to wrap the WTL (Windows Template Libaray), using VC > >>>7.1 and porting some old code previously use win32ui.pyd. > >>>Basically it is easy to do, though gccxml failed to parse the ATL/WTL code > >>>so I can not use Pyste. > >>>But there is a trouble, does anybody know how to automaticly convert > >>>PyUnicode to 'const char *'? Without this, I have to change lot of code > >>>lines to explictly use str() function. > >> I'm not an expert in it, but I thought Unicode used 16- or 32- byte > >> wchar_t characters. How would you convert it to char const*? > > > > unicode allows different encodings, some (such as utf-8) with variably > > sized character representations. This means that conversions usually > > can't be done on-the-fly without helper constructs, i.e. some memory > > management is needed. > > > > As an example, I'm doing such conversions in a xml library. The C > > implementation uses 'xmlChar *', which is just an alias for 'char *', > > but really holds utf-8 encoded text. > > I convert it to various string types (the public API is parametrized > > for the string type): > > To do that kind of narrowing, at the moment, the only way would be to > write a thin wrapper function: > > void f(char const*); > > void f_thin_wrapper(object unicode) > { > str narrowed(unicode); > f(extract(str)); > } > > we may have some support for doing this automatically in the version > of Boost.Python which integrates with Luabind, but that's a ways off > yet. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > Hi, all: I have found a method to do this, by register a convert function: inline void* convert_to_cstring_from_unicode(PyObject* obj) { if (!PyUnicode_Check(obj)) return 0; PyObject* str = PyUnicode_AsEncodedString(obj, "mbcs", NULL); if (!str) throw_error_already_set(); //We must release the str before we return to python, gard here static leak_gard _gard; unicode_str_map[obj] = str; return PyString_AsString(str); } converter::registry::insert(convert_to_cstring_from_unicode, type_id()); But the problem is that the PyString object must be freed when the call is completed, I currently do this by applying a custom call policy to the methods using 'const char*' type of parameters, but if there were reclusive calls into the same fuction, it'll much complex. In this procedure, I found that if we can apply the call policies before the argument conversion procedure and in the context of the call policy object (a call policy object is always attached with a method, right?), the problem will be solved much easier and safer. We'll be able to replace the PyUnicode object with a PyString object (in Windows platform, always MBCS encoding), maybe save the original args tuple in the call policy object, then convert the args to C++ (it'll success because the arg is a PyString) and call the C++ function, when postcall(args, result) called, we can just release the newly allocated args tuple, replace it with the original one. This will give us more control on how the args be processed. Lijun Qin http://www.solidshare.com From dave at boost-consulting.com Fri Aug 1 13:15:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Aug 2003 07:15:29 -0400 Subject: [C++-sig] Re: Automatic PyUnicode to 'const char*' References: <20030731174424.7728.63710.Mailman@mail.python.org> <005001c3588a$805b8b00$0200a8c0@barrack> Message-ID: "Lijun Qin" writes: > Hi, all: > > I have found a method to do this, by register a convert function: > > inline void* convert_to_cstring_from_unicode(PyObject* obj) > { > if (!PyUnicode_Check(obj)) return 0; > PyObject* str = PyUnicode_AsEncodedString(obj, "mbcs", NULL); > if (!str) throw_error_already_set(); > > //We must release the str before we return to python, gard here > static leak_gard _gard; > > unicode_str_map[obj] = str; > return PyString_AsString(str); > } > > converter::registry::insert(convert_to_cstring_from_unicode, > type_id()); > > But the problem is that the PyString object must be freed when the > call is completed, I currently do this by applying a custom call > policy to the methods using 'const char*' type of parameters, but if > there were reclusive "recursive", I think. > calls into the same fuction, it'll much complex. > > In this procedure, I found that if we can apply the call policies > before the argument conversion procedure and in the context of the > call policy object (a call policy object is always attached with a > method, right?) Right. > the problem will be solved much easier and safer. We'll be able to > replace the PyUnicode object with a PyString object (in Windows > platform, always MBCS encoding), maybe save the original args tuple > in the call policy object This is the key thing which I had forgotten: call policies can have state. You can keep a stack (linked list) of "original args tuples" in the call policy in order to deal with recursion. > then convert the args to C++ (it'll success because the arg is a > PyString) and call the C++ function, when postcall(args, result) > called, we can just release the newly allocated args tuple, replace > it with the original one. This will give us more control on how the > args be processed. Yes, that sounds brilliant! So this approach does not use the convert_to_cstring_from_unicode converter, correct? I think it has inspired me, also, to consider expanding the conversion interface. I was looking for a way for converters to maintain state (e.g. to be able to keep a PyString alive during the conversion, or to be able to fabricate a vector from a Python list and then write the modified elements of the vector back into the list after the call) without incurring the cost of a polymorphic postcall operation for each converter in a function call. One possibility might be to define an abstract postcall object, and pass a pointer to a chain of those, which lives in the call policy, to all converters during function calls. Any converter which needed to maintain state could add a postcall object to the chain. That would essentially reduce the postcall check to a single step for N arguments, in the usual case that there were no postcall operations. In non-function contexts, such as char const* p = extract(s); the pointer to the postcall chain would be NULL, so any converters which required a postcall chain could simply report "no match". -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Aug 1 16:16:37 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Aug 2003 10:16:37 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F294F35.A6988D6A@sitius.com> Message-ID: Nikolay Mladenov writes: > Diffs to the cvs from before couple of days: Hi Nikolay, In future, please post patches as unified diffs (you can use cvs diff -wu). This patch appears to have some significant bogus code in it, especially in function.cpp. Just for example, I think the following block would never be entered: > ! //adjust the parameter tuple size > ! if(j ! { > ! handle<> args3( PyTuple_New(j) ); > ! > ! for (size_t l = 0; l != j; ++ l) > ! { > ! PyTuple_SET_ITEM(args3.get(), l, PyTuple_GET_ITEM(args3.get(), l) ); > ! PyTuple_SET_ITEM(args2.get(), l, 0); > ! } > ! args2 = args3; > ! } > } > } > } It had better not be, because it is getting all the elements of args3 and putting them back there! I've enclosed the modified patch which seems to be working on my machine. I had to rename lots of variables in order to make sense of things. Please look it over to make sure it makes sense to you. -------------- next part -------------- A non-text attachment was scrubbed... Name: nikolay.patch Type: text/x-patch Size: 10857 bytes Desc: not available URL: -------------- next part -------------- -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Aug 1 18:39:25 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Aug 2003 12:39:25 -0400 Subject: [C++-sig] Re: Wrapper for exception translation References: <2040C0A1CA23D51181A30050BAAC990274AAC2@berexch.ber.haufemg.com> <001201c34936$303e0b60$44a837c2@gieke> <013401c357a6$db402e70$44a837c2@gieke> Message-ID: Gottfried Gan?auge writes: > Hi Dave, > > I digged through the class_<> implementation and I think I know what I must > do to implement it. Like you suggested I would add another argument to the > class_base constructor which is used as another base class for the newly > created class. > > The only problem I'm having is the programming interface for the user: > I could the simply pass a const pointer to the python exception type to the > protected class_<> constructor. This would - at least for my feeling - look > a bit strange because this would be the only low level python detail on this > level. Additionally it would require from the programmer that he knows the > low level name of the exception type. > > Alternatively I could create an object wrapper around the exception types > and pass a const reference to one of those. This is not too complicated but > it takes it's time. Furthermore I'm not sure about your reaction to my plans > being too complicated :-(. Your plans are complex, but comprehensible and clean. So I support them. Ultimately, I'd like to have an object wrapper around all of the exception classes. I'd like to present as much of the Python API as possible at a high level. It would be great if we could also do: throw IndexError(some_argument); And have it mean the same as: >>> raise IndexError, some_argument > I'm on vacation this week and the next so I currently work only > sporadically. > I think I could have a first prototype by monday, august 18. Sounds very promising; I look forward to it! -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Fri Aug 1 23:10:10 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 01 Aug 2003 17:10:10 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> Message-ID: <3F2AD732.A94E2127@sitius.com> The change that breaks it has happened between Feb 06 2003 and Feb 07 2003 and as far as I can tell it comes from: mpl/aux_/has_xxx.hpp around line 79 the definition of struct msvc_is_incomplete and than detail/iterator.hpp around line 83 What do you think, can it be fixed? Nikolay Nikolay Mladenov wrote: > > David Abrahams wrote: > > > > Nikolay Mladenov ?nickm at sitius.com? writes: > > > > ? I can't get boost_python to compile with this swich, and I have > > ? 1.29.0 compiled with it. > > > > You're saying Boost.Python 1.29.0 used to compile with /vmg? > > Yes. Without a problem. > > > This is compiler insanity, plain and > > simple. > > I can easily believe that:). Though the error seems to come from some > msvc workaround code. > > > > > If indeed it used to compile, all I can suggest is that you do what I > > did this morning: a binary search through time for the CVS change > > which caused /vmg to start failing. Tedious but effective. > > Okey, I 'll try that. From dave at boost-consulting.com Sat Aug 2 04:43:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Aug 2003 22:43:43 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> Message-ID: Nikolay Mladenov writes: > The change that breaks it has happened between Feb 06 2003 and Feb 07 > 2003 > and as far as I can tell it comes from: > mpl/aux_/has_xxx.hpp around line 79 > the definition of struct msvc_is_incomplete > and than detail/iterator.hpp around line 83 > What do you think, can it be fixed? Maybe. Can you figure out which of these two changes is responsible for your problem? I'm pretty sure it's has_xxx.hpp, but I'd like to know for sure. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 2 04:46:06 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Aug 2003 22:46:06 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> Message-ID: Nikolay Mladenov writes: > The change that breaks it has happened between Feb 06 2003 and Feb 07 > 2003 > and as far as I can tell it comes from: > mpl/aux_/has_xxx.hpp around line 79 > the definition of struct msvc_is_incomplete > and than detail/iterator.hpp around line 83 > What do you think, can it be fixed? Hmm, it looks like /vmg has to completely break that msvc_is_incomplete template: template< typename T > struct msvc_is_incomplete { struct incomplete_; BOOST_STATIC_CONSTANT(bool, value = sizeof(void (T::*)()) == sizeof(void (incomplete_::*)()) ); }; I think msvc_is_incomplete::value would always be true. -- Dave Abrahams Boost Consulting www.boost-consulting.com From agurtovoy at meta-comm.com Sat Aug 2 09:21:10 2003 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Sat, 2 Aug 2003 02:21:10 -0500 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> Message-ID: <00f501c358c6$b8946e10$b344a8c0@metacomm.com> David Abrahams wrote: > Nikolay Mladenov writes: > > > The change that breaks it has happened between Feb 06 2003 and Feb 07 > > 2003 > > and as far as I can tell it comes from: > > mpl/aux_/has_xxx.hpp around line 79 > > the definition of struct msvc_is_incomplete > > and than detail/iterator.hpp around line 83 > > What do you think, can it be fixed? > > Hmm, it looks like /vmg has to completely break that > msvc_is_incomplete template: > > template< typename T > > struct msvc_is_incomplete > { > struct incomplete_; > BOOST_STATIC_CONSTANT(bool, value = > sizeof(void (T::*)()) == sizeof(void (incomplete_::*)()) > ); > }; > > I think msvc_is_incomplete::value would always be true. Yeah. Unfortunately, that's the only way I know to implement 'has_xxx' on MSVC so that it doesn't bark on incomplete types, and there is some code around which relies on it. On the other hand, Boost.Python probably doesn't depend on it, and since '/vmg' is not the default option, what we _can_ do is to guard the 'is_incomplete' check with something like BOOST_MPL_AUX_HAS_XXX_MSVC_NO_IS_INCOMPLETE and ask to define the symbol when compiling with '/vmg' or '#pragma pointers_to_members(full_generality, ...)'. If that sounds like a reasonable compromise - in particular, to Nikolay - please feel free to implement it. Aleksey From dave at boost-consulting.com Sat Aug 2 13:46:17 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Aug 2003 07:46:17 -0400 Subject: [C++-sig] Re: args patch In-Reply-To: <00f501c358c6$b8946e10$b344a8c0@metacomm.com> (Aleksey Gurtovoy's message of "Sat, 2 Aug 2003 02:21:10 -0500") References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> Message-ID: Aleksey Gurtovoy writes: > David Abrahams wrote: >> Nikolay Mladenov writes: >> >> > The change that breaks it has happened between Feb 06 2003 and Feb 07 >> > 2003 >> > and as far as I can tell it comes from: >> > mpl/aux_/has_xxx.hpp around line 79 >> > the definition of struct msvc_is_incomplete >> > and than detail/iterator.hpp around line 83 >> > What do you think, can it be fixed? >> >> Hmm, it looks like /vmg has to completely break that >> msvc_is_incomplete template: >> >> template< typename T > >> struct msvc_is_incomplete >> { >> struct incomplete_; >> BOOST_STATIC_CONSTANT(bool, value = >> sizeof(void (T::*)()) == sizeof(void (incomplete_::*)()) >> ); >> }; >> >> I think msvc_is_incomplete::value would always be true. > > Yeah. Unfortunately, that's the only way I know to implement 'has_xxx' on > MSVC so that it doesn't bark on incomplete types, and there is some code > around which relies on it. It seems to me that it can't know the answer for incomplete types, and therefore it shouldn't produce one - it should be an error. How does the conforming version manage it? > On the other hand, Boost.Python probably doesn't depend on it Right. > and since '/vmg' is not the default option, what we _can_ do is to > guard the 'is_incomplete' check with something like > BOOST_MPL_AUX_HAS_XXX_MSVC_NO_IS_INCOMPLETE and ask to define the > symbol when compiling with '/vmg' or '#pragma > pointers_to_members(full_generality, ..)'. Sounds like a plan. > If that sounds like a reasonable compromise - in particular, to > Nikolay - please feel free to implement it. Nikolay, let me know what you think. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 2 18:01:55 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Aug 2003 12:01:55 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> Message-ID: Aleksey Gurtovoy writes: >> I think msvc_is_incomplete::value would always be true. > > Yeah. Unfortunately, that's the only way I know to implement 'has_xxx' on > MSVC so that it doesn't bark on incomplete types, and there is some code > around which relies on it. On the other hand, Boost.Python probably doesn't > depend on it, and since '/vmg' is not the default option, what we _can_ do > is to guard the 'is_incomplete' check with something like > BOOST_MPL_AUX_HAS_XXX_MSVC_NO_IS_INCOMPLETE and ask to define the symbol > when compiling with '/vmg' or '#pragma pointers_to_members(full_generality, > ...)'. > > If that sounds like a reasonable compromise - in particular, to Nikolay - > please feel free to implement it. I did you one better. Now it just works with no BOOST_MPL_AUX_HAS_XXX_MSVC_NO_IS_INCOMPLETE switches required from the user: --- has_xxx.hpp 8 Jul 2003 05:10:02 -0000 1.16 +++ has_xxx.hpp 2 Aug 2003 15:58:44 -0000 1.17 @@ -3,8 +3,8 @@ // See http://www.boost.org for updates, documentation, and revision history. //----------------------------------------------------------------------------- // -// Copyright (c) 2002 -// Aleksey Gurtovoy +// Copyright (c) 2002-2003 +// Aleksey Gurtovoy and David Abrahams // // Permission to use, copy, modify, distribute and sell this software // and its documentation for any purpose is hereby granted without fee, @@ -73,10 +73,14 @@ template< typename T > struct msvc_is_incomplete { - struct incomplete_; - BOOST_STATIC_CONSTANT(bool, value = - sizeof(void (T::*)()) == sizeof(void (incomplete_::*)()) - ); + // MSVC is capable of some kinds of SFINAE. If U is an incomplete + // type, it won't pick the second overload + static char tester(...); + template + static char(& tester(type_wrapper) )[sizeof(U) + 1]; + + BOOST_STATIC_CONSTANT( + bool, value = sizeof(tester(type_wrapper())) == 1); }; -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Sat Aug 2 21:43:15 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Sat, 02 Aug 2003 15:43:15 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F294F35.A6988D6A@sitius.com> Message-ID: <3F2C1453.255B036D@sitius.com> David Abrahams wrote: > > Nikolay Mladenov writes: > > > Diffs to the cvs from before couple of days: > > Hi Nikolay, > > In future, please post patches as unified diffs (you can use cvs diff > -wu). > > This patch appears to have some significant bogus code in it, > especially in function.cpp. Just for example, I think the following > block would never be entered: > > > ! //adjust the parameter tuple size > > ! if(j > ! { > > ! handle<> args3( PyTuple_New(j) ); > > ! > > ! for (size_t l = 0; l != j; ++ l) > > ! { > > ! PyTuple_SET_ITEM(args3.get(), l, PyTuple_GET_ITEM(args3.get(), l) ); > > ! PyTuple_SET_ITEM(args2.get(), l, 0); > > ! } > > ! args2 = args3; > > ! } > > } > > } > > } > > It had better not be, because it is getting all the elements of args3 > and putting them back there! Yeah, I don't remember if the things have been different when I wrote this or I have just imagined that I can end up with min_arity < n_args < max_arity. I guess I have meant to copy arg2 -> arg3 > > ! PyTuple_SET_ITEM(args3.get(), l, PyTuple_GET_ITEM(args2.get(), l) ); But anyway it seems really unreachable now. > > I've enclosed the modified patch which seems to be working on my > machine. I had to rename lots of variables in order to make sense of > things. Please look it over to make sure it makes sense to you. > I like it better. Please apply it. Nikolay From dave at boost-consulting.com Sat Aug 2 22:21:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Aug 2003 16:21:40 -0400 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope In-Reply-To: <3F2C1CDF.26797.29B50CEC@localhost> (Niall Douglas's message of "Sat, 2 Aug 2003 20:19:43 +0100") References: <3F2C1CDF.26797.29B50CEC@localhost> Message-ID: Hi Niall, Please post Boost.Python questions to the C++-sig (see http://www.boost.org/more/mailing_lists.htm). "Niall Douglas" writes: > Hi, > > I was wondering if Boost.Python could be extended such that: > > enum_("").value("CONST", CONST); > > .. would place its members in the highest scope possible ie; you'd > access it as my_module.CONST. We have an export_values() member function which accomplishes that. http://www.boost.org/libs/python/doc/v2/enum.html#enum_-spec > I suggest this because the library I'm creating bindings for has > loads of unnamed enums at global scope for creating constants and > sticking them in some "unnamed" scope is counter-intuitive. Since > pyste has to deal with these, it creates problems :( If you're using Pyste, you *really* should post this to the C++-sig, since Nicodemus (the Pyste author) doesn't read my emails. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sat Aug 2 22:55:25 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 2 Aug 2003 17:55:25 -0300 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope References: <3F2C1CDF.26797.29B50CEC@localhost> Message-ID: <001001c35938$692021e0$0101a8c0@sergio> ----- Original Message ----- From: "David Abrahams" To: "Niall Douglas" ; "pysig" Sent: Saturday, August 02, 2003 5:21 PM Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope > > Hi Niall, > > Please post Boost.Python questions to the C++-sig (see > http://www.boost.org/more/mailing_lists.htm). > > "Niall Douglas" writes: >> I was wondering if Boost.Python could be extended such that: >> >> enum_("").value("CONST", CONST); >> >> .. would place its members in the highest scope possible ie; you'd >> access it as my_module.CONST. > > We have an export_values() member function which accomplishes that. > > http://www.boost.org/libs/python/doc/v2/enum.html#enum_-spec > > > I suggest this because the library I'm creating bindings for has > > loads of unnamed enums at global scope for creating constants and > > sticking them in some "unnamed" scope is counter-intuitive. Since > > pyste has to deal with these, it creates problems :( Nice, I didn't know that either. I think this mirrors the enum behaviour of C++ better. How should Pyste support this? I believe it is more interesting if Pyste always called export_values(), but this would break backwards compability. Thoughts? Niall, another solution would be to explicitly export the names to the global namespace in the Python side (untested): # my_module.py import _my_module # this is the extension module for name, value in _my_module.unnamed.__dict__: globals()[name] = value with this, your users now just have to: import my_module x = my_module.CONST etc etc From agurtovoy at meta-comm.com Sat Aug 2 23:02:16 2003 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Sat, 2 Aug 2003 16:02:16 -0500 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com><00f501c358c6$b8946e10$b344a8c0@metacomm.com> Message-ID: <024001c35939$5aeff8b0$b344a8c0@metacomm.com> David Abrahams wrote: > >> I think msvc_is_incomplete::value would always be true. > > > > Yeah. Unfortunately, that's the only way I know to implement 'has_xxx' on > > MSVC so that it doesn't bark on incomplete types, and there is some code > > around which relies on it. > > > It seems to me that it can't know the answer for incomplete types, and > therefore it shouldn't produce one - it should be an error. We don't really want that. Consider: #include // ... typedef find_if< types, is_same<_1,std::iostream> >::type r; // error? > How does the conforming version manage it? SFINAE-based version just works ('has_xxx' returns 'false'). Aleksey From agurtovoy at meta-comm.com Sat Aug 2 23:16:33 2003 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Sat, 2 Aug 2003 16:16:33 -0500 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> Message-ID: <026801c3593b$5a0845e0$b344a8c0@metacomm.com> David Abrahams wrote: > > If that sounds like a reasonable compromise - in particular, to Nikolay - > > please feel free to implement it. > > I did you one better. Now it just works with no > BOOST_MPL_AUX_HAS_XXX_MSVC_NO_IS_INCOMPLETE switches required from > the user: > > --- has_xxx.hpp 8 Jul 2003 05:10:02 -0000 1.16 > +++ has_xxx.hpp 2 Aug 2003 15:58:44 -0000 1.17 > @@ -3,8 +3,8 @@ > // See http://www.boost.org for updates, documentation, and revision history. > //-------------------------------------------------------------------------- --- > // > -// Copyright (c) 2002 > -// Aleksey Gurtovoy > +// Copyright (c) 2002-2003 > +// Aleksey Gurtovoy and David Abrahams > // > // Permission to use, copy, modify, distribute and sell this software > // and its documentation for any purpose is hereby granted without fee, > @@ -73,10 +73,14 @@ > template< typename T > > struct msvc_is_incomplete > { > - struct incomplete_; > - BOOST_STATIC_CONSTANT(bool, value = > - sizeof(void (T::*)()) == sizeof(void (incomplete_::*)()) > - ); > + // MSVC is capable of some kinds of SFINAE. If U is an incomplete > + // type, it won't pick the second overload > + static char tester(...); > + template > + static char(& tester(type_wrapper) )[sizeof(U) + 1]; > + > + BOOST_STATIC_CONSTANT( > + bool, value = sizeof(tester(type_wrapper())) == 1); > }; Clever! Some kinds of SFINAE make MSVC much more ICE-prone, though. I guess the regressions will show us if that's the case or not. Thanks for taking care of it! Aleksey From dave at boost-consulting.com Sun Aug 3 01:29:08 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Aug 2003 19:29:08 -0400 Subject: [C++-sig] Re: args patch In-Reply-To: <024001c35939$5aeff8b0$b344a8c0@metacomm.com> (Aleksey Gurtovoy's message of "Sat, 2 Aug 2003 16:02:16 -0500") References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> <024001c35939$5aeff8b0$b344a8c0@metacomm.com> Message-ID: Aleksey Gurtovoy writes: > David Abrahams wrote: >> >> I think msvc_is_incomplete::value would always be true. >> > >> > Yeah. Unfortunately, that's the only way I know to implement 'has_xxx' > on >> > MSVC so that it doesn't bark on incomplete types, and there is some code >> > around which relies on it. >> >> >> It seems to me that it can't know the answer for incomplete types, and >> therefore it shouldn't produce one - it should be an error. > > We don't really want that. Consider: > > #include > > // ... > typedef find_if< types, is_same<_1,std::iostream> >::type r; // error? > > >> How does the conforming version manage it? > > SFINAE-based version just works ('has_xxx' returns 'false'). So does my fix ;-> -- Dave Abrahams Boost Consulting www.boost-consulting.com From s_sourceforge at nedprod.com Sun Aug 3 01:31:56 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 00:31:56 +0100 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope In-Reply-To: References: <3F2C1CDF.26797.29B50CEC@localhost> (Niall Douglas's message of "Sat, 2 Aug 2003 20:19:43 +0100") Message-ID: <3F2C57FC.24151.2A9BF539@localhost> Nicodemus wrote: > Nice, I didn't know that either. I think this mirrors the enum > behaviour of C++ better. How should Pyste support this? I believe it > is more interesting if Pyste always called export_values(), but this > would break backwards compability. Thoughts? Command line switch. I'm pretty sure with time everyone will switch. > Niall, another solution would be to explicitly export the names to the > global namespace in the Python side (untested): > > # my_module.py > import _my_module # this is the extension module > > for name, value in _my_module.unnamed.__dict__: > globals()[name] = value It's alright - it's easier to customise pyste to make it do what I prefer now Dave has said how. BTW, did you receive my extensive list of bugs & ideas I sent to your email address? I even supplied fixes! :) Lastly, I just want to add what I'm doing for everyone's reference. I've spent the last week generating a SWIG solution and a boost.python based solution to try and evaluate which is the better for generating a set of bindings for my library TnFOX. Unfortunately, it would seem currently neither or else I'm missing something. TnFOX is composed of FOX and my extensions. FOX itself is pretty straightforward though its headers most unfortunately aren't standalone. My extensions aren't using as many fancy tricks as Boost, but they do use policies, embedded classes and various object semantics which wouldn't be considered vanilla C++ (and hence SWIG has a rotten time). Furthermore as I only recently learned what templates can do (I bought Alexandrescu's book), I'm expecting my usage of these new tricks to increase. Hence my instinct is telling me that Boost.Python is probably better in the long run. However, I am singularly failing thus far to get anything remotely resembling even a single working class - it's tempting to go back to writing more extensions, but shortly I'll be starting on the typelist based stuff and I wanted to see how the python bindings could cope first :-| Cheers, Niall From dave at boost-consulting.com Sun Aug 3 01:33:10 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Aug 2003 19:33:10 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F294F35.A6988D6A@sitius.com> <3F2C1453.255B036D@sitius.com> Message-ID: Nikolay Mladenov writes: > > I like it better. Please apply it. Already done. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sun Aug 3 03:47:33 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 2 Aug 2003 22:47:33 -0300 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope References: <3F2C1CDF.26797.29B50CEC@localhost> (Niall Douglas's message of "Sat, 2 Aug 2003 20:19:43 +0100") <3F2C57FC.24151.2A9BF539@localhost> Message-ID: <009f01c35961$360b8410$0101a8c0@sergio> ----- Original Message ----- From: "Niall Douglas" To: "pysig" Sent: Saturday, August 02, 2003 8:31 PM Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope > Nicodemus wrote: > > > Nice, I didn't know that either. I think this mirrors the enum > > behaviour of C++ better. How should Pyste support this? I believe it > > is more interesting if Pyste always called export_values(), but this > > would break backwards compability. Thoughts? > > Command line switch. I'm pretty sure with time everyone will switch. Agreed. > > Niall, another solution would be to explicitly export the names to the > > global namespace in the Python side (untested): > > > > # my_module.py > > import _my_module # this is the extension module > > > > for name, value in _my_module.unnamed.__dict__: > > globals()[name] = value > > It's alright - it's easier to customise pyste to make it do what I > prefer now Dave has said how. Indeed, it is easy enough to do so, just some hacking in EnumExporter.py. 8) > BTW, did you receive my extensive list of bugs & ideas I sent to your > email address? I even supplied fixes! :) Sorry, I think didn't get any email from you (I don't remember, and unfortunately I'm not at my computer right now to confirm 8( )... Anyway, could you send them again, please? Thanks a lot! 8) Regards, Nicodemus. From Paul_Kunz at SLAC.Stanford.EDU Sun Aug 3 02:49:14 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 02 Aug 2003 17:49:14 -0700 Subject: [C++-sig] numarray and boost.python Message-ID: <200308030049.h730nEr03106@libra3.slac.stanford.edu> I'm trying to make an interface between numarray and C++ with Boost. After reading the mail archives on this subject, I downloaded num_util from http://www.eos.ubc.ca/research/clouds/num_util.html Although the software is date 3 July 2003, I found I had to make two changes for it to compile... Index: python/num_util.cpp =================================================================== RCS file: /afs/slac/g/ek/reason_cvs/hippodraw/python/num_util.cpp,v retrieving revision 1.1 diff -r1.1 num_util.cpp 23c23 < KindStringMapEntry(PyArray_NTYPES, "PyArray_NTYPES"), --- > // KindStringMapEntry(PyArray_NTYPES, "PyArray_NTYPES"), Index: python/num_util.h =================================================================== RCS file: /afs/slac/g/ek/reason_cvs/hippodraw/python/num_util.h,v retrieving revision 1.2 diff -r1.2 num_util.h 5c5,6 < #include --- > /* #include */ > #include Could someone confirm that I'm on the right track or doing the wrong thing? From paustin at eos.ubc.ca Sun Aug 3 06:07:16 2003 From: paustin at eos.ubc.ca (Philip Austin) Date: Sat, 2 Aug 2003 21:07:16 -0700 Subject: [C++-sig] numarray and boost.python In-Reply-To: <200308030049.h730nEr03106@libra3.slac.stanford.edu> References: <200308030049.h730nEr03106@libra3.slac.stanford.edu> Message-ID: <16172.35444.946839.96988@gull.eos.ubc.ca> Paul F. Kunz writes: > I'm trying to make an interface between numarray and C++ with > Boost. After reading the mail archives on this subject, I downloaded > num_util from > > http://www.eos.ubc.ca/research/clouds/num_util.html > > Although the software is date 3 July 2003, I found I had to make two > changes for it to compile... Right, the boost numeric support can be toggled between Numeric and numarray using numeric::array::set_module_and_type Currently we set this to use Numeric in num_test_mod.cpp -- we'll switch to numarray after it includes support for object arrays (presumably this is coming in v. 0.7). Just to reiterate, boost::python and Numpy can be connected using boost::python::numeric::array without num_util, we are just providing some utility functions we find useful in our own code. Regards, Phil Voice: (604) 822-2175 Fax: (604) 822-6088 email: paustin at eos.ubc.ca Associate Professor Atmospheric Sciences Programme Department of Earth and Ocean Sciences The University of British Columbia 6339 Stores Road Vancouver, BC V6T 1Z4 From dave at boost-consulting.com Sun Aug 3 06:33:16 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 00:33:16 -0400 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope In-Reply-To: <3F2C57FC.24354.2A9BF6C0@localhost> (Niall Douglas's message of "Sun, 3 Aug 2003 00:31:56 +0100") References: <3F2C1CDF.26797.29B50CEC@localhost> <3F2C57FC.24354.2A9BF6C0@localhost> Message-ID: "Niall Douglas" writes: > On 2 Aug 2003 at 16:21, David Abrahams wrote: > >> If you're using Pyste, you *really* should post this to the C++-sig, >> since Nicodemus (the Pyste author) doesn't read my emails. > > I'm subscribed. I also have a bug for you (latest version of > boost.python off CVS): Please post bug reports to the C++-sig also. > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : error > C2678: binary '<<' : no operator found which takes a left-hand > operand of type 'const boost::python::detail::unwrap_other::type' > (or there is no acceptable conversion) > with > [ > T=boost::python::other > ] > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : > while compiling class-template member function 'PyObject > *boost::python::detail::operator_r::apply::execute(con > st R &,const L &)' > with > [ > > L=boost::python::detail::unwrap_other m>>::type, > R=FX::FXId > ] > d:\Tornado\TClient\boost\boost\python\operators.hpp(63) : see > reference to class template instantiation > 'boost::python::detail::operator_r::apply' being > compiled > with > [ > > L=boost::python::detail::unwrap_other m>>::type, > R=FX::FXId > ] > d:\Tornado\TClient\boost\boost\python\operators.hpp(107) : > see reference to class template instantiation > 'boost::python::detail::operator_r_inner' being compiled > with > [ > id=op_lshift, > > L=boost::python::detail::unwrap_other m>>::type, > R=FX::FXId > ] > d:\Tornado\TClient\boost\boost\python\class.hpp(330) : see > reference to class template instantiation > 'boost::python::detail::binary_op_r::apply' being compiled > with > [ > id=op_lshift, > > L=boost::python::detail::unwrap_other m>>::type, > T=FX::FXId > ] > d:\Tornado\TClient\TnFOX\pythonbinds\_tnfox.cpp(1846) : see > reference to function template instantiation > 'boost::python::class_::self > &boost::python::class_::def ::FXStream>,boost::python::self_ns::self_t>(const > boost::python::detail::operator_ &)' being compiled > with > [ > T=FX::FXId, > X1=boost::noncopyable, > X2=`anonymous-namespace'::FX_FXId_Wrapper, > id=op_lshift, > L=boost::python::other, > R=boost::python::self_ns::self_t > ] > > This results from a user defined << operator which pyste defined > using .def( other< FX::FXStream >() << self ). This appears to be > correct. What appears to be correct? > The same problem occurs for the >> operator and furthermore it seems > to happen with basic types as well as user defined ones (though > still working with FXStream). Removing them all makes the problem go > away :) Removing what makes the problem go away? What compiler are you using? Can you post a small reproducible test case? -- Dave Abrahams Boost Consulting www.boost-consulting.com From brett.calcott at paradise.net.nz Sun Aug 3 09:14:04 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 3 Aug 2003 17:14:04 +1000 Subject: [C++-sig] Re: Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> <026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: Is this patch MS version specific? Trying to build using VC7 from latest cvs with this patch: ...failed vc-C++ ..\..\..\libs\python\build\bin\boost_python.dll\msvc\debug\runtime-link-dyna mic\numeric.obj... vc-C++ ..\..\..\libs\python\build\bin\boost_python.dll\msvc\debug\runtime-link-dyna mic\list.obj list.cpp X:/boost/boost/mpl/aux_/has_xxx.hpp|80 error 2988| unrecognizable template declaration/definition X:/boost/boost/mpl/aux_/has_xxx.hpp|84| see reference to class template instantiation 'boost::mpl::aux::msvc_is_incomplete' being compiled X:/boost/boost/mpl/aux_/has_xxx.hpp|80 error 2059| syntax error : '' X:/boost/boost/mpl/aux_/has_xxx.hpp|82 error 2332| 'enum' : missing tag name X:/boost/boost/mpl/aux_/has_xxx.hpp|82 error 2238| unexpected token(s) preceding ';' From dave at boost-consulting.com Sun Aug 3 13:48:45 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 07:48:45 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> <026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: "Brett Calcott" writes: > Is this patch MS version specific? > > Trying to build using VC7 from latest cvs with this patch: > > > ...failed vc-C++ > ..\..\..\libs\python\build\bin\boost_python.dll\msvc\debug\runtime-link-dyna > mic\numeric.obj... > vc-C++ > ..\..\..\libs\python\build\bin\boost_python.dll\msvc\debug\runtime-link-dyna > mic\list.obj > list.cpp > X:/boost/boost/mpl/aux_/has_xxx.hpp|80 error 2988| unrecognizable template > declaration/definition > X:/boost/boost/mpl/aux_/has_xxx.hpp|84| see reference to class > template instantiation 'boost::mpl::aux::msvc_is_incomplete' being > compiled > X:/boost/boost/mpl/aux_/has_xxx.hpp|80 error 2059| syntax error : ' Parse>' > X:/boost/boost/mpl/aux_/has_xxx.hpp|82 error 2332| 'enum' : missing tag name > X:/boost/boost/mpl/aux_/has_xxx.hpp|82 error 2238| unexpected token(s) > preceding ';' Fixed now, sorry. -- Dave Abrahams Boost Consulting www.boost-consulting.com From s_sourceforge at nedprod.com Sun Aug 3 16:19:28 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 15:19:28 +0100 Subject: [C++-sig] Re: Boost.Python unnamed enums at global scope In-Reply-To: References: <3F2C57FC.24354.2A9BF6C0@localhost> (Niall Douglas's message of "Sun, 3 Aug 2003 00:31:56 +0100") Message-ID: <3F2D2800.26671.2DC883D7@localhost> On 3 Aug 2003 at 0:33, David Abrahams wrote: > > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : error > > C2678: binary '<<' : no operator found which takes a left-hand > > operand of type 'const boost::python::detail::unwrap_other::type' > > (or there is no acceptable conversion) > > with > > [ > > T=boost::python::other > > ] > > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : > > while compiling class-template member function 'PyObject > > *boost::python::detail::operator_r::apply::execute(c > > on st R &,const L &)' > > with > > [ > > > > L=boost::python::detail::unwrap_other > ea m>>::type, > > R=FX::FXId > > ] > > d:\Tornado\TClient\boost\boost\python\operators.hpp(63) : > > see > > reference to class template instantiation > > 'boost::python::detail::operator_r::apply' being > > compiled > > with > > [ > > > > L=boost::python::detail::unwrap_other > ea m>>::type, > > R=FX::FXId > > ] > > d:\Tornado\TClient\boost\boost\python\operators.hpp(107) : > > see reference to class template instantiation > > 'boost::python::detail::operator_r_inner' being compiled > > with > > [ > > id=op_lshift, > > > > L=boost::python::detail::unwrap_other > ea m>>::type, > > R=FX::FXId > > ] > > d:\Tornado\TClient\boost\boost\python\class.hpp(330) : see > > reference to class template instantiation > > 'boost::python::detail::binary_op_r::apply' being compiled > > with > > [ > > id=op_lshift, > > > > L=boost::python::detail::unwrap_other > ea m>>::type, > > T=FX::FXId > > ] > > d:\Tornado\TClient\TnFOX\pythonbinds\_tnfox.cpp(1846) : see > > reference to function template instantiation > > 'boost::python::class_::self > > &boost::python::class_::def > FX ::FXStream>,boost::python::self_ns::self_t>(const > > boost::python::detail::operator_ &)' being compiled > > with > > [ > > T=FX::FXId, > > X1=boost::noncopyable, > > X2=`anonymous-namespace'::FX_FXId_Wrapper, > > id=op_lshift, > > L=boost::python::other, > > R=boost::python::self_ns::self_t > > ] > > > > This results from a user defined << operator which pyste defined > > using .def( other< FX::FXStream >() << self ). This appears to be > > correct. > > What appears to be correct? How pyste has generated the << operator specification ie; I'm saying pyste appears to be generating the right code. > > The same problem occurs for the >> operator and furthermore it seems > > to happen with basic types as well as user defined ones (though > > still working with FXStream). Removing them all makes the problem go > > away :) > > Removing what makes the problem go away? The definition ie; remove all overloads of the << and >> operators. > What compiler are you using? MSVC7.1 > Can you post a small reproducible test case? I'll get onto it. Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 3 17:45:11 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 16:45:11 +0100 Subject: [C++-sig] Failure to deduce template argument types Message-ID: <3F2D3C17.24124.2E16FF13@localhost> What's going on here? (MSVC7.1): d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector17 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14) volatile)' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17) volatile' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector17 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14) const)' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17) const' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector17 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14))' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17)' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector16 boost::python::detail::get_signature(RT (__cdecl *)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14))' : could not deduce template argument for 'T1 (__cdecl *)(T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16)' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(89) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector16 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13) volatile const)' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16) volatile const' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector16 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13) volatile)' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16) volatile' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector16 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13) const)' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16) const' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector16 boost::python::detail::get_signature(RT (__thiscall ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13))' : could not deduce template argument for 'T1 (__thiscall T2::* )(T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16)' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(111) : see declaration of 'boost::python::detail::get_signature' d:\Tornado\TClient\boost\boost\python\make_function.hpp(95) : error C2784: 'boost::mpl::vector15 boost::python::detail::get_signature(RT (__cdecl *)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13))' : could not deduce template argument for 'T1 (__cdecl *)(T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15)' from 'FX::FXuint (__cdecl *)(FX::FXWindow *,FX::FXuint,const char *,const char *,...)' d:\Tornado\TClient\boost\boost\python\signature.hpp(89) : see declaration of 'boost::python::detail::get_signature' <... keeps going and going removing the last Tx (eg; vector15, vector14, vector13 etc) from each error ...> Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 3 17:45:11 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 16:45:11 +0100 Subject: [C++-sig] 64 bit integer bug in pyste Message-ID: <3F2D3C17.6006.2E16FDB5@localhost> When using 64 bit integers, GCCXML reports long long. Under MSVC this should be __int64. You could use instead BOOST_PYTHON_LONG_LONG which resolves on all platforms. Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 3 17:45:10 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 16:45:10 +0100 Subject: [C++-sig] Boost.Python << & >> bug Message-ID: <3F2D3C16.13081.2E16FAD0@localhost> The following section of this message contains a file attachment prepared for transmission using the Internet MIME message format. If you are using Pegasus Mail, or any another MIME-compliant system, you should be able to save it or view it from within your mailer. If you cannot, please ask your system administrator for assistance. ---- File information ----------- File: Test.cpp Date: 3 Aug 2003, 16:29 Size: 2899 bytes. Type: Program-source -------------- next part -------------- A non-text attachment was scrubbed... Name: Test.cpp Type: application/octet-stream Size: 2899 bytes Desc: not available URL: From s_sourceforge at nedprod.com Sun Aug 3 17:45:10 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 16:45:10 +0100 Subject: [C++-sig] Boost.Python << & >> bug Message-ID: <3F2D3C16.5165.2E16FB3E@localhost> On 3 Aug 2003 at 15:14, c++-sig at python.org wrote: Enclosed is the condensed example as requested. There are actually two bugs but I think the first (the original) is the same as the second - comment out the FXId one to see the second. What's happening IMHO is that boost.python's wrappings of user types are failing to cast down to their containing types so therefore the compiler gets confused. Hence the error message from before. The second bug is similar (MSVC7.1 report): d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'const FX::FXStream' (or there is no acceptable conversion) d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : while compiling class-template member function 'PyObject *boost::python::detail::operator_l::apply::execute(con st L &,const R &)' with [ L=FX::FXStream, R=boost::python::detail::unwrap_other>::type ] Here because FXStream does not provide an overload for anything in boost, it can't know it's really an unsigned char. Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 3 17:45:10 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 16:45:10 +0100 Subject: [C++-sig] (Fwd) Previous email to Nicodemus Message-ID: <3F2D3C16.27885.2E16FC9C@localhost> ------- Forwarded message follows ------- From: Niall Douglas To: xxxxxxxx at xxxxxxxxx.com.br Subject: Whoops, found newer version of pyste! Date sent: Sat, 2 Aug 2003 20:16:50 +0100 Hi again, Sorry, it only occurred to me after sending the previous email that Boost was probably on CVS. However, the latest version still has the problem with passing backslashes to Win32 GCCXML. It's GCCXML that barfs (and I got the precompiled binary off its web site). Also, unnamed enums don't trap properly, at least here. Changing the line in EnumExporters.Export to: if rename[0:2] == "$_" or rename == '._0': This fixes it. I've looked through the Boost.Python source and I think the changes necessary to make passing "" as the scope name to enter into the upper-most scope are probably quite easy. I'll send an email to Dave Abrahams and see what he says. Next extension: my .pyste file is actually a full blown script which reads the contents of a directory for the header files and then dynamically creates the variable = AllFromHeader(filepath). Hence it needs to know where it lives which currently it can't. I propose adding the following to pyste.py: def CreateContext(interfacepath): 'create the context where a interface file will be executed' context = {} # location context['mylocation'] = interfacepath # infos ... and simply have CreateContext()'s invocation also pass the path of the .pyste file. Now the .pyste file knows where it is, which will be relative to where the header files will be. Next idea: couldn't pyste automatically recognise properties via a get/set method combo and use .add_property()? It would need to be optional on the command line because some people would consider it too dissimilar from the C++ library original. Next point: pyste seems to want inherited members return policy set for each and every subclass. So if I bind FXWindow and FXTopWindow which inherits FXTopWindow, I must reapply set_policy() for all FXTopWindow's inherited methods from FXWindow. To be honest, this doesn't bother me too much because you can create functions in the .pyste file called applyFXWindow(var) and applyFXTopWindow(var) and the latter simply calls applyFXWindow() on its var before adding its own unique stuff - unfortunately in this case pyste adds too many definitions of BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for the same class. Anyway, I just wanted to say that the new version is much better and my thanks to you for it. Time for bed now :) Cheers, Niall ------- End of forwarded message ------- ------- End of forwarded message ------- From nicodemus at globalite.com.br Sun Aug 3 18:06:06 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 3 Aug 2003 13:06:06 -0300 Subject: [C++-sig] (Fwd) Previous email to Nicodemus References: <3F2D3C16.27885.2E16FC9C@localhost> Message-ID: <001f01c359d9$28512e10$0101a8c0@sergio> Yeah, I didn't got this email before. 8) Thanks for sending again. ----- Original Message ----- From: "Niall Douglas" To: Sent: Sunday, August 03, 2003 12:45 PM Subject: [C++-sig] (Fwd) Previous email to Nicodemus > Hi again, > > However, the latest version still has the problem with passing > backslashes to Win32 GCCXML. It's GCCXML that barfs (and I got the > precompiled binary off its web site). Yes, GCCXML expects forward slashes only. Does this trouble you? > Also, unnamed enums don't trap properly, at least here. Changing the > line in EnumExporters.Export to: > > if rename[0:2] == "$_" or rename == '._0': Hmm, I see. There's no documentation avaiable for GCCXML, so it is kind of a mistery to predict all the weird names that it assigns for unnamed enums. 8) Thanks! > I've looked through the Boost.Python source and I > think the changes necessary to make passing "" as the scope name to > enter into the upper-most scope are probably quite easy. I'll send an > email to Dave Abrahams and see what he says. Yes, I believe you mean export_values(). > Next extension: my .pyste file is actually a full blown script which > reads the contents of a directory for the header files and then > dynamically creates the variable = AllFromHeader(filepath). Nice. That's an advantage of they being python scripts. 8) > Hence it needs to know where it lives which currently it can't. I propose > adding the following to pyste.py: > > def CreateContext(interfacepath): > 'create the context where a interface file will be executed' > context = {} > # location > context['mylocation'] = interfacepath > # infos > > ... and simply have CreateContext()'s invocation also pass the path > of the .pyste file. Now the .pyste file knows where it is, which will > be relative to where the header files will be. I see your problem, but I find the solution kind of a "hack". Have you tried if sys.path[0] gives the directory where the pyste file is? If it doesn't, I think we will have to use this solution, but I prefer following the upper-case conventin for constants: INTERFACE_PATH or something like that. > Next idea: couldn't pyste automatically recognise properties via a > get/set method combo and use .add_property()? It would need to be > optional on the command line because some people would consider it > too dissimilar from the C++ library original. Certainly, and should be easy enough to do. I think a command line is not necessary, because we can always expose the get/set methods and the properties. This will have to wait a little though, because I have lots of fixes to make in Pyste as it is. 8) > Next point: pyste seems to want inherited members return policy set > for each and every subclass. So if I bind FXWindow and FXTopWindow > which inherits FXTopWindow, I must reapply set_policy() for all > FXTopWindow's inherited methods from FXWindow. I think you mistake the classes in this example. Could you clarify? > Anyway, I just wanted to say that the new version is much better and > my thanks to you for it. Time for bed now :) Thanks, and thanks for your feedback! Regards, Nicodemus. From dave at boost-consulting.com Sun Aug 3 19:31:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 13:31:40 -0400 Subject: [C++-sig] Re: Failure to deduce template argument types References: <3F2D3C17.24124.2E16FF13@localhost> Message-ID: "Niall Douglas" writes: > What's going on here? (MSVC7.1): How many arguments to the function you're wrapping? See file:///C:/boost/libs/python/doc/v2/configuration.html#app-defined -- Dave Abrahams Boost Consulting www.boost-consulting.com From s_sourceforge at nedprod.com Sun Aug 3 21:43:39 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 20:43:39 +0100 Subject: [C++-sig] (Fwd) Previous email to Nicodemus In-Reply-To: <001f01c359d9$28512e10$0101a8c0@sergio> Message-ID: <3F2D73FB.18840.2EF1541A@localhost> On 3 Aug 2003 at 13:06, Nicodemus wrote: > Yeah, I didn't got this email before. 8) > Thanks for sending again. It seems then that there's something wrong with email between us. Maybe your email system thinks I'm spam? ;) > > However, the latest version still has the problem with passing > > backslashes to Win32 GCCXML. It's GCCXML that barfs (and I got the > > precompiled binary off its web site). > > Yes, GCCXML expects forward slashes only. Does this trouble you? Absolutely. On Win32 GCCXML dies a very horrible death if there is a single backslash in its command line. Since pyste takes backslashes in its input off its command line, this creates a problem eg; me passing command line variables to pyste which obviously would contain backslashes. Why on earth couldn't DOS just have taken normal slashes! :( > Hmm, I see. There's no documentation avaiable for GCCXML, so it is > kind of a mistery to predict all the weird names that it assigns for > unnamed enums. 8) Thanks! Not really. GCC itself allocates temporary symbols starting with $. That's why you can't use $ in your own symbol names on most systems. You can see plenty more if you investigate the embedded assembler in GCC. > > Next extension: my .pyste file is actually a full blown script which > > reads the contents of a directory for the header files and then > > dynamically creates the variable = AllFromHeader(filepath). > > Nice. That's an advantage of they being python scripts. 8) It's why python's great! I haven't had so much fun programming in it since BBC Basic V on the Acorn Archimedes (a wonderful system for its day)! A marriage between my C++ and python environments would be ideal ... at least till I get some time to write the lazy functional language I've always wanted to write (Haskell's too esoteric). > I see your problem, but I find the solution kind of a "hack". Have you > tried if sys.path[0] gives the directory where the pyste file is? If > it doesn't, I think we will have to use this solution, but I prefer > following the upper-case conventin for constants: Err, doesn't sys.path refer to the script which invoked python? I think so. Anyway, anything execfile'd is considered not standalone as far as I understand ie; it merely reads the file into a string and compiles that to a code object ie; it's no different from exec. Anyway I've not tried it, and don't have enough experience with python to say for sure, so I'll shut up now :) > > Next point: pyste seems to want inherited members return policy set > > for each and every subclass. So if I bind FXWindow and FXTopWindow > > which inherits FXTopWindow, I must reapply set_policy() for all > > FXTopWindow's inherited methods from FXWindow. > > I think you mistake the classes in this example. Could you clarify? class FXTopWindow : public FXWindow // in FXTopWindow.h { FXObject *foo2(); } class FXWindow // in FXWindow.h { FXObject *foo(); }; If I do AllFromHeader on FXTopWindow.h, it pulls in all the base classes of FXTopWindow (correctly) and then asks for you to set the return policies of foo() and foo2(). Now if I'm also doing FXAllFromHeader on FXWindow.h in the same pyste file, it'll want a return policy set on foo(). My point is that if you've already set the policy for foo() in FXWindow, you also set the policy for all inherited versions of foo() in all subclasses of FXWindow (because apart from covariant return, return types must stay identical in overloads in C++). Therefore you shouldn't need to set it again (except that pyste does actually want you to). Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 3 21:52:56 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 3 Aug 2003 20:52:56 +0100 Subject: [C++-sig] Re: Failure to deduce template argument types In-Reply-To: Message-ID: <3F2D7628.3245.2EF9D306@localhost> On 3 Aug 2003 at 13:31, David Abrahams wrote: > "Niall Douglas" writes: > > > What's going on here? (MSVC7.1): > > How many arguments to the function you're wrapping? 15, which is exactly the limit. Is the limit inclusive or exclusive? I'll probably find out quicker by recompiling. BTW my inheritence depth exceeds 10. But I assume the limit refers to most classes which can be multiply inherited at one go? Cheers, Niall From dave at boost-consulting.com Mon Aug 4 03:12:10 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 21:12:10 -0400 Subject: [C++-sig] Re: Failure to deduce template argument types References: <3F2D7628.3245.2EF9D306@localhost> Message-ID: "Niall Douglas" writes: > On 3 Aug 2003 at 13:31, David Abrahams wrote: > >> "Niall Douglas" writes: >> >> > What's going on here? (MSVC7.1): >> >> How many arguments to the function you're wrapping? > > 15, which is exactly the limit. Is the limit inclusive or exclusive? > I'll probably find out quicker by recompiling. Don't forget that if it's a member function there's a hidden "this" argument. > > BTW my inheritence depth exceeds 10. But I assume the limit refers to > most classes which can be multiply inherited at one go? Yes. There's no inheritance depth limit. -- Dave Abrahams Boost Consulting www.boost-consulting.com From brett.calcott at paradise.net.nz Mon Aug 4 03:17:04 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Mon, 4 Aug 2003 11:17:04 +1000 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com><3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com><026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: > Fixed now, sorry. > Not checked in though? Head is still this: ---------------------------- revision 1.17 date: 2003/08/02 15:58:44; author: david_abrahams; state: Exp; lines: +11 -7 Improved the incomplete type detection workaround for MSVC. It now works even with the /vmg switch which makes all member pointers the same size. ---------------------------- From dave at boost-consulting.com Mon Aug 4 03:22:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 21:22:57 -0400 Subject: [C++-sig] Re: Boost.Python << & >> bug References: <3F2D3C16.13081.2E16FAD0@localhost> Message-ID: "Niall Douglas" writes: > // Comment out this for bug no. 2 > scope* FX_FXId_scope = new scope( > class_< FX::FXId >("FXId", no_init) > .def( other< FX::FXStream >() << self ) > .def( other< FX::FXStream >() >> self ) > ); Niall, Why are you dynamically allocating (and leaking) scope objects? That's very bad juju (but probably has nothing to do with your other problems). -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 4 03:41:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 21:41:23 -0400 Subject: [C++-sig] Re: Boost.Python << & >> bug References: <3F2D3C16.5165.2E16FB3E@localhost> Message-ID: "Niall Douglas" writes: > On 3 Aug 2003 at 15:14, c++-sig at python.org wrote: > > Enclosed is the condensed example as requested. I assume you're referring to the enclosure in the other message? > There are actually > two bugs but I think the first (the original) is the same as the > second - comment out the FXId one to see the second. It's not clear what you want me to comment out. Please next time include a preprocessor directive which makes the change #ifdef BUG1 ... #else ... #endif > What's happening IMHO is that boost.python's wrappings of user types > are failing to cast down to their containing types I don't know what that means. > so therefore the compiler gets confused. Hence the error message > from before. No this is a failure of your wrapping code. Very simply, class_< FX::FXId >("FXId", no_init) .def( other< FX::FXStream >() << self ) .def( other< FX::FXStream >() >> self ) Attempts to wrap two operator expressions which take an FXStream on the lhs and and FXId on the rhs. But you don't have anything which would match those expressions. Try it: // C++ code FXStream x; FXId y; x << y; // <== error friend FX::FXStream& operator<<(FX::FXStream& store,const FXId* obj){return store;} friend FX::FXStream& operator>>(FX::FXStream& store,FXId*& obj){return store;} These declare operators which take an FXId* on the rhs: x << &y; > The second bug is similar (MSVC7.1 report): > > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : error > C2678: binary '<<' : no operator found which takes a left-hand > operand of type 'const FX::FXStream' (or there is no acceptable > conversion) > d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : > while compiling class-template member function 'PyObject > *boost::python::detail::operator_l::apply::execute(con > st L &,const R &)' > with > [ > L=FX::FXStream, > > R=boost::python::detail::unwrap_other char>>::type > ] > > Here because FXStream does not provide an overload for anything in > boost, it can't know it's really an unsigned char. I don't know what that means either. The problem you're seeing above may be due to a documentation bug on my part. These operator wrapping facilities are only suitable for wrapping operators which work on rvalue arguments. If you want to wrap your operators which work on non-const lvalues, you should write something more like: FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; ... .def('__lshift__', pmf, return_self()); FWIW, Wrapping all these different operators for lots of different integer types is probably a waste of time because Python only has one int type. Wrapping overloads on int and ushort, for example, is redundant. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dawson at physics.uq.edu.au Mon Aug 4 03:55:05 2003 From: dawson at physics.uq.edu.au (Christopher Dawson) Date: Mon, 04 Aug 2003 11:55:05 +1000 Subject: [C++-sig] Subscript Operators In-Reply-To: References: <3F2D3C16.13081.2E16FAD0@localhost> Message-ID: <3F2DBCF9.6000404@physics.uq.edu.au> Hi there, I am attempting to wrap a Matrix class using Boost::Python, for the most part it has been pleasantly easy. However I have been unable to wrap the subscripting operator (int,int) to something similar in python. Is this currently possible and if so can anyone help? Regards, Chris. From dave at boost-consulting.com Mon Aug 4 05:07:05 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 23:07:05 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> <026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: "Brett Calcott" writes: >> Fixed now, sorry. >> > > Not checked in though? > > Head is still this: > > ---------------------------- > revision 1.17 > date: 2003/08/02 15:58:44; author: david_abrahams; state: Exp; lines: > +11 -7 > Improved the incomplete type detection workaround for MSVC. It now > works even with the /vmg switch which makes all member pointers the > same size. > ---------------------------- I beg to differ: ---------------------------- revision 1.18 date: 2003/08/03 11:48:55; author: david_abrahams; state: Exp; lines: +15 -1 Workaround for a heinous vc7 bug ---------------------------- Index: has_xxx.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/mpl/aux_/has_xxx.hpp,v retrieving revision 1.17 retrieving revision 1.18 diff -w -u -c -w -u -r1.17 -r1.18 cvs server: conflicting specifications of output style cvs server: conflicting specifications of output style --- has_xxx.hpp 2 Aug 2003 15:58:44 -0000 1.17 +++ has_xxx.hpp 3 Aug 2003 11:48:55 -0000 1.18 @@ -70,14 +70,28 @@ struct has_xxx_tag; +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + template + struct msvc_incomplete_array + { + typedef char (&type)[sizeof(U) + 1]; + }; +# endif + template struct msvc_is_incomplete { // MSVC is capable of some kinds of SFINAE. If U is an incomplete // type, it won't pick the second overload static char tester(...); + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + template + static typename msvc_incomplete_array::type tester(type_wrapper); +# else template static char(& tester(type_wrapper) )[sizeof(U) + 1]; +# endif BOOST_STATIC_CONSTANT( bool, value = sizeof(tester(type_wrapper())) == 1); -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 4 05:10:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Aug 2003 23:10:29 -0400 Subject: [C++-sig] Re: Boost.Python << & >> bug References: <3F2D3C16.5165.2E16FB3E@localhost> Message-ID: David Abrahams writes: > The problem you're seeing above may be due to a documentation bug on > my part. These operator wrapping facilities are only suitable for > wrapping operators which work on rvalue arguments. If you want to > wrap your operators which work on non-const lvalues, you should write > something more like: > > FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; > > ... > .def('__lshift__', pmf, return_self()); Hmm, I could change those wrappers so that the "self" argument was required to be an lvalue. That would preclude implicit conversions to the self type from being used, but it would allow the self object to be mutated by the call. I doubt it would break any real code. Thoughts from the group? -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Mon Aug 4 09:36:43 2003 From: romany at actimize.com (Roman Yakovenko) Date: Mon, 4 Aug 2003 10:36:43 +0300 Subject: [C++-sig] a few questions about properties Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027AFF@exchange.adrembi.com> Hi. For all question I will introduce here I find solution. But I don't fill good with them. So... struct CConst { private: explicit CConst( int i ) : m_value(i){}; public: const static CConst const_1; const static CConst const_2; int get_value() const { return m_value; } const int& get_value_by_ref() const { return m_value; } private: int m_value; }; const CConst CConst::const_1(1); const CConst CConst::const_2(2); const CConst& get_const_1() { return CConst::const_1; } const CConst& get_const_2() { return CConst::const_2; } BOOST_PYTHON_MODULE(py_smart_const) { class_( "CConst", no_init ) .add_property( "value", &CConst::get_value ) //error .add_property( "value", &CConst::get_value_by_ref ) .def( "const_1", &get_const_1, return_value_policy< reference_existing_object >() ) .staticmethod("const_1") .def( "const_2", &get_const_2, return_value_policy< reference_existing_object >() ) .staticmethod("const_2"); } The first question is how can I add class property? In my example I write 2 functions get_const_1 and get_const_2 and also I get staticmethod and not class property. The second one is how can I specify property return value policy? In my example .add_property( "value", &CConst::get_value_by_ref ) will not compile with error specify_a_return_value_policy_to_wrap_functions_returning. I think that there is no special reason ( except luck of time ), am I right? Thanks. Roman. From brett.calcott at paradise.net.nz Mon Aug 4 09:53:21 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Mon, 4 Aug 2003 17:53:21 +1000 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2527FC.50969E27@sitius.com> <3F2556E3.3F4C0A8C@sitius.com><3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com><00f501c358c6$b8946e10$b344a8c0@metacomm.com><026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: > > I beg to differ: > ---------------------------- > revision 1.18 > date: 2003/08/03 11:48:55; author: david_abrahams; state: Exp; lines: +15 -1 > Workaround for a heinous vc7 bug > ---------------------------- weird. I saved the output of cvs log command, and it definitely had 1.17 as the head this morning (GMT+10). X:\boost\boost\mpl\aux_>ls -l temp -rw-rw-rw- 1 user group 3501 Aug 4 11:15 temp X:\boost\boost\mpl\aux_>cat temp RCS file: /cvsroot/boost/boost/boost/mpl/aux_/has_xxx.hpp,v Working file: has_xxx.hpp head: 1.17 ... It doesn't now though. Thanks, Brett From pierre.barbier at cirad.fr Mon Aug 4 10:15:07 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Mon, 04 Aug 2003 10:15:07 +0200 Subject: [C++-sig] Re: cvs anonymous user access denied In-Reply-To: References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027AFC@exchange.adrembi.com> Message-ID: <3F2E160B.2000804@cirad.fr> As there are problems with the CVS version right now, I'm trying to get the nightly tarball's in order to check my directories (it's too slow to do this using the web browsing CVS interface) but I can't get any of these thow ! When trying to get the sourceforge one, I get a "404: Not Found" error, and when trying to get the boost-consulting tgz, I get a "403: Forbidden" error. David Abrahams wrote: >Alternatively, you can download last night's CVS tarball and use >local CVS on your machine: > > http://cvs.sourceforge.net/cvstarballs/boost-cvsroot.tar.gz > >or, from two nights ago: > > http://www.boost-consulting.com/boost-cvsroot.tar.gz > >Good luck, > > -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77 fax : (33) 4 67 61 56 68 From dave at boost-consulting.com Mon Aug 4 13:44:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 07:44:20 -0400 Subject: [C++-sig] Re: args patch References: <3F2440E7.C2000F56@sitius.com> <3F2556E3.3F4C0A8C@sitius.com> <3F25D683.B25CBCAF@sitius.com> <3F2939B0.4B8047E8@sitius.com> <3F29514D.506729DF@sitius.com> <3F296B6B.BDB7991A@sitius.com> <3F2AD732.A94E2127@sitius.com> <00f501c358c6$b8946e10$b344a8c0@metacomm.com> <026801c3593b$5a0845e0$b344a8c0@metacomm.com> Message-ID: "Brett Calcott" writes: >> >> I beg to differ: >> ---------------------------- >> revision 1.18 >> date: 2003/08/03 11:48:55; author: david_abrahams; state: Exp; lines: > +15 -1 >> Workaround for a heinous vc7 bug >> ---------------------------- > > > weird. I saved the output of cvs log command, and it definitely had 1.17 as > the head this morning (GMT+10). > > X:\boost\boost\mpl\aux_>ls -l temp > -rw-rw-rw- 1 user group 3501 Aug 4 11:15 temp > > X:\boost\boost\mpl\aux_>cat temp > > RCS file: /cvsroot/boost/boost/boost/mpl/aux_/has_xxx.hpp,v > Working file: has_xxx.hpp > head: 1.17 > ... > > > It doesn't now though. For the rest of this month, the anonymous CVS is about 24 hours behind the developer CVS, FWIW. -- Dave Abrahams Boost Consulting www.boost-consulting.com From pierre.barbier at cirad.fr Mon Aug 4 15:16:39 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Mon, 04 Aug 2003 15:16:39 +0200 Subject: [C++-sig] Two patches for g++-3.2 Message-ID: <3F2E5CB7.4050107@cirad.fr> Hi, the latest CVS version of boost did not compile with g++-3.2. There were an error in the MPL with the forward definition of the quote3 template class. I found a patch that works fine with g++-3.2 and should work with other compiler. Another problem was in cast.hpp in which g++ complained about a too big integer to be signed. I modified the line according to what's written in /usr/include/stdint.h on my linux distribution. And now there is no more error, and it still should be compatible with every compiler. I hope I didn't make any mistake ... -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77 fax : (33) 4 67 61 56 68 -------------- next part -------------- A non-text attachment was scrubbed... Name: patch_if.hpp Type: text/x-c++hdr Size: 383 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: patch_cast.hpp Type: text/x-c++hdr Size: 340 bytes Desc: not available URL: From dave at boost-consulting.com Mon Aug 4 17:49:32 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 11:49:32 -0400 Subject: [C++-sig] Anonymous CVS mirror Message-ID: After several days of work, there is now an anonymous mirror of our CVS repository, decompressed each night from the current SourceForge CVS tarball: cvs -d :pserver:anonymous at boost-consulting.com:/boost login cvs -d :pserver:anonymous at boost-consulting.com:/boost co boost Enjoy, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 4 17:52:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 11:52:43 -0400 Subject: [C++-sig] Re: Two patches for g++-3.2 References: <3F2E5CB7.4050107@cirad.fr> Message-ID: Pierre Barbier de Reuille writes: > Hi, > > the latest CVS version of boost did not compile with g++-3.2. There > were an error in the MPL with the forward definition of the quote3 > template class. > I found a patch that works fine with g++-3.2 and should work with > other compiler. > > Another problem was in cast.hpp in which g++ complained about a too > big integer to be signed. I modified the line according to what's > written in /usr/include/stdint.h on my linux distribution. And now > there is no more error, and it still should be compatible with every > compiler. > > I hope I didn't make any mistake ... The first fix doesn't work; I checked in something better. Thanks for the second; that warning's been bothering me! -- Dave Abrahams Boost Consulting www.boost-consulting.com From abeyer at uni-osnabrueck.de Mon Aug 4 18:18:52 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Mon, 4 Aug 2003 18:18:52 +0200 (CEST) Subject: [C++-sig] Python 2.3 Message-ID: <1536.192.124.248.20.1060013932.squirrel@webmail.rz.uni-osnabrueck.de> I am trying to use Boost.Python 1.30.0 with Python 2.3 under Windows XP. I have successfully built the Boost.Python lib with MinGW for Python 2.2.3, but I failed for 2.3. Of course, I have set the PYTHON_ROOT and PYTHON_VERSION variables for the new version. Has anyone else encountered problems when compiling Boost.Python for Python 2.3? Here are the details (using Bjam 3.1.4): g++ -c -Wall -ftemplate-depth-100 -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -g -O0 -fn o-inline -I"..\..\..\libs\python\build" -isystem "C:\boost_1_30_0" -isystem "C:\Python23\include" -o "..\..\..\libs\python\build\bin\boost_python.dll\mingw\debug\runtime-link-dynamic\numeric.obj" "..\..\..\libs\python\build\../src\numeric.cpp" mingw-C++-action ..\..\..\libs\python\build\bin\boost_python.dll\mingw\debug\runtime-link-dynamic\numeric.obj In file included from C:/boost_1_30_0/boost/python/converter/arg_to_python.hpp:18, from C:/boost_1_30_0/boost/python/call.hpp:14, from C:/boost_1_30_0/boost/python/object_core.hpp:14, from C:/boost_1_30_0/boost/python/object.hpp:9, from C:/boost_1_30_0/boost/python/tuple.hpp:9, from C:/boost_1_30_0/boost/python/numeric.hpp:9, from ../../../libs/python/src/numeric.cpp:7: C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `&' token C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: syntax error before `&' token C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `const' C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: syntax error before `const' C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `>' token [... and so on ...] From conanb at STCG.net Mon Aug 4 19:25:49 2003 From: conanb at STCG.net (Conan Brink) Date: Mon, 4 Aug 2003 10:25:49 -0700 Subject: [C++-sig] Python 2.3 Message-ID: Python 2.3 changed the name of LONG_LONG to PY_LONG_LONG. Option 1: I solved this in my local copy of 1.30.0 by checking the python version, and if it is >= 2.3, I use PY_LONG_LONG, and if it is < 2.3, I use LONG_LONG. So my lines 103-106 of boost/python/converter/builtin_converters.hpp have been replaced by the following eight lines (apologies if this lousy mail client has messed up the formatting): # ifdef HAVE_LONG_LONG # if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x)) # else BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed PY_LONG_LONG, PyLong_FromLongLong(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned PY_LONG_LONG, PyLong_FromUnsigned # endif # endif Similar changes then become required in libs/python/src/converter/builtin_converters.cpp and libs/python/test/test_builtin_converters.cpp Option 2: You could #define LONG_LONG as PY_LONG_LONG if your python version is >= 2.3 (or, alternatively, #define PY_LONG_LONG to be LONG_LONG if your version is < 2.3, and then also change all other occurrences of LONG_LONG to PY_LONG_LONG). Option 3: The CVS version of Boost.Python introduces BOOST_PYTHON_LONG_LONG, which then frees you from having to care about which version of Python you're using (for this particular issue). -Conan -----Original Message----- From: abeyer at uni-osnabrueck.de [mailto:abeyer at uni-osnabrueck.de] Sent: Monday, August 04, 2003 9:19 AM To: c++-sig at python.org Subject: [C++-sig] Python 2.3 I am trying to use Boost.Python 1.30.0 with Python 2.3 under Windows XP. I have successfully built the Boost.Python lib with MinGW for Python 2.2.3, but I failed for 2.3. Of course, I have set the PYTHON_ROOT and PYTHON_VERSION variables for the new version. Has anyone else encountered problems when compiling Boost.Python for Python 2.3? Here are the details (using Bjam 3.1.4): g++ -c -Wall -ftemplate-depth-100 -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -g -O0 -fn o-inline -I"..\..\..\libs\python\build" -isystem "C:\boost_1_30_0" -isystem "C:\Python23\include" -o "..\..\..\libs\python\build\bin\boost_python.dll\mingw\debug\runtime-lin k-dynamic\numeric.obj" "..\..\..\libs\python\build\../src\numeric.cpp" mingw-C++-action ..\..\..\libs\python\build\bin\boost_python.dll\mingw\debug\runtime-link -dynamic\numeric.obj In file included from C:/boost_1_30_0/boost/python/converter/arg_to_python.hpp:18, from C:/boost_1_30_0/boost/python/call.hpp:14, from C:/boost_1_30_0/boost/python/object_core.hpp:14, from C:/boost_1_30_0/boost/python/object.hpp:9, from C:/boost_1_30_0/boost/python/tuple.hpp:9, from C:/boost_1_30_0/boost/python/numeric.hpp:9, from ../../../libs/python/src/numeric.cpp:7: C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `&' token C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: syntax error before `&' token C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `const' C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: syntax error before `const' C:/boost_1_30_0/boost/python/converter/builtin_converters.hpp:106: parse error before `>' token [... and so on ...] _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig This message contains information that may be confidential and privileged. Unless you are the addressee (or authorized to receive messages for the addressee), you may not use, copy, or disclose to anyone the message or any information contained in the message. If you have received the message in error, please advise the sender by reply e-mail and delete the message. Nothing in this message should be interpreted as a digital or electronic signature that can be used to authenticate a contract or any other legal document. From alex at glumol.com Tue Aug 5 00:51:48 2003 From: alex at glumol.com (Alex) Date: Tue, 5 Aug 2003 00:51:48 +0200 Subject: [C++-sig] deriving basic python type Message-ID: <005e01c35ada$fd50b0c0$81123951@knar> Hi In python I can do this : class my_int(int): def __rshift__(self, a): #changing the >> operator behavior for example... return self + a The example is quite stupid but is there a way I can make such a class in C++(a class deriving the python int or other python types) then exporting it in python ? a python question: can't we overload the = operator in python ?? -------------- next part -------------- An HTML attachment was scrubbed... URL: From s_sourceforge at nedprod.com Tue Aug 5 00:54:18 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 4 Aug 2003 23:54:18 +0100 Subject: [C++-sig] Re: Boost.Python << & >> bug In-Reply-To: Message-ID: <3F2EF22A.6605.34C725E1@localhost> The following section of this message contains a file attachment prepared for transmission using the Internet MIME message format. If you are using Pegasus Mail, or any another MIME-compliant system, you should be able to save it or view it from within your mailer. If you cannot, please ask your system administrator for assistance. ---- File information ----------- File: Test.cpp Date: 4 Aug 2003, 22:26 Size: 2380 bytes. Type: Program-source -------------- next part -------------- A non-text attachment was scrubbed... Name: Test.cpp Type: application/octet-stream Size: 2380 bytes Desc: not available URL: From s_sourceforge at nedprod.com Tue Aug 5 00:54:18 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 4 Aug 2003 23:54:18 +0100 Subject: [C++-sig] Re: Failure to deduce template argument types In-Reply-To: Message-ID: <3F2EF22A.23828.34C727CC@localhost> On 3 Aug 2003 at 21:12, David Abrahams wrote: > > 15, which is exactly the limit. Is the limit inclusive or exclusive? > > I'll probably find out quicker by recompiling. > > Don't forget that if it's a member function there's a hidden "this" > argument. I knocked it up to 25. Same problem. I thought then, right, let's come at it from the bottom up ie; start with the topmost base class and add those inheriting downwards. I got as far as FXObject (the base class) and guess what, even it won't compile! Currently MSVC7.1 grabs 2Gb of RAM and dies with a failure to allocate more stack. I have no idea what the problem is. I'll play for a day or two more, but time is ticking (everything must be finished by end of August) and I may just have to give up and go for SWIG. I'd been thinking perhaps I could customise pyste to spit out SWIG interface files ... Cheers, Niall From s_sourceforge at nedprod.com Tue Aug 5 00:54:18 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 4 Aug 2003 23:54:18 +0100 Subject: [C++-sig] Re: Boost.Python << & >> bug In-Reply-To: Message-ID: <3F2EF22A.31288.34C72681@localhost> On 3 Aug 2003 at 21:41, David Abrahams wrote: > > Enclosed is the condensed example as requested. > > I assume you're referring to the enclosure in the other message? Yeah my email program mangled it :( > No this is a failure of your wrapping code. Very simply, > > class_< FX::FXId >("FXId", no_init) > .def( other< FX::FXStream >() << self ) > .def( other< FX::FXStream >() >> self ) > > Attempts to wrap two operator expressions which take an FXStream on > the lhs and and FXId on the rhs. But you don't have anything which > would match those expressions. Try it: > > // C++ code > FXStream x; > FXId y; > x << y; // <== error > > friend FX::FXStream& operator<<(FX::FXStream& store,const FXId* > obj){return store;} friend FX::FXStream& operator>>(FX::FXStream& > store,FXId*& obj){return store;} > > These declare operators which take an FXId* on the rhs: > > x << &y; Yeah sorry about that - I had actually corrected this but forgot to recorrect it after another pyste cycle. However if you change the << overload in FXId to take a reference, it's the same problem. See attached. > > Here because FXStream does not provide an overload for anything in > > boost, it can't know it's really an unsigned char. > > I don't know what that means either. I meant that the compiler when faced with "a << b" where there is no direct overload for operator<<(a,b) must cast either a or b to something else to find an overload which can accept them. I had assumed that boost.python provides template class wrapper { ... operator type() const; in order for the wrapper classes to cast down to their containing types so that the overloads provided by the code being wrapped can do their work. Or I suppose the wrapper could also inherit publicly from the wrapped type, but this would probably be less flexible. > The problem you're seeing above may be due to a documentation bug on > my part. These operator wrapping facilities are only suitable for > wrapping operators which work on rvalue arguments. If you want to > wrap your operators which work on non-const lvalues, you should write > something more like: > > FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; > > ... > .def('__lshift__', pmf, return_self()); Ok, maybe if I explain what FXStream is: FXStream is like an iostream, or most accurately like QDataStream in Qt. You read and write variables from and to whatever backs it. Therefore usage would be as follows: FXStream s; s << 5; int foo; s >> foo; etc. Can boost.python wrap this sort of usage? > FWIW, Wrapping all these different operators for lots of different > integer types is probably a waste of time because Python only has one > int type. Wrapping overloads on int and ushort, for example, is > redundant. Mmm. This is a problem I was going to tackle eventually. I can't use python's pickle for various reasons so I have to really interface python directly with this. And I most certainly need to write short ints for example. Personally I'd envisage an ideal wrap as exposing as much as possible of the underlying interface. You'd almost certainly never use 85% of it as at a python level you'd keep pretty high-level. But occasionally you would need to get down & dirty, especially if for example the end-user didn't have access to the source. Cheers, Niall From s_sourceforge at nedprod.com Tue Aug 5 00:54:19 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 4 Aug 2003 23:54:19 +0100 Subject: [C++-sig] Re: Boost.Python << & >> bug In-Reply-To: Message-ID: <3F2EF22B.18831.34C72BF1@localhost> On 3 Aug 2003 at 23:10, David Abrahams wrote: > > FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; > > > > ... > > .def('__lshift__', pmf, return_self()); > > Hmm, I could change those wrappers so that the "self" argument was > required to be an lvalue. That would preclude implicit conversions to > the self type from being used, but it would allow the self object to > be mutated by the call. I doubt it would break any real code. > Thoughts from the group? Like it or not, most C++ programmers have never seen the spec and so wouldn't understand what you've just said. My copy is an extremely antiquated 1996 edition which doesn't have function try blocks etc. and while I've read through it several times, I'm still unclear! If I /do/ read you right, wouldn't making self a lvalue preclude auto- casting up to an inherited type? If so in my previous bug report, subclasses of FXId which use its FXStream << & >> overloads when passed as-is would surely no longer work? Also, surely a rvalue can be mutated through calling a non-const method on it? Or does that mean it then becomes a lvalue? Jeesh, I don't know anymore ... Cheers, Niall From nicodemus at globalite.com.br Tue Aug 5 02:19:53 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 04 Aug 2003 21:19:53 -0300 Subject: [C++-sig] (Fwd) Previous email to Nicodemus In-Reply-To: <3F2D73FB.18840.2EF1541A@localhost> References: <3F2D73FB.18840.2EF1541A@localhost> Message-ID: <3F2EF829.80803@globalite.com.br> Niall Douglas wrote: >On 3 Aug 2003 at 13:06, Nicodemus wrote: > > >>Yeah, I didn't got this email before. 8) >>Thanks for sending again. >> >> > >It seems then that there's something wrong with email between us. >Maybe your email system thinks I'm spam? ;) > > No, I don't think so... but I'm sure I didn't got it (just searched in my inbox). >>>However, the latest version still has the problem with passing >>>backslashes to Win32 GCCXML. It's GCCXML that barfs (and I got the >>>precompiled binary off its web site). >>> >>> >>Yes, GCCXML expects forward slashes only. Does this trouble you? >> >> > >Absolutely. On Win32 GCCXML dies a very horrible death if there is a >single backslash in its command line. Since pyste takes backslashes >in its input off its command line, this creates a problem eg; me >passing command line variables to pyste which obviously would contain >backslashes. > > I see. No problem, Pyste can be made to convert automatically backslashes to forward slashes. 8) >>Hmm, I see. There's no documentation avaiable for GCCXML, so it is >>kind of a mistery to predict all the weird names that it assigns for >>unnamed enums. 8) Thanks! >> >> > >Not really. GCC itself allocates temporary symbols starting with $. >That's why you can't use $ in your own symbol names on most systems. >You can see plenty more if you investigate the embedded assembler in >GCC. > You are right. Any name starting with $ is certainly an internal name. >>>Next extension: my .pyste file is actually a full blown script which >>>reads the contents of a directory for the header files and then >>>dynamically creates the variable = AllFromHeader(filepath). >>> >>> >>Nice. That's an advantage of they being python scripts. 8) >> >> > >It's why python's great! I haven't had so much fun programming in it >since BBC Basic V on the Acorn Archimedes (a wonderful system for its >day)! A marriage between my C++ and python environments would be >ideal ... at least till I get some time to write the lazy functional >language I've always wanted to write (Haskell's too esoteric). > Yes, I have this feeling too. But the merriage you propose between C++ and Python is already possible: we have been using it with great sucess at our company. >>I see your problem, but I find the solution kind of a "hack". Have you >>tried if sys.path[0] gives the directory where the pyste file is? If >>it doesn't, I think we will have to use this solution, but I prefer >>following the upper-case conventin for constants: >> >> > >Err, doesn't sys.path refer to the script which invoked python? I >think so. Anyway, anything execfile'd is considered not standalone as >far as I understand ie; it merely reads the file into a string and >compiles that to a code object ie; it's no different from exec. >Anyway I've not tried it, and don't have enough experience with >python to say for sure, so I'll shut up now :) > You are right... it was just a guess. I didn't test because I was not at my computer at the time. I guess a variable named INTERFACE_PATH in the pyste file's namespace is good enough then. >class FXTopWindow : public FXWindow // in FXTopWindow.h >{ > FXObject *foo2(); >} > >class FXWindow // in FXWindow.h >{ > FXObject *foo(); >}; > >If I do AllFromHeader on FXTopWindow.h, it pulls in all the base >classes of FXTopWindow (correctly) and then asks for you to set the >return policies of foo() and foo2(). > >Now if I'm also doing FXAllFromHeader on FXWindow.h in the same pyste >file, it'll want a return policy set on foo(). My point is that if >you've already set the policy for foo() in FXWindow, you also set the >policy for all inherited versions of foo() in all subclasses of >FXWindow (because apart from covariant return, return types must stay >identical in overloads in C++). > I couldn't reproduce this problem, actually. If you do an AllFromHeader in FXTopWindow, it should only complain about the lack of policy for FXTopWindow.foo2, since FXWindow won't be exported at that time. In other words, only when a function is about to be exported the check for a policy is made. But if instead of "foo2()" in FXTopWindow you meant "foo()", then I see the problem. 8) Regards, Nicodemus. From s_sourceforge at nedprod.com Tue Aug 5 04:16:02 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 5 Aug 2003 03:16:02 +0100 Subject: Twas a bug in MSVC7.1 (was: Re: [C++-sig] Re: Failure to deduce template argument types) In-Reply-To: <3F2EF22A.23828.34C727CC@localhost> References: Message-ID: <3F2F2172.17493.357FD6F4@localhost> On 4 Aug 2003 at 23:54, Niall Douglas wrote: > I thought then, right, let's come at it from the bottom up ie; start > with the topmost base class and add those inheriting downwards. I got > as far as FXObject (the base class) and guess what, even it won't > compile! Currently MSVC7.1 grabs 2Gb of RAM and dies with a failure to > allocate more stack. I found the problem! If you try compiling the (hopefully this time) attached file on MSVC7.1 it dies horribly as above. The cause? Comment out the anonymous namespace declaration towards the middle of the file. It now compiles perfectly. Nicodemus: In light of this could you fix pyste so that it never generates an unnamed namespace? Is anyone in here friendly with some MS developers? Last time I tried submitting a bug report to MS I had to fill in a dozen forms and open a "support contract". Arse to that ... Cheers, Niall From s_sourceforge at nedprod.com Tue Aug 5 04:16:01 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 5 Aug 2003 03:16:01 +0100 Subject: Twas a bug in MSVC7.1 (was: Re: [C++-sig] Re: Failure to deduce template argument types) In-Reply-To: <3F2EF22A.23828.34C727CC@localhost> References: Message-ID: <3F2F2171.11830.357FD6A4@localhost> The following section of this message contains a file attachment prepared for transmission using the Internet MIME message format. If you are using Pegasus Mail, or any another MIME-compliant system, you should be able to save it or view it from within your mailer. If you cannot, please ask your system administrator for assistance. ---- File information ----------- File: Test2.cpp Date: 5 Aug 2003, 3:15 Size: 1635 bytes. Type: Program-source -------------- next part -------------- A non-text attachment was scrubbed... Name: Test2.cpp Type: application/octet-stream Size: 1635 bytes Desc: not available URL: From s_sourceforge at nedprod.com Tue Aug 5 04:26:48 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 5 Aug 2003 03:26:48 +0100 Subject: [C++-sig] (Fwd) Previous email to Nicodemus In-Reply-To: <3F2EF829.80803@globalite.com.br> References: <3F2D73FB.18840.2EF1541A@localhost> Message-ID: <3F2F23F8.1889.3589B5FC@localhost> On 4 Aug 2003 at 21:19, Nicodemus wrote: > >It's why python's great! I haven't had so much fun programming in it > >since BBC Basic V on the Acorn Archimedes (a wonderful system for its > > day)! A marriage between my C++ and python environments would be > >ideal ... at least till I get some time to write the lazy functional > >language I've always wanted to write (Haskell's too esoteric). > > Yes, I have this feeling too. But the merriage you propose between C++ > and Python is already possible: we have been using it with great > sucess at our company. I've wrapped /easy/ stuff ok and fine. But this library is proving hard. Has anyone tried wrapping the Qt library with boost.python? If so, please let me know - FOX is very like Qt. > >class FXTopWindow : public FXWindow // in FXTopWindow.h > >{ > > FXObject *foo2(); > >} > > > >class FXWindow // in FXWindow.h > >{ > > FXObject *foo(); > >}; > > > >If I do AllFromHeader on FXTopWindow.h, it pulls in all the base > >classes of FXTopWindow (correctly) and then asks for you to set the > >return policies of foo() and foo2(). > > > >Now if I'm also doing FXAllFromHeader on FXWindow.h in the same pyste > > file, it'll want a return policy set on foo(). My point is that if > >you've already set the policy for foo() in FXWindow, you also set the > > policy for all inherited versions of foo() in all subclasses of > >FXWindow (because apart from covariant return, return types must stay > > identical in overloads in C++). > > > > I couldn't reproduce this problem, actually. If you do an > AllFromHeader in FXTopWindow, it should only complain about the lack > of policy for FXTopWindow.foo2, since FXWindow won't be exported at > that time. In other words, only when a function is about to be > exported the check for a policy is made. But if instead of "foo2()" in > FXTopWindow you meant "foo()", then I see the problem. 8) No, because FXWindow::foo() is inherited by FXTopWindow, ie; there is also a FXTopWindow::foo(). My point is that if you tell pyste what FXWindow::foo() returns, it already knows the answer for FXTopWindow:foo() and doesn't need to ask again. Cheers, Niall From dave at boost-consulting.com Tue Aug 5 05:02:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 23:02:57 -0400 Subject: [C++-sig] Re: Twas a bug in MSVC7.1 References: <3F2F2172.17493.357FD6F4@localhost> Message-ID: "Niall Douglas" writes: > On 4 Aug 2003 at 23:54, Niall Douglas wrote: > >> I thought then, right, let's come at it from the bottom up ie; start >> with the topmost base class and add those inheriting downwards. I got >> as far as FXObject (the base class) and guess what, even it won't >> compile! Currently MSVC7.1 grabs 2Gb of RAM and dies with a failure to >> allocate more stack. > > I found the problem! If you try compiling the (hopefully this time) > attached file on MSVC7.1 it dies horribly as above. > > The cause? > > Comment out the anonymous namespace declaration towards the middle of > the file. It now compiles perfectly. > > Nicodemus: In light of this could you fix pyste so that it never > generates an unnamed namespace? > > Is anyone in here friendly with some MS developers? Yes; I've forwarded your report on to one of the compiler guys. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 05:20:27 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 23:20:27 -0400 Subject: [C++-sig] Re: Boost.Python << & >> bug References: <3F2EF22A.31288.34C72681@localhost> Message-ID: "Niall Douglas" writes: > On 3 Aug 2003 at 21:41, David Abrahams wrote: > >> > Enclosed is the condensed example as requested. >> >> I assume you're referring to the enclosure in the other message? > > Yeah my email program mangled it :( > >> No this is a failure of your wrapping code. Very simply, >> >> class_< FX::FXId >("FXId", no_init) >> .def( other< FX::FXStream >() << self ) >> .def( other< FX::FXStream >() >> self ) >> >> Attempts to wrap two operator expressions which take an FXStream on >> the lhs and and FXId on the rhs. But you don't have anything which >> would match those expressions. Try it: >> >> // C++ code >> FXStream x; >> FXId y; >> x << y; // <== error >> >> friend FX::FXStream& operator<<(FX::FXStream& store,const FXId* >> obj){return store;} friend FX::FXStream& operator>>(FX::FXStream& >> store,FXId*& obj){return store;} >> >> These declare operators which take an FXId* on the rhs: >> >> x << &y; > > Yeah sorry about that - I had actually corrected this but forgot to > recorrect it after another pyste cycle. However if you change the << > overload in FXId to take a reference, it's the same problem. See > attached. That's the same problem we were having before: no support for lvalues. That's now fixed in CVS. You can apply the enclosed patch to try it. -------------- next part -------------- A non-text attachment was scrubbed... Name: operators.patch Type: text/x-patch Size: 2100 bytes Desc: not available URL: -------------- next part -------------- >> > Here because FXStream does not provide an overload for anything in >> > boost, it can't know it's really an unsigned char. >> >> I don't know what that means either. > > I meant that the compiler when faced with "a << b" where there is no > direct overload for operator<<(a,b) must cast either a or b to > something else to find an overload which can accept them. Don't know what you mean by "direct overload". > I had assumed that boost.python provides template class > wrapper { ... operator type() const; in order for the wrapper classes > to cast down to their containing types Huh? Sorry, you lost me. > so that the overloads provided by the code being wrapped can do > their work. Or I suppose the wrapper could also inherit publicly > from the wrapped type, but this would probably be less flexible. None of the above. >> The problem you're seeing above may be due to a documentation bug on >> my part. These operator wrapping facilities are only suitable for >> wrapping operators which work on rvalue arguments. If you want to >> wrap your operators which work on non-const lvalues, you should write >> something more like: >> >> FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; >> >> ... >> .def('__lshift__', pmf, return_self()); > > Ok, maybe if I explain what FXStream is: FXStream is like an > iostream I think I figured that out. > , or most accurately like QDataStream in Qt. You read and > write variables from and to whatever backs it. > > Therefore usage would be as follows: > FXStream s; > s << 5; > int foo; > s >> foo; > etc. > > Can boost.python wrap this sort of usage? I just fixed it so that it can. However, you may have trouble with the return type of your operator<<, if it's a reference. There's no provision for using call policies with operators. >> FWIW, Wrapping all these different operators for lots of different >> integer types is probably a waste of time because Python only has one >> int type. Wrapping overloads on int and ushort, for example, is >> redundant. > > Mmm. This is a problem I was going to tackle eventually. I can't use > python's pickle for various reasons so I have to really interface > python directly with this. And I most certainly need to write short > ints for example. You'd better pick a different interface, then, 'cause Python doesn't give you short ints. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 05:21:54 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Aug 2003 23:21:54 -0400 Subject: [C++-sig] Re: Boost.Python << & >> bug References: <3F2EF22B.18831.34C72BF1@localhost> Message-ID: "Niall Douglas" writes: > On 3 Aug 2003 at 23:10, David Abrahams wrote: > >> > FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<; >> > >> > ... >> > .def('__lshift__', pmf, return_self()); >> >> Hmm, I could change those wrappers so that the "self" argument was >> required to be an lvalue. That would preclude implicit conversions to >> the self type from being used, but it would allow the self object to >> be mutated by the call. I doubt it would break any real code. >> Thoughts from the group? > > Like it or not, most C++ programmers have never seen the spec and so > wouldn't understand what you've just said. My copy is an extremely > antiquated 1996 edition which doesn't have function try blocks etc. > and while I've read through it several times, I'm still unclear! Err, lvalue and rvalue are much older concepts than 1996. They come from 'C'. > If I /do/ read you right, wouldn't making self a lvalue preclude > auto- casting up to an inherited type? No, the opposite. > If so in my previous bug report, subclasses of FXId which use its > FXStream << & >> overloads when passed as-is would surely no longer > work? The opposite. > Also, surely a rvalue can be mutated through calling a non-const > method on it? Absolutely not. C++ doesn't let you bind rvalues to non-const references. -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Tue Aug 5 08:04:39 2003 From: romany at actimize.com (Roman Yakovenko) Date: Tue, 5 Aug 2003 09:04:39 +0300 Subject: [C++-sig] property and documentation Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B00@exchange.adrembi.com> Hi. 1. add_static_property - function of class_ is not referenced in documentation. Nevertheless it works pretty good. 2. How can I specify return value policy for properties ? Thanks. Roman From pierre.barbier at cirad.fr Tue Aug 5 11:28:00 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Tue, 05 Aug 2003 11:28:00 +0200 Subject: [C++-sig] Lates CVS version non compiling Message-ID: <3F2F78A0.1080501@cirad.fr> Hello, I retrieved the latest CVS version of boost using the boost-consulting repository (which is the most accessible). But I have this compilation error : ******************* begin of output ************************************* gcc-C++-action libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o In file included from /home/barbier/apps/boost/boost/graph/breadth_first_search.hpp:37, from libs/python/src/object/inheritance.cpp:8: /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:164: syntax error before `&&' token /home/barbier/apps/boost/boost/graph/graph_concepts.hpp: In member function `void boost::VertexListGraphConcept::constraints()': /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:193: `vertices' not declared /home/barbier/apps/boost/boost/graph/graph_concepts.hpp: In member function `void boost::VertexListGraphConcept::const_constraints(const G&)': /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:206: `vertices' not declared /usr/bin//g++-3.2 -c -Wall -ftemplate-depth-100 -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -g -O0 -fno-inline -fPIC -I"libs/python/build" -I "/usr/include/python2.2" -I "/home/barbier/apps/boost" -o "libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o" "libs/python/build/../src/object/inheritance.cpp" ...failed gcc-C++-action libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o... ***************************** end of output ********************** ... and I cannot figure out what's the problem ... My g++ version is : $ g++ --version g++ (GCC) 3.2.3 (Debian) Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77 fax : (33) 4 67 61 56 68 From dave at boost-consulting.com Tue Aug 5 13:01:44 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 07:01:44 -0400 Subject: [C++-sig] Re: property and documentation References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B00@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: > Hi. > 1. add_static_property - function of class_ is not referenced in documentation. > Nevertheless it works pretty good. Would you like to suggest a documentation patch? > 2. How can I specify return value policy for properties ? Just use make_function explicitly on the get function and your call policy and pass the result on to add_property. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 13:23:56 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 07:23:56 -0400 Subject: [C++-sig] Re: Lates CVS version non compiling References: <3F2F78A0.1080501@cirad.fr> Message-ID: Pierre Barbier de Reuille writes: > Hello, I retrieved the latest CVS version of boost using the > boost-consulting repository (which is the most accessible). But I have > this compilation error : > > ******************* begin of output ************************************* > gcc-C++-action > libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o > In file included from > /home/barbier/apps/boost/boost/graph/breadth_first_search.hpp:37, > from libs/python/src/object/inheritance.cpp:8: > /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:164: syntax error > before `&&' token > /home/barbier/apps/boost/boost/graph/graph_concepts.hpp: In member function > `void boost::VertexListGraphConcept::constraints()': > /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:193: `vertices' not > declared > /home/barbier/apps/boost/boost/graph/graph_concepts.hpp: In member function > `void boost::VertexListGraphConcept::const_constraints(const G&)': > /home/barbier/apps/boost/boost/graph/graph_concepts.hpp:206: `vertices' not > declared > > /usr/bin//g++-3.2 -c -Wall -ftemplate-depth-100 > -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -g -O0 > -fno-inline -fPIC -I"libs/python/build" -I > "/usr/include/python2.2" -I > "/home/barbier/apps/boost" -o > "libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o" > "libs/python/build/../src/object/inheritance.cpp" > > ...failed gcc-C++-action > libs/python/build/bin/libboost_python.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/inheritance.o... > ***************************** end of output ********************** > > ... and I cannot figure out what's the problem ... > My g++ version is : > $ g++ --version g++ (GCC) 3.2.3 (Debian) > Copyright (C) 2002 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. It's working for me, though I can't promise that the boost-consulting mirror isn't lagging too far behind. Please try updating again. -- Dave Abrahams Boost Consulting www.boost-consulting.com From pierre.barbier at cirad.fr Tue Aug 5 14:00:17 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Tue, 05 Aug 2003 14:00:17 +0200 Subject: [C++-sig] Re: Lates CVS version non compiling In-Reply-To: References: <3F2F78A0.1080501@cirad.fr> Message-ID: <3F2F9C51.4030105@cirad.fr> David Abrahams wrote: >It's working for me, though I can't promise that the boost-consulting >mirror isn't lagging too far behind. Please try updating again. > > > The update gives nothing new, but I'll see tomorrow if things are better ... hoping the mirror will be mirrored by then :o) -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77 fax : (33) 4 67 61 56 68 From romany at actimize.com Tue Aug 5 14:03:48 2003 From: romany at actimize.com (Roman Yakovenko) Date: Tue, 5 Aug 2003 15:03:48 +0300 Subject: [C++-sig] Re: property and documentation Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF50205FD@exchange.adrembi.com> Yes. class.html is edited file. class_orig.html is file from cvs. If you need also tests in C++ and in Python I can write it. Thanks for the answer. Roman > -----Original Message----- > From: David Abrahams [mailto:dave at boost-consulting.com] > Sent: Tuesday, August 05, 2003 1:02 PM > To: c++-sig at python.org > Subject: [C++-sig] Re: property and documentation > > > "Roman Yakovenko" writes: > > > Hi. > > 1. add_static_property - function of class_ is not > referenced in documentation. > > Nevertheless it works pretty good. > > Would you like to suggest a documentation patch? > > > 2. How can I specify return value policy for properties ? > > Just use make_function explicitly on the get function and your call > policy and pass the result on to add_property. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Tue Aug 5 14:57:55 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 08:57:55 -0400 Subject: [C++-sig] Re: deriving basic python type References: <005e01c35ada$fd50b0c0$81123951@knar> Message-ID: "Alex" writes: > Hi > In python I can do this : > > class my_int(int): > def __rshift__(self, a): #changing the >> operator behavior for example... > return self + a > > The example is quite stupid but is there a way I can make such a > class in C++(a class deriving the python int or other python types) > then exporting it in python ? There's no *easy* way right now, but it's a fairly easy mod to the Boost.Python sources. Gottfried Gan?auge has been working on a patch for another purpose which should make it possible. Gottfried, how's it coming along? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 15:05:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 09:05:35 -0400 Subject: [C++-sig] Re: property and documentation References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF50205FD@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: > Yes. class.html is edited file. class_orig.html is file from cvs. Well, it isn't fair to simply copy the effects of add_property; they don't have the same semantics. > If you need also tests in C++ and in Python I can write it. Yes, please. A patch to one of the existing tests would probably be best. > Thanks for the answer. > > Roman > >> -----Original Message----- >> From: David Abrahams [mailto:dave at boost-consulting.com] >> Sent: Tuesday, August 05, 2003 1:02 PM >> To: c++-sig at python.org >> Subject: [C++-sig] Re: property and documentation >> >> >> "Roman Yakovenko" writes: >> >> > Hi. >> > 1. add_static_property - function of class_ is not >> referenced in documentation. >> > Nevertheless it works pretty good. >> >> Would you like to suggest a documentation patch? >> >> > 2. How can I specify return value policy for properties ? >> >> Just use make_function explicitly on the get function and your call >> policy and pass the result on to add_property. >> >> -- >> Dave Abrahams >> Boost Consulting >> www.boost-consulting.com >> >> >> _______________________________________________ >> C++-sig mailing list >> C++-sig at python.org >> http://mail.python.org/mailman/listinfo/c++-sig >> > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Tue Aug 5 18:03:42 2003 From: romany at actimize.com (Roman Yakovenko) Date: Tue, 5 Aug 2003 19:03:42 +0300 Subject: [C++-sig] Re: property and documentation Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF50205FF@exchange.adrembi.com> > Well, it isn't fair to simply copy the effects of add_property; they > don't have the same semantics. 1. There is no difference in function definitions except their names. 2. The difference is Effects: Creates a new Python property class instance, passing object(fget) (and object(fset) in the second form) to its constructor, then adds that property to the Python class with the given attribute name. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ If you meant smth different, then I don't understand. Also I send you 2 files. I believe that I checked all cases. Also I believe that you will find some things that I will have to fix. (Life is not easy as I'd like to be.) Roman. > -----Original Message----- > From: David Abrahams [mailto:dave at boost-consulting.com] > Sent: Tuesday, August 05, 2003 3:06 PM > To: c++-sig at python.org > Subject: [C++-sig] Re: property and documentation > > > "Roman Yakovenko" writes: > > > Yes. class.html is edited file. class_orig.html is file from cvs. > > Well, it isn't fair to simply copy the effects of add_property; they > don't have the same semantics. > > > If you need also tests in C++ and in Python I can write it. > > Yes, please. A patch to one of the existing tests would probably be > best. > > > Thanks for the answer. > > > > Roman > > > >> -----Original Message----- > >> From: David Abrahams [mailto:dave at boost-consulting.com] > >> Sent: Tuesday, August 05, 2003 1:02 PM > >> To: c++-sig at python.org > >> Subject: [C++-sig] Re: property and documentation > >> > >> > >> "Roman Yakovenko" writes: > >> > >> > Hi. > >> > 1. add_static_property - function of class_ is not > >> referenced in documentation. > >> > Nevertheless it works pretty good. > >> > >> Would you like to suggest a documentation patch? > >> > >> > 2. How can I specify return value policy for properties ? > >> > >> Just use make_function explicitly on the get function and your call > >> policy and pass the result on to add_property. > >> > >> -- > >> Dave Abrahams > >> Boost Consulting > >> www.boost-consulting.com > >> > >> > >> _______________________________________________ > >> C++-sig mailing list > >> C++-sig at python.org > >> http://mail.python.org/mailman/listinfo/c++-sig > >> > > > > > > _______________________________________________ > > C++-sig mailing list > > C++-sig at python.org > > http://mail.python.org/mailman/listinfo/c++-sig > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.cpp Type: application/octet-stream Size: 1931 bytes Desc: properties.cpp URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.py Type: application/octet-stream Size: 1145 bytes Desc: properties.py URL: From s_sourceforge at nedprod.com Tue Aug 5 19:16:13 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 5 Aug 2003 18:16:13 +0100 Subject: [C++-sig] const char arrays Message-ID: <3F2FF46D.25651.38B7FB97@localhost> Are const char arrays supported by boost.python? eg; static const char deleteTypeName[]; Obviously we'd prefer them to become python strings. BTW MSVC7.1 here stops with "reference to a zero-sized array is illegal". BTW a full list of what boost.python doesn't support in the docs would be really, really useful - then I can know it's not me misconfiguring something. BTW, I've been trying to find docs on how to implement your own custom converters. Basically I'd like to convert a FXString to a python one automatically and back again. I've come up with: namespace boost { namespace python { BOOST_PYTHON_TO_PYTHON_BY_VALUE(FX::FXString, PyString_FromStringAndSize(x.text(), x.length())) }} // namespace For the other direction I tried: struct FXString_rvalue_from_python { static void init() { slot_rvalue_from_python(); } static unaryfunc *get_slot(PyObject *obj) { return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0; } static FX::FXString extract(PyObject *intermediate) { return FX::FXString(PyString_AsString(intermediate), PyString_Size(intermediate)); } }; Problem is that slot_rvalue_from_python<> in builtin_converters.hpp is in an unnamed namespace and so therefore is inaccessible to me :( Furthermore, string literals in const char * form don't appear to cast to a FXString first as usual. Instead the compiler treats them as a const char *, which AFAICS Boost.python doesn't support (it seems to not to support any pointer to any basic type actually :( ). This is odd because throughout the header files it /looks/ like it support const literals to python strings, but it sure ain't working here (I get a static assertion failure in make_instance_impl::execute() with is_class::value being value). Any way of working around this? ie; to get const char * literals to become python strings? This library I'm making bindings for works exclusively with C style strings as its lower levels. Cheers, Niall From dave at boost-consulting.com Tue Aug 5 20:02:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 14:02:57 -0400 Subject: [C++-sig] Re: const char arrays References: <3F2FF46D.25651.38B7FB97@localhost> Message-ID: "Niall Douglas" writes: > Are const char arrays supported by boost.python? Supported how? > eg; > > static const char deleteTypeName[]; > > Obviously we'd prefer them to become python strings. When? > BTW MSVC7.1 here > stops with "reference to a zero-sized array is illegal". That is correct. The code is ill-formed. This has nothing whatsoever to do with Boost.Python. > BTW a full list of what boost.python doesn't support in the docs > would be really, really useful - then I can know it's not me > misconfiguring something. It would take a long time to write that. It won't wash your socks or > BTW, I've been trying to find docs on how to implement your own > custom converters. Basically I'd like to convert a FXString to a > python one automatically and back again. I've come up with: > > namespace boost { namespace python { > BOOST_PYTHON_TO_PYTHON_BY_VALUE(FX::FXString, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This macro is not for public consumption; I should probably #undef it at the end of the header file that defines it. > PyString_FromStringAndSize(x.text(), x.length())) > }} // namespace > > For the other direction I tried: > > struct FXString_rvalue_from_python > { > static void init() > { > slot_rvalue_from_python FXString_rvalue_from_python>(); > } > static unaryfunc *get_slot(PyObject *obj) > { > return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0; > } > static FX::FXString extract(PyObject *intermediate) > { > return FX::FXString(PyString_AsString(intermediate), > PyString_Size(intermediate)); > } > }; > > Problem is that slot_rvalue_from_python<> in builtin_converters.hpp > is in an unnamed namespace and so therefore is inaccessible to me :( I think you should read up on unnamed namespaces again. Anyway, that template is in a source file, for good reason. It's not for public consumption. I suggest you follow the example set in item 2 here: http://www.boost.org/libs/python/doc/v2/faq.html#question2 > Furthermore, string literals in const char * form don't appear to > cast to a FXString first as usual. Instead the compiler treats them > as a const char *, which AFAICS Boost.python doesn't support (it > seems to not to support any pointer to any basic type actually :( > ). It certainly does support char const*, depending on what you mean by "support". This function can be wrapped successfully: char const* f(char const*); You can see that it works from libs/python/test/builtin_converters.* > This is odd because throughout the header files it /looks/ like it > support const literals to python strings, but it sure ain't working > here (I get a static assertion failure in > make_instance_impl::execute() with is_class::value being value). I assume you mean "being false". Clearly you're using an inappropriate call policy such as return_internal_reference or reference_existing_object. > Any way of working around this? ie; to get const char * literals to > become python strings? This library I'm making bindings for works > exclusively with C style strings as its lower levels. There's nothing to work around AFAICT. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 20:11:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 14:11:50 -0400 Subject: [C++-sig] Re: property and documentation References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF50205FF@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: >> Well, it isn't fair to simply copy the effects of add_property; they >> don't have the same semantics. > 1. There is no difference in function definitions except their >> names. No, one calls base::add_static_property and the other calls base::add_property. > 2. The difference is > > Effects: Creates a new Python property class instance, passing object(fget) (and object(fset) in the second form) to its constructor, then adds that property to the Python class with the given attribute name. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > ^^^^^ I'm not sure what you're trying to highlight here, but it doesn't make sense on my screen. > If you meant smth different, then I don't understand. See enclosed. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- > Also I send you 2 files. I believe that I checked all cases. Thanks; I'll add them. > Also I believe that you will find some things that I will have to > fix. (Life is not easy as I'd like to be.) We'll see. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 5 20:13:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 14:13:43 -0400 Subject: [C++-sig] Re: property and documentation References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF50205FF@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: > Also I send you 2 files. I believe that I checked all cases. > Also I believe that you will find some things that I will have to fix. > (Life is not easy as I'd like to be.) Yup. Please reformulate the python file using doctest or the unittest module. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Tue Aug 5 20:35:49 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Aug 2003 11:35:49 -0700 (PDT) Subject: [C++-sig] Re: Lates CVS version non compiling In-Reply-To: <3F2F9C51.4030105@cirad.fr> Message-ID: <20030805183549.98654.qmail@web20203.mail.yahoo.com> The source code bundles published here are based on the Boost CVS from 2003-08-04 20:30 PDT (last night): http://cci.lbl.gov/cctbx_build/show_results.cgi?build_tag=2003_08_04_2056 Unpack cctbx_bundle.selfx and throw away everything but cctbx_sources/boost. The boost tree is untouched. As you will see, compilation worked in nine different configurations under six different operating systems. In addition I've manually verified that all tests in libs/python/test work under redhat80/gcc3.2 (to be more precise: all tests that do not require the unit test library and that are not expected to fail). Ralf --- Pierre Barbier de Reuille wrote: > David Abrahams wrote: > > >It's working for me, though I can't promise that the boost-consulting > >mirror isn't lagging too far behind. Please try updating again. > > > > > > > The update gives nothing new, but I'll see tomorrow if things are better > ... hoping the mirror will be mirrored by then :o) __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From rwgk at yahoo.com Tue Aug 5 20:47:33 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Aug 2003 11:47:33 -0700 (PDT) Subject: [C++-sig] Re: const char arrays In-Reply-To: Message-ID: <20030805184733.43655.qmail@web20206.mail.yahoo.com> --- David Abrahams wrote: > "Niall Douglas" writes: > > Problem is that slot_rvalue_from_python<> in builtin_converters.hpp > > is in an unnamed namespace and so therefore is inaccessible to me :( > > I think you should read up on unnamed namespaces again. Anyway, that > template is in a source file, for good reason. It's not for public > consumption. > > I suggest you follow the example set in item 2 here: > http://www.boost.org/libs/python/doc/v2/faq.html#question2 You may also like to read the three old messages listed under "Custom rvalue converters" near the top of this page: http://cci.lbl.gov/~rwgk/boost_python/ In particular, the third link should be highly relevant. Ralf __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From s_sourceforge at nedprod.com Tue Aug 5 21:06:57 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 5 Aug 2003 20:06:57 +0100 Subject: [C++-sig] Re: const char arrays In-Reply-To: <20030805184733.43655.qmail@web20206.mail.yahoo.com> References: Message-ID: <3F300E61.20282.391D5D6F@localhost> On 5 Aug 2003 at 11:47, Ralf W. Grosse-Kunstleve wrote: > --- David Abrahams wrote: > > "Niall Douglas" writes: > > > Problem is that slot_rvalue_from_python<> in > > > builtin_converters.hpp is in an unnamed namespace and so therefore > > > is inaccessible to me :( > > > > I think you should read up on unnamed namespaces again. Anyway, > > that template is in a source file, for good reason. It's not for > > public consumption. Is it not better I try to solve problems myself before bothering others? I only post here when I really don't know what to do next. > > I suggest you follow the example set in item 2 here: > > http://www.boost.org/libs/python/doc/v2/faq.html#question2 > > You may also like to read the three old messages listed under "Custom > rvalue converters" near the top of this page: > > http://cci.lbl.gov/~rwgk/boost_python/ > > In particular, the third link should be highly relevant. Now /that/ is precisely what I was looking for. Thank you very much! Could not a new section be opened in the docs called "custom rvalue converters"? It seems a waste of time for me to bash my head against a wall and yours to keep answering the same questions over and over. Cheers, Niall From dave at boost-consulting.com Tue Aug 5 21:29:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Aug 2003 15:29:46 -0400 Subject: [C++-sig] Re: const char arrays References: <3F300E61.20282.391D5D6F@localhost> Message-ID: "Niall Douglas" writes: > On 5 Aug 2003 at 11:47, Ralf W. Grosse-Kunstleve wrote: > >> --- David Abrahams wrote: >> > "Niall Douglas" writes: >> > > Problem is that slot_rvalue_from_python<> in >> > > builtin_converters.hpp is in an unnamed namespace and so therefore >> > > is inaccessible to me :( >> > >> > I think you should read up on unnamed namespaces again. Anyway, >> > that template is in a source file, for good reason. It's not for >> > public consumption. > > Is it not better I try to solve problems myself before bothering > others? Absolutely, and thanks for that. > I only post here when I really don't know what to do next. You could make it easier for us to help you by posting small examples that demonstrate what you're trying to do and what result you expect, and taking care with the precision of what you write, making sure that you have supplied enough information. I spent 5 minutes wondering why I couldn't find slot_rvalue_from_python in builtin_converters.hpp. If you are unable to convert char const* to python a small reproducible example and a copy of the error message would help. >> > I suggest you follow the example set in item 2 here: >> > http://www.boost.org/libs/python/doc/v2/faq.html#question2 >> >> You may also like to read the three old messages listed under "Custom >> rvalue converters" near the top of this page: >> >> http://cci.lbl.gov/~rwgk/boost_python/ >> >> In particular, the third link should be highly relevant. > > Now /that/ is precisely what I was looking for. Thank you very much! > > Could not a new section be opened in the docs called "custom rvalue > converters"? It seems a waste of time for me to bash my head against > a wall and yours to keep answering the same questions over and over. Sure, we just need a volunteer to write it . -- Dave Abrahams Boost Consulting www.boost-consulting.com From s_sourceforge at nedprod.com Wed Aug 6 05:03:21 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Wed, 6 Aug 2003 04:03:21 +0100 Subject: [C++-sig] Re: Boost.Python << & >> bug In-Reply-To: Message-ID: <3F307E09.21178.3AD184A3@localhost> On 4 Aug 2003 at 23:21, David Abrahams wrote: > > Like it or not, most C++ programmers have never seen the spec and so > > wouldn't understand what you've just said. My copy is an extremely > > antiquated 1996 edition which doesn't have function try blocks etc. > > and while I've read through it several times, I'm still unclear! > > Err, lvalue and rvalue are much older concepts than 1996. They come > from 'C'. I know - however the C++ spec defines 99% of the C spec too. What I find interesting is that nowhere in my copy of the spec are lvalue or rvalue defined. I had assumed lvalues are to the left of the equals and rvalues are to the right such that lvalue=rvalue, but (lvalue=rvalue) is a rvalue too. I taught myself C++ from the terse online docs in MSVC4. Some feel that it is terrible there are programmers like me practising out there, but I would argue that I've never been able to afford anything better and few university courses here teach C++. > > If I /do/ read you right, wouldn't making self a lvalue preclude > > auto- casting up to an inherited type? > > No, the opposite. > > > If so in my previous bug report, subclasses of FXId which use its > > FXStream << & >> overloads when passed as-is would surely no longer > > work? > > The opposite. In which case it looks like my definitions of the two are inverted. Hence, your proposal looks like a good idea. I know I've probably sounded really ignorant in these past two emails or so, but if you don't ask questions then you don't realise you're wrong. My apologies if it's annoyed anyone. Cheers, Niall From s_sourceforge at nedprod.com Wed Aug 6 05:03:21 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Wed, 6 Aug 2003 04:03:21 +0100 Subject: [C++-sig] Re: Failure to deduce template argument types In-Reply-To: <3F2D7628.3245.2EF9D306@localhost> References: Message-ID: <3F307E09.6830.3AD18601@localhost> On 3 Aug 2003 at 20:52, Niall Douglas wrote: Just for reference if anyone gets that those repeated errors about failing to deduce template arguments, it's because you have an ellipsis in your argument list of at least one method :) So, I guess, I kinda was exceeding the MAX_ARITY after all ... Cheers, Niall From s_sourceforge at nedprod.com Wed Aug 6 05:03:20 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Wed, 6 Aug 2003 04:03:20 +0100 Subject: [C++-sig] Re: const char arrays In-Reply-To: Message-ID: <3F307E08.3651.3AD182F4@localhost> On 5 Aug 2003 at 15:29, David Abrahams wrote: > > Is it not better I try to solve problems myself before bothering > > others? > > Absolutely, and thanks for that. I should add that really I don't know what I'm doing - I'm looking for stuff which seems associated and plugging in new values. My problem is that the terse explanation of each template in the docs doesn't help me see how they all fit together to get the job done. I know that a database of API's is built and through this the binding happens partially at compile-time partially at run-time. eg; below I illustrate a conceptual problem with boost::python::object. > > I only post here when I really don't know what to do next. > > You could make it easier for us to help you by posting small examples > that demonstrate what you're trying to do and what result you expect, > and taking care with the precision of what you write, making sure that > you have supplied enough information. I spent 5 minutes wondering why > I couldn't find slot_rvalue_from_python in builtin_converters.hpp. If > you are unable to convert char const* to python a small reproducible > example and a copy of the error message would help. My problem here is that I'm binding a large library I didn't write and so much stuff depends on other stuff. So I can't just cut & paste the bit I need - I have to alter it which then usually causes a different error report. Hence to get an isolated example takes hours of trial & error :( > > Could not a new section be opened in the docs called "custom rvalue > > converters"? It seems a waste of time for me to bash my head against > > a wall and yours to keep answering the same questions over and over. > > Sure, we just need a volunteer to write it . Ah, but I don't know what I'm doing so that would seem unwise. I'll firstly say (with some joy) that my test class wrapper finally compiled today without error and my thanks to this list for helping me. I've not tried linking yet (bedtime now). A question (and only because of the atlantic clock difference): in the example http://mail.python.org/pipermail/c++-sig/2003- May/004133.html: struct custom_string_to_python_str { static PyObject* convert(custom_string const& s) { return boost::python::incref(boost::python::object(s.value()).ptr()); } }; Isn't this making use of boost.python's inbuilt std::string converter? ie; it's not converting to a python string itself. For some non-std::string based string, would it be more like: struct custom_string_to_python_str { static PyObject* convert(custom_string const& s) { return boost::python::incref(PyString_FromStringAndSize(s.text(), s.length())); } }; I get that boost::python::object encapsulates a python object, and that ptr() returns that object, but I can't see a conversion path in the original without going through std::string (which seems inefficient). Cheers, Niall From rwgk at yahoo.com Wed Aug 6 07:45:33 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Aug 2003 22:45:33 -0700 (PDT) Subject: [C++-sig] Re: const char arrays In-Reply-To: <3F307E08.3651.3AD182F4@localhost> Message-ID: <20030806054533.88952.qmail@web20209.mail.yahoo.com> --- Niall Douglas wrote: > struct custom_string_to_python_str > { > static PyObject* convert(custom_string const& s) > { > return > boost::python::incref(boost::python::object(s.value()).ptr()); > } > }; > > Isn't this making use of boost.python's inbuilt std::string > converter? ie; it's not converting to a python string itself. Yes. Just to keep the example simple. Or maybe because I was too lazy to figure out the raw C API call. > For some non-std::string based string, would it be more like: > > struct custom_string_to_python_str > { > static PyObject* convert(custom_string const& s) > { > return > boost::python::incref(PyString_FromStringAndSize(s.text(), > s.length())); > } > }; Close, but I think you are leaking a reference count. This should do the job: return PyString_FromStringAndSize(s.text(), s.length()); The bottom line is that you have to return a new Python reference. How exactly you do this is entirely up to you. Ralf __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From skchim0 at engr.uky.edu Wed Aug 6 07:47:56 2003 From: skchim0 at engr.uky.edu (satish k.chimakurthi) Date: Wed, 6 Aug 2003 01:47:56 -0400 Subject: [C++-sig] Python and C++ - Newbie question !! Message-ID: <200308060147.56718.skchim0@engr.uky.edu> Hello all, This is the first time I am posting to this group. I would like to introduce myself as a grad.student at the University Of Kentucky. I hope that most of you have heard of LLNL'S OVERTURE framework (www.llnl.gov/casc/Overture)...which is a framework of huge number of C++ LIBRARIES, useful for grid generation and other purposes Using OVERTURE'S FRAMEWORK OF CLASSES, I have written a small program for my application and obviously my code is written in C++ since OVERTURE itself is entirely in C++. I declare a number of objects in my code using the standard classes that are defined in OVERTURE FRAMEWORK. In order to run my code in OVERTURE, I would need to make it using a Makefile which contains all the rules needed to link the code to the OVERTURE framework. However, I need to do the same thing from python. I would like to use python as an input mechanism to this code and would like to make it in the Overture framework from Python. The python module that we generate to do this should be in a position to understand the functionality of all the classes which are defined somewhere in the software but whose objects are declared in the code that we write in OVERTURE. Can someone tell me how I can go about this ?? I am really confused with all the documentation that is there... Thanks a lot for your help in advance, SATISH -- SATISH K.CHIMAKURTHI GRAD. RESEARCH ASSISTANT UNIVERSITY OF KENTUCKY LEXINGTON KENTUCKY STATE From pierre.barbier at cirad.fr Wed Aug 6 10:05:12 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Wed, 06 Aug 2003 10:05:12 +0200 Subject: [C++-sig] Re: Lates CVS version non compiling In-Reply-To: <20030805183549.98654.qmail@web20203.mail.yahoo.com> References: <20030805183549.98654.qmail@web20203.mail.yahoo.com> Message-ID: <3F30B6B8.6060200@cirad.fr> The boost version you gave me is indeed working fine, but the CVS one on boost-consulting.com is still not compiling. I'll try a check-out on sourceforge ... Ralf W. Grosse-Kunstleve wrote: >The source code bundles published here are based on the Boost CVS from >2003-08-04 20:30 PDT (last night): > >http://cci.lbl.gov/cctbx_build/show_results.cgi?build_tag=2003_08_04_2056 > >Unpack cctbx_bundle.selfx and throw away everything but cctbx_sources/boost. >The boost tree is untouched. > >As you will see, compilation worked in nine different configurations under six >different operating systems. In addition I've manually verified that all tests >in libs/python/test work under redhat80/gcc3.2 (to be more precise: all tests >that do not require the unit test library and that are not expected to fail). > >Ralf > > > -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77 fax : (33) 4 67 61 56 68 From benny at kramekweb.com Wed Aug 6 12:54:18 2003 From: benny at kramekweb.com (Benny Kramek) Date: Wed, 6 Aug 2003 13:54:18 +0300 Subject: [C++-sig] Inheriting a Python class from a C++ class Message-ID: <20030806135418.1ab0f296.benny@kramekweb.com> Hi, this is my first message here. This is what I would like to do: an abstract class in c++ a python class inherits from this class python code calls a c++ function that takes as an argument an instance of the c++ abstract base class Here is a simple code example of what I tried //--- animal.cpp --- #include using namespace boost::python; class Animal { public: virtual void sleep(int hours) = 0; }; class AnimalWrap : public Animal { public: AnimalWrap(PyObject* self_) : self(self_) {} void sleep(int hours) { return call_method(self, "sleep"); } PyObject* self; }; void checkAnimal(Animal* animal) { // ... } BOOST_PYTHON_MODULE(animal) { class_("Animal", no_init) ; def("checkAnimal", checkAnimal); } //--- animal.cpp --- # --- baboon.py --- import animal class Baboon(animal.Animal): def __init__(self): pass def sleep(self, hours): print 'sleeping' george = Baboon() animal.checkAnimal(george) # --- baboon.py --- when I execute baboon.py I get the following error: Traceback (most recent call last): File "baboon.py", line 11, in ? animal.checkAnimal(george) TypeError: bad argument type for built-in operation I also tried changing the checkAnimal c++ function to take a reference as an argument instead of a pointer, but i get the same error. Thank you, Benny Kramek From prabhu at aero.iitm.ernet.in Wed Aug 6 13:11:21 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Wed, 6 Aug 2003 16:41:21 +0530 Subject: [C++-sig] Python and C++ - Newbie question !! In-Reply-To: <200308060147.56718.skchim0@engr.uky.edu> References: <200308060147.56718.skchim0@engr.uky.edu> Message-ID: <16176.57945.949490.391246@monster.linux.in> Hi, >>>>> "SKC" == satish k chimakurthi writes: [snip] SKC> However, I need to do the same thing from python. I would SKC> like to use python as an input mechanism to this code and SKC> would like to make it in the Overture framework from SKC> Python. The python module that we generate to do this should SKC> be in a position to understand the functionality of all the SKC> classes which are defined somewhere in the software but whose SKC> objects are declared in the code that we write in OVERTURE. SKC> Can someone tell me how I can go about this ?? You'll need to wrap parts of the Overture library to Python and this will require quite a bit of effort initially. You only need to wrap parts that you intend to use. Once you wrap the libraries to Python you can use Overture from Python. You can use Boost.Python or SWIG to generate the Python wrappers. You'll need to read the respective tutorials/manuals, start with the small examples, get familiar and then go on to try and wrap Overture itself. >From what I can tell of Overture this is not going to be a trivial project. Good luck! cheers, prabhu From dave at boost-consulting.com Wed Aug 6 13:29:48 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 07:29:48 -0400 Subject: [C++-sig] Re: INTERFACING C++ TO PYTHON In-Reply-To: <200308060048.46134.skchim0@engr.uky.edu> (satish k. chimakurthi's message of "Wed, 6 Aug 2003 00:48:46 -0400") References: <200308060048.46134.skchim0@engr.uky.edu> Message-ID: "satish k.chimakurthi" writes: > Dear sir, > > I am a grad.student at the UNIVERSITY OF KENTUCKY. This mail is with reference > to "Boost.python" that I have come across recently Hi Satish, Please take your Boost.Python questions to the C++-sig: http://www.boost.org/mailing_lists.htm#cplussig > I am basically a newbie in python. In my research I need to use > LLNL'S "Overture-ogen C++ software framework" for grid generation. > > I wrote a small code for my application using this huge C++ > framework which is I can run this code within the "Overture > framework" using standard rules for making which I have in a > Makefile > > However, I would want to use PYTHON to do the samething and would > like to glue my C++ code to python so that I can use python not only > as an input mechanism to this code, but also run my code in the > OVERTURE FRAMEWORK, but from outside. In short, I would like to > provide an interface to this C++ framework so that I can access the > various features of the framework by mere manipulation of my > underlying C++ code that I would write. > > Can I use Boost.python to do this ?? Probably. If I understand you correctly, that's what Boost.Python is made for. > Can you cite any references to learn more about this ?? Did you read the documentation at http://www.boost.org/libs/python? > Thanks in advance for your time and patience, > > With Best Regards, > > Satish I'm happy to help. > -- > SATISH K.CHIMAKURTHI > GRAD. RESEARCH ASSISTANT > UNIVERSITY OF KENTUCKY > LEXINGTON > KENTUCKY STATE > -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 13:43:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 07:43:20 -0400 Subject: [C++-sig] Re: const char arrays References: <3F307E08.3651.3AD182F4@localhost> <20030806054533.88952.qmail@web20209.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- Niall Douglas wrote: >> struct custom_string_to_python_str >> { >> static PyObject* convert(custom_string const& s) >> { >> return >> boost::python::incref(boost::python::object(s.value()).ptr()); >> } >> }; >> >> Isn't this making use of boost.python's inbuilt std::string >> converter? ie; it's not converting to a python string itself. > > Yes. Just to keep the example simple. Or maybe because I was too lazy to figure > out the raw C API call. Err, no. Trace it in a debugger; the conversion should not go through std::string at all. If it does I'm very surprised. >> For some non-std::string based string, would it be more like: >> >> struct custom_string_to_python_str >> { >> static PyObject* convert(custom_string const& s) >> { >> return >> boost::python::incref(PyString_FromStringAndSize(s.text(), >> s.length())); >> } >> }; > > Close, but I think you are leaking a reference count. This should do the job: > > return PyString_FromStringAndSize(s.text(), s.length()); > > The bottom line is that you have to return a new Python reference. > How exactly you do this is entirely up to you. On the other hand, Ralf's instincts were good; it's generally better to use high-level Boost.Python calls than low-level Python 'C' API calls. When the converter mechanism is ready for us to document, it will probably not be returning raw PyObject*s. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 13:47:37 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 07:47:37 -0400 Subject: [C++-sig] Re: Inheriting a Python class from a C++ class References: <20030806135418.1ab0f296.benny@kramekweb.com> Message-ID: Benny Kramek writes: > Hi, this is my first message here. > > This is what I would like to do: > > an abstract class in c++ > a python class inherits from this class > python code calls a c++ function that takes as an argument an instance > of the c++ abstract base class > > Here is a simple code example of what I tried > > //--- animal.cpp --- > > #include > > using namespace boost::python; > > class Animal > { > public: > virtual void sleep(int hours) = 0; > }; > > class AnimalWrap : public Animal > { > public: > AnimalWrap(PyObject* self_) : self(self_) {} > void sleep(int hours) { return call_method(self, "sleep"); } > PyObject* self; > }; > > void checkAnimal(Animal* animal) > { > // ... > } > > BOOST_PYTHON_MODULE(animal) > { > class_("Animal", no_init) ^^^^^^^ You have to eliminate this. > ; > > def("checkAnimal", checkAnimal); > } > > //--- animal.cpp --- > > # --- baboon.py --- > > import animal > > class Baboon(animal.Animal): > def __init__(self): > pass and ^^^^^^^^^^^^^^^^^^^ this. Your Baboon class must contain an Animal class somewhere, or it will never be able to be passed where an Animal* is expected. You can also def __init__(self): animal.Animal.__init__(self) of course. > def sleep(self, hours): > print 'sleeping' > > george = Baboon() > > animal.checkAnimal(george) > > # --- baboon.py --- > > when I execute baboon.py I get the following error: > > Traceback (most recent call last): > File "baboon.py", line 11, in ? > animal.checkAnimal(george) > TypeError: bad argument type for built-in operation > > I also tried changing the checkAnimal c++ function to take a > reference as an argument instead of a pointer, but i get the same > error. > > Thank you, > Benny Kramek -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Wed Aug 6 14:19:01 2003 From: romany at actimize.com (Roman Yakovenko) Date: Wed, 6 Aug 2003 15:19:01 +0300 Subject: [C++-sig] Re: property and documentation Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020600@exchange.adrembi.com> Done. If this version is not good for you I will fix it too. Thanks for good library. Roman > -----Original Message----- > From: David Abrahams [mailto:dave at boost-consulting.com] > Sent: Tuesday, August 05, 2003 8:14 PM > To: c++-sig at python.org > Subject: [C++-sig] Re: property and documentation > > > "Roman Yakovenko" writes: > > > Also I send you 2 files. I believe that I checked all cases. > > Also I believe that you will find some things that I will > have to fix. > > (Life is not easy as I'd like to be.) > > Yup. Please reformulate the python file using doctest or the > unittest module. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.py Type: application/octet-stream Size: 1562 bytes Desc: properties.py URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.cpp Type: application/octet-stream Size: 1931 bytes Desc: properties.cpp URL: From dave at boost-consulting.com Wed Aug 6 14:50:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 08:50:53 -0400 Subject: [C++-sig] Re: def_readonly and const array members References: <3C609AD34AAF22488364057AA72EAC14019EE474@adsl-64-170-107-114.dsl.snfc21.pacbell.net> Message-ID: "Jeff Brewer" writes: > I am trying to wrap structs that have character arrays and I'm having > problems since I moved from MSVC 7 to MSVC 7.1 (VS .NET 2003). Here is > the struct I'm trying to expose the theArray member of using > class_::def_readonly: > > struct testStruct > { > unsigned char theArray[16]; > }; > > I've created a to_python converter for the unsigned char [16] type but > I'm getting a "TypeError: No to_python (by-value) converter found for > C++ type: unsigned char const volatile [8]" when I try to access the > theArray member in Python. I've tried putting volatile in my typedef for > the array, but that doesn't seem to help (how C++ binds these type > modifiers always confuses me so maybe I put it in the wrong place). > > Thank you for the help, > > Jeff Brewer > jeff at purplemagma.com Jeff, the problem appears to be a bug in MSVC 7.1, namely that typeid(unsigned char[16]) != typeid(unsigned char const volatile[16]) As it should be. I'm looking into a workaround now. -- Dave Abrahams Boost Consulting www.boost-consulting.com From abeyer at uni-osnabrueck.de Wed Aug 6 15:04:24 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Wed, 6 Aug 2003 15:04:24 +0200 (CEST) Subject: [C++-sig] Containers for derived classes Message-ID: <1201.192.124.248.20.1060175064.squirrel@webmail.rz.uni-osnabrueck.de> I would like to do the following: In C++: Class "C" is a container holding objects of type "A". In Python: Class "B" is derived from class "A" and instances of "B" get stored in containers of type "C". When I store objects of Type B in C, they get 'downcasted' to A. Objects returned from the container are hence no longer of type B, but of type A. Of course I could store the original boost::python::object somewhere. However, the FAQ says there are more elegant ways by using boost::shared_ptr: "When a shared_ptr is converted back to Python, the library checks to see if it's one of those "Python object managers" and if so just returns the original Python object." I have played with it, but I had no luck so far. Has anyone an example using shared_ptr that fits my purpose? Thanks! Andreas From dave at boost-consulting.com Wed Aug 6 15:42:17 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 09:42:17 -0400 Subject: [C++-sig] Re: def_readonly and const array members In-Reply-To: <3C609AD34AAF22488364057AA72EAC14019EE474@adsl-64-170-107-114.dsl.snfc21.pacbell.net> (Jeff Brewer's message of "Thu, 24 Jul 2003 15:35:01 -0700") References: <3C609AD34AAF22488364057AA72EAC14019EE474@adsl-64-170-107-114.dsl.snfc21.pacbell.net> Message-ID: "Jeff Brewer" writes: > I am trying to wrap structs that have character arrays and I'm having > problems since I moved from MSVC 7 to MSVC 7.1 (VS .NET 2003). Here is > the struct I'm trying to expose the theArray member of using > class_::def_readonly: > > struct testStruct > { > unsigned char theArray[16]; > }; > > I've created a to_python converter for the unsigned char [16] type but > I'm getting a "TypeError: No to_python (by-value) converter found for > C++ type: unsigned char const volatile [8]" when I try to access the > theArray member in Python. I've tried putting volatile in my typedef for > the array, but that doesn't seem to help (how C++ binds these type > modifiers always confuses me so maybe I put it in the wrong place). > > Thank you for the help, > > Jeff Brewer > jeff at purplemagma.com Jeff, the problem appears to be a bug in MSVC 7.1, namely that typeid(unsigned char[16]) != typeid(unsigned char const volatile[16]) As it should be. I'm looking into a workaround now. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 15:51:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 09:51:12 -0400 Subject: [C++-sig] Re: def_readonly and const array members References: <3C609AD34AAF22488364057AA72EAC14019EE474@adsl-64-170-107-114.dsl.snfc21.pacbell.net> Message-ID: David Abrahams writes: > "Jeff Brewer" writes: > >> I am trying to wrap structs that have character arrays and I'm having >> problems since I moved from MSVC 7 to MSVC 7.1 (VS .NET 2003). Here is >> the struct I'm trying to expose the theArray member of using >> class_::def_readonly: >> >> struct testStruct >> { >> unsigned char theArray[16]; >> }; >> >> I've created a to_python converter for the unsigned char [16] type but >> I'm getting a "TypeError: No to_python (by-value) converter found for >> C++ type: unsigned char const volatile [8]" when I try to access the >> theArray member in Python. I've tried putting volatile in my typedef for >> the array, but that doesn't seem to help (how C++ binds these type >> modifiers always confuses me so maybe I put it in the wrong place). >> >> Thank you for the help, >> >> Jeff Brewer >> jeff at purplemagma.com > > Jeff, the problem appears to be a bug in MSVC 7.1, namely that > > typeid(unsigned char[16]) != typeid(unsigned char const volatile[16]) > > As it should be. I'm looking into a workaround now. Done and checked in. Here's the patch to boost/python/registered.hpp: --- registered.hpp.~1.2.~ 2002-08-14 02:26:32.000000000 -0400 +++ registered.hpp 2003-08-06 09:49:09.000000000 -0400 @@ -10,6 +10,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -34,10 +35,15 @@ { }; -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// collapses a few more types to the same static instance +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) +// collapses a few more types to the same static instance. MSVC7.1 +// fails to strip cv-qualification from array types in typeid. For +// some reason we can't use this collapse there or array converters +// will not be found. template -struct registered : registered {}; +struct registered + : registered {}; # endif // -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 15:54:07 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 09:54:07 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1201.192.124.248.20.1060175064.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: > I would like to do the following: > > In C++: > Class "C" is a container holding objects of type "A". > > In Python: > Class "B" is derived from class "A" and instances of "B" get stored in > containers of type "C". > > When I store objects of Type B in C, they get 'downcasted' to A. That direction is normally referred to as "up", and if you're really holding A's by value, you're "slicing", not "upcasting". > Objects > returned from the container are hence no longer of type B, but of type A. > Of course I could store the original boost::python::object somewhere. > However, the FAQ says there are more elegant ways by using > boost::shared_ptr: > "When a shared_ptr is converted back to Python, the library checks to > see if it's one of those "Python object managers" and if so just returns > the original Python object." > > I have played with it, but I had no luck so far. What did you do? Please post some code which illustrates. > Has anyone an example using shared_ptr that fits my purpose? If you make C a container of shared_ptr, it should just work. -- Dave Abrahams Boost Consulting www.boost-consulting.com From abeyer at uni-osnabrueck.de Wed Aug 6 16:58:26 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Wed, 6 Aug 2003 16:58:26 +0200 (CEST) Subject: [C++-sig] Re: Containers for derived classes Message-ID: <1288.192.124.248.20.1060181906.squirrel@webmail.rz.uni-osnabrueck.de> >> However, the FAQ says there are more elegant ways by using >> boost::shared_ptr: >> "When a shared_ptr is converted back to Python, the library checks to >> see if it's one of those "Python object managers" and if so just returns >> the original Python object." >> >> I have played with it, but I had no luck so far. > >What did you do? Please post some code which illustrates. > >> Has anyone an example using shared_ptr that fits my purpose? > >If you make C a container of shared_ptr, it should just work. OK, this is what I have tried: --- begin ptr_test.cpp #include #include using namespace boost; class A { public: A(int i) : val(i) { } int val; }; typedef shared_ptr A_ptr; class C { public: void set(A_ptr& a) { this->a=a; } A_ptr& get() { return this->a; } private: A_ptr a; }; BOOST_PYTHON_MODULE(ptr_test) { using namespace boost::python; class_("A", init< int >() ) .def_readwrite("val", &A::val) ; class_("C", init< >() ) .def("set", &C::set, with_custodian_and_ward<1, 2>()) .def("get", &C::get, return_internal_reference<>() ) ; } --- end ptr_test.cpp This code raises a TypeError in Python: >>> from ptr_test import * >>> a=A(0) >>> c=C() >>> c.set(a) Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation I can change the module definition for class A to: // ... class_("A", init< int >() ) .def_readwrite("val", &A::val) ; // ... Then I get the following: >>> from ptr_test import * >>> a=A(0) >>> c=C() >>> c.set(a) >>> a1=c.get() Traceback (most recent call last): File "", line 1, in ? TypeError: No Python class registered for C++ class N5boost10shared_ptrI1AEE From nickm at sitius.com Wed Aug 6 21:21:05 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Wed, 06 Aug 2003 15:21:05 -0400 Subject: [C++-sig] Re: Anonymous CVS mirror References: Message-ID: <3F315521.DDB3A09@sitius.com> Dave, Is it really every night? has_xxx.hpp is still 1.16 in your mirror. Nikolay David Abrahams wrote: > > After several days of work, there is now an anonymous mirror of our > CVS repository, decompressed each night from the current SourceForge > CVS tarball: > > cvs -d :pserver:anonymous at boost-consulting.com:/boost login > ?no password? > > cvs -d :pserver:anonymous at boost-consulting.com:/boost co boost > > Enjoy, > Dave > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 21:45:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 15:45:29 -0400 Subject: [C++-sig] Re: Anonymous CVS mirror References: <3F315521.DDB3A09@sitius.com> Message-ID: Nikolay Mladenov writes: > Dave, > > Is it really every night? has_xxx.hpp is still 1.16 in your mirror. Yes, but I don't know what time the cvs tarball at SF gets updated. If you can find out when that is, I'll set the cron job to update the repository afterwards. In the meantime, I'll run the script again. THe new repository image should be up there in a half hour. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 6 21:42:18 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Aug 2003 15:42:18 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1288.192.124.248.20.1060181906.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: >>> However, the FAQ says there are more elegant ways by using >>> boost::shared_ptr: >>> "When a shared_ptr is converted back to Python, the library checks to >>> see if it's one of those "Python object managers" and if so just returns >>> the original Python object." >>> >>> I have played with it, but I had no luck so far. >> >>What did you do? Please post some code which illustrates. >> >>> Has anyone an example using shared_ptr that fits my purpose? >> >>If you make C a container of shared_ptr, it should just work. > > OK, this is what I have tried: > > --- begin ptr_test.cpp > > #include > #include > > using namespace boost; > > class A { > public: > A(int i) : val(i) { } > int val; > }; > typedef shared_ptr A_ptr; > > class C { > public: > void set(A_ptr& a) { this->a=a; } ^^^^^^ This is your problem. Use A_ptr const& or better yet, plain A_ptr. Using a non-const reference means that Boost.Python has to find an actual A_ptr object within the source Python object. > A_ptr& get() { return this->a; } Likewise, you'd be better off just returning by-value here. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Thu Aug 7 00:03:55 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 6 Aug 2003 15:03:55 -0700 (PDT) Subject: [C++-sig] Re: Anonymous CVS mirror In-Reply-To: Message-ID: <20030806220355.3149.qmail@web20208.mail.yahoo.com> --- David Abrahams wrote: > Yes, but I don't know what time the cvs tarball at SF gets updated. > If you can find out when that is, I'll set the cron job to update the > repository afterwards. It wouldn't be hard to set up a script that automatically cvs update's every hour using a regular Sourceforge user ID and password. Recently this works very reliably. The next step would be to strip out the "CVS" directories and pack everything into a .tar.gz file to be posted on the web. Does this sound interesting? Ralf __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From abeyer at uni-osnabrueck.de Thu Aug 7 09:56:26 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Thu, 7 Aug 2003 09:56:26 +0200 (CEST) Subject: [C++-sig] Re: Containers for derived classes Message-ID: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> > abeyer at uni-osnabrueck.de writes: > >>>> However, the FAQ says there are more elegant ways by using >>>> boost::shared_ptr: >>>> "When a shared_ptr is converted back to Python, the library checks to >>>> see if it's one of those "Python object managers" and if so just returns >>>> the original Python object." >>>> >>>> I have played with it, but I had no luck so far. >>> >>>What did you do? Please post some code which illustrates. >>> >>>> Has anyone an example using shared_ptr that fits my purpose? >>> >>>If you make C a container of shared_ptr, it should just work. >> >> OK, this is what I have tried: >> >> --- begin ptr_test.cpp >> >> #include >> #include >> >> using namespace boost; >> >> class A { >> public: >> A(int i) : val(i) { } >> int val; >> }; >> typedef shared_ptr A_ptr; >> >> class C { >> public: >> void set(A_ptr& a) { this->a=a; } > ^^^^^^ > > This is your problem. Use A_ptr const& or better yet, plain A_ptr. > > Using a non-const reference means that Boost.Python has to find an > actual A_ptr object within the source Python object. > >> A_ptr& get() { return this->a; } > > Likewise, you'd be better off just returning by-value here. Sorry, it still doesn't work: class C { public: void set(A_ptr a) { this->a=a; } A_ptr get() { return this->a; } private: A_ptr a; }; BOOST_PYTHON_MODULE(ptr_test) { using namespace boost::python; class_("A", init< int >() ) .def_readwrite("val", &A::val) ; class_("C", init< >() ) .def("set", &C::set ) .def("get", &C::get ) ; } Then, I get in Python: >>> from ptr_test import * >>> a=A(0) >>> c=C() >>> c.set(a) >>> a1=c.get() >>> a >>> a1 >>> a.val 0 >>> a1.val 0 >>> a.val=1 >>> a1.val 1 >>> Hence, a and a1 are not the same Python objects, but the same C++ objects. Thus, sub-classing A still doesn't work: >>> class B(A): ... def __init__(self, i): ... A.__init__(self, i) ... self.name = "foo" ... >>> b=B(0) >>> c.set(b) >>> b1=c.get() >>> b <__main__.B object at 0x008F77B0> >>> b1 >>> From dave at boost-consulting.com Thu Aug 7 13:49:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Aug 2003 07:49:38 -0400 Subject: [C++-sig] Re: Anonymous CVS mirror References: <20030806220355.3149.qmail@web20208.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> Yes, but I don't know what time the cvs tarball at SF gets updated. >> If you can find out when that is, I'll set the cron job to update the >> repository afterwards. > > It wouldn't be hard to set up a script that automatically cvs update's every > hour using a regular Sourceforge user ID and password. Recently this works very > reliably. The next step would be to strip out the "CVS" directories and pack > everything into a .tar.gz file to be posted on the web. Does this sound > interesting? Oh, sure. You don't even need to strip out CVS directories; just use "cvs export". -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Aug 7 13:51:24 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Aug 2003 07:51:24 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: > Hence, a and a1 are not the same Python objects, but the same C++ objects. > Thus, sub-classing A still doesn't work: Which version of Boost.Python are you using? I wouldn't expect it to work with any released version. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Aug 7 15:42:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Aug 2003 09:42:41 -0400 Subject: [C++-sig] Re: boost.python, native arrays like double a[3] in classes howto?? In-Reply-To: <23518.1060250781@www60.gmx.net> (antonxx@gmx.de's message of "Thu, 7 Aug 2003 12:06:21 +0200 (MEST)") References: <23518.1060250781@www60.gmx.net> Message-ID: The following message is a courtesy copy of an article that has been posted to gmane.comp.lib.boost.devel as well. antonxx at gmx.de writes: Stephane, Please bring your Boost.Python questions to the C++-sig (see http://www.boost.org/more/mailing_lists.htm#cplussig). In fact if you scan the recent archives of that list you'll see that a very similar question was answered just yesterday. > Hi I have a class like: > > class MyClass { > public: > double myvector[3]; > }; > > Is it possible to use it in boost.python 1.30.0? > I did not find information howto do this, > but I also did not find information thats its not possible. > > My problem I get compiler errors When requesting support please show the code you wrote and the errors it produced. Regards, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Thu Aug 7 19:33:56 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Thu, 07 Aug 2003 13:33:56 -0400 Subject: [C++-sig] Problem with BPL from cvs Message-ID: <3F328D84.36277C3E@sitius.com> I started building with very recent version from the cvs, and something that was building 1_29_0 now fails. I have a small example that duplicates it. Tried compiling with MSVC 6.5 with and without STLPort-4.5.3 ////////////////////////////////////////////////// class OBJ{ public : class PROP{}; PROP prop() const; }; #include using namespace boost::python; object get_prop(const OBJ &o) { return o.prop(); } BOOST_PYTHON_MODULE(obj) { scope s( class_("OBJ" ) .def("prop", &get_prop) ); class_ ("PROP"); } //////////////////////////////////////////////// the error message is: d:\projects\boost_1_31_0\boost\boost\python\object_core.hpp(231) : error C2893: Failed to specialize function template 'const T *__cdecl boost::python::api::object::to_ptr(const T &)' With the following template arguments: 'class OBJ::PROP' s:\temp\inner.cpp(12) : see reference to function template instantiation '__thiscall boost::python::api::object::boost::python::api::object(const class OBJ::PROP &)' being compiled d:\projects\boost_1_31_0\boost\boost\python\object_core.hpp(231) : error C2143: syntax error : missing ')' before 'const' s:\temp\inner.cpp(12) : see reference to function template instantiation '__thiscall boost::python::api::object::boost::python::api::object(const class OBJ::PROP &)' being compiled d:\files\microsoft visual studio\vc98\include\xmemory(70) : fatal error C1004: unexpected end of file found s:\temp\inner.cpp(12) : see reference to function template instantiation '__thiscall boost::python::api::object::boost::python::api::object(const class OBJ::PROP &)' being compiled Error executing cl.exe. From dave at boost-consulting.com Thu Aug 7 21:02:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Aug 2003 15:02:30 -0400 Subject: [C++-sig] Re: Problem with BPL from cvs References: <3F328D84.36277C3E@sitius.com> Message-ID: Nikolay Mladenov writes: > I started building with very recent version from the cvs, > and something that was building 1_29_0 now fails. > I have a small example that duplicates it. > Tried compiling with MSVC 6.5 with and without STLPort-4.5.3 > > ////////////////////////////////////////////////// > class OBJ{ > public : > class PROP{}; > PROP prop() const; > }; > > #include > > using namespace boost::python; > object get_prop(const OBJ &o) > { > return o.prop(); ^^^^^^^^ object(o.prop()) The object constructor is explicit. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Thu Aug 7 21:17:13 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Thu, 07 Aug 2003 15:17:13 -0400 Subject: [C++-sig] Re: Problem with BPL from cvs References: <3F328D84.36277C3E@sitius.com> Message-ID: <3F32A5B9.C46560EB@sitius.com> Thanks, I've missed that. But it doesn't change much, still the same errors David Abrahams wrote: > > Nikolay Mladenov ?nickm at sitius.com? writes: > > ? I started building with very recent version from the cvs, > ? and something that was building 1_29_0 now fails. > ? I have a small example that duplicates it. > ? Tried compiling with MSVC 6.5 with and without STLPort-4.5.3 > ? > ? ////////////////////////////////////////////////// > ? class OBJ{ > ? public : > ? class PROP{}; > ? PROP prop() const; > ? }; > ? > ? #include ?boost/python.hpp? > ? > ? using namespace boost::python; > ? object get_prop(const OBJ ?o) > ? { > ? return o.prop(); > ^^^^^^^^ > object(o.prop()) > > The object constructor is explicit. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com From rwgk at yahoo.com Thu Aug 7 21:11:24 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 7 Aug 2003 12:11:24 -0700 (PDT) Subject: [C++-sig] Re: Anonymous CVS mirror In-Reply-To: Message-ID: <20030807191124.60143.qmail@web20207.mail.yahoo.com> --- David Abrahams wrote: > Oh, sure. You don't even need to strip out CVS directories; just use > "cvs export". But cvs update consumes less bandwidth at Sourceforge. I'll try to work on it later. Ralf __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From dave at boost-consulting.com Thu Aug 7 21:15:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Aug 2003 15:15:19 -0400 Subject: [C++-sig] Re: Problem with BPL from cvs References: <3F328D84.36277C3E@sitius.com> <3F32A5B9.C46560EB@sitius.com> Message-ID: Nikolay Mladenov writes: > Thanks, I've missed that. > But it doesn't change much, still the same errors Compiler bug, sorry. I don't know how to help. You probably ought to ask on some MS-specific group. -- Dave Abrahams Boost Consulting www.boost-consulting.com From chrisby_1 at hotmail.com Thu Aug 7 21:59:02 2003 From: chrisby_1 at hotmail.com (Chris Berry) Date: Thu, 07 Aug 2003 19:59:02 +0000 Subject: [C++-sig] (no subject) Message-ID: Hi There! I'm browseing the net looking for a modern day general Programmers C++ referencing manual that is not selective. I came across your email on Google and wondered if you might be able to suggest one. I'm currently programming using a C++ compiler in Linux Mandrake 9.1 with the FLTK library and have hit a snag with one of the generation variables 'addchild'. Most of the C++ books I have are selective, ie: msn, Boreland etc: and are unhelpful. Hope you don't mind me asking. Best wishes.....................................Chris J Berry (MR) _________________________________________________________________ Tired of 56k? Get a FREE BT Broadband connection http://www.msn.co.uk/specials/btbroadband From s_sourceforge at nedprod.com Fri Aug 8 03:25:05 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Fri, 8 Aug 2003 02:25:05 +0100 Subject: [C++-sig] Boost.python suggestion + pyste bug Message-ID: <3F330A01.29851.5B23910@localhost> It's taken me a few hours, but I've finally found the cause of the mysterious "AttributeError: can't set attribute" error I kept getting when I imported my wrapper dll. If you replace line 29 to 32 in errors.cpp with: catch(const boost::python::error_already_set&) { // The python error reporting has already been handled. PyErr_SetString(PyExc_RuntimeError, "Boost.python API wrapped more than once"); } Then you'll get a much nicer and useful error message. I appreciate that the comment implies it's already been handled, but I'm definitely getting "AttributeError: can't set attribute" here which is really not useful. Oh Nicodemus! Pyste is generating multiple def()'s with the same name where it doesn't need them. Here's what's happening: if A inherits B which inherits C and each of A, B & C provide a method called "metaClass", then when wrapping A only pyste currently adds a .def("metaClass", &X::metaClass) where X is A,B,C ie; it adds one for B & C too where under C++ inheritance rules B::metaClass() and C::metaClass() disappear. It shouldn't add the B::metaClass() nor C::metaClass(). A similar problem exists where A, B & C all define a class (let's call it FXMapEntry). Once again pyste writes out class definitions for each and every FXMapEntry for each of A, B & C where really it should only do so for A::FXMapEntry. And lastly, the other similar problem is for enum's. If A, B & C all define an enum where C::ID_LAST is B::ID_FIRST and B::ID_LAST is A::ID_FIRST etc. then pyste defines all the ID_LAST's and ID_FIRST's (and thus causing a runtime error). It should in this case only define those items defined in the most derived class. Speaking of enum's, multiple anonymous enum's (which pyste generates as _enum) cause boost.python to die because it likes every enum's first parameter to be a unique type (couldn't we change this behaviour for simple types?). I worked around this by having pyste specify a "UniqueInt" where n is a globally incremented counter. The definition of UniqueInt is: template struct UniqueInt { int v; enum { value=num }; UniqueInt(int _v) : v(_v) { } operator int() const { return v; } }; Lastly, am I right in thinking that pyste currently does not use boost.python's ability to represent C++ class inheritance trees the same in python classes? I'm thinking that if you were to add support for this, it kinda works with the fixes necessary for fixing the bugs above. Cheers, Niall From nicodemus at globalite.com.br Fri Aug 8 05:01:58 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 08 Aug 2003 00:01:58 -0300 Subject: [C++-sig] Boost.python suggestion + pyste bug In-Reply-To: <3F330A01.29851.5B23910@localhost> References: <3F330A01.29851.5B23910@localhost> Message-ID: <3F3312A6.2030803@globalite.com.br> Hi Niall, Niall Douglas wrote: >Oh Nicodemus! Pyste is generating multiple def()'s with the same name >where it doesn't need them. Here's what's happening: if A inherits B >which inherits C and each of A, B & C provide a method called >"metaClass", then when wrapping A only pyste currently adds a >.def("metaClass", &X::metaClass) where X is A,B,C ie; it adds one for >B & C too where under C++ inheritance rules B::metaClass() and >C::metaClass() disappear. It shouldn't add the B::metaClass() nor >C::metaClass(). > >A similar problem exists where A, B & C all define a class (let's >call it FXMapEntry). Once again pyste writes out class definitions >for each and every FXMapEntry for each of A, B & C where really it >should only do so for A::FXMapEntry. > >And lastly, the other similar problem is for enum's. If A, B & C all >define an enum where C::ID_LAST is B::ID_FIRST and B::ID_LAST is >A::ID_FIRST etc. then pyste defines all the ID_LAST's and ID_FIRST's >(and thus causing a runtime error). It should in this case only >define those items defined in the most derived class. > Ouch! Those were really serious, thanks a lot for the report! I fixed them in the CVS, and added a test case that exercices this. >Speaking of enum's, multiple anonymous enum's (which pyste generates >as _enum) cause boost.python to die because it likes >every enum's first parameter to be a unique type (couldn't we change >this behaviour for simple types?). I worked around this by having >pyste specify a "UniqueInt" where n is a globally incremented >counter. The definition of UniqueInt is: > >template struct UniqueInt { int v; enum { value=num }; >UniqueInt(int _v) : v(_v) { } operator int() const { return v; } }; > > Hmm, thanks again for reporting this. I'll fix this as soon as possible. >Lastly, am I right in thinking that pyste currently does not use >boost.python's ability to represent C++ class inheritance trees the >same in python classes? I'm thinking that if you were to add support >for this, it kinda works with the fixes necessary for fixing the bugs >above. > What do you mean? It should export classes in the same way as if you were doing it by hand, but automatically. One difference is that it now automatically exports the members of base classes that were not exported themselves, as a feature request here in the list: struct A { void foo(); }; struct B: A { void bar(); }; If you export only B, you will get A's foo method too, as if you were exporting both A and B. Regards, Nicodemus. From fincher.8 at osu.edu Fri Aug 8 07:42:01 2003 From: fincher.8 at osu.edu (Jeremy Fincher) Date: Fri, 8 Aug 2003 01:42:01 -0400 Subject: [C++-sig] A few questions... Message-ID: <200308080142.01728.fincher.8@osu.edu> I'm new to Boost::Python (and C++ in general, though I'm at least somewhat more experienced with C++ than B::P :)), and am having a bit of trouble with it. First, it seems that Debian doesn't include bjam in its boost packages; I've read in several places that it's just as possible to compile Boost (and Boost::Python) stuff with make. Does anyone have any Makefiles they've used to compile a Boost::Python project that I could examine and learn from? Also, the documentation on special operators seems to be a bit unclear. The documentation says this about the Rational example: "What is the business of operator<< .def(str(self))? Well, the method str requires the operator<< to do its work (i.e. operator<< is used by the method defined by def(str(self)). " Does this mean that if I use ".def(str(self))" in my class_ definition, I need to have defined an overloaded << in the same way? My actual class defines a method "std::string str()" -- is there a way to declare that as my Python __str__ method? If I could compile my code, I'd try out '.def("__str__", &IrcMsg::str)', but I can't :| I've got a question or two more about how to declare an __init__ with keyword parameters, but I'll wait until I can compile my code to ask that :) Thanks! Jeremy From fincher.8 at osu.edu Fri Aug 8 10:53:26 2003 From: fincher.8 at osu.edu (Jeremy Fincher) Date: Fri, 8 Aug 2003 04:53:26 -0400 Subject: [C++-sig] A few questions... In-Reply-To: <200308080142.01728.fincher.8@osu.edu> References: <200308080142.01728.fincher.8@osu.edu> Message-ID: <200308080453.26892.fincher.8@osu.edu> I've resolved most of my issues in my previous email; I've gotten my module compiled, it imports, and most everything works well. One thing I'm missing is the ability to expose an attribute of my class that's a std::vector. I get: >>> m.args Traceback (most recent call last): File "", line 1, in ? TypeError: No Python class registered for C++ class St6vectorISsSaISsEE when I try to access that attribute. What do I need to do to expose that attribute? Also, I've noticed this: >>> id(m.host) 135696488 >>> id(m.host) 135694928 Apparently the host attribute (as well as all the other wrapped std::string attributes) is being copied every time it's accessed. These are constant strings that should remain alive as long as the message itself (m, in this case) is alive. What can I do to prevent this needless copying from occurring? I read about the various call policies, but I had a hard time understanding them and none immediately struck me as applicable. That's all (for now! Bwahaha!) Thanks, Jeremy From brett.calcott at paradise.net.nz Fri Aug 8 10:02:38 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Fri, 8 Aug 2003 18:02:38 +1000 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: > > Sorry, it still doesn't work: > > class C { > public: > void set(A_ptr a) { this->a=a; } > A_ptr get() { return this->a; } > private: > A_ptr a; > }; > > BOOST_PYTHON_MODULE(ptr_test) > { > using namespace boost::python; > class_("A", init< int >() ) > .def_readwrite("val", &A::val) > ; > class_("C", init< >() ) > .def("set", &C::set ) > .def("get", &C::get ) > ; > } > > Then, I get in Python: > >>> from ptr_test import * > >>> a=A(0) > >>> c=C() > >>> c.set(a) > >>> a1=c.get() > >>> a > > >>> a1 > > >>> a.val > 0 > >>> a1.val > 0 > >>> a.val=1 > >>> a1.val > 1 > >>> > Hence, a and a1 are not the same Python objects, but the same C++ objects. > Thus, sub-classing A still doesn't work: > > >>> class B(A): > ... def __init__(self, i): > ... A.__init__(self, i) > ... self.name = "foo" > ... > >>> b=B(0) > >>> c.set(b) > >>> b1=c.get() > >>> b > <__main__.B object at 0x008F77B0> > >>> b1 > > >>> The problem is that for python object 'identity' the PyObject must survive making it from the python interpreter to C++, and back again. In this case it doesn't -- it is deleted when you set it, and a new one is constructed when it returns. Try this instead: ... // class_("A", init< int >() ) class_("A", init< int >() ) ... This does work. Why? Because Boost.Python uses shared_ptr *internally* to construct this object, and it does it in a special way so that the PyObject is referenced as part of the shared_ptr construct -- so it survives the round trip. Unfortunately, you can no longer do this (something I'd like to do in a similar situation.) class C { public: void set(A_ptr a) { this->a=a; } A_ptr get() { return this->a; } void create(int i) { a = A_ptr(new A(i)); } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private: A_ptr a; }; >>>c.create(1) >>>c.get() TypeError: No to_python (by-value) converter found for C++ type: class boost::s ared_ptr Because this particular shared_ptr is created in C++, it doesn't have the funky embedded PyObject in it. So, you get identity, but you lose consistent treatment of shared_ptr. I haven't figure a way to work around this... HTH, Brett From brett.calcott at paradise.net.nz Fri Aug 8 10:10:17 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Fri, 8 Aug 2003 18:10:17 +1000 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: > > Unfortunately, you can no longer do this (something I'd like to do in a > similar situation.) > Sorry, this is ambiguous, and may be confusing. I meant "You can no longer do the following...": From dave at boost-consulting.com Fri Aug 8 13:51:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Aug 2003 07:51:19 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: Brett, I hate to be so blunt, but unless I'm misunderstanding you, this explanation is almost completely wrong. "Brett Calcott" writes: > The problem is that for python object 'identity' the PyObject must survive > making it from the python interpreter to C++, and back again. True. > In this case it doesn't -- it is deleted when you set it, and a new > one is constructed when it returns. False; with all recent CVS versions boost::shared_ptr converted from python actually manages the containing Python object and will convert back into the same object when converted to python. > > Try this instead: > > ... > // class_("A", init< int >() ) > class_("A", init< int >() ) > ... > > > This does work. Why? Because Boost.Python uses shared_ptr *internally* to > construct this object ??? False. Where did you get that idea? shared_ptr is not used internally unless you ask for it explicitly AFAICT. > and it does it in a special way so that the PyObject is referenced > as part of the shared_ptr construct -- so it survives the round > trip. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Fri Aug 8 15:57:34 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 8 Aug 2003 19:27:34 +0530 Subject: [C++-sig] Possible bug with HeldType? Message-ID: <16179.44110.910254.135813@monster.linux.in> Hi, I just ran into a problem that I have not seen before with Boost.Python. Consider the following: // ---------------- holder.hpp ---------------------- #include struct A { virtual void f() {}; }; struct Holder { Holder() {} void add(A* a) {arr.push_back(a);} private: std::vector arr; }; // -------------------------------------------------- I wrap this using Pyste and get something that looks like this (edited for brevity): // ---------------- holder.cpp ---------------------- struct A_Wrapper: A { A_Wrapper(PyObject* self_, const A& p0): A(p0), self(self_) {} A_Wrapper(PyObject* self_): A(), self(self_) {} void f() {call_method< void >(self, "f");} void default_f() { A::f(); } PyObject* self; }; void add_wrapper(Holder* c, std::auto_ptr< A > o) { c->add(o.get()); o.release(); } BOOST_PYTHON_MODULE(holder) { class_< A, std::auto_ptr< A_Wrapper > >("A", init< >()) .def(init< const A& >()) .def("f", &A::f, &A_Wrapper::default_f); class_< Holder >("Holder", init< >()) .def(init< const Holder& >()) .def("add", &add_wrapper); } // -------------------------------------------------- This looks correct to my eyes. However I am unable to do something like this in Python: In [1]: import holder In [2]: a = holder.A() In [3]: h = holder.Holder() In [4]: h.add(a) ArgumentError: Python argument types in Holder.add(Holder, A) did not match C++ signature: add(P6Holder, t8auto_ptr1Z1A) I could swear that this code used to work fine a month back. BTW, the new traceback is a nice change from the original unhelpful RuntimeError, thanks! Anyway, I changed: void add_wrapper(Holder* c, std::auto_ptr< A > o) to read like so: void add_wrapper(Holder* c, std::auto_ptr< A_Wrapper > o) and it runs fine. I also noticed that if A does not have virtual functions and I dont create a wrapper, the code works just fine. So is this a bug or am I or Pyste doing something wrong? I'm using boost off CVS and running under Debian GNU/Linux, gcc 2.95.4 20011002 (Debian prerelease). Thanks! cheers, prabhu From abeyer at uni-osnabrueck.de Fri Aug 8 16:56:30 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Fri, 8 Aug 2003 16:56:30 +0200 (CEST) Subject: [C++-sig] Re: Containers for derived classes Message-ID: <1387.192.124.248.20.1060354590.squirrel@webmail.rz.uni-osnabrueck.de> > abeyer at uni-osnabrueck.de writes: > >> Hence, a and a1 are not the same Python objects, but the same C++ objects. >> Thus, sub-classing A still doesn't work: > > Which version of Boost.Python are you using? I wouldn't expect it to > work with any released version. Well, now I have got a CVS version from today (08/08) - downloaded from anonymous at cvs.boost.sourceforge.net:/cvsroot/boost, so it may be 24 hrs old. Still, I am having the same trouble: >>> from ptr_test import * >>> a=A(0) >>> c=C() >>> c.set(a) >>> a1=c.get() >>> a >>> a1 >>> I.e. the identity is not preserved. Could this be a problem with MinGW, which I am using? To be sure, here is the complete code again: #include #include using namespace boost; class A { public: A(int i) : val(i) { } int val; }; typedef shared_ptr A_ptr; class C { public: void set(A_ptr a) { this->a=a; } A_ptr get() { return this->a; } void f() { a.get()->val *= 2; } private: A_ptr a; }; BOOST_PYTHON_MODULE(ptr_test) { using namespace boost::python; class_("A", init< int >() ) .def_readwrite("val", &A::val) ; class_("C" ) .def("set", &C::set ) .def("get", &C::get ) .def("f", &C::f ) ; } From dave at boost-consulting.com Fri Aug 8 18:07:24 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Aug 2003 12:07:24 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1387.192.124.248.20.1060354590.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: > I.e. the identity is not preserved. Could this be a problem with MinGW, > which I am using? > To be sure, here is the complete code again: > > #include > #include > > using namespace boost; > > class A { > public: > A(int i) : val(i) { } > int val; > }; > typedef shared_ptr A_ptr; > > class C { > public: > void set(A_ptr a) { this->a=a; } > A_ptr get() { return this->a; } > void f() { a.get()->val *= 2; } > private: > A_ptr a; > }; > > BOOST_PYTHON_MODULE(ptr_test) > { > using namespace boost::python; > class_("A", init< int >() ) > .def_readwrite("val", &A::val) > ; > class_("C" ) > .def("set", &C::set ) > .def("get", &C::get ) > .def("f", &C::f ) > ; > } OK, I understand the problem now. It's not a MinGW issue. The problem is that when you ask for A to be held by A_ptr, an A_ptr lvalue converter gets registered, since there is actually an A_ptr object inside the Python wrapper. Lvalue converters can be used where only an rvalue is needed, as in: void set(A_ptr a) and they get special priority over rvalue converters. The only way to get the behavior you want is actually to NOT hold A objects by A_ptr: class("A", init() ) ... so that the rvalue converter that gets registered can be found. Clearly, we need special rules for shared_ptr, so that this won't happen. I'm just not sure whether we need special rules for all smart pointer types, yet. Any thoughts? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Aug 8 18:46:39 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Aug 2003 12:46:39 -0400 Subject: [C++-sig] Re: Possible bug with HeldType? References: <16179.44110.910254.135813@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > This looks correct to my eyes. However I am unable to do something > like this in Python: > > In [1]: import holder > In [2]: a = holder.A() > In [3]: h = holder.Holder() > In [4]: h.add(a) > ArgumentError: Python argument types in > Holder.add(Holder, A) > did not match C++ signature: > add(P6Holder, t8auto_ptr1Z1A) > > I could swear that this code used to work fine a month back. BTW, the > new traceback is a nice change from the original unhelpful > RuntimeError, thanks! Use a more-modern GCC and you'll get real type names in there as well. > Anyway, I changed: > > void add_wrapper(Holder* c, std::auto_ptr< A > o) > > to read like so: > > void add_wrapper(Holder* c, std::auto_ptr< A_Wrapper > o) > > and it runs fine. I also noticed that if A does not have virtual > functions and I dont create a wrapper, the code works just fine. > > So is this a bug or am I or Pyste doing something wrong? It surprises me that you're saying the same C++ code worked a month ago. I don't see how that's possible. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Aug 8 19:13:44 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Aug 2003 13:13:44 -0400 Subject: [C++-sig] Re: A few questions... References: <200308080142.01728.fincher.8@osu.edu> <200308080453.26892.fincher.8@osu.edu> Message-ID: Jeremy Fincher writes: > I've resolved most of my issues in my previous email; I've gotten my module > compiled, it imports, and most everything works well. > > One thing I'm missing is the ability to expose an attribute of my class that's > a std::vector. I get: > >>>> m.args > Traceback (most recent call last): > File "", line 1, in ? > TypeError: No Python class registered for C++ class St6vectorISsSaISsEE > > when I try to access that attribute. What do I need to do to expose that > attribute? You could wrap it with class_ >(...) ... But more likely you want to register a custom to-python converter which converts it into a list of Python strings. You might follow http://www.boost.org/libs/python/doc/v2/faq.html#question2 to find more information about how to do that. > Also, I've noticed this: > >>>> id(m.host) > 135696488 >>>> id(m.host) > 135694928 > > Apparently the host attribute (as well as all the other wrapped > std::string attributes) is being copied every time it's accessed. > These are constant strings that should remain alive as long as the > message itself (m, in this case) is alive. What can I do to prevent > this needless copying from occurring? Nothing. A Python string has no way to reference the characters stored inside a std::string. Well, OK, not truly nothing. You could write a thin getter function which returns an object that is wrapped: // untested! struct my_string { my_string(object owner, std::string const& s) : owner(owner), s(s) {} ... // access methods object owner; // keep the owner alive std::string const& s; // reference the underlying string }; template struct wrap_string { my_string get(object self) { return my_string(self, extract()().*pm); } }; ... class_("my_string") .def(...) ; class_("Whatever") .add_property( "some_string_member", &wrap_string::get) ... ; However, I doubt it's worthwhile or any faster than just doing the copying. Why are you worried about copying these strings? > I read about the various call policies, but I had a hard time > understanding them and none immediately struck me as applicable. Right. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Fri Aug 8 19:59:57 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 8 Aug 2003 23:29:57 +0530 Subject: [C++-sig] Re: Possible bug with HeldType? In-Reply-To: References: <16179.44110.910254.135813@monster.linux.in> Message-ID: <16179.58653.637808.177379@monster.linux.in> Hi, >>>>> "DA" == David Abrahams writes: >> I could swear that this code used to work fine a month back. >> BTW, the new traceback is a nice change from the original >> unhelpful RuntimeError, thanks! DA> Use a more-modern GCC and you'll get real type names in there DA> as well. Thats nice! >> Anyway, I changed: >> void add_wrapper(Holder* c, std::auto_ptr< A > o) >> to read like so: >> void add_wrapper(Holder* c, std::auto_ptr< A_Wrapper > o) >> So is this a bug or am I or Pyste doing something wrong? DA> It surprises me that you're saying the same C++ code worked a DA> month ago. I don't see how that's possible. It has been about a month since I touched this code and back then, IIRC, it was working fine. I had a small example that I was using to experiment with std::auto_ptr. From what I can remember it worked then. That was a while back and I might have made some kind of mistake or perhaps not tested it carefully enough. One possibility is that I tested it with a class that had no virtual functions and therefore no wrapper class. Unfortunately, I'm unable to find any hard evidence. Its most likely that I didn't test carefully enough. Anyway, from your response I understand that for classes with virtual functions I need the add_wrapper function to use std::auto_ptr and not std::auto_ptr. This is a bit of a pain with Pyste since if Nicodemus changes the name of the wrapper class I'd have to change the pyste files. Its easy to get things working now since I know how the wrapper classes are named. Is there an alternative way to do this that insulates the user from future changes to the wrapper name? Thanks and sorry for the false alarm. cheers, prabhu From dave at boost-consulting.com Fri Aug 8 23:23:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Aug 2003 17:23:46 -0400 Subject: [C++-sig] Re: Possible bug with HeldType? References: <16179.44110.910254.135813@monster.linux.in> <16179.58653.637808.177379@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Hi, > >>>>>> "DA" == David Abrahams writes: > > >> I could swear that this code used to work fine a month back. > >> BTW, the new traceback is a nice change from the original > >> unhelpful RuntimeError, thanks! > > DA> Use a more-modern GCC and you'll get real type names in there > DA> as well. > > Thats nice! > > >> Anyway, I changed: > >> void add_wrapper(Holder* c, std::auto_ptr< A > o) > >> to read like so: > >> void add_wrapper(Holder* c, std::auto_ptr< A_Wrapper > o) > >> So is this a bug or am I or Pyste doing something wrong? > > DA> It surprises me that you're saying the same C++ code worked a > DA> month ago. I don't see how that's possible. > > It has been about a month since I touched this code and back then, > IIRC, it was working fine. I had a small example that I was using to > experiment with std::auto_ptr. From what I can remember it worked > then. That was a while back and I might have made some kind of > mistake or perhaps not tested it carefully enough. One possibility is > that I tested it with a class that had no virtual functions and > therefore no wrapper class. Sounds likely. > Unfortunately, I'm unable to find any hard evidence. Its most > likely that I didn't test carefully enough. > > Anyway, from your response I understand that for classes with > virtual functions I need the add_wrapper function to use > std::auto_ptr and not std::auto_ptr. No, you can write implicitly_convertible< std::auto_ptr, std::auto_ptr >(); > This is a bit of a pain with Pyste since if Nicodemus changes the > name of the wrapper class I'd have to change the pyste files. Its > easy to get things working now since I know how the wrapper classes > are named. Is there an alternative way to do this that insulates > the user from future changes to the wrapper name? Not that I know of; I guess Nicodemus ought to do this implicitly_convertible trick himself. Hmm, Boost.Python could detect that case and do it for you. > Thanks and sorry for the false alarm. Sure thing. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Sat Aug 9 03:47:28 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 9 Aug 2003 07:17:28 +0530 Subject: [C++-sig] Re: Possible bug with HeldType? In-Reply-To: References: <16179.44110.910254.135813@monster.linux.in> <16179.58653.637808.177379@monster.linux.in> Message-ID: <16180.21168.723671.574050@monster.linux.in> >>>>> "DA" == David Abrahams writes: >> Anyway, from your response I understand that for classes with >> virtual functions I need the add_wrapper function to use >> std::auto_ptr and not std::auto_ptr. DA> No, you can write DA> implicitly_convertible< DA> std::auto_ptr, std::auto_ptr >> (); Neat. >> This is a bit of a pain with Pyste since if Nicodemus changes >> the name of the wrapper class I'd have to change the pyste >> files. Its easy to get things working now since I know how the >> wrapper classes are named. Is there an alternative way to do >> this that insulates the user from future changes to the wrapper >> name? DA> Not that I know of; I guess Nicodemus ought to do this DA> implicitly_convertible trick himself. DA> Hmm, Boost.Python could detect that case and do it for you. That would be great. If not, I'll try and add the implicitly_convertible trick to my 'holder' patch. Thanks! cheers, prabhu From brett.calcott at paradise.net.nz Sat Aug 9 06:20:29 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Aug 2003 14:20:29 +1000 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: > Brett, I hate to be so blunt, but unless I'm misunderstanding you, > this explanation is almost completely wrong. Blunt is fine. honesty won't offend. > > > The problem is that for python object 'identity' the PyObject must survive > > making it from the python interpreter to C++, and back again. > > True. > > > In this case it doesn't -- it is deleted when you set it, and a new > > one is constructed when it returns. > > False; with all recent CVS versions boost::shared_ptr converted from > python actually manages the containing Python object and will convert > back into the same object when converted to python. Ok, I'm confused. Clearly object identity is *not* preserved - so they can't be the same PyObject. Doesn't that require the old one to have been deleted (well, derefed at least) and a new one created? From your other reply it seems that this is the case - because of the ordering of the converters. I can't see what was False about what I said here. > > > > > Try this instead: > > > > ... > > // class_("A", init< int >() ) > > class_("A", init< int >() ) > > ... > > > > > > This does work. Why? Because Boost.Python uses shared_ptr *internally* to > > construct this object > > Where did you get that idea? By incorrect reasoning :( My apologies. From dave at boost-consulting.com Sat Aug 9 13:18:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Aug 2003 07:18:46 -0400 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: "Brett Calcott" writes: >> Brett, I hate to be so blunt, but unless I'm misunderstanding you, >> this explanation is almost completely wrong. > > Blunt is fine. honesty won't offend. > >> >> > The problem is that for python object 'identity' the PyObject must > survive >> > making it from the python interpreter to C++, and back again. >> >> True. >> >> > In this case it doesn't -- it is deleted when you set it, and a new >> > one is constructed when it returns. >> >> False; with all recent CVS versions boost::shared_ptr converted from >> python actually manages the containing Python object and will convert >> back into the same object when converted to python. > > Ok, I'm confused. Clearly object identity is *not* preserved - so they can't > be the same PyObject. Doesn't that require the old one to have been deleted > (well, derefed at least) Yes, at least that. > and a new one created? From your other reply it seems that this is > the case - because of the ordering of the converters. I can't see > what was False about what I said here. I think you were basically right, sorry. I had no idea that the availability of a shared_ptr lvalue could interfere with the use of the special converter. I thought I was doing that with specialization, but apparently not. >> >> > >> > Try this instead: >> > >> > ... >> > // class_("A", init< int >() ) >> > class_("A", init< int >() ) >> > ... >> > >> > >> > This does work. Why? Because Boost.Python uses shared_ptr > *internally* to >> > construct this object >> >> Where did you get that idea? > > By incorrect reasoning :( > My apologies. -- Dave Abrahams Boost Consulting www.boost-consulting.com From fincher.8 at osu.edu Sat Aug 9 21:06:46 2003 From: fincher.8 at osu.edu (Jeremy Fincher) Date: Sat, 9 Aug 2003 15:06:46 -0400 Subject: [C++-sig] Re: A few questions... In-Reply-To: References: <200308080142.01728.fincher.8@osu.edu> <200308080453.26892.fincher.8@osu.edu> Message-ID: <200308091506.46442.fincher.8@osu.edu> On Friday 08 August 2003 01:13 pm, David Abrahams wrote: > You could wrap it with > > class_ >(...) > ... > > But more likely you want to register a custom to-python converter > which converts it into a list of Python strings. You might follow > http://www.boost.org/libs/python/doc/v2/faq.html#question2 to find > more information about how to do that. I'm still working on this :) Some of that page is pretty hard for me to get through (but again, I'm pretty new to C++, too) > Nothing. A Python string has no way to reference the characters > stored inside a std::string. > > Well, OK, not truly nothing. You could write a thin getter function > which returns an object that is wrapped: > > // untested! > > struct my_string > { > my_string(object owner, std::string const& s) > > : owner(owner), s(s) {} > > ... > // access methods > > object owner; // keep the owner alive > std::string const& s; // reference the underlying string > }; > > template > struct wrap_string > { > my_string get(object self) > { > return my_string(self, extract()().*pm); > } > }; > > > ... > > class_("my_string") > .def(...) > ; > > class_("Whatever") > .add_property( > "some_string_member", > &wrap_string::get) > ... > ; > > However, I doubt it's worthwhile or any faster than just doing the > copying. Why are you worried about copying these strings? I'm worried about the copying of the strings because I'm writing this code to replace a class written in Python, so its major point is optimization. Copying strings on every access (especially accesses to these strings is *the* most commonly performed operation in my code) seems antithetical to this point. Is there a better way to define a class to replace a Python class than this? From your code above, it looks like I'll have to do some stuff with the object type provided by Boost.Python. If that does turn out to be the case, and I change my class to keep object (str) attributes rather than std::string attributes, I assume there's some way (return_internal_reference?) to return the object from inside my class rather than making a copy of it. What I haven't seen, though, at least in the std::string case, is a way to specify such policies in a .def_readonly or .add_property expression. Is there a better way to do what I want to do that I'm missing? Jeremy From dave at boost-consulting.com Sat Aug 9 22:19:03 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Aug 2003 16:19:03 -0400 Subject: [C++-sig] Re: A few questions... References: <200308080142.01728.fincher.8@osu.edu> <200308080453.26892.fincher.8@osu.edu> <200308091506.46442.fincher.8@osu.edu> Message-ID: Jeremy Fincher writes: > On Friday 08 August 2003 01:13 pm, David Abrahams wrote: >> You could wrap it with >> >> class_ >(...) >> ... >> >> But more likely you want to register a custom to-python converter >> which converts it into a list of Python strings. You might follow >> http://www.boost.org/libs/python/doc/v2/faq.html#question2 to find >> more information about how to do that. > > I'm still working on this :) Some of that page is pretty hard for me to get > through (but again, I'm pretty new to C++, too) > >> Nothing. A Python string has no way to reference the characters >> stored inside a std::string. >> >> Well, OK, not truly nothing. You could write a thin getter function >> which returns an object that is wrapped: >> >> // untested! >> >> struct my_string >> { >> my_string(object owner, std::string const& s) >> >> : owner(owner), s(s) {} >> >> ... >> // access methods >> >> object owner; // keep the owner alive >> std::string const& s; // reference the underlying string >> }; >> >> template >> struct wrap_string >> { >> my_string get(object self) >> { >> return my_string(self, extract()().*pm); >> } >> }; >> >> >> ... >> >> class_("my_string") >> .def(...) >> ; >> >> class_("Whatever") >> .add_property( >> "some_string_member", >> &wrap_string::get) >> ... >> ; >> >> However, I doubt it's worthwhile or any faster than just doing the >> copying. Why are you worried about copying these strings? > > I'm worried about the copying of the strings because I'm writing this code to > replace a class written in Python, so its major point is > optimization. There's almost no point in trying to optimize by rewriting in C++ unless a substantial amount of C++ code will be executed for each Python call. Crossing the language boundary generally has a cost. Python allocates new string objects at the drop of a hat, so you're not likely to notice it against the background noise of your entire program. > Copying strings on every access (especially accesses to these > strings is *the* most commonly performed operation in my code) seems > antithetical to this point. If you're concerned about copying strings, sink more of your algorithm into C++ so these accesses happen from the C++ side. > Is there a better way to define a class to replace a Python class > than this? Depends what you mean by "better". What are dissatisfies you about the above? > From your code above, it looks like I'll have to do some stuff with the > object type provided by Boost.Python. If that does turn out to be the case, > and I change my class to keep object (str) attributes rather than std::string > attributes Oh, sure, if you can change your class, just keep boost::python::object or boost::python::str instances around instead. > I assume there's some way (return_internal_reference?) to return the > object from inside my class rather than making a copy of it. You don't need any special call policies; you just return the object or str. > What I haven't seen, though, at least in the std::string case, is a > way to specify such policies in a .def_readonly or .add_property > expression. > > Is there a better way to do what I want to do that I'm missing? I guess so. If you want to manage Python objects in your C++ code, just use object, str, list, et al. -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Sun Aug 10 09:39:55 2003 From: romany at actimize.com (Roman Yakovenko) Date: Sun, 10 Aug 2003 10:39:55 +0300 Subject: [C++-sig] property unitest Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020606@exchange.adrembi.com> I wrote a test for add_property and add_static_property functionality. A few days ago I send those files to the group, but it seems that those files did not have been inserted into CVS. May be I need to fix something else in those files ? Thanks for good library. Roman > > > -----Original Message----- > > From: David Abrahams [mailto:dave at boost-consulting.com] > > Sent: Tuesday, August 05, 2003 8:14 PM > > To: c++-sig at python.org > > Subject: [C++-sig] Re: property and documentation > > > > > > "Roman Yakovenko" writes: > > > > > Also I send you 2 files. I believe that I checked all cases. > > > Also I believe that you will find some things that I will > > have to fix. > > > (Life is not easy as I'd like to be.) > > > > Yup. Please reformulate the python file using doctest or the > > unittest module. > > > > -- > > Dave Abrahams > > Boost Consulting > > www.boost-consulting.com > > > > > > _______________________________________________ > > C++-sig mailing list > > C++-sig at python.org > > http://mail.python.org/mailman/listinfo/c++-sig > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.py Type: application/octet-stream Size: 1562 bytes Desc: properties.py URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: properties.cpp Type: application/octet-stream Size: 1931 bytes Desc: properties.cpp URL: From RaoulGough at yahoo.co.uk Sun Aug 10 13:50:23 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Sun, 10 Aug 2003 12:50:23 +0100 Subject: [C++-sig] Adding __len__ to range objects Message-ID: I recently wanted to know how many items were in a C++ vector, which I had only exposed to Python via iterator pairs (boost::python::range). Currently, len(range_object) doesn't work because range doesn't provide a __len__ method, but it isn't hard to add this. I did the following in d:/CVS/boost/boost/boost/python/object/iterator.hpp: in template <...> struct iterator_range, add typename std::iterator_traits::difference_type distance () const { return std::distance (m_start, m_finish); } in template <...> object demand_iterator_class (...) return class_(name, no_init) .def("__iter__", identity_function()) .setattr("next", next_function) .def("__len__", &range_::distance) ; and everything worked OK. This seems to me like a useful addition - any comments? If it seems sensible, maybe David Abrahams could add something similar to the CVS? -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From prabhu at aero.iitm.ernet.in Sun Aug 10 20:57:02 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Mon, 11 Aug 2003 00:27:02 +0530 Subject: [C++-sig] Doubts with wrapping/using abstract bases. Message-ID: <16182.38270.865264.267282@monster.linux.in> Hi, I think I have a fairly serious misunderstanding of how Boost.Python wraps abstract virtual classes. I'd appreciate any clarifications. Here is a simple example: // ---------------- holder.hpp ---------------------- #include #include struct A { virtual ~A() {} virtual void f()=0; }; struct B: A { void f() {std::cout << "B::f\n";} }; struct Holder { Holder() {} void add(A* a) {arr.push_back(a);} A* get(const std::size_t n) {return arr[n];} private: std::vector arr; }; void func(A* a) {a->f();} // -------------------------------------------------- I wrap this with Pyste (CVS) and get wrapper code that looks like so (edited for brevity): // -------------------------------------------------- #include #include using namespace boost::python; struct A_Wrapper: A { A_Wrapper(PyObject* self_, const A& p0): A(p0), self(self_) {} A_Wrapper(PyObject* self_): A(), self(self_) {} void f() {call_method< void >(self, "f");} PyObject* self; }; struct B_Wrapper: B { B_Wrapper(PyObject* self_, const B& p0): B(p0), self(self_) {} B_Wrapper(PyObject* self_): B(), self(self_) {} void f() {call_method< void >(self, "f");} void default_f() {B::f();} PyObject* self; }; void add_wrapper(Holder* c, std::auto_ptr< B_Wrapper > o) {c->add(o.get()); o.release();} BOOST_PYTHON_MODULE(holder) { class_< A, boost::noncopyable, std::auto_ptr< A_Wrapper > > ("A", init< >()); class_< B, bases< A > , std::auto_ptr< B_Wrapper > >("B", init< >()) .def(init< const B& >()) .def("f", &B::f, (void (B_Wrapper::*)())&B_Wrapper::default_f); class_< Holder >("Holder", init< >()) .def(init< const Holder& >()) .def("add", &add_wrapper) .def("get", &Holder::get, return_internal_reference< 1 >()); def("func", &func); } // -------------------------------------------------- This looks good to me. Now I try the following from Python: >>> import holder >>> b = holder.B() >>> b.f() B::f >>> holder.func(b) B::f >>> # Everything is OK. >>> h = holder.Holder () >>> h.add(b) >>> b1 = h.get(0) >>> b1.f() Traceback (most recent call last): File "", line 1, in ? AttributeError: 'A' object has no attribute 'f' I did not expect this since this is perfectly legal in C++, i.e. b1->f() in C++ is legal and used commonly. So what am I doing wrong? Thanks! cheers, prabhu From RaoulGough at yahoo.co.uk Sun Aug 10 21:28:50 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Sun, 10 Aug 2003 20:28:50 +0100 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. References: <16182.38270.865264.267282@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Hi, > > I think I have a fairly serious misunderstanding of how Boost.Python > wraps abstract virtual classes. I'd appreciate any clarifications. > > Here is a simple example: > > // ---------------- holder.hpp ---------------------- > #include > #include > > struct A { > virtual ~A() {} > virtual void f()=0; > }; [snip] > BOOST_PYTHON_MODULE(holder) > { > class_< A, boost::noncopyable, std::auto_ptr< A_Wrapper > > > ("A", init< >()); Here's the problem - the Python reflection of class "A" does not include the function f at all. You would need to get something like class_< A, boost::noncopyable, std::auto_ptr< A_Wrapper > > ("A", init< >()) .def ("f", &A::f); for the code to work. Not sure how to get pyste to do that though. [snip] > Traceback (most recent call last): > File "", line 1, in ? > AttributeError: 'A' object has no attribute 'f' > > I did not expect this since this is perfectly legal in C++, > i.e. b1->f() in C++ is legal and used commonly. So what am I doing > wrong? How about adding the extra "def" manually to see whether it fixes the problem? Sorry I can't help on the Pyste side of this. Mayeb some semi-relevant stuff by Googling for pyste pure virtual. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From prabhu at aero.iitm.ernet.in Sun Aug 10 21:46:29 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Mon, 11 Aug 2003 01:16:29 +0530 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: References: <16182.38270.865264.267282@monster.linux.in> Message-ID: <16182.41237.725378.565233@monster.linux.in> hi, >>>>> "RG" == Raoul Gough writes: >> struct A { virtual ~A() {} virtual void f()=0; }; RG> [snip] >> BOOST_PYTHON_MODULE(holder) { class_< A, boost::noncopyable, >> std::auto_ptr< A_Wrapper > > ("A", init< >()); RG> Here's the problem - the Python reflection of class "A" does RG> not include the function f at all. You would need to get RG> something like RG> class_< A, boost::noncopyable, std::auto_ptr< A_Wrapper > > RG> ("A", init< >()) .def ("f", &A::f); I did not say so but that was the first thing I experimented with and nope it does not work either. Here is the error I get. >>> import holder >>> b = holder.B() >>> h = holder.Holder () >>> h.add(b) >>> b1 = h.get(0) >>> b1.f() Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in B.f(B) did not match C++ signature: f(Q227_GLOBAL_.N.holder.cppNpcTEb9B_Wrapper {lvalue}) f(1B {lvalue}) [snip] >> I did not expect this since this is perfectly legal in C++, >> i.e. b1->f() in C++ is legal and used commonly. So what am I >> doing wrong? RG> How about adding the extra "def" manually to see whether it RG> fixes the problem? Sorry I can't help on the Pyste side of RG> this. Mayeb some semi-relevant stuff by Googling for pyste RG> pure virtual. I think I should be able to add support for this quite easily in Pyste and send in a patch but I don't think that is the problem here. :( BTW, the tutorial never mentions that you do indeed need to "def" the pure virtual function. cheers, prabhu From nicodemus at globalite.com.br Sun Aug 10 23:42:48 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 10 Aug 2003 18:42:48 -0300 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: References: <16182.38270.865264.267282@monster.linux.in> Message-ID: <3F36BC58.4020106@globalite.com.br> Raoul Gough wrote: >Prabhu Ramachandran writes: > > >>Traceback (most recent call last): >> File "", line 1, in ? >>AttributeError: 'A' object has no attribute 'f' >> >>I did not expect this since this is perfectly legal in C++, >>i.e. b1->f() in C++ is legal and used commonly. So what am I doing >>wrong? >> >> > >How about adding the extra "def" manually to see whether it fixes the >problem? Sorry I can't help on the Pyste side of this. Mayeb some >semi-relevant stuff by Googling for pyste pure virtual. > Adding the f's def manually works, but problem is, you can now crash the interpreter fairly easily: [d:\temp]python Python 2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from holder import * >>> b = B() >>> h = Holder() >>> h.add(b) >>> x = h.get(0) >>> x.f() B::f >>> a = A() >>> a.f() Traceback (most recent call last): File "", line 1, in ? RuntimeError: unidentifiable C++ exception >>> a.f() [d:\temp] I think the solution is to provide a default implementation for f in A_Wrapper that raises an exception when called: >>> from holder import * >>> a = A() >>> a.f() Traceback (most recent call last): File "", line 1, in ? RuntimeError: abstract function called >>> I implemented this, and the code is in CVS now. Thanks a lot once again Prabhu! 8) Regards, Nicodemus. From dave at boost-consulting.com Mon Aug 11 00:27:54 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 10 Aug 2003 18:27:54 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > I recently wanted to know how many items were in a C++ vector, which I > had only exposed to Python via iterator pairs (boost::python::range). > Currently, len(range_object) doesn't work because range doesn't > provide a __len__ method, but it isn't hard to add this. I did the > following in d:/CVS/boost/boost/boost/python/object/iterator.hpp: > > in template <...> struct iterator_range, add > > typename std::iterator_traits::difference_type > distance () const { > return std::distance (m_start, m_finish); > } > > in template <...> object demand_iterator_class (...) > > return class_(name, no_init) > .def("__iter__", identity_function()) > .setattr("next", next_function) > .def("__len__", &range_::distance) > ; > > and everything worked OK. This seems to me like a useful addition - > any comments? If it seems sensible, maybe David Abrahams could add > something similar to the CVS? It only works for random-access iterators. You could fix it so that it would only create the __len__ function for random-access iterators; that would be better. Then, also, range() creates an iterator-returning function, not an iteratable-returning function. There are subtle differences. for x in some_list: print x for x in some_list: print x # prints the same elements but: for x in some_iterator: print x for x in some_iterator: print x # prints nothing None of the Python iterators support __len__ and I wonder if it's a good idea to add it to an iterator we create. Your thoughts? -- Dave Abrahams Boost Consulting www.boost-consulting.com From s_sourceforge at nedprod.com Mon Aug 11 00:36:09 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 10 Aug 2003 23:36:09 +0100 Subject: [C++-sig] Boost.python suggestion + pyste bug In-Reply-To: <3F3312A6.2030803@globalite.com.br> References: <3F330A01.29851.5B23910@localhost> Message-ID: <3F36D6E9.26447.148AA3E2@localhost> On 8 Aug 2003 at 0:01, Nicodemus wrote: > >Lastly, am I right in thinking that pyste currently does not use > >boost.python's ability to represent C++ class inheritance trees the > >same in python classes? I'm thinking that if you were to add support > >for this, it kinda works with the fixes necessary for fixing the bugs > > above. > > What do you mean? It should export classes in the same way as if you > were doing it by hand, but automatically. One difference is that it > now automatically exports the members of base classes that were not > exported themselves, as a feature request here in the list: > > struct A > { > void foo(); > }; > > struct B: A > { > void bar(); > }; > > If you export only B, you will get A's foo method too, as if you were > exporting both A and B. Firstly my apologies for the late reply, I've been laid up in bed these last few days with what looks like influenza. Odd given it's 30C outside! You're not quite understanding me. I shall illustrate: If I have classes A, B & C where A inherits B and B inherits C, and I were exporting classes A and C to python, I should write: class_("C").def(... class_ >("A").def(... // NOT bases Currently pyste does not generates bases<> for anything. I can understand this because it is complex - you must analyse what classes each interface file exports before being able to say what inherits what *also* *exposed*. However if you've fixed those bugs I reported with some other method, then cool, I can do without this. Cheers, Niall From dave at boost-consulting.com Mon Aug 11 00:30:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 10 Aug 2003 18:30:30 -0400 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> Message-ID: Nicodemus writes: > RuntimeError: abstract function called > >>> > > I implemented this, and the code is in CVS now. Thanks, Nicodemus! Could you please change the message to use correct terminology, though? C++ doesn't have abstract functions, only pure virtual functions. It doesn't have virtual classes, only abstract classes and virtual bases. Thanks again, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 11 00:57:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 10 Aug 2003 18:57:33 -0400 Subject: [C++-sig] Re: property unitest References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020606@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: > I wrote a test for add_property and add_static_property functionality. > A few days ago I send those files to the group, but it seems that those > files did not have been inserted into CVS. May be I need to fix something > else in those files ? Nope. They're committed now. Thank you very much for your contribution! -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Aug 11 01:05:01 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 10 Aug 2003 20:05:01 -0300 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> Message-ID: <3F36CF9D.9090203@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>RuntimeError: abstract function called >> >>> >> >>I implemented this, and the code is in CVS now. >> >> > >Thanks, Nicodemus! > >Could you please change the message to use correct terminology, >though? > >C++ doesn't have abstract functions, only pure virtual functions. It >doesn't have virtual classes, only abstract classes and virtual bases. > >Thanks again, > Sure, thanks for the reminder! Regards, Nicodemus. From nicodemus at globalite.com.br Mon Aug 11 01:18:16 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 10 Aug 2003 20:18:16 -0300 Subject: [C++-sig] Boost.python suggestion + pyste bug In-Reply-To: <3F36D6E9.26447.148AA3E2@localhost> References: <3F330A01.29851.5B23910@localhost> <3F36D6E9.26447.148AA3E2@localhost> Message-ID: <3F36D2B8.4020402@globalite.com.br> Niall Douglas wrote: >On 8 Aug 2003 at 0:01, Nicodemus wrote: > > >>>Lastly, am I right in thinking that pyste currently does not use >>>boost.python's ability to represent C++ class inheritance trees the >>>same in python classes? I'm thinking that if you were to add support >>>for this, it kinda works with the fixes necessary for fixing the bugs >>>above. >>> >>What do you mean? It should export classes in the same way as if you >>were doing it by hand, but automatically. One difference is that it >>now automatically exports the members of base classes that were not >>exported themselves, as a feature request here in the list: >> >>struct A >>{ >> void foo(); >>}; >> >>struct B: A >>{ >> void bar(); >>}; >> >>If you export only B, you will get A's foo method too, as if you were >>exporting both A and B. >> > >Firstly my apologies for the late reply, I've been laid up in bed >these last few days with what looks like influenza. Odd given it's >30C outside! > >You're not quite understanding me. I shall illustrate: > >If I have classes A, B & C where A inherits B and B inherits C, and I >were exporting classes A and C to python, I should write: > >class_("C").def(... > >class_ >("A").def(... // NOT bases > >Currently pyste does not generates bases<> for anything. I can >understand this because it is complex - you must analyse what classes >each interface file exports before being able to say what inherits >what *also* *exposed*. > >However if you've fixed those bugs I reported with some other method, >then cool, I can do without this. > Oh, I understand now, sorry. I thought you were talking about methods. The current way is proposital. The bases<> template must expose the base classes that were *exported*: struct A { void foo(){}; }; struct B: A { void foobar(){}; }; struct C: B { void bar(){}; }; exporting only A and C, you get: class_< A >("A", init< >()) .def(init< const A& >()) .def("foo", &A::foo) ; class_< C, bases< A > >("C", init< >()) .def(init< const C& >()) .def("bar", &C::bar) .def("foobar", &B::foobar) ; Which is correct. If you try to change bases< A > to bases< B >, your extension won't work (it will compile, but it will raise an exception when you try to import it). Now, if you are saying that bases<> are always empty, I guess the problem is that you're using AllFromHeader, which is broken in the current CVS. Try changing from AllFromHeader to Class calls, that should make the problem go away. Regards, Nicodemus. From Gottfried.Ganssauge at HAUFE.DE Mon Aug 11 09:26:23 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 11 Aug 2003 09:26:23 +0200 Subject: [C++-sig] Re: deriving basic python type Message-ID: <2040C0A1CA23D51181A30050BAAC990274AAE9@berexch.ber.haufemg.com> Arrh ... to be honest: not at all. I'm back from my vacation today and planned to have a first version by friday. Cheers, Gottfried > -----Original Message----- > From: David Abrahams [mailto:dave at boost-consulting.com] > Sent: Tuesday, August 05, 2003 2:58 PM > To: c++-sig at python.org > Cc: Gottfried Gan?auge > Subject: [C++-sig] Re: deriving basic python type > > > "Alex" writes: > > > Hi > > In python I can do this : > > > > class my_int(int): > > def __rshift__(self, a): #changing the >> operator > behavior for example... > > return self + a > > > > The example is quite stupid but is there a way I can make such a > > class in C++(a class deriving the python int or other python types) > > then exporting it in python ? > > There's no *easy* way right now, but it's a fairly easy mod to the > Boost.Python sources. Gottfried Gan?auge has been working on a patch > for another purpose which should make it possible. Gottfried, how's > it coming along? > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From abeyer at uni-osnabrueck.de Mon Aug 11 10:48:39 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Mon, 11 Aug 2003 10:48:39 +0200 (CEST) Subject: [C++-sig] Re: Adding __len__ to range objects Message-ID: <1138.192.124.248.20.1060591719.squirrel@webmail.rz.uni-osnabrueck.de> > Raoul Gough writes: > >> I recently wanted to know how many items were in a C++ vector, which I >> had only exposed to Python via iterator pairs (boost::python::range). >> Currently, len(range_object) doesn't work because range doesn't >> provide a __len__ method, but it isn't hard to add this. I did the >> following in d:/CVS/boost/boost/boost/python/object/iterator.hpp: >> >> in template <...> struct iterator_range, add >> >> typename std::iterator_traits::difference_type >> distance () const { >> return std::distance (m_start, m_finish); >> } >> >> in template <...> object demand_iterator_class (...) >> >> return class_(name, no_init) >> .def("__iter__", identity_function()) >> .setattr("next", next_function) >> .def("__len__", &range_::distance) >> ; >> >> and everything worked OK. This seems to me like a useful addition - >> any comments? If it seems sensible, maybe David Abrahams could add >> something similar to the CVS? > > It only works for random-access iterators. You could fix it so that > it would only create the __len__ function for random-access > iterators; that would be better. > > Then, also, range() creates an iterator-returning function, not an > iteratable-returning function. There are subtle differences. > > for x in some_list: > print x > > for x in some_list: > print x # prints the same elements > > but: > > for x in some_iterator: > print x > > for x in some_iterator: > print x # prints nothing > > None of the Python iterators support __len__ and I wonder if it's a > good idea to add it to an iterator we create. Your thoughts? > Raoul, I think what you actually want is a conversion from std::vector to python::list. That gives you the len-method as well as the __getitem__ function. Either you register your own class with the python methods __iter__, __len__, __getitem__ or you use the python::list() function to create a 'real' python list. I would not change the range() function to return something in-between a list and an iterator. Dave, maybe a return value converter like range() that creates a python list from a C++ vector would be helpfull. Andreas From abeyer at uni-osnabrueck.de Mon Aug 11 10:54:03 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Mon, 11 Aug 2003 10:54:03 +0200 (CEST) Subject: [C++-sig] Re: Containers for derived classes Message-ID: <1143.192.124.248.20.1060592043.squirrel@webmail.rz.uni-osnabrueck.de> > abeyer at uni-osnabrueck.de writes: > >> I.e. the identity is not preserved. Could this be a problem with MinGW, >> which I am using? >> To be sure, here is the complete code again: >> >> #include >> #include >> >> using namespace boost; >> >> class A { >> public: >> A(int i) : val(i) { } >> int val; >> }; >> typedef shared_ptr A_ptr; >> >> class C { >> public: >> void set(A_ptr a) { this->a=a; } >> A_ptr get() { return this->a; } >> void f() { a.get()->val *= 2; } >> private: >> A_ptr a; >> }; >> >> BOOST_PYTHON_MODULE(ptr_test) >> { >> using namespace boost::python; >> class_("A", init< int >() ) >> .def_readwrite("val", &A::val) >> ; >> class_("C" ) >> .def("set", &C::set ) >> .def("get", &C::get ) >> .def("f", &C::f ) >> ; >> } > > OK, I understand the problem now. It's not a MinGW issue. The > problem is that when you ask for A to be held by A_ptr, an A_ptr > lvalue converter gets registered, since there is actually an A_ptr > object inside the Python wrapper. Lvalue converters can be used where > only an rvalue is needed, as in: > > void set(A_ptr a) > > and they get special priority over rvalue converters. The only way to > get the behavior you want is actually to NOT hold A objects by A_ptr: > > class("A", init() ) > ... > > so that the rvalue converter that gets registered can be found. > > Clearly, we need special rules for shared_ptr, so that this won't > happen. I'm just not sure whether we need special rules for all > smart pointer types, yet. Any thoughts? > Now it works great. 1. No, I do not think we need special rules for every smart pointer. However, shared_ptr is explicitely mentioned for this problem in the FAQ. Maybe we need rules for shared_ptr. 2. It would be great to put the above example into the Howto/FAQ. (Maybe along with a few comments on lvalue/rvalue conversion.) Thanks for the help, Andreas From brett.calcott at paradise.net.nz Mon Aug 11 12:36:59 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Mon, 11 Aug 2003 20:36:59 +1000 Subject: [C++-sig] Re: Containers for derived classes References: <1083.192.124.248.20.1060242986.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: > > > > Ok, I'm confused. Clearly object identity is *not* preserved - so they can't > > be the same PyObject. Doesn't that require the old one to have been deleted > > (well, derefed at least) > > Yes, at least that. > > > and a new one created? From your other reply it seems that this is > > the case - because of the ordering of the converters. I can't see > > what was False about what I said here. > > I think you were basically right, sorry. I had no idea that the > availability of a shared_ptr lvalue could interfere with the use of > the special converter. I thought I was doing that with > specialization, but apparently not. > Right, it was the next step where I was talk complete rubbish. I assumed because this didn't work: > class_("A", init< int >() ) and this did: > class_("A", init< int >() ) that it was something to do with the held type (not the converter). I'll be more careful in future before I make bold sweeping statements about how Boost.Python works. And I *am* still writing something on the internals, as promised. It's just taking longer than I thought. Cheers, Brett From RaoulGough at yahoo.co.uk Mon Aug 11 13:11:05 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 11 Aug 2003 12:11:05 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: > Raoul Gough writes: [snip] >> in template <...> struct iterator_range, add >> >> typename std::iterator_traits::difference_type >> distance () const { >> return std::distance (m_start, m_finish); >> } [snip] > > It only works for random-access iterators. You could fix it so that > it would only create the __len__ function for random-access > iterators; that would be better. Yes, that would be easy enough I guess. BTW, do you mean it wouldn't work at all for (e.g.) forward_iterators, or just that it isn't as efficient? I thought std::distance worked for most (or all) categories, but is only constant time for random_access_iterators. It's still going to be (a lot) faster than the equivalent code in Python. > > Then, also, range() creates an iterator-returning function, not an > iteratable-returning function. There are subtle differences. > > for x in some_list: > print x > > for x in some_list: > print x # prints the same elements > > but: > > for x in some_iterator: > print x > > for x in some_iterator: > print x # prints nothing Yes, I would actually expect this since I know that it is an iterator pair :-) On the other hand, the following should work OK, unless I'm mistaken: iterator_copy = some_iterator for x in some_iterator: print x for x in iterator_copy: print x # Prints same > > None of the Python iterators support __len__ and I wonder if it's a > good idea to add it to an iterator we create. Your thoughts? Yes, maybe it isn't such a great idea after all. One real drawback that I thought of is that adding this might break existing code. A (broken) user-defined iterator might not provide enough smarts for std::distance to work, and yet still be compatible with the existing range support. Adding len would break this, since the distance function would get generated even if it is never used or wanted. I can think of two ways around this: add a new range_with_len type (seems excessive), or provide some way for the client code to access the generated class_ object to add their own extensions (probably difficult?) -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From RaoulGough at yahoo.co.uk Mon Aug 11 13:35:46 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 11 Aug 2003 12:35:46 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <1138.192.124.248.20.1060591719.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: >David Abrahams writes: [snip] >> None of the Python iterators support __len__ and I wonder if it's a >> good idea to add it to an iterator we create. Your thoughts? >> > Raoul, I think what you actually want is a conversion from std::vector to > python::list. That gives you the len-method as well as the __getitem__ > function. Either you register your own class with the python methods > __iter__, __len__, __getitem__ or you use the python::list() function to > create a 'real' python list. Hmmmm... creating a python list from Python would be quite an overhead, since it would have to iterate over the entire sequence, just as manually counting the elements would (including whatever Python to C++ interfacing overheads for each next() call). My reasoning goes like this - the iterator-pair object is very lightweight, and yet the basic Python iterator interface does not expose all of it's functionality (e.g. the ability to know how far it is from the end). In general, a python iterator might not know this, but boost::python::range does, certainly for random_access iterators, and much faster than any Python code could work it out for forward_iterator or bidirectional_iterator. > I would not change the range() function to > return something in-between a list and an iterator. Dave, maybe a return > value converter like range() that creates a python list from a C++ vector > would be helpfull. I don't really understand how the boost::python list TypeWrapper works, but I suspect it would also have to iterate over the entire sequence, since there doesn't seem to be any specialization of the list constructor for random access iterators (are Python lists even stored contiguously?) To explain my original motivation, I was hoping to: a) avoid exposing the entire vector from my class's interface b) avoid making Python understand std::vector c) know how long a sequence the iterator pair represents and adding len() to range solved all of these problems at once :-) -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From sf.lists at web.de Mon Aug 11 14:43:28 2003 From: sf.lists at web.de (Stefan Fleiter) Date: Mon, 11 Aug 2003 14:43:28 +0200 Subject: [C++-sig] derived class without virtual method Message-ID: <3F378F70.6050604@web.de> Hi, I am using boost::python 1.30 to wrap some C++-Library. In this library I have a class Cursor and a dreived class ExtCursor I use for wrapping to python. I always use ExtCursor, neither it nor its base class Cursor has any virtual method. When I wrap ExtCursor its member variable of type std::vector reports a size of one in the destructor, but there are no methods which could change its size yet. If I add *any* virtual method to the base class Cursor this effect does not show. Does boost::python use any rtti or such which depends on a vtable? Any other ideas? Greets, Stefan From dave at boost-consulting.com Mon Aug 11 15:15:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Aug 2003 09:15:20 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > David Abrahams writes: > >> Raoul Gough writes: > [snip] >>> in template <...> struct iterator_range, add >>> >>> typename std::iterator_traits::difference_type >>> distance () const { >>> return std::distance (m_start, m_finish); >>> } > [snip] >> >> It only works for random-access iterators. You could fix it so that >> it would only create the __len__ function for random-access >> iterators; that would be better. > > Yes, that would be easy enough I guess. BTW, do you mean it wouldn't > work at all for (e.g.) forward_iterators, or just that it isn't as > efficient? I thought std::distance worked for most (or all) > categories, but is only constant time for random_access_iterators. > It's still going to be (a lot) faster than the equivalent code in > Python. You're right, it would work for everything input iterator and above, which is everything that range() works on. >> Then, also, range() creates an iterator-returning function, not an >> iteratable-returning function. There are subtle differences. >> >> for x in some_list: >> print x >> >> for x in some_list: >> print x # prints the same elements >> >> but: >> >> for x in some_iterator: >> print x >> >> for x in some_iterator: >> print x # prints nothing > > Yes, I would actually expect this since I know that it is an iterator > pair :-) I think you're slightly confused. It is that in C++, but in Python it is an iterator. Traditionally, len(x) only applies to iterables in Python. > On the other hand, the following should work OK, unless I'm > mistaken: > > iterator_copy = some_iterator > for x in some_iterator: print x > for x in iterator_copy: print x # Prints same You're mistaken. iterator_copy and some_iterator both refer to the same object. Try it: >>> i = iter(range(5)) >>> j = i >>> for x in i: print x ... 0 1 2 3 4 >>> for x in j: print x ... >> None of the Python iterators support __len__ and I wonder if it's a >> good idea to add it to an iterator we create. Your thoughts? > > Yes, maybe it isn't such a great idea after all. One real drawback > that I thought of is that adding this might break existing code. A > (broken) user-defined iterator might not provide enough smarts for > std::distance to work, and yet still be compatible with the existing > range support. It would always supply enough smarts. However, I am nervous about supplying __len__ for anything below random-access, especially for input iterators where it is probably destructive. > Adding len would break this, since the distance function would get > generated even if it is never used or wanted. I don't think that's a problem. > I can think of two ways around this: add a new range_with_len type > (seems excessive), or provide some way for the client code to access > the generated class_ object to add their own extensions (probably > difficult?) I think you're barking up the wrong tree. Maybe we ought to simply change our tune and say that range() produces an iterable-returning function rather than an iterator-returning function. If we did that we could always generate __len__, and for that matter we could also generate __getitem__/__setitem__ for random-access ranges. -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Mon Aug 11 16:25:54 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 11 Aug 2003 15:25:54 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: > Raoul Gough writes: [snip] >> On the other hand, the following should work OK, unless I'm >> mistaken: >> >> iterator_copy = some_iterator >> for x in some_iterator: print x >> for x in iterator_copy: print x # Prints same > > You're mistaken. iterator_copy and some_iterator both refer to the > same object. Try it: > > >>> i = iter(range(5)) > >>> j = i > >>> for x in i: print x > ... > 0 > 1 > 2 > 3 > 4 > >>> for x in j: print x > ... Of course - silly of me, but I still get confused sometimes by Python's reference copying. >> One real drawback >> that I thought of is that adding this might break existing code. A >> (broken) user-defined iterator might not provide enough smarts for >> std::distance to work, and yet still be compatible with the existing >> range support. > > It would always supply enough smarts. However, I am nervous about > supplying __len__ for anything below random-access, especially for > input iterators where it is probably destructive. Well, I'm not so sure - std::distance almost certainly requires iterator_traits<>::iterator_category which (AFAIK) range doesn't at the moment. Since range currently only needs next() functionality, it wouldn't need to know what the iterator's category is, but adding len() wants more information for efficiency reasons. > >> Adding len would break this, since the distance function would get >> generated even if it is never used or wanted. > > I don't think that's a problem. Well, it certainly wouldn't be hard to fix code that does break. > >> I can think of two ways around this: add a new range_with_len type >> (seems excessive), or provide some way for the client code to access >> the generated class_ object to add their own extensions (probably >> difficult?) > > I think you're barking up the wrong tree. Maybe we ought to simply > change our tune and say that range() produces an iterable-returning > function rather than an iterator-returning function. If we did that > we could always generate __len__, and for that matter we could also > generate __getitem__/__setitem__ for random-access ranges. Sounds good to me. I think Andreas was also suggesting something in this direction. I was almost going to suggest adding a _new_ C++ sequence wrapper (e.g. called view or sequence_view) that provides the extra stuff as well as __iter__ support via the existing range code. The only real benefit would be that the client code could then choose whether to include the more sophisticated support. Maybe you could achieve this via an optional iterator_category anyway (as you pointed out, __len__ is probably a bad idea for input_iterators). -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Mon Aug 11 17:00:09 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Aug 2003 11:00:09 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > David Abrahams writes: > >> Raoul Gough writes: > [snip] >>> On the other hand, the following should work OK, unless I'm >>> mistaken: >>> >>> iterator_copy = some_iterator >>> for x in some_iterator: print x >>> for x in iterator_copy: print x # Prints same >> >> You're mistaken. iterator_copy and some_iterator both refer to the >> same object. Try it: >> >> >>> i = iter(range(5)) >> >>> j = i >> >>> for x in i: print x >> ... >> 0 >> 1 >> 2 >> 3 >> 4 >> >>> for x in j: print x >> ... > > Of course - silly of me, but I still get confused sometimes by > Python's reference copying. > >>> One real drawback >>> that I thought of is that adding this might break existing code. A >>> (broken) user-defined iterator might not provide enough smarts for >>> std::distance to work, and yet still be compatible with the existing >>> range support. >> >> It would always supply enough smarts. However, I am nervous about >> supplying __len__ for anything below random-access, especially for >> input iterators where it is probably destructive. > > Well, I'm not so sure - std::distance almost certainly requires > iterator_traits<>::iterator_category which (AFAIK) range doesn't at > the moment. Technically, range() does require iterator_category, since it requires real iterators. But no, it does not enforce that requirement. > Since range currently only needs next() functionality, it > wouldn't need to know what the iterator's category is, but adding > len() wants more information for efficiency reasons. Yes. >>> Adding len would break this, since the distance function would get >>> generated even if it is never used or wanted. >> >> I don't think that's a problem. > > Well, it certainly wouldn't be hard to fix code that does break. No it wouldn't. It was wrong anyway ;-> >>> I can think of two ways around this: add a new range_with_len type >>> (seems excessive), or provide some way for the client code to access >>> the generated class_ object to add their own extensions (probably >>> difficult?) >> >> I think you're barking up the wrong tree. Maybe we ought to simply >> change our tune and say that range() produces an iterable-returning >> function rather than an iterator-returning function. If we did that >> we could always generate __len__, and for that matter we could also >> generate __getitem__/__setitem__ for random-access ranges. > > Sounds good to me. I think Andreas was also suggesting something in > this direction. I was almost going to suggest adding a _new_ C++ > sequence wrapper (e.g. called view or sequence_view) that provides the > extra stuff as well as __iter__ support via the existing range > code. The only real benefit would be that the client code could then > choose whether to include the more sophisticated support. Too many options; not enough benefit. > Maybe you could achieve this via an optional iterator_category > anyway (as you pointed out, __len__ is probably a bad idea for > input_iterators). Don't know what this means. Anyway, I'm not going to implement this one myself. Patches (including docs and tests) will be gratefully considered. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Mon Aug 11 17:05:26 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Mon, 11 Aug 2003 20:35:26 +0530 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: <3F36BC58.4020106@globalite.com.br> References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> Message-ID: <16183.45238.143458.663526@monster.linux.in> >>>>> "N" == nicodemus writes: N> Raoul Gough wrote: [PR on error with pure virtual functions] >>> Traceback (most recent call last): File "", line 1, in >>> ? AttributeError: 'A' object has no attribute 'f' [snip] [RG on adding the def to fix the problem] >> How about adding the extra "def" manually to see whether it >> fixes the problem? Sorry I can't help on the Pyste side of >> this. Mayeb some semi-relevant stuff by Googling for pyste pure >> virtual. N> Adding the f's def manually works, but problem is, you can now N> crash the interpreter fairly easily: Well, I don't know what I'm doing wrong but as I said earlier I did try with the "def" for f and it still does not work along when held with std::auto_ptr (with gcc 2.95.4). It does work without the held type though. Here is the example along with the Pyste file and the error. // ----------------------- holder.hpp --------------- #include #include struct A { virtual ~A() {} virtual void f()=0; }; struct B: A{ void f() {std::cout << "B::f\n";} }; struct Holder { Holder() {} void add(A* a) {arr.push_back(a);} A* get(const std::size_t n) {return arr[n];} private: std::vector arr; }; void func(A* a) {a->f();} // -------------------------------------------------- // -------------------- holder.pyste ---------------- A = Class('A', 'holder.hpp') B = Class('B', 'holder.hpp') def held_type_func(name): return 'std::auto_ptr< %s >'%name holder(A, held_type_func) holder(B, held_type_func) Holder = Class('Holder', 'holder.hpp') set_policy(Holder.get, return_internal_reference()) add_wrapper = Wrapper('add_wrapper', """ void add_wrapper(Holder* c, std::auto_ptr< B_Wrapper > o) { c->add(o.get()); o.release(); } """) set_wrapper(Holder.add, add_wrapper) func = Function('func', 'holder.hpp') // -------------------------------------------------- // ------------------ test_holder.py ---------------- import holder b = holder.B() b.f() holder.func(b) h = holder.Holder () h.add(b) b1 = h.get(0) b1.f() // -------------------------------------------------- Here is the error that I get when I run this script with holder.so compiled using gcc 2.95.4 with boost CVS (from this morning) with the libboost*.so compiled and Pyste from CVS. B::f B::f Traceback (most recent call last): File "test_holder.py", line 8, in ? x.f() Boost.Python.ArgumentError: Python argument types in B.f(B) did not match C++ signature: f(Q227_GLOBAL_.N.holder.cppYtV9Va9B_Wrapper {lvalue}) f(1B {lvalue}) I also tried manually adding an implicitly_convertible< std::auto_ptr, std::auto_ptr > (); and changed B_Wrapepr to B in the add_wrapper function but continue to get errors. Any help would be appreciated. Thanks! Dave, you mentioned that Boost.Python could automatically handle the conversion and eliminate the need for the implicitly_convertible statement. Do you plan to do this or do you prefer that we use implicitly_convertible and find a way to add it from Pyste? Thanks! N> I implemented this, and the code is in CVS now. Thanks a lot N> once again Prabhu! 8) Many thanks! cheers, prabhu From dave at boost-consulting.com Mon Aug 11 18:37:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Aug 2003 12:37:23 -0400 Subject: [C++-sig] def_visitor Message-ID: I have just checked in changes which cause all class_<...>::def invocations which aren't applied to [member] function pointers to go through a new def_visitor<...> interface. Examples are: .def(init<...>()) .def("foo", some_callable_python_object) .def(self + int) .def(vector_indexing_suite<...>(...)) This gives us a simple non-intrusive way to add new def() functionality and lays the groundwork for pure_virtual() and the new init function generator. -- Dave Abrahams Boost Consulting www.boost-consulting.com From conanb at STCG.net Mon Aug 11 18:55:55 2003 From: conanb at STCG.net (Conan Brink) Date: Mon, 11 Aug 2003 09:55:55 -0700 Subject: [C++-sig] Accessing Python derived-class members from C++ base Message-ID: Given a C++ base class "Base" and a Python class "Derived" derived from it, I have a method in Base that needs to access arbitrary attributes of an instance of Derived. Is there any way to do this other than explicitly passing an extra copy of "self" into the method calls to Base? A simple example of this clunky interface follows. (yes, it's a really silly problem to be solving in this manner, but it illustrates the interface) C++: namespace py = boost::python; struct Base { Base() {} void DoubleIt(py::object self, std::string name); }; void Base::DoubleIt(py::object self, std::string name) { self.attr(name.c_str()) = self.attr(name.c_str()) * 2; }; BOOST_PYTHON_MODULE(Utility) { py::def("Dist", &Dist); py::class_("Base", py::init<>()) .def("DoubleIt", &Base::DoubleIt) ; } Python: class Derived(Base): pass d = Derived() d.i = 1 d.a = 'Foo' print d.i print d.a d.DoubleIt(d, 'i') d.DoubleIt(d, 'a') print d.i print d.a Output is, naturally: 1 Foo 2 FooFoo But I'd sure like to get rid of the extra "d" in the calls to DoubleIt. -Conan This message contains information that may be confidential and privileged. Unless you are the addressee (or authorized to receive messages for the addressee), you may not use, copy, or disclose to anyone the message or any information contained in the message. If you have received the message in error, please advise the sender by reply e-mail and delete the message. Nothing in this message should be interpreted as a digital or electronic signature that can be used to authenticate a contract or any other legal document. From RaoulGough at yahoo.co.uk Tue Aug 12 02:15:33 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Tue, 12 Aug 2003 01:15:33 +0100 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> <16183.45238.143458.663526@monster.linux.in> Message-ID: Prabhu Ramachandran writes: >>>>>> "N" == nicodemus writes: [snip Pyste code, etc...] > > Here is the error that I get when I run this script with holder.so > compiled using gcc 2.95.4 with boost CVS (from this morning) with the > libboost*.so compiled and Pyste from CVS. > > B::f > B::f > Traceback (most recent call last): > File "test_holder.py", line 8, in ? > x.f() > Boost.Python.ArgumentError: Python argument types in > B.f(B) > did not match C++ signature: > f(Q227_GLOBAL_.N.holder.cppYtV9Va9B_Wrapper {lvalue}) > f(1B {lvalue}) Might help for you to demangle that symbol, but I would guess the problem is somehow related to A_Wrapper and B_Wrapper being incompatible. They share a common base class, A, but that probably doesn't help here. Let's see if I understand this (any or all of this could be wrong!) ... [reordered from above] > // ------------------ test_holder.py ---------------- > import holder > b = holder.B() Here type(b) is and b actually contains a std::auto_ptr. > b.f() this calls B.f from Python, which goes to B_Wrapper::default_f in C++ and then to B::f > holder.func(b) > h = holder.Holder () > h.add(b) This uses add_wrapper which upcasts the B_Wrapper * to an A * and inserts it into the container. Note that it also releases() the value from the std::auto_ptr in b, so any subsequent b.f() call will fail. Is this really what you want? > b1 = h.get(0) h.get(0) returns an A* on the C++ side, which gets returned to Python as an A_Wrapper ("print type(b1)" gives ) > b1.f() This call A.f on the python side, which (via virtual dispatch) calls B_Wrapper::f() on the C++ side, since the A* really points to the original B_Wrapper object. B_Wrapper::f() then attempts call_method(self, "f") which is what is failing: > Boost.Python.ArgumentError: Python argument types in > B.f(B) > did not match C++ signature: > f(Q227_GLOBAL_.N.holder.cppYtV9Va9B_Wrapper {lvalue}) > f(1B {lvalue}) Don't really understand why this is happending. The "self" object passed to call_method will probably be of type holder.A (since that was the type returned to Python from h.get(0)). Can anybody take it from here? BTW, have you considered using boost::shared_ptr? I wouldn't trust std::auto_ptr with this kind of stuff. Also, storing raw pointers in a vector is just asking for trouble if you ask me. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From RaoulGough at yahoo.co.uk Tue Aug 12 02:21:01 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Tue, 12 Aug 2003 01:21:01 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: > Raoul Gough writes: >> David Abrahams writes: [snip] >>> I think you're barking up the wrong tree. Maybe we ought to simply >>> change our tune and say that range() produces an iterable-returning >>> function rather than an iterator-returning function. If we did that >>> we could always generate __len__, and for that matter we could also >>> generate __getitem__/__setitem__ for random-access ranges. >> >> Sounds good to me. I think Andreas was also suggesting something in >> this direction. I was almost going to suggest adding a _new_ C++ >> sequence wrapper (e.g. called view or sequence_view) that provides the >> extra stuff as well as __iter__ support via the existing range >> code. The only real benefit would be that the client code could then >> choose whether to include the more sophisticated support. > > Too many options; not enough benefit. Yep. > >> Maybe you could achieve this via an optional iterator_category >> anyway (as you pointed out, __len__ is probably a bad idea for >> input_iterators). > > Don't know what this means. Just thinking that a parameter somewhere that defaults to iterator_traits::iterator_category would allow the user to choose a weaker iterator category if they didn't want the extra stuff. Probably not worth the effort, actually. > > Anyway, I'm not going to implement this one myself. Patches > (including docs and tests) will be gratefully considered. I should get some time to work something out this week. Will post the results when ready. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Tue Aug 12 05:01:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Aug 2003 23:01:12 -0400 Subject: [C++-sig] Re: Accessing Python derived-class members from C++ base References: Message-ID: "Conan Brink" writes: > Given a C++ base class "Base" and a Python class "Derived" derived from > it, I have a method in Base that needs to access arbitrary attributes of > an instance of Derived. Is there any way to do this other than > explicitly passing an extra copy of "self" into the method calls to > Base? Just use static member functions or free functions: > A simple example of this clunky interface follows. > (yes, it's a really silly problem to be solving in this manner, but it > illustrates the interface) > > C++: > > namespace py = boost::python; > > struct Base { > Base() {} > void DoubleIt(py::object self, std::string name); ^ static > }; You can also use the undocumented back_reference to help with overload resolution in case you want module-scope functions. void DoubleIt(back_reference self, char const* name) { self.source().attr(name) *= 2; } ...But you may not care so much about that since you're attaching these to the Python 'Base' class anyway. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 12 05:03:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Aug 2003 23:03:30 -0400 Subject: [C++-sig] Re: derived class without virtual method References: <3F378F70.6050604@web.de> Message-ID: Stefan Fleiter writes: > Hi, > > I am using boost::python 1.30 to wrap some C++-Library. > In this library I have a class Cursor and a dreived class ExtCursor > I use for wrapping to python. > > I always use ExtCursor, neither it nor its base class Cursor has any > virtual method. > When I wrap ExtCursor its member variable of type std::vector > reports a size of one in the destructor, but there are no methods > which could change its size yet. > > If I add *any* virtual method to the base class Cursor > this effect does not show. > > Does boost::python use any rtti or such which depends on a vtable? Definitely, it uses RTTI in many places, though I doubt that has any relationship to your problem. > Any other ideas? I think your problem is described too vaguely for anyone to help you. Code for small reproducible cases helps. -- Dave Abrahams Boost Consulting www.boost-consulting.com From cavok at filibusta.crema.unimi.it Tue Aug 12 05:15:21 2003 From: cavok at filibusta.crema.unimi.it (Domenico Andreoli) Date: Tue, 12 Aug 2003 05:15:21 +0200 Subject: [C++-sig] how to convert c++ objects to Python? Message-ID: <20030812031521.GA17656@filibusta.crema.unimi.it> hi, i have a c++ function that returns a reference to a c++ object. i want to expose this function to Python making it return the Python version of the object. i'm using Boost.Python. i understood that i have to use to_python_converter but the body of the A_to_Python::convert function is mystery for me. Boost documentation's example solves the problem in a manner i'm not able to apply to my case. my A object is complex and i'd like to somewhat (re)use the class_ object. ---------------- CUT HERE ---------------- #include using namespace boost::python; struct A { void f() {} }; A a; struct A_to_Python { static PyObject* convert(const A& a) { // documentation says: // return PyObject_New(noddy_NoddyObject, &noddy_NoddyType); } }; A& get_A() { return a; } BOOST_PYTHON_MODULE(hello) { class_("A") .def("f", &A::f) ; to_python_converter(); def("get_A", get_A, return_value_policy()); } ---------------- CUT HERE ---------------- please, somebody enlighten me. many thanks domenico -----[ Domenico Andreoli, aka cavok --[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc ---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50 From dave at boost-consulting.com Tue Aug 12 06:37:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Aug 2003 00:37:34 -0400 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> <16183.45238.143458.663526@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Well, I don't know what I'm doing wrong but as I said earlier I did > try with the "def" for f and it still does not work along when held > with std::auto_ptr (with gcc 2.95.4). It does work without the held > type though. Here is the example along with the Pyste file and the > error. Your problem is now fixed in CVS. Have a nice day, -- Dave Abrahams (your friendly neighborhood Boost.Python man) Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 12 06:38:58 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Aug 2003 00:38:58 -0400 Subject: [C++-sig] Re: how to convert c++ objects to Python? References: <20030812031521.GA17656@filibusta.crema.unimi.it> Message-ID: cavok at filibusta.crema.unimi.it writes: > hi, > > i have a c++ function that returns a reference to a c++ object. i want > to expose this function to Python making it return the Python version > of the object. i'm using Boost.Python. > > i understood that i have to use to_python_converter Why do you think that? Your code should work find without it as written. > but the body of the > A_to_Python::convert function is mystery for me. Boost documentation's > example solves the problem in a manner i'm not able to apply to my case. > my A object is complex and i'd like to somewhat (re)use the class_ object. > > ---------------- CUT HERE ---------------- > #include > > using namespace boost::python; > > struct A > { > void f() {} > }; > > A a; > > struct A_to_Python > { > static PyObject* convert(const A& a) > { > // documentation says: > // return PyObject_New(noddy_NoddyObject, &noddy_NoddyType); > } > }; > > A& get_A() { return a; } > > BOOST_PYTHON_MODULE(hello) > { > class_("A") > .def("f", &A::f) > ; > > to_python_converter(); > > def("get_A", get_A, return_value_policy()); > } > ---------------- CUT HERE ---------------- > > please, somebody enlighten me. > > many thanks > domenico > > -----[ Domenico Andreoli, aka cavok > --[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc > ---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50 > > ------------------------ Yahoo! Groups Sponsor ---------------------~--> > Buy Ink Cartridges or Refill Kits for Your HP, Epson, Canon or Lexmark > Printer at Myinks.com. Free s/h on orders $50 or more to the US & Canada. http://www.c1tracking.com/l.asp?cid=5511 > http://us.click.yahoo.com/l.m7sD/LIdGAA/qnsNAA/EbFolB/TM > ---------------------------------------------------------------------~-> > > Info: > Wiki: > Unsubscribe: > > > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ > > > -- Dave Abrahams Boost Consulting www.boost-consulting.com From abeyer at uni-osnabrueck.de Tue Aug 12 18:11:30 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Tue, 12 Aug 2003 18:11:30 +0200 (CEST) Subject: [C++-sig] Getting Python Object for C++ object Message-ID: <1362.192.124.248.20.1060704690.squirrel@webmail.rz.uni-osnabrueck.de> It is already a classical problem: I would like to find the python object for a given C++ object from within the C++ object. However, there is no way I gonna wrap the classes as shown in the corresponding Howto example. Thus, I will have to use shared_ptr instead. Eventually I would like to call peer-objects with 'self' as an argument from within C++ as well as from python. (BTW the latter is quite simple.) My first attempt was the following: class A : public enable_shared_from_this { public: virtual python::object get_self() { shared_ptr self = shared_from_this(); assert(self != 0); return python::object(self.get()); } virtual ~A() {}; }; Certainly this only works after a shared pointer has actually been created, e.g. by adding 'a' to another object which only accepts shared_ptr. Like: typedef shared_ptr A_ptr; class C { public: void set(A_ptr a) {this->a = a;} A_ptr get() { return this->a; }; private: A_ptr a; }; This will create a shared_ptr for an instance of 'A' if it gets added to 'C' with set(). After that, shared_from_this() actually returns a valid shared_ptr. However, that pointer apparently points to another (new?) shared_ptr, because the python::object returned is a new one. (Who can explain why shared_from_this() doesn't return the shared_ptr created by boost:python?) Here are the details: BOOST_PYTHON_MODULE(self_test) { using namespace boost::python; class_("A" ) .def("get_self", &A::get_self) ; class_("C" ) .def("set", &C::set ) .def("get", &C::get ) ; } >>> from self_test import * >>> a=A() >>> a.get_self() Traceback (most recent call last): File "", line 1, in ? RuntimeError: boost::bad_weak_ptr >>> c=C() >>> c.set(a) >>> a >>> c.get() # works >>> a.get_self() # returns new object >>> Ok, this didn't work. However, 'C' seems to have the right shared_ptr of 'A'. So my work-around is that instances of A ask 'c' for their shared_ptr. However, that is quit a hack: class A { A() : c(NULL) {}; python::object get_self() { assert(c); return python::object(c->get()); } C *c; }; void C::set(A_ptr a) { this->a=a; // store instance a->c = this; // register at 'a' } >>> from self_test import * >>> a=A() >>> c=C() >>> c.set(a) >>> a >>> c.get() >>> a.get_self() >>> Has anyone a better idea? Andreas From s_sourceforge at nedprod.com Tue Aug 12 21:54:09 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Tue, 12 Aug 2003 20:54:09 +0100 Subject: [C++-sig] Boost.python suggestion + pyste bug In-Reply-To: <3F36D2B8.4020402@globalite.com.br> References: <3F36D6E9.26447.148AA3E2@localhost> Message-ID: <3F3953F1.14395.1E403F58@localhost> On 10 Aug 2003 at 20:18, Nicodemus wrote: > Now, if you are saying that bases<> are always empty, I guess the > problem is that you're using AllFromHeader, which is broken in the > current CVS. Try changing from AllFromHeader to Class calls, that > should make the problem go away. Ah, but if you remember, my pyste file self-generates itself. This means it will adapt to changes in the base library almost automatically. BTW Nicodemus, you have said you have placed your recent bug fixes in CVS. Last night I pulled a fresh copy off the CVS on boost- consulting.com and there had been no changes to pyste whatsoever. What's going on? Is your CVS different from the sourceforge developers one? Cheers, Niall From dave at boost-consulting.com Tue Aug 12 23:49:25 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Aug 2003 17:49:25 -0400 Subject: [C++-sig] Re: Boost.python suggestion + pyste bug References: <3F36D6E9.26447.148AA3E2@localhost> <3F3953F1.14395.1E403F58@localhost> Message-ID: "Niall Douglas" writes: > On 10 Aug 2003 at 20:18, Nicodemus wrote: > >> Now, if you are saying that bases<> are always empty, I guess the >> problem is that you're using AllFromHeader, which is broken in the >> current CVS. Try changing from AllFromHeader to Class calls, that >> should make the problem go away. > > Ah, but if you remember, my pyste file self-generates itself. This > means it will adapt to changes in the base library almost > automatically. > > BTW Nicodemus, you have said you have placed your recent bug fixes in > CVS. Last night I pulled a fresh copy off the CVS on boost- > consulting.com and there had been no changes to pyste whatsoever. > > What's going on? Is your CVS different from the sourceforge > developers one? The boost-consulting mirror is updated nightly by downloading and unpacking the SF CVS tarball, but it's hard to say whether it's updated before or after SF makes its nightly tarball. So the mirror could be as much as 2 days out-of-date. The SF tarball is always 1 day out-of-date. I think I'll change the mirror job to happen in the morning so we're more likely to be up-to-date. -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Wed Aug 13 00:02:26 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Tue, 12 Aug 2003 17:02:26 -0500 Subject: [C++-sig] Re: Boost.python suggestion + pyste bug References: <3F36D6E9.26447.148AA3E2@localhost> <3F3953F1.14395.1E403F58@localhost> Message-ID: <3F3963F2.5090501@vrac.iastate.edu> David Abrahams wrote: > "Niall Douglas" writes: > > >>On 10 Aug 2003 at 20:18, Nicodemus wrote: >> >> >>>Now, if you are saying that bases<> are always empty, I guess the >>>problem is that you're using AllFromHeader, which is broken in the >>>current CVS. Try changing from AllFromHeader to Class calls, that >>>should make the problem go away. >> >>Ah, but if you remember, my pyste file self-generates itself. This >>means it will adapt to changes in the base library almost >>automatically. >> >>BTW Nicodemus, you have said you have placed your recent bug fixes in >>CVS. Last night I pulled a fresh copy off the CVS on boost- >>consulting.com and there had been no changes to pyste whatsoever. >> >>What's going on? Is your CVS different from the sourceforge >>developers one? > > > The boost-consulting mirror is updated nightly by downloading and > unpacking the SF CVS tarball, but it's hard to say whether it's > updated before or after SF makes its nightly tarball. So the mirror > could be as much as 2 days out-of-date. The SF tarball is always 1 > day out-of-date. I think I'll change the mirror job to happen in the > morning so we're more likely to be up-to-date. The tarball may be more out of date than just 1 or 2 days. In my experience with downloading CVS snapshots, they are often many days behind. For example, I have a cron job that tries to download three repository tarballs every night using wget(1) for tape backup purposes, and it won't download the file unless the remote copy is different from the local copy. One of those repository tarballs has not been updated since July 25 in spite of numerous commits I and other people have made in the last 11 days (most of the committers were out of town between July 26 and August 1). I may have something screwed up with my wget(1) options, but I'm inclined to believe that it's been at least 11 days since the tarball was re-rolled by SourceForge. My suspicion is that the SourceForge folks have a script that iterates over their /cvsroot directory and tars up the repositories one by one. As the number of repositories grows and as the size of each active repository grows, this process would slow down and make the tarballs get more and more out of date. -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ From nicodemus at globalite.com.br Wed Aug 13 00:18:59 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 12 Aug 2003 19:18:59 -0300 Subject: [C++-sig] Boost.python suggestion + pyste bug In-Reply-To: <3F3953F1.14395.1E403F58@localhost> References: <3F36D6E9.26447.148AA3E2@localhost> <3F3953F1.14395.1E403F58@localhost> Message-ID: <3F3967D3.6070906@globalite.com.br> Niall Douglas wrote: >On 10 Aug 2003 at 20:18, Nicodemus wrote: > > > >>Now, if you are saying that bases<> are always empty, I guess the >>problem is that you're using AllFromHeader, which is broken in the >>current CVS. Try changing from AllFromHeader to Class calls, that >>should make the problem go away. >> >> > >Ah, but if you remember, my pyste file self-generates itself. This >means it will adapt to changes in the base library almost >automatically. > I see. I will try to get AllFromHeader working in the new system ASAIC. 8) Regards, Nicodemus. From dave at boost-consulting.com Wed Aug 13 01:14:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Aug 2003 19:14:23 -0400 Subject: [C++-sig] Re: Boost.python suggestion + pyste bug References: <3F36D6E9.26447.148AA3E2@localhost> <3F3953F1.14395.1E403F58@localhost> Message-ID: David Abrahams writes: > "Niall Douglas" writes: > >> On 10 Aug 2003 at 20:18, Nicodemus wrote: >> >>> Now, if you are saying that bases<> are always empty, I guess the >>> problem is that you're using AllFromHeader, which is broken in the >>> current CVS. Try changing from AllFromHeader to Class calls, that >>> should make the problem go away. >> >> Ah, but if you remember, my pyste file self-generates itself. This >> means it will adapt to changes in the base library almost >> automatically. >> >> BTW Nicodemus, you have said you have placed your recent bug fixes in >> CVS. Last night I pulled a fresh copy off the CVS on boost- >> consulting.com and there had been no changes to pyste whatsoever. >> >> What's going on? Is your CVS different from the sourceforge >> developers one? > > The boost-consulting mirror is updated nightly by downloading and > unpacking the SF CVS tarball, but it's hard to say whether it's > updated before or after SF makes its nightly tarball. So the mirror > could be as much as 2 days out-of-date. The SF tarball is always 1 > day out-of-date. I think I'll change the mirror job to happen in the > morning so we're more likely to be up-to-date. Ouch. Fortunately if you don't need a CVS history you can use http://www.boost-consulting.com/boost.tar.bz2 which is updated hourly from developer CVS. -- Dave Abrahams Boost Consulting www.boost-consulting.com From sf.lists at web.de Wed Aug 13 15:30:57 2003 From: sf.lists at web.de (Stefan Fleiter) Date: Wed, 13 Aug 2003 15:30:57 +0200 Subject: [C++-sig] Re: derived class without virtual method In-Reply-To: References: <3F378F70.6050604@web.de> Message-ID: <3F3A3D91.6000709@web.de> Hi, David Abrahams wrote: > I think your problem is described too vaguely for anyone to help you. > Code for small reproducible cases helps. The problem is quite complex and involves many software libraries. I have not been able to produce a testcase. :-/ Have to live with a workaround. Many thanks, though. Stefan From sf.lists at web.de Wed Aug 13 15:32:11 2003 From: sf.lists at web.de (Stefan Fleiter) Date: Wed, 13 Aug 2003 15:32:11 +0200 Subject: [C++-sig] Parameter translation python, C++ Message-ID: <3F3A3DDB.4010807@web.de> Hi, when I call a boost::python method from python with a parameter of type float and there is only a C++ Method with a parameter of type double I get an "unidentifiable C++ exception". C++-Code: -------------------------------------------------------- void pybind(db::ExtCursor& cur, int column, float value) { // do something } BOOST_PYTHON_MODULE(_dblib) { void (*bind4)(db::ExtCursor&, int, double) = &pybind; py::class_< db::ExtCursor, boost::noncopyable >("ExtCursor", py::init< db::Connection& >()) .def("bind", bind4, "bind value to query") } Python-Code: -------------------------------------------------------- self._cCursor.bind(0, 2.3) // _cCursor is db::ExtCursor PS: I am using boost::python 1.30. Thanks, Stefan From dave at boost-consulting.com Wed Aug 13 16:14:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Aug 2003 10:14:57 -0400 Subject: [C++-sig] Re: Parameter translation python, C++ References: <3F3A3DDB.4010807@web.de> Message-ID: Stefan Fleiter writes: > Hi, > > when I call a boost::python method from python > with a parameter of type float and there is only > a C++ Method with a parameter of type double > I get an "unidentifiable C++ exception". > > C++-Code: > -------------------------------------------------------- > void pybind(db::ExtCursor& cur, int column, float value) ^^^^^ > { > // do something > } > > BOOST_PYTHON_MODULE(_dblib) > { > > void (*bind4)(db::ExtCursor&, int, double) = &pybind; ^^^^^^ I can't believe your compiler lets you get away with this. > py::class_< db::ExtCursor, boost::noncopyable >("ExtCursor", > py::init< db::Connection& >()) > .def("bind", bind4, "bind value to query") > } > > Python-Code: > -------------------------------------------------------- > self._cCursor.bind(0, 2.3) // _cCursor is db::ExtCursor > > > PS: I am using boost::python 1.30. Your example is missing the definition of ExtCursor. Anyway, the exception is either: 1. Actually a crash (most likely in your code), if you're running on windows. Try #including libs/python/test/module_tail.cpp in your module 2. A regular C++ exception thrown by your code for which you've not installed a translator. -- Dave Abrahams Boost Consulting www.boost-consulting.com From sf.lists at web.de Wed Aug 13 17:31:35 2003 From: sf.lists at web.de (Stefan Fleiter) Date: Wed, 13 Aug 2003 17:31:35 +0200 Subject: [C++-sig] Re: Parameter translation python, C++ In-Reply-To: References: <3F3A3DDB.4010807@web.de> Message-ID: <3F3A59D7.3060306@web.de> Hi, >>when I call a boost::python method from python >>with a parameter of type float and there is only >>a C++ Method with a parameter of type double >>I get an "unidentifiable C++ exception". >>C++-Code: >>-------------------------------------------------------- >>void pybind(db::ExtCursor& cur, int column, float value) Sorry, this is a double, I had two shells open and copied this from the working version. > I can't believe your compiler lets you get away with this. No, g++ 3.2.3 would not do that. :-) >> py::class_< db::ExtCursor, boost::noncopyable >("ExtCursor", >> py::init< db::Connection& >()) >> .def("bind", bind4, "bind value to query") >>} >> >>Python-Code: >>-------------------------------------------------------- >>self._cCursor.bind(0, 2.3) // _cCursor is db::ExtCursor > Anyway, the exception is either: > > 1. Actually a crash (most likely in your code), if you're running on > windows. Try #including libs/python/test/module_tail.cpp in your > module I do run Linux. I get the exception even if pybind is defined empty ( {} ). > 2. A regular C++ exception thrown by your code for which you've not > installed a translator. See above, an empty method can't throw an exception. And last but not least: If I change "double" to "float" everything is ok. Greets, Stefan From dave at boost-consulting.com Wed Aug 13 17:57:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Aug 2003 11:57:20 -0400 Subject: [C++-sig] Re: Parameter translation python, C++ References: <3F3A3DDB.4010807@web.de> <3F3A59D7.3060306@web.de> Message-ID: Stefan Fleiter writes: > Hi, > >>>when I call a boost::python method from python >>>with a parameter of type float and there is only >>>a C++ Method with a parameter of type double >>>I get an "unidentifiable C++ exception". > >>>C++-Code: >>>-------------------------------------------------------- >>>void pybind(db::ExtCursor& cur, int column, float value) > > Sorry, this is a double, I had two shells open and copied this from > the working version. > >> I can't believe your compiler lets you get away with this. > No, g++ 3.2.3 would not do that. :-) > >>> py::class_< db::ExtCursor, boost::noncopyable >("ExtCursor", >>> py::init< db::Connection& >()) >>> .def("bind", bind4, "bind value to query") >>>} >>> >>>Python-Code: >>>-------------------------------------------------------- >>>self._cCursor.bind(0, 2.3) // _cCursor is db::ExtCursor > >> Anyway, the exception is either: >> 1. Actually a crash (most likely in your code), if you're running on >> windows. Try #including libs/python/test/module_tail.cpp in your >> module > I do run Linux. > I get the exception even if pybind is defined empty ( {} ). > > >> 2. A regular C++ exception thrown by your code for which you've not >> installed a translator. > See above, an empty method can't throw an exception. > > And last but not least: > If I change "double" to "float" everything is ok. > Honestly, I don't see how this could have anything to do with Boost.Python. If it doesn't fail on the following code, I think it has to be in your code. If it does, I think it has to be a compiler bug. #include namespace db { struct ExtCursor { ExtCursor(int) {} }; } void pybind(db::ExtCursor& cur, int column, double value) { } namespace py = boost::python; BOOST_PYTHON_MODULE(foo_ext) { void (*bind4)(db::ExtCursor&, int, double) = &pybind; py::class_< db::ExtCursor, boost::noncopyable >( "ExtCursor", py::init< int >()) .def("bind", bind4, "bind value to query") ; } ---------- from foo_ext import * print ExtCursor(3).bind(0, 2.3) -- Dave Abrahams Boost Consulting www.boost-consulting.com From sf.lists at web.de Wed Aug 13 19:28:10 2003 From: sf.lists at web.de (Stefan Fleiter) Date: Wed, 13 Aug 2003 19:28:10 +0200 Subject: [C++-sig] Re: Parameter translation python, C++ In-Reply-To: References: <3F3A3DDB.4010807@web.de> <3F3A59D7.3060306@web.de> Message-ID: <3F3A752A.9090707@web.de> Hi, David Abrahams wrote: > Honestly, I don't see how this could have anything to do with > Boost.Python. If it doesn't fail on the following code, I think it > has to be in your code. It was. I'll go back in my hole and come back when I'll have a question or a bug I can reproduce with a small testcase. I'm really sorry. Greets, Stefan From ahakim777 at yahoo.com Wed Aug 13 20:43:52 2003 From: ahakim777 at yahoo.com (Ammar Hakim) Date: Wed, 13 Aug 2003 11:43:52 -0700 (PDT) Subject: [C++-sig] Returning NULL from C++ Message-ID: <20030813184352.37650.qmail@web20305.mail.yahoo.com> Hello All, How do I wrap a C++ function which does something like this: struct A {}; A* get_A() { if(some_condition) return NULL; else return pointer_to_A; } I would like the NULL to be converted into a None in Python. Cheers, Ammar __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From dave at boost-consulting.com Thu Aug 14 01:34:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Aug 2003 19:34:41 -0400 Subject: [C++-sig] Re: Returning NULL from C++ References: <20030813184352.37650.qmail@web20305.mail.yahoo.com> Message-ID: Ammar Hakim writes: > Hello All, > > How do I wrap a C++ function which does something like > this: > > struct A {}; > > A* > get_A() > { > if(some_condition) > return NULL; > else > return pointer_to_A; > } > > I would like the NULL to be converted into a None in > Python. That functionality is built-in. However, the library will force you to use a call policy to deal with the semantics of the pointer you're returning in the other case (e.g. is it a new piece of memory or a reference to an existing object?) -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Aug 14 02:51:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Aug 2003 20:51:35 -0400 Subject: [C++-sig] Re: Getting Python Object for C++ object References: <1362.192.124.248.20.1060704690.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: Anxious to clear this from my "unread" pile, I'm going to try to help... abeyer at uni-osnabrueck.de writes: > It is already a classical problem: I would like to find the python object > for a given C++ object from within the C++ object. However, there is no > way I gonna wrap the classes as shown in the corresponding Howto > example. I assume that you mean creating a wrapper subclass is impossible for you. Understandable. > Thus, I will have to use shared_ptr instead. Since you seem to be willing to change interfaces, you can modify the class itself to take an initial PyObject* argument and specialize boost::python::has_back_reference: namespace boost { namespace python { template <> struct has_back_reference : mpl::true_ {}; }} But this is hardly a more attractive solution. > Eventually I would like to call peer-objects with 'self' as an argument > from within C++ as well as from python. (BTW the latter is quite simple.) > My first attempt was the following: > > class A : public enable_shared_from_this { > public: > virtual python::object get_self() { > shared_ptr self = shared_from_this(); > assert(self != 0); > return python::object(self.get()); ^^^^^^^^^^ This will trip you up. Boost.Python can't convert a raw pointer into an existing Python object; when you explicitly convert a pointer to Python it creates a new Python object and copies the pointee. You want return python::object(self); instead. > } > > virtual ~A() {}; > }; > > Certainly this only works after a shared pointer has > actually been created, e.g. by adding 'a' to another object > which only accepts shared_ptr. Like: > > typedef shared_ptr A_ptr; > class C { > public: > void set(A_ptr a) {this->a = a;} > A_ptr get() { return this->a; }; > private: > A_ptr a; > }; > > This will create a shared_ptr for an instance of 'A' if it gets > added to 'C' with set(). Yes, but it won't make the shared_from_this() call succeed unless you've assigned that shared_ptr into a->_internal_weak_this. [Peter, I notice that enable_shared_from_this.hpp is mentioned in the docs and enable_shared_from_this<> is mentioned in the sp_techniques doc, but there's no mention of this crucial fact] > After that, shared_from_this() actually returns a valid > shared_ptr. However, that pointer apparently points to another > (new?) shared_ptr, because the python::object returned is a new > one. (Who can explain why shared_from_this() doesn't return the > shared_ptr created by boost:python?) I hope I already have. I didn't read the stuff that follows; please let me know if I still need to. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Thu Aug 14 08:24:54 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Thu, 14 Aug 2003 11:54:54 +0530 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> <16183.45238.143458.663526@monster.linux.in> Message-ID: <16187.11062.292705.748170@monster.linux.in> >>>>> "DA" == David Abrahams writes: DA> Prabhu Ramachandran writes: >> Well, I don't know what I'm doing wrong but as I said earlier I >> did try with the "def" for f and it still does not work along >> when held with std::auto_ptr (with gcc 2.95.4). It does work >> without the held type though. Here is the example along with >> the Pyste file and the error. DA> Your problem is now fixed in CVS. Yes, looks like it is. Many thanks!! Regards, prabhu From prabhu at aero.iitm.ernet.in Thu Aug 14 08:34:51 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Thu, 14 Aug 2003 12:04:51 +0530 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. In-Reply-To: References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> <16183.45238.143458.663526@monster.linux.in> Message-ID: <16187.11659.666491.946542@monster.linux.in> >>>>> "RG" == Raoul Gough writes: [snip explanation by RG of how test_holder.py works] Thanks for the explanation, it confirmed my understanding! RG> BTW, have you considered using boost::shared_ptr? I wouldn't RG> trust std::auto_ptr with this kind of stuff. Also, storing raw RG> pointers in a vector is just asking for trouble if you ask me. Dave enlightened me on the advantages of using boost::shared_ptr a month or so back. Unfortunately I am not in a position to change my code at this time for two reasons: (a) I'll need to investigate if there is a performance hit for my kind of code (b) I don't have the time to change the interface in my code right now and carefully eliminate cyclic reference loops etc. Storing pointers in a vector is asking for trouble? It might be true in general but I'd say using pointers carefully is not bad. It has worked well for me so far. cheers, prabhu From RaoulGough at yahoo.co.uk Thu Aug 14 14:48:32 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Thu, 14 Aug 2003 13:48:32 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: [snip] > Anyway, I'm not going to implement this one myself. Patches > (including docs and tests) will be gratefully considered. OK, I've added len and read-only indexing to boost::python::range, dependant on iterator type. I've posted my current progress to http://home.clara.net/raoulgough/boost/ - any comments are welcome. There is a test script (currently stand-alone) and no docs yet. I'll wait a few days to see if anybody suggests any changes before advancing. Basically, I've renamed iterator_next to iterator_range_utils, the original execute to execute_next and added execute_getitem. Distance is a separate free function, since it doesn't need any policies. Then it's simply a case of deciding which of these to instantiate and add to the returned Python object (done on the basis of is_convertible with the std:: iterator_categories). The hooks in demand_iterator_class look like this: ! class_ result (name, no_init); ! ! result .def("__iter__", identity_function()) ! .setattr("next", next_function); ! ! maybe_add_len ! ::value> ! ::apply (result); ! ! maybe_add_getitem ! ::value> ! ::apply (result, policies); Full details on the web site... -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Thu Aug 14 15:44:10 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 09:44:10 -0400 Subject: [C++-sig] Re: Getting Python Object for C++ object In-Reply-To: <000701c3625f$958655d0$1d00a8c0@pdimov2> (Peter Dimov's message of "Thu, 14 Aug 2003 15:28:35 +0300") References: <1362.192.124.248.20.1060704690.squirrel@webmail.rz.uni-osnabrueck.de> <002501c36248$afbf40e0$1d00a8c0@pdimov2> <000701c3625f$958655d0$1d00a8c0@pdimov2> Message-ID: "Peter Dimov" writes: > David Abrahams wrote: >>>> Yes, but it won't make the shared_from_this() call succeed unless >>>> you've assigned that shared_ptr into a->_internal_weak_this. >>>> >>>> [Peter, I notice that enable_shared_from_this.hpp is mentioned in >>>> the docs and enable_shared_from_this<> is mentioned in the >>>> sp_techniques doc, but there's no mention of this crucial fact] >>> >>> Which crucial fact? >> >> Sorry. I mean that a derived class needs to initialize the >> _internal_weak_this in order to get shared_from_this() to work. >> Unless I've missed some other crucial fact, of course ;-> > > No, the derived class doesn't need to do anything. There is no > _internal_weak_this in the interface. Are we loooking at the same file? It's a public data member, and AFAICT there's nothing to initialize it, so that responsibility must lie with derived classes (or the general public, of course). Aha! shared_ptr itself takes care of that when you assign to it. Thanks for explaining that. Using template friends and a private data member on compilers which support it would've helped clarify that (or regular docs for enable_shared_from_this, of course)! > AFAICS the poster's problem is that, as you pointed out, > python::object(self.get()) creates a new object, not that I know > anything about (Boost.)Python, of course. Good guess, then ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Aug 14 15:46:45 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 09:46:45 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > David Abrahams writes: > [snip] >> Anyway, I'm not going to implement this one myself. Patches >> (including docs and tests) will be gratefully considered. > > OK, I've added len and read-only indexing to boost::python::range, > dependant on iterator type. I've posted my current progress to > http://home.clara.net/raoulgough/boost/ - any comments are > welcome. There is a test script (currently stand-alone) and no docs > yet. I'll wait a few days to see if anybody suggests any changes > before advancing. Nit: could you redo the diffs using the -u option? I typically use -wdu. Unified diffs are much easier to read. Thanks, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Aug 14 15:48:59 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 09:48:59 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > David Abrahams writes: > [snip] >> Anyway, I'm not going to implement this one myself. Patches >> (including docs and tests) will be gratefully considered. > > OK, I've added len and read-only indexing to boost::python::range, > dependant on iterator type. I've posted my current progress to > http://home.clara.net/raoulgough/boost/ - any comments are > welcome. There is a test script (currently stand-alone) and no docs > yet. I'll wait a few days to see if anybody suggests any changes > before advancing. One other point: I notice you're wondering whether to support slices; probably you should have a look at Joel's recent indexing suite work. Maybe once we start to get into range-as-iterable instead of -as-iterator we should also be handling some of the object lifetime and iterator validity issues. If this seems reasonable to you, you probably ought to talk it over with Joel. -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Thu Aug 14 16:19:06 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Thu, 14 Aug 2003 15:19:06 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: > Raoul Gough writes: [snip] >> http://home.clara.net/raoulgough/boost/ - any comments are >> welcome. > > Nit: could you redo the diffs using the -u option? I typically use > -wdu. Unified diffs are much easier to read. I actually meant to use -cp, which is what gdb prefers for patches. Anyway, I've now updated it to -wdu format (and I agree - it is easier to read). -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From warkid at hotbox.ru Thu Aug 14 17:05:06 2003 From: warkid at hotbox.ru (Kerim Borchaev) Date: Thu, 14 Aug 2003 19:05:06 +0400 Subject: [C++-sig] Callable object instance as object method. Message-ID: <113870809671.20030814190506@hotbox.ru> Hello! I want to use a C++ callable object instance as python object method: //callable_as_method.cpp///////////////////////////////// struct C{ }; struct Callable{ void call(C& c){ } }; #include #include #include BOOST_PYTHON_MODULE(callable_as_method) { using namespace boost::python; class_("Callable") .def("__call__", Callable::call); class_ c("C"); c.setattr("method", Callable()); } ////////////////////////////////////////////////////////// And when I run this test: #test_callable_as_method.py############### import test c = test.C() c.method(c) c.method() ########################################## I get this result: Traceback (most recent call last): File "test_callable_as_method.py", line 5, in ? c.method() TypeError: bad argument type for built-in operation That's (apparently) happens because 'method' is exported not as a function. Is it possible to export it in such a way that C().method whould result in bound method object? Best regards, Kerim mailto:warkid at hotbox.ru From dave at boost-consulting.com Thu Aug 14 17:11:13 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 11:11:13 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: Raoul Gough writes: > David Abrahams writes: > >> Raoul Gough writes: > [snip] >>> http://home.clara.net/raoulgough/boost/ - any comments are >>> welcome. >> >> Nit: could you redo the diffs using the -u option? I typically use >> -wdu. Unified diffs are much easier to read. > > I actually meant to use -cp, which is what gdb prefers for patches. gdb?? Why/how does a debugger use patches? > Anyway, I've now updated it to -wdu format (and I agree - it is easier > to read). Thanks. -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Thu Aug 14 18:17:12 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Thu, 14 Aug 2003 17:17:12 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: David Abrahams writes: > Raoul Gough writes: > >> David Abrahams writes: >> >>> Raoul Gough writes: >> [snip] >>>> http://home.clara.net/raoulgough/boost/ - any comments are >>>> welcome. >>> >>> Nit: could you redo the diffs using the -u option? I typically use >>> -wdu. Unified diffs are much easier to read. >> >> I actually meant to use -cp, which is what gdb prefers for patches. > > gdb?? Why/how does a debugger use patches? I should have said "what the gdb *maintainers*" prefer. I hacked in the support for DLL symbol extraction a while back (and fixed some bugs). As someone once said, "use the source, Luke!". Or maybe, "he's been on the source again" :-) Hey, now that I think of it - the enhancements I did for gdb were directly related to my work using Python extension modules, and probably warrant a change to the FAQ (the bit about gdb on Windows being a dog with DLLs). If you go to http://sources.redhat.com/gdb/onlinedocs/gdb_19.html and search for python within the page, you'll see how I attack Python extensions with gdb on Windows. Basically, you set a break in Python's line reader (PyOS_Readline), continue 'til the Python command prompt appears and give it an import statement. gdb then breaks before Python reads another line, and you can set more breakpoints in the newly loaded DLL. There are even worse tricks involving breaking in KERNEL32!LoadLibraryExA, but that is a bit hairy. Theoretically, you should be able to "catch load", but nobody's implemented that yet for Windows (AFAIK). Anyway, the DLL symbol support is in Cygwin's current gdb release, not sure about MinGW. If your info file has the docs, then it should work (Under Configurations - Native - Cygwin Native - Non-debug DLL symbols) -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Thu Aug 14 18:43:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 12:43:46 -0400 Subject: [C++-sig] Re: Callable object instance as object method. References: <113870809671.20030814190506@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello! > > I want to use a C++ callable object instance as python object method: > > //callable_as_method.cpp///////////////////////////////// > struct C{ > }; > > struct Callable{ > void call(C& c){ > } > }; > > #include > #include > #include > > BOOST_PYTHON_MODULE(callable_as_method) > { > using namespace boost::python; > class_("Callable") > .def("__call__", Callable::call); > class_ c("C"); > c.setattr("method", Callable()); > } > ////////////////////////////////////////////////////////// > > And when I run this test: > > #test_callable_as_method.py############### > import test > c = test.C() > c.method(c) > c.method() > ########################################## > > I get this result: > > Traceback (most recent call last): > File "test_callable_as_method.py", line 5, in ? > c.method() > TypeError: bad argument type for built-in operation > > That's (apparently) happens because 'method' is exported not as a > function. No, try updating to the latest CVS and you'll see (from the improved error reporting) that the c object isn't getting passed to the method. If you want to pursue your approach, you'd need to add a __get__ method to handle the creation of a bound method (see http://www.python.org/dev/doc/devel/ref/descriptors.html). > Is it possible to export it in such a way that C().method whould > result in bound method object? There's no really easy way yet, but I intend to create one. In the meantime, you could try simply: class("C") .setattr( "method" , detail::make_function_aux( Callable() , default_call_policies() , detail::args_from_python() , mpl::vector()) ) ; Don't bother wrapping Callable with class_<>. I'll see what I can do about formalizing this mechanism. -- Dave Abrahams Boost Consulting www.boost-consulting.com From gideon at computer.org Thu Aug 14 21:28:39 2003 From: gideon at computer.org (gideon may) Date: Thu, 14 Aug 2003 21:28:39 +0200 Subject: [C++-sig] Question regarding objects of enums Message-ID: <43342072.1060896519@[10.0.0.6]> Hi Dave, I tried to compile my library with the current cvs version and stumbled on a problem with enums. The following worked with boost 1.30.0 but fails with the cvs version (using MSVC 7): class MyClass { public: enum Direction { UP, DOWN }; }; enum Color { RED, GREEN, BLUE }; void make_object() { object o1 = object(RED); // Works object o2 = object(MyClass::UP); // Fails } TIA, Gideon Here is the output of the build : -------------------------------------------------- E:\boost-03-08-14-0400\boost\python\object_core.hpp(230) : error C2893: Failed to specialize function template 'const T *boost:: python::api::object::to_ptr(const T &)' With the following template arguments: 'boost::add_const::type' with [ T=boost::detail::reference_unwrapper::apply::type ] object.cpp(26) : see reference to function template instantiation 'boost::python::api::object::object(const T &)' being compiled with [ T=MyClass::Direction ] E:\boost-03-08-14-0400\boost\python\object_core.hpp(230) : error C2143: syntax error : missing ')' before 'const' C:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xmemory(136) : fatal error C1004: unexpected end of file found "cl" /Zm800 -nologo -GX -c -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB /Ogity /O2 /Gs /Ob2 /GX /GR /MD /Op /Zc:wchar_t,forScope -I"..\..\..\libs\python\test" -I"E:\boost-03-08-14-0400" -I"C:\Python22\include" -I"C:\Program Files\Microsoft Visual Studio . NET\VC7\include" -Fo"..\..\..\libs\python\test\bin\object_ext.pyd\vc7\release\runtime-link-d ynamic\object.obj" -Tp"object.cpp " -------------------------------------------------- From sam at gabrielinteractive.com Thu Aug 14 22:38:36 2003 From: sam at gabrielinteractive.com (Sam Bloomquist) Date: Thu, 14 Aug 2003 15:38:36 -0500 Subject: [C++-sig] class data members and visual studio.net 2003 Message-ID: I am currently working on moving an application from visual studio 6.0 to visual studio .net 2003 and boost 1.29.0 to boost 1.30.0 and am having a few problems with class data members. My c++ struct and python wrapper are as follows: struct JunkObject { bool operator == (JunkObject& jo); std::string m_sName; int m_iID; }; class_("JunkObject") .def_readwrite("name", &JunkObject::m_sName) .def_readwrite("id", &JunkObject::m_iID); # Then in python when I do this... obj = plus.JunkObject() obj.id = 5 # where "plus" is my boost python module, everthing is fine. But if I do... obj.name = "Bob" # my program crashes. Does anyone see something I'm missing? This worked fine in msvs 6.0 and boost 1.29. -Sam Bloomquist Gabriel Interactive, Inc. From dave at boost-consulting.com Fri Aug 15 00:48:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Aug 2003 18:48:20 -0400 Subject: [C++-sig] Re: Question regarding objects of enums References: <43342072.1060896519@[10.0.0.6]> Message-ID: gideon may writes: > Hi Dave, > > I tried to compile my library with the current cvs version and > stumbled on a problem with enums. The following worked with > boost 1.30.0 but fails with the cvs version (using MSVC 7): > > class MyClass { > public: > enum Direction { > UP, DOWN > }; > }; > > enum Color { > RED, GREEN, BLUE > }; > > > void make_object() > { > object o1 = object(RED); // Works > object o2 = object(MyClass::UP); // Fails > } > > TIA, > > Gideon VC7 bug. Fixed in CVS with enclosed patch. -------------- next part -------------- A non-text attachment was scrubbed... Name: object_core.patch Type: text/x-patch Size: 2640 bytes Desc: not available URL: -------------- next part -------------- -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Fri Aug 15 06:44:51 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 15 Aug 2003 10:14:51 +0530 Subject: [C++-sig] vector_indexing_suite and bool. Message-ID: <16188.25923.428821.911730@monster.linux.in> Hi, Thanks for the vector_indexing_suite! It is really nice and seems to work wonderfully! However, I just ran into one problem with it. I tried wrapping a std::vector and things don't compile because the vector_indexing_suite::get_item(...) returns a reference to the bool which the compiler has problems with. Here is the trivial test program and error message that I get with g++-2.95.4 and Boost from CVS. // -------------------------------------------------- #include #include using namespace boost::python; BOOST_PYTHON_MODULE(vec_index) { class_< std::vector > ("VectorBool") .def(vector_indexing_suite< std::vector, true> ()); } // -------------------------------------------------- Compiling this produces this error: /skratch/prabhu/cvs/boost/boost/python/suite/indexing/vector_indexing_suite.hpp: In function `static bool & boost::python::vector_indexing_suite >,true,boost::python::detail::final_vector_derived_policies >,true> >::get_item(vector > &, unsigned int)': /skratch/prabhu/cvs/boost/boost/python/suite/indexing/detail/indexing_suite_detail.hpp:410: instantiated from `boost::python::detail::no_proxy_helper >,boost::python::detail::final_vector_derived_policies >,true>,boost::python::detail::container_element >,unsigned int,boost::python::detail::final_vector_derived_policies >,true> >,unsigned int>::base_get_item_(const boost::python::back_reference > &> &, PyObject *)' /skratch/prabhu/cvs/boost/boost/python/suite/indexing/indexing_suite.hpp:200: instantiated from `boost::python::indexing_suite >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool>::base_get_item(boost::python::back_reference > &>, PyObject *)' /skratch/prabhu/cvs/boost/boost/python/suite/indexing/indexing_suite.hpp:179: instantiated from `boost::python::indexing_suite >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool>::visit >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> >(boost::python::class_ >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> &) const' /skratch/prabhu/cvs/boost/boost/python/def_visitor.hpp:32: instantiated from `boost::python::def_visitor_access::visit >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool> >, boost::python::class_ >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> >(const boost::python::def_visitor >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool> > &, boost::python::class_ >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> &)' /skratch/prabhu/cvs/boost/boost/python/def_visitor.hpp:68: instantiated from `boost::python::def_visitor >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool> >::visit >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> >(boost::python::class_ >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified> &) const' /skratch/prabhu/cvs/boost/boost/python/class.hpp:288: instantiated from `boost::python::class_ >,boost::python::detail::not_specified,boost::python::detail::not_specified,boost::python::detail::not_specified>::def >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool> >(const boost::python::def_visitor >,boost::python::detail::final_vector_derived_policies >,true>,true,false,bool,unsigned int,bool> > &)' vec_index.cpp:9: instantiated from here /skratch/prabhu/cvs/boost/boost/python/suite/indexing/vector_indexing_suite.hpp:73: initializing non-const `bool &' with `_Bit_reference' will use a temporary /skratch/prabhu/cvs/boost/boost/python/suite/indexing/vector_indexing_suite.hpp:73: warning: returning reference to temporary I made a local copy of the vector_indexing_suite and changed this: static data_type& get_item(Container& container, index_type i) to: static data_type get_item(Container& container, index_type i) and my test program compiles cleanly. This is obviously not a fix but just to let you know that this is the only problem. Thanks! cheers, prabhu From djowel at gmx.co.uk Fri Aug 15 07:18:16 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Fri, 15 Aug 2003 13:18:16 +0800 Subject: [C++-sig] vector_indexing_suite and bool. References: <16188.25923.428821.911730@monster.linux.in> Message-ID: <000b01c362ec$a9657b70$0100a8c0@godzilla> Prabhu Ramachandran wrote: > Hi, > > Thanks for the vector_indexing_suite! It is really nice and seems to > work wonderfully! However, I just ran into one problem with it. I > tried wrapping a std::vector and things don't compile because > the vector_indexing_suite::get_item(...) returns a reference to the > bool which the compiler has problems with. Here is the trivial test > program and error message that I get with g++-2.95.4 and Boost from > CVS. > > // -------------------------------------------------- > #include > #include > > using namespace boost::python; > > BOOST_PYTHON_MODULE(vec_index) > { > class_< std::vector > ("VectorBool") > .def(vector_indexing_suite< std::vector, true> ()); > } > // -------------------------------------------------- [snip errors] > I made a local copy of the vector_indexing_suite and changed this: > > static data_type& > get_item(Container& container, index_type i) > to: > > static data_type > get_item(Container& container, index_type i) > > and my test program compiles cleanly. This is obviously not a fix but > just to let you know that this is the only problem. Thanks for trying it out, Prabhu. I'll go and find a solution to this problem. I think, off the top of my head, that get_item should be: static typename mpl::if_< is_class , data_type& , data_type >::type get_item(Container& container, index_type i) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From gideon at computer.org Fri Aug 15 08:36:14 2003 From: gideon at computer.org (gideon may) Date: Fri, 15 Aug 2003 08:36:14 +0200 Subject: [C++-sig] Re: Question regarding objects of enums In-Reply-To: References: <43342072.1060896519@[10.0.0.6]> Message-ID: <83395005.1060936574@localhost> Thanks! PS, What is the release schedule for Boost 1.31.0 ? I've noticed a lot of traffic on the boost list on regression tests, but haven't seen a time plan lately. Am looking forward releasing my next version with boost 1.31.0 ;-). --David Abrahams wrote: > gideon may writes: > >> Hi Dave, >> >> I tried to compile my library with the current cvs version and >> stumbled on a problem with enums. The following worked with >> boost 1.30.0 but fails with the cvs version (using MSVC 7): >> >> class MyClass { >> public: >> enum Direction { >> UP, DOWN >> }; >> }; >> >> enum Color { >> RED, GREEN, BLUE >> }; >> >> >> void make_object() >> { >> object o1 = object(RED); // Works >> object o2 = object(MyClass::UP); // Fails >> } >> >> TIA, >> >> Gideon > > VC7 bug. Fixed in CVS with enclosed patch. > > From warkid at hotbox.ru Fri Aug 15 10:31:28 2003 From: warkid at hotbox.ru (Kerim Borchaev) Date: Fri, 15 Aug 2003 12:31:28 +0400 Subject: [C++-sig] Re: Re: Callable object instance as object method. Message-ID: <160933593125.20030815123128@hotbox.ru> Hello! Dave Abrahams wrote: >> Is it possible to export it in such a way that C().method whould >> result in bound method object? > > There's no really easy way yet, but I intend to create one. In the > meantime, you could try simply: > > class("C") > .setattr( > "method" > , detail::make_function_aux( > Callable() > , default_call_policies() > , detail::args_from_python() > , mpl::vector()) > ) > ; Yes it works(assuming Callable has operator()). Thanks. Best regards, Kerim mailto:warkid at hotbox.ru From prabhu at aero.iitm.ernet.in Fri Aug 15 10:49:49 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 15 Aug 2003 14:19:49 +0530 Subject: [C++-sig] vector_indexing_suite and bool. In-Reply-To: <000b01c362ec$a9657b70$0100a8c0@godzilla> References: <16188.25923.428821.911730@monster.linux.in> <000b01c362ec$a9657b70$0100a8c0@godzilla> Message-ID: <16188.40621.820090.833931@monster.linux.in> >>>>> "Joel" == Joel de Guzman writes: [ PR problem with exposing std::vector ] Joel> Thanks for trying it out, Prabhu. I'll go and find a solution My pleasure! Exposing std::vector was one of the few things that I needed and your vector_indexing_suite works wonderfully! Now I just need to get Pyste to support this. More on that later. Joel> to this problem. I think, off the top of my head, that Joel> get_item should be: Joel> static typename mpl::if_< Joel> is_class Joel> , data_type& Joel> , data_type Joel> >::type Joel> get_item(Container& container, index_type i) Yes, that fixes it. Many thanks! cheers, prabhu From abeyer at uni-osnabrueck.de Fri Aug 15 10:58:13 2003 From: abeyer at uni-osnabrueck.de (abeyer at uni-osnabrueck.de) Date: Fri, 15 Aug 2003 10:58:13 +0200 (CEST) Subject: [C++-sig] Re: Getting Python Object for C++ object Message-ID: <1163.192.124.248.20.1060937893.squirrel@webmail.rz.uni-osnabrueck.de> >> Eventually I would like to call peer-objects with 'self' as an argument >> from within C++ as well as from python. (BTW the latter is quite simple.) >> My first attempt was the following: >> >> class A : public enable_shared_from_this { >> public: >> virtual python::object get_self() { >> shared_ptr self = shared_from_this(); >> assert(self != 0); >> return python::object(self.get()); > ^^^^^^^^^^ > This will trip you up. Boost.Python can't convert a raw pointer into > an existing Python object; when you explicitly convert a pointer to > Python it creates a new Python object and copies the pointee. You want > > return python::object(self); > > instead. That works. Find below an example. Note, that I am referencing the '_internal_weak_this' in order to find out if I actually have a shared pointer for this. (I do not want to wait for the bad_weak_ptr exception.) Dave, I am not on the boost developer list. Could you suggest the following extension to enable_shared_from_this: bool has_shared_from_this() { return ! _internal_weak_this.expired(); } Find following a description of the problem and its solution, which may go into FAQ and/or a respective tutorial, if you like. Assume, you have written a class 'A' in C++, which has an update function for updating peer objects. The update function takes another object and calls its 'hello()' method with self as an argument. This is typically used in event handling mechanisms. >>> from self_test import * >>> a=A() >>> a >>> class B: ... def hello(self, other): ... print self, 'got called from', other ... >>> b=B() >>> a.update(b) <__main__.B instance at 0x008FAE40> got called from >>> Crucial is, that 'a' passes its original python object to 'b' and not a copy. This is relatively simple to accomplish for calls from python, because the python object for 'a' is easily accessible in that case. A possible implementation in C++ looks like the following: static void call_from_py(python::object self, PyObject* other) { python::call_method( other, "hello", self ); } The trick is to define call_from_py() static and to explicitely get the reference to the called object ('self'). The boost.python wrapping for that function is not at all fancy: class_("A" ) .def("update", &A::call_from_py) ; However, what if we want to call A's update function from within C++? In that case the python object is not (directly) accesible. In that case we can make use of shared pointers. boost.python creates shared pointers for each python object. If we pass the right shared pointer to a python::object constructor boost.python can find an existing python object and return a reference to that object. Thus, we are left with finding 'the right shared pointer'. With the public enable_shared_from_this<> template we can get an _existing_ shared pointer from within a C++ object. However, such pointer must be available. class A : public enable_shared_from_this { public: typedef shared_ptr A_ptr; virtual A_ptr self() { if( _internal_weak_this.expired() ) throw RuntimeError("Shared pointer not available."); shared_ptr self = shared_from_this(); assert(self != 0); return self; } void call_from_cpp(PyObject* other) { python::call_method( other, "hello", python::object(self()) ); } virtual ~A() {} } In order to test this, we create another class 'C', which stores instances of 'A' and calls their 'call_from_cpp()' methods: class C { private: typedef A::A_ptr A_ptr; public: void set(A_ptr a) { this->a=a; } // store instance void update(PyObject* peer) { if(a.get()) a->call_from_cpp(peer); } private: A_ptr a; }; Note that C.set() takes an A_ptr as argument. Now, we can do the following: >>> a.self() # No A_ptr has been created, yet. Traceback (most recent call last): File "", line 1, in ? RuntimeError: Shared pointer not available. >>> c=C() >>> c.set(a) # This creates the A_ptr >>> a.self() # Ahh! The same as 'a'! >>> c.update(b) <__main__.B instance at 0x008FAE40> got called from >>> And here is the complete example file: --- self_test.cpp --- /* How to get the python object for a raw pointer? * * Andreas Beyer */ #include #include #include #include #include #include using namespace boost; struct RuntimeError { RuntimeError(std::string msg) : message(msg) { } const char *what() const throw() { return message.c_str(); } std::string message; }; void runtime_error(RuntimeError const &x) { PyErr_SetString(PyExc_RuntimeError, x.what()); } class A : public enable_shared_from_this { public: typedef shared_ptr A_ptr; /* Here 'a' tries to get the shared_ptr representing the * python object from boost::python. * Certainly this only works after a shared pointer has * actually been created, e.g. by adding 'a' to a container * of type C. After that, shared_from_this() actually returns * a valid shared_ptr, which can be used for getting the * respective python::object. */ virtual A_ptr self() { if( _internal_weak_this.expired() ) throw RuntimeError("Shared pointer not available."); shared_ptr self = shared_from_this(); assert(self != 0); return self; } /* This is how you send a message to another python object * with self as an argument: * Make the function static and pass the implicit argument 'self'. * Unfortunately this only works if call_from_py() is called * from the python interpreter. Otherwise, the python object is * not available. (Except of course if the calling instance has * a reference to the python object stored somewhere.) */ static void call_from_py(python::object self, PyObject* other) { python::call_method( other, "hello", self ); } /* This function allows you to call the peer without (explicitely) * knowing the python::object of the sender. However, it requires * that a shared pointer for 'a' has been created before (e.g. by * adding 'a' to a container 'c'. Otherwise, 'a' cannot find its * corresponding A_ptr. */ void call_from_cpp(PyObject* other) { python::call_method( other, "hello", python::object(self()) ); } virtual ~A() {}; }; class C { private: typedef A::A_ptr A_ptr; public: void set(A_ptr a) { this->a=a; } // store instance A_ptr get() { return this->a; } // An example, using the python object for 'a' from within C++. void update(PyObject* peer) { if(a.get()) a->call_from_cpp(peer); } private: A_ptr a; }; BOOST_PYTHON_MODULE(self_test) { using namespace boost::python; register_exception_translator(&::runtime_error); class_("A" ) .def("self", &A::self) .def("update", &A::call_from_py) ; class_("C" ) .def("set", &C::set ) .def("get", &C::get ) .def("update", &C::update) ; } --- end --- From prabhu at aero.iitm.ernet.in Fri Aug 15 11:18:08 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 15 Aug 2003 14:48:08 +0530 Subject: [C++-sig] Pyste: support for user defined code. Message-ID: <16188.42320.282016.867488@monster.linux.in> Hi, I was thinking of adding a new feature to Pyste so that a user could add arbitrary code to the code generated by Pyste. Something along these lines: ud = UserDefined() ud.addToHeader(['h1.hpp', 'h2.hpp']) ud.addToDeclaration("""// insert code in the declaration area """) ud.addToModule("""// insert code inside the module area""") You get the general idea. This should make it easy for users to add code of their own in the appropriate places. This makes it easy to experiment and also makes it quite trivial to expose a std::vector using vector_indexing_suite. It also makes it easy to deal with any new features in Boost.Python that are not readily useable from Pyste. What do you folks think? cheers, prabhu From ayverdisonnur at hotmail.com Fri Aug 15 14:19:30 2003 From: ayverdisonnur at hotmail.com (sonnur ayverdi) Date: Fri, 15 Aug 2003 12:19:30 +0000 Subject: [C++-sig] About floating point numbers... Message-ID: Hello, I took your email address from an article about floating point numbers.I'd like to ask you a question about this subject.I hope you help me. I use C++Builder .I write the code below that has the problem and try to explain the problem: int deg; double mul; Ansistring ans; if ans = 999.9 and mul = 10.0 atof(ans.c_str())*mul = 9999 deg = (int)(atof(ans.c_str())*mul) deg is found 9999 (There is no problem) But when I try to run this program in Windows98 if ans = 999.9 and mul = 10.0 atof(ans.c_str())*mul = 9999 deg = (int)(atof(ans.c_str())*mul) deg is found 9998 (******THE PROBLEM******) It is also same if the number is 999.8->9997, 999.4->9993, 999.3->2.But this bug occurs only in Windows 98,there is no problem with this number in Windows95. I hope you will help me with this subject. Thanks a lot Sonnur _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 From dave at boost-consulting.com Fri Aug 15 15:13:27 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Aug 2003 09:13:27 -0400 Subject: [C++-sig] Re: Question regarding objects of enums References: <43342072.1060896519@[10.0.0.6]> <83395005.1060936574@localhost> Message-ID: gideon may writes: > Thanks! > > PS, > > What is the release schedule for Boost 1.31.0 ? There is no schedule. > I've noticed a lot of traffic on the boost list on regression tests, > but haven't seen a time plan lately. Am looking forward releasing my > next version with boost 1.31.0 ;-). If you watch the boost list traffic, you know as much as I do. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Aug 15 15:18:24 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Aug 2003 09:18:24 -0400 Subject: [C++-sig] Re: Getting Python Object for C++ object References: <1163.192.124.248.20.1060937893.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: abeyer at uni-osnabrueck.de writes: >>> Eventually I would like to call peer-objects with 'self' as an argument >>> from within C++ as well as from python. (BTW the latter is quite simple.) >>> My first attempt was the following: >>> >>> class A : public enable_shared_from_this { >>> public: >>> virtual python::object get_self() { >>> shared_ptr self = shared_from_this(); >>> assert(self != 0); >>> return python::object(self.get()); >> ^^^^^^^^^^ >> This will trip you up. Boost.Python can't convert a raw pointer into >> an existing Python object; when you explicitly convert a pointer to >> Python it creates a new Python object and copies the pointee. You want >> >> return python::object(self); >> >> instead. > > That works. Find below an example. Note, that I am referencing the > '_internal_weak_this' in order to find out if I actually have a shared > pointer for this. (I do not want to wait for the bad_weak_ptr exception.) > Dave, I am not on the boost developer list. Could you suggest the > following extension to enable_shared_from_this: > > bool has_shared_from_this() > { > return ! _internal_weak_this.expired(); > } No offense, but I don't have time to make postings for other people; please subscribe to the list. You can always turn off mail delivery. You're likely to get a some feedback from such a comprehensive post; I'm not gonna be a conduit for a whole technical discussion. > Find following a description of the problem and its solution, which may go > into FAQ and/or a respective tutorial, if you like. Thanks! Where do _you_ think it should go? Can you produce it in the form of a patch? > Assume, you have written a class 'A' in C++, which has an update function > for updating peer objects. What's a "peer object"? > The update function takes another object and calls its 'hello()' > method with self as an argument. This is typically used in event > handling mechanisms. > >>>> from self_test import * >>>> a=A() >>>> a > >>>> class B: > ... def hello(self, other): > ... print self, 'got called from', other > ... >>>> b=B() >>>> a.update(b) > <__main__.B instance at 0x008FAE40> got called from 0x008F7750> >>>> > > Crucial is, that 'a' passes its original python object to 'b' and not a > copy. This is relatively simple to accomplish for calls from python, > because the python object for 'a' is easily accessible in that case. A > possible implementation in C++ looks like the following: > > static void call_from_py(python::object self, PyObject* other) { > python::call_method( other, "hello", self ); > } > > The trick is to define call_from_py() static and to explicitely get the > reference to the called object ('self'). The boost.python wrapping for > that function is not at all fancy: > > class_("A" ) > .def("update", &A::call_from_py) > ; > > However, what if we want to call A's update function from within C++? In > that case the python object is not (directly) accesible. In that case we > can make use of shared pointers. boost.python creates shared pointers for > each python object. If we pass the right shared pointer to a > python::object constructor boost.python can find an existing python object > and return a reference to that object. Thus, we are left with finding 'the > right shared pointer'. With the public enable_shared_from_this<> template > we can get an _existing_ shared pointer from within a C++ object. However, > such pointer must be available. > > class A : public enable_shared_from_this { > public: > typedef shared_ptr A_ptr; > virtual A_ptr self() { > if( _internal_weak_this.expired() ) > throw RuntimeError("Shared pointer not available."); > shared_ptr self = shared_from_this(); > assert(self != 0); > return self; > } > void call_from_cpp(PyObject* other) { > python::call_method( other, "hello", python::object(self()) ); > } > virtual ~A() {} > } > > In order to test this, we create another class 'C', which stores instances > of 'A' and calls their 'call_from_cpp()' methods: > > class C { > private: > typedef A::A_ptr A_ptr; > public: > void set(A_ptr a) { this->a=a; } // store instance > void update(PyObject* peer) { if(a.get()) a->call_from_cpp(peer); } > private: > A_ptr a; > }; > > Note that C.set() takes an A_ptr as argument. Now, we can do the following: > >>>> a.self() # No A_ptr has been created, yet. > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: Shared pointer not available. >>>> c=C() >>>> c.set(a) # This creates the A_ptr >>>> a.self() # Ahh! The same as 'a'! > >>>> c.update(b) > <__main__.B instance at 0x008FAE40> got called from 0x008F7750> >>>> > > And here is the complete example file: > > --- self_test.cpp --- > > /* How to get the python object for a raw pointer? > * > * Andreas Beyer > */ > > #include > #include > #include > #include > #include > #include > > using namespace boost; > > struct RuntimeError { > RuntimeError(std::string msg) : message(msg) { } > const char *what() const throw() { return message.c_str(); } > std::string message; > }; > > void runtime_error(RuntimeError const &x) { > PyErr_SetString(PyExc_RuntimeError, x.what()); > } > > class A : public enable_shared_from_this { > public: > typedef shared_ptr A_ptr; > > /* Here 'a' tries to get the shared_ptr representing the > * python object from boost::python. > * Certainly this only works after a shared pointer has > * actually been created, e.g. by adding 'a' to a container > * of type C. After that, shared_from_this() actually returns > * a valid shared_ptr, which can be used for getting the > * respective python::object. > */ > virtual A_ptr self() { > if( _internal_weak_this.expired() ) > throw RuntimeError("Shared pointer not available."); > shared_ptr self = shared_from_this(); > assert(self != 0); > return self; > } > /* This is how you send a message to another python object > * with self as an argument: > * Make the function static and pass the implicit argument 'self'. > * Unfortunately this only works if call_from_py() is called > * from the python interpreter. Otherwise, the python object is > * not available. (Except of course if the calling instance has > * a reference to the python object stored somewhere.) > */ > static void call_from_py(python::object self, PyObject* other) { > python::call_method( other, "hello", self ); > } > > /* This function allows you to call the peer without (explicitely) > * knowing the python::object of the sender. However, it requires > * that a shared pointer for 'a' has been created before (e.g. by > * adding 'a' to a container 'c'. Otherwise, 'a' cannot find its > * corresponding A_ptr. > */ > void call_from_cpp(PyObject* other) { > python::call_method( other, "hello", python::object(self()) ); > } > > virtual ~A() {}; > }; > > class C { > private: > typedef A::A_ptr A_ptr; > public: > void set(A_ptr a) { this->a=a; } // store instance > A_ptr get() { return this->a; } > // An example, using the python object for 'a' from within C++. > void update(PyObject* peer) { if(a.get()) a->call_from_cpp(peer); } > private: > A_ptr a; > }; > > BOOST_PYTHON_MODULE(self_test) > { > using namespace boost::python; > register_exception_translator(&::runtime_error); > > class_("A" ) > .def("self", &A::self) > .def("update", &A::call_from_py) > ; > class_("C" ) > .def("set", &C::set ) > .def("get", &C::get ) > .def("update", &C::update) > ; > } > > --- end --- -- Dave Abrahams Boost Consulting www.boost-consulting.com From pdimov at mmltd.net Fri Aug 15 15:46:57 2003 From: pdimov at mmltd.net (Peter Dimov) Date: Fri, 15 Aug 2003 16:46:57 +0300 Subject: [C++-sig] Re: Getting Python Object for C++ object References: <1163.192.124.248.20.1060937893.squirrel@webmail.rz.uni-osnabrueck.de> Message-ID: wrote in message news:1163.192.124.248.20.1060937893.squirrel at webmail.rz.uni-osnabrueck.de > > That works. Find below an example. Note, that I am referencing the > '_internal_weak_this' in order to find out if I actually have a shared > pointer for this. Please don't. _internal_things are implementation details. > (I do not want to wait for the bad_weak_ptr > exception.) Dave, I am not on the boost developer list. Could you > suggest the > following extension to enable_shared_from_this: > > bool has_shared_from_this() > { > return ! _internal_weak_this.expired(); > } [...] > class A : public enable_shared_from_this { > public: > typedef shared_ptr A_ptr; > virtual A_ptr self() { > if( _internal_weak_this.expired() ) > throw RuntimeError("Shared pointer not available."); > shared_ptr self = shared_from_this(); Sorry, I can't bring myself to view this as a legitimate motivating example for the extension you are proposing. The only thing the code does is throw another exception in place of bad_weak_ptr. > assert(self != 0); > return self; > } > void call_from_cpp(PyObject* other) { > python::call_method( other, "hello", > python::object(self()) ); } > virtual ~A() {} > } From prabhu at aero.iitm.ernet.in Fri Aug 15 18:18:43 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 15 Aug 2003 21:48:43 +0530 Subject: [C++-sig] Bug: Pyste and pure virtual functions. Message-ID: <16189.2019.660768.875214@monster.linux.in> hi, Just found a bug with Pyste's generation of the default wrapper function for pure virtual functions. Here is a simple example. // ------------- simple.hpp ------------------------- class A { public: virtual unsigned int f() = 0; }; // -------------------------------------------------- Wrapping this with the following fails. simple = Class('A', 'simple.hpp') This is because Pyste generates the following code: unsigned int default_f() { PyErr_SetString(PyExc_RuntimeError, "pure virtual function called"); throw_error_already_set(); return unsigned int(); } Which generates a parse error. Additionally returning some_class() also requires that the class have a nullary constructor which might not always be available. I find that generating this code instead works fine under gcc 2.95.4: unsigned int default_f() { PyErr_SetString(PyExc_RuntimeError, "pure virtual function called"); throw error_already_set(); } This compiles cleanly (with no warnings) for me but is it valid C++ and will it work properly under all compilers? If this is OK I'll send in a patch to fix this. If not, are there other ways to handle this correctly? Thanks! cheers, prabhu From mike at nospam.com Fri Aug 15 22:37:30 2003 From: mike at nospam.com (Mike Rovner) Date: Fri, 15 Aug 2003 13:37:30 -0700 Subject: [C++-sig] arg type equivivalence (constness) Message-ID: Hi, I got a run-time error that Python call to wrapped MyFun(myinst) doesn't mach signature MyFun(const MyClass*) (where myinst = new MyClass(), i.e. non-const pointer). I'd like to keep signature intact as I have to call it with both const and non-const args. VC7.1, cvs boost from Aug 6. As I vaguely recall this subject was discussed earlier, but I can't find any refs although. Any pointers please. Regards, Mike From nicodemus at globalite.com.br Sat Aug 16 00:22:02 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 15 Aug 2003 19:22:02 -0300 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <16188.42320.282016.867488@monster.linux.in> References: <16188.42320.282016.867488@monster.linux.in> Message-ID: <3F3D5D0A.5090703@globalite.com.br> Prabhu Ramachandran wrote: >Hi, > >I was thinking of adding a new feature to Pyste so that a user could >add arbitrary code to the code generated by Pyste. Something along >these lines: > >ud = UserDefined() >ud.addToHeader(['h1.hpp', 'h2.hpp']) >ud.addToDeclaration("""// insert code in the declaration area """) >ud.addToModule("""// insert code inside the module area""") > >You get the general idea. > >This should make it easy for users to add code of their own in the >appropriate places. This makes it easy to experiment and also makes >it quite trivial to expose a std::vector using vector_indexing_suite. >It also makes it easy to deal with any new features in Boost.Python >that are not readily useable from Pyste. > Seems easy, but I think a more functional interface would fit with the rest better: add_include('h1.hpp', 'h2.hpp') add_code(MODULE, ''' class_< std::vector > ("VectorBool") .def(vector_indexing_suite< std::vector, true> ());''') Thoughts? From nicodemus at globalite.com.br Sat Aug 16 00:25:02 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 15 Aug 2003 19:25:02 -0300 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <16189.2019.660768.875214@monster.linux.in> References: <16189.2019.660768.875214@monster.linux.in> Message-ID: <3F3D5DBE.2040307@globalite.com.br> Hi Prabhu! Prabhu Ramachandran wrote: >hi, > > unsigned int default_f() { > PyErr_SetString(PyExc_RuntimeError, "pure virtual function called"); > throw_error_already_set(); > return unsigned int(); > } > >Which generates a parse error. Additionally returning some_class() >also requires that the class have a nullary constructor which might >not always be available. I find that generating this code instead >works fine under gcc 2.95.4: > > unsigned int default_f() { > PyErr_SetString(PyExc_RuntimeError, "pure virtual function called"); > throw error_already_set(); > } > >This compiles cleanly (with no warnings) for me but is it valid C++ >and will it work properly under all compilers? If this is OK I'll >send in a patch to fix this. If not, are there other ways to handle >this correctly? > Hi Prabhu! My first version was like yours, but the missing return generates warnings with Intel 6, so I added it. I didn't know it would generate an error in gcc, thought 8/ Any suggestions? Regards, Nicodemus. From dave at boost-consulting.com Sat Aug 16 01:38:13 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Aug 2003 19:38:13 -0400 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: "Mike Rovner" writes: > Hi, > > I got a run-time error that Python call to wrapped MyFun(myinst) doesn't > mach signature MyFun(const MyClass*) > (where myinst = new MyClass(), i.e. non-const pointer). Huh? you can't write myinst = new MyClass() in Python, so how are you calling this wrapped function? > I'd like to keep signature intact as I have to call it with both const and > non-const args. > > VC7.1, cvs boost from Aug 6. > > As I vaguely recall this subject was discussed earlier, but I can't find any > refs although. > Any pointers please. Sorry, Mike. Too much missing detail and too confusing. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Sat Aug 16 05:26:23 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 16 Aug 2003 08:56:23 +0530 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <3F3D5D0A.5090703@globalite.com.br> References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> Message-ID: <16189.42079.420614.256221@monster.linux.in> >>>>> "N" == nicodemus writes: N> Prabhu Ramachandran wrote: >> Hi, >> >> I was thinking of adding a new feature to Pyste so that a user >> could add arbitrary code to the code generated by Pyste. >> Something along these lines: >> >> ud = UserDefined() ud.addToHeader(['h1.hpp', 'h2.hpp']) >> ud.addToDeclaration("""// insert code in the declaration area >> """) ud.addToModule("""// insert code inside the module >> area""") N> Seems easy, but I think a more functional interface would fit N> with the rest better: N> add_include('h1.hpp', 'h2.hpp') add_code(MODULE, ''' N> class_< std::vector > ("VectorBool") N> .def(vector_indexing_suite< std::vector, N> true> ());''') Thats fine too but will there be a problem with ordering of the code if the interface is functional? i.e. if I have a class('A', 'h.hpp') and then want to add the user defined code after this, is it possible to do with this approach? I also thought that the UserDefined approach would be easier to implement. cheers, prabhu From prabhu at aero.iitm.ernet.in Sat Aug 16 05:32:30 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 16 Aug 2003 09:02:30 +0530 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <3F3D5DBE.2040307@globalite.com.br> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> Message-ID: <16189.42446.457079.929814@monster.linux.in> >>>>> "N" == nicodemus writes: N> Hi Prabhu! Prabhu Ramachandran wrote: >> Which generates a parse error. Additionally returning >> some_class() also requires that the class have a nullary >> constructor which might not always be available. I find that >> generating this code instead works fine under gcc 2.95.4: >> >> unsigned int default_f() { PyErr_SetString(PyExc_RuntimeError, >> "pure virtual function called"); throw error_already_set(); } [snip] N> Hi Prabhu! N> My first version was like yours, but the missing return N> generates warnings with Intel 6, so I added it. I didn't know N> it would generate an error in gcc, thought 8/ Any suggestions? Well, it will generate errors under Intel 6 also if the returned class has no nullary constructor. I'm not sure if 'return unsigned int();' will also compile correctly. One alternative is that for standard types (int, float etc.) the brackets are removed but the return value is there. For classes/structures that are returned we add the brackets or alternatively dont return anything and live with the warnings. It would be nice if there were a better way. cheers, prabhu From prabhu at aero.iitm.ernet.in Sat Aug 16 11:03:01 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 16 Aug 2003 14:33:01 +0530 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <16189.42446.457079.929814@monster.linux.in> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> Message-ID: <16189.62277.555787.72953@monster.linux.in> >>>>> "PR" == Prabhu Ramachandran writes: >>>>> "N" == nicodemus writes: [snip] N> My first version was like yours, but the missing return N> generates warnings with Intel 6, so I added it. I didn't know N> it would generate an error in gcc, thought 8/ Any suggestions? PR> Well, it will generate errors under Intel 6 also if the PR> returned class has no nullary constructor. I'm not sure if PR> 'return unsigned int();' will also compile correctly. PR> One alternative is that for standard types (int, float etc.) PR> the brackets are removed but the return value is there. For PR> classes/structures that are returned we add the brackets or PR> alternatively dont return anything and live with the warnings. PR> It would be nice if there were a better way. I just found an obvious way to get around this -- simply call the wrapped function (afterall this is only to satisfy the compiler). Attached is a patch to fix the problem with Pyste from CVS. This works fine for me. BTW, Boost.Python from current (anonymous access) CVS does not build cleanly and produces lots of errors that look like this: /cvs/boost/boost/python/object_core.hpp: In instantiation of `boost::python::api::is_derived_impl': /cvs/boost/boost/python/object_core.hpp:258: instantiated from `boost::python::api::is_derived' /cvs/boost/boost/python/object_core.hpp:258: instantiated from `boost::python::api::object_base_initializer(const boost::python::scope &)' /cvs/boost/boost/python/object_core.hpp:270: instantiated from here /cvs/boost/boost/python/object_core.hpp:231: invalid use of undefined type `struct boost::python::api::is_derived_impl' /cvs/boost/boost/python/object_core.hpp:232: forward declaration of `struct boost::python::api::is_derived_impl' /cvs/boost/boost/python/object_core.hpp:231: invalid use of undefined type `struct boost::python::api::is_derived_impl' /cvs/boost/boost/python/object_core.hpp:232: forward declaration of `struct boost::python::api::is_derived_impl' [snip similar errors] I checked out a copy as of "2003-08-14" and things build cleanly. cheers, prabhu -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Pyste-bugfix.patch URL: From dave at boost-consulting.com Sat Aug 16 13:22:26 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Aug 2003 07:22:26 -0400 Subject: [C++-sig] Re: Bug: Pyste and pure virtual functions. References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > BTW, Boost.Python from current (anonymous access) CVS does not build > cleanly and produces lots of errors that look like this: > > /cvs/boost/boost/python/object_core.hpp: In instantiation of `boost::python::api::is_derived_impl': Works for me. Which compiler? -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Sat Aug 16 13:31:50 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 16 Aug 2003 17:01:50 +0530 Subject: [C++-sig] Re: Bug: Pyste and pure virtual functions. In-Reply-To: References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> Message-ID: <16190.5670.182669.681031@monster.linux.in> >>>>> "DA" == David Abrahams writes: DA> Prabhu Ramachandran writes: >> BTW, Boost.Python from current (anonymous access) CVS does not >> build cleanly and produces lots of errors that look like this: >> >> /cvs/boost/boost/python/object_core.hpp: In instantiation of >> `boost::python::api::is_derived_impl> &,boost::python::api::object>': DA> Works for me. Which compiler? gcc version 2.95.4 20011002 (Debian prerelease). Perhaps it is due to the usual sourceforge anonymous CVS lags real CVS issue but I've been trying since yesterday. Thanks. cheers, prabhu From dave at boost-consulting.com Sat Aug 16 15:39:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Aug 2003 09:39:30 -0400 Subject: [C++-sig] Re: Bug: Pyste and pure virtual functions. References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <16190.5670.182669.681031@monster.linux.in> Message-ID: Prabhu Ramachandran writes: >>>>>> "DA" == David Abrahams writes: > > DA> Prabhu Ramachandran writes: > >> BTW, Boost.Python from current (anonymous access) CVS does not > >> build cleanly and produces lots of errors that look like this: > >> > >> /cvs/boost/boost/python/object_core.hpp: In instantiation of > >> `boost::python::api::is_derived_impl >> &,boost::python::api::object>': > > DA> Works for me. Which compiler? > > gcc version 2.95.4 20011002 (Debian prerelease). Perhaps it is due to > the usual sourceforge anonymous CVS lags real CVS issue but I've been > trying since yesterday. No, it's real. I'm fixing it now. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 16 15:57:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Aug 2003 09:57:00 -0400 Subject: [C++-sig] Re: Bug: Pyste and pure virtual functions. References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <16190.5670.182669.681031@monster.linux.in> Message-ID: Prabhu Ramachandran writes: >>>>>> "DA" == David Abrahams writes: > > DA> Prabhu Ramachandran writes: > >> BTW, Boost.Python from current (anonymous access) CVS does not > >> build cleanly and produces lots of errors that look like this: > >> > >> /cvs/boost/boost/python/object_core.hpp: In instantiation of > >> `boost::python::api::is_derived_impl >> &,boost::python::api::object>': > > DA> Works for me. Which compiler? > > gcc version 2.95.4 20011002 (Debian prerelease). Perhaps it is due to > the usual sourceforge anonymous CVS lags real CVS issue but I've been > trying since yesterday. Now fixed. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 16 15:57:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Aug 2003 09:57:23 -0400 Subject: [C++-sig] Re: Bug: Pyste and pure virtual functions. In-Reply-To: <16190.5670.182669.681031@monster.linux.in> (Prabhu Ramachandran's message of "Sat, 16 Aug 2003 17:01:50 +0530") References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <16190.5670.182669.681031@monster.linux.in> Message-ID: Prabhu Ramachandran writes: >>>>>> "DA" == David Abrahams writes: > > DA> Prabhu Ramachandran writes: > >> BTW, Boost.Python from current (anonymous access) CVS does not > >> build cleanly and produces lots of errors that look like this: > >> > >> /cvs/boost/boost/python/object_core.hpp: In instantiation of > >> `boost::python::api::is_derived_impl >> &,boost::python::api::object>': > > DA> Works for me. Which compiler? > > gcc version 2.95.4 20011002 (Debian prerelease). Perhaps it is due to > the usual sourceforge anonymous CVS lags real CVS issue but I've been > trying since yesterday. Now fixed. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sat Aug 16 20:27:40 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 15:27:40 -0300 Subject: [C++-sig] Patches for pyste regarding exception specifications In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274AABD@berexch.ber.haufemg.com> References: <2040C0A1CA23D51181A30050BAAC990274AABD@berexch.ber.haufemg.com> Message-ID: <3F3E779C.1040906@globalite.com.br> Gottfried.Ganssauge at HAUFE.DE wrote: > ... > > Thanks a lot Gottfried, your patch looks very clean! I will > > commit it as > > soon as Prabhu and I have fixed the "Order Bug". > Good luck! > I Gottfried! I implemented your patch in the current CVS. I left out the ability of exporting exceptions that you proposed in the "Wrapper for exception translation" thread, because it seems that this is still in progress, but as soon as it is ready I will be glad to add support for it in Pyste. Thanks again! Nicodemus. From nicodemus at globalite.com.br Sat Aug 16 20:31:59 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 15:31:59 -0300 Subject: [C++-sig] Re: Twas a bug in MSVC7.1 In-Reply-To: <3F2F2172.17493.357FD6F4@localhost> References: <3F2F2172.17493.357FD6F4@localhost> Message-ID: <3F3E789F.30903@globalite.com.br> Niall Douglas wrote: >The cause? > >Comment out the anonymous namespace declaration towards the middle of >the file. It now compiles perfectly. > >Nicodemus: In light of this could you fix pyste so that it never >generates an unnamed namespace? > Ouch, sorry for have missed that! Niall, there's an option in pyste named --pyste-ns=, where you can specify the namespace where the declarations are written. You could try --pyste-ns=pyste or something, that should solve your problem. Sorry again about the delay! Nicodemus. From nicodemus at globalite.com.br Sat Aug 16 20:46:21 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 15:46:21 -0300 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <16189.62277.555787.72953@monster.linux.in> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> Message-ID: <3F3E7BFD.3060300@globalite.com.br> Hi Prabhu! Prabhu Ramachandran wrote: >>>>>>"PR" == Prabhu Ramachandran writes: >>>>>> >>>>>> > > > >>>>>>"N" == nicodemus writes: >>>>>> >>>>>> >[snip] > N> My first version was like yours, but the missing return > N> generates warnings with Intel 6, so I added it. I didn't know > N> it would generate an error in gcc, thought 8/ Any suggestions? > > PR> Well, it will generate errors under Intel 6 also if the > PR> returned class has no nullary constructor. I'm not sure if > PR> 'return unsigned int();' will also compile correctly. > > PR> One alternative is that for standard types (int, float etc.) > PR> the brackets are removed but the return value is there. For > PR> classes/structures that are returned we add the brackets or > PR> alternatively dont return anything and live with the warnings. > PR> It would be nice if there were a better way. > >I just found an obvious way to get around this -- simply call the >wrapped function (afterall this is only to satisfy the compiler). >Attached is a patch to fix the problem with Pyste from CVS. This >works fine for me. > > I tried this approach too, but then it doesn't link: it complains about the abstract function being referenced inside the default_() method and is unable to resolve find it (I'm using Intel 6 on Windows). 8/ Anyone got other ideas? Regards, Nicodemus. From prabhu at aero.iitm.ernet.in Sat Aug 16 21:00:50 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sun, 17 Aug 2003 00:30:50 +0530 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <3F3E7BFD.3060300@globalite.com.br> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <3F3E7BFD.3060300@globalite.com.br> Message-ID: <16190.32610.411325.659813@monster.linux.in> >>>>> "N" == nicodemus writes: N> Hi Prabhu! Prabhu Ramachandran wrote: >> I just found an obvious way to get around this -- simply call >> the wrapped function (afterall this is only to satisfy the >> compiler). Attached is a patch to fix the problem with Pyste >> from CVS. This works fine for me. N> I tried this approach too, but then it doesn't link: it N> complains about the abstract function being referenced inside N> the default_() method and is unable to resolve find it (I'm N> using Intel 6 on Windows). 8/ Anyone got other ideas? Huh? How is that possible? Did you use my patch? I specifically chose to use method.name and not method.FullName() since method.name would resolve to the wrapped function. Here is an example: struct A_Wrapper: A { // [ snip ] // f is a pure virtual function. unsigned int f() { return call_method< unsigned int >(self, "f"); } unsigned int default_f() { PyErr_SetString(PyExc_RuntimeError, "pure virtual function called"); throw_error_already_set(); return A::f(); // <---------- WRONG. return f(); // <------------- CORRECT. } }; As far as I can tell this is perfectly legal and the compiler cannot complain since f is a valid overridden virtual function. I've also tested this with my code and it builds everything fine -- no link problems and everything seems to work ok. cheers, prabhu From nicodemus at globalite.com.br Sat Aug 16 21:13:55 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 16:13:55 -0300 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <16190.32610.411325.659813@monster.linux.in> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <3F3E7BFD.3060300@globalite.com.br> <16190.32610.411325.659813@monster.linux.in> Message-ID: <3F3E8273.3000201@globalite.com.br> Prabhu Ramachandran wrote: >>>>>>"N" == nicodemus writes: >>>>>> >>>>>> > > N> Hi Prabhu! Prabhu Ramachandran wrote: > > >> I just found an obvious way to get around this -- simply call > >> the wrapped function (afterall this is only to satisfy the > >> compiler). Attached is a patch to fix the problem with Pyste > >> from CVS. This works fine for me. > > N> I tried this approach too, but then it doesn't link: it > N> complains about the abstract function being referenced inside > N> the default_() method and is unable to resolve find it (I'm > N> using Intel 6 on Windows). 8/ Anyone got other ideas? > >Huh? How is that possible? Did you use my patch? I specifically >chose to use method.name and not method.FullName() since method.name >would resolve to the wrapped function. Here is an example: > > Oh, sorry about that! I thought you wanted to call the abstract method, so I "fixed" your patch! ;) Your patch works perfectly, really sorry about that! 8) Thanks once again Prabhu! It is in CVS now. Regards, Nicodemus. From prabhu at aero.iitm.ernet.in Sat Aug 16 21:27:46 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sun, 17 Aug 2003 00:57:46 +0530 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <3F3E8273.3000201@globalite.com.br> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <3F3E7BFD.3060300@globalite.com.br> <16190.32610.411325.659813@monster.linux.in> <3F3E8273.3000201@globalite.com.br> Message-ID: <16190.34226.951475.795617@monster.linux.in> >>>>> "N" == nicodemus writes: N> I tried this approach too, but then it doesn't link: it N> complains about the abstract function being referenced inside N> the default_() method and is unable to resolve find it (I'm N> using Intel 6 on Windows). 8/ Anyone got other ideas? >> >> Huh? How is that possible? Did you use my patch? I >> specifically chose to use method.name and not method.FullName() >> since method.name would resolve to the wrapped function. Here >> is an example: N> Oh, sorry about that! I thought you wanted to call the abstract N> method, so I "fixed" your patch! ;) Your patch works perfectly, N> really sorry about that! 8) Thanks once again Prabhu! It is in N> CVS now. No problem. :) Thanks for checking it in! Any ideas on the user defined code support I was talking about earlier? Thanks. prabhu From nicodemus at globalite.com.br Sat Aug 16 21:51:47 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 16:51:47 -0300 Subject: [C++-sig] Bug: Pyste and pure virtual functions. In-Reply-To: <16190.34226.951475.795617@monster.linux.in> References: <16189.2019.660768.875214@monster.linux.in> <3F3D5DBE.2040307@globalite.com.br> <16189.42446.457079.929814@monster.linux.in> <16189.62277.555787.72953@monster.linux.in> <3F3E7BFD.3060300@globalite.com.br> <16190.32610.411325.659813@monster.linux.in> <3F3E8273.3000201@globalite.com.br> <16190.34226.951475.795617@monster.linux.in> Message-ID: <3F3E8B53.1090302@globalite.com.br> Prabhu Ramachandran wrote: >>>>>>"N" == nicodemus writes: >>>>>> >>>>>> > > N> I tried this approach too, but then it doesn't link: it > N> complains about the abstract function being referenced inside > N> the default_() method and is unable to resolve find it (I'm > N> using Intel 6 on Windows). 8/ Anyone got other ideas? > >> > >> Huh? How is that possible? Did you use my patch? I > >> specifically chose to use method.name and not method.FullName() > >> since method.name would resolve to the wrapped function. Here > >> is an example: > > N> Oh, sorry about that! I thought you wanted to call the abstract > N> method, so I "fixed" your patch! ;) Your patch works perfectly, > N> really sorry about that! 8) Thanks once again Prabhu! It is in > N> CVS now. > >No problem. :) Thanks for checking it in! > Thanks to you for submitting the patch! 8) >Any ideas on the user defined code support I was talking about >earlier? > Sorry! I just responded to that, please follow it up in that thread! Thanks again, Nicodemus. From nicodemus at globalite.com.br Sat Aug 16 21:51:50 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 16:51:50 -0300 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <16189.42079.420614.256221@monster.linux.in> References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> Message-ID: <3F3E8B56.7000402@globalite.com.br> Hi Prabhu! Prabhu Ramachandran wrote: >>>>>>"N" == nicodemus writes: >>>>>> >>>>>> > > N> Prabhu Ramachandran wrote: > >> Hi, > >> > >> I was thinking of adding a new feature to Pyste so that a user > >> could add arbitrary code to the code generated by Pyste. > >> Something along these lines: > >> > >> ud = UserDefined() ud.addToHeader(['h1.hpp', 'h2.hpp']) > >> ud.addToDeclaration("""// insert code in the declaration area > >> """) ud.addToModule("""// insert code inside the module > >> area""") > > N> Seems easy, but I think a more functional interface would fit > N> with the rest better: > > N> add_include('h1.hpp', 'h2.hpp') add_code(MODULE, ''' > N> class_< std::vector > ("VectorBool") > N> .def(vector_indexing_suite< std::vector, > N> true> ());''') > >Thats fine too but will there be a problem with ordering of the code >if the interface is functional? i.e. if I have a class('A', 'h.hpp') >and then want to add the user defined code after this, is it possible >to do with this approach? I also thought that the UserDefined >approach would be easier to implement. > Yeah, no problem. The ordering is kept, since the exporters are kept in a list. So, how about this interface: add_include('header1', 'header2', 'header3') add_code(MODULE, ) add_code(DECLARATION, ) add_code(GLOBAL_DECLARATION, ) # outside the namespace generated by pyste. # Any suggestions for a better name? Does it cover all the needs, or am I missing something? 8) I plan to work on this tomorrow, or perhaps a little today. Any suggestions are appreciated!! Regards, Nicodemus. From dave at boost-consulting.com Sat Aug 16 22:19:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Aug 2003 16:19:46 -0400 Subject: [C++-sig] Re: Pyste: support for user defined code. References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> Message-ID: Nicodemus writes: > Hi Prabhu! > > Prabhu Ramachandran wrote: > >>>>>>>"N" == nicodemus writes: >>>>>>> >> >> N> Prabhu Ramachandran wrote: >> >> Hi, >> >> >> >> I was thinking of adding a new feature to Pyste so that a user >> >> could add arbitrary code to the code generated by Pyste. >> >> Something along these lines: >> >> >> >> ud = UserDefined() ud.addToHeader(['h1.hpp', 'h2.hpp']) >> >> ud.addToDeclaration("""// insert code in the declaration area >> >> """) ud.addToModule("""// insert code inside the module >> >> area""") >> >> N> Seems easy, but I think a more functional interface would fit >> N> with the rest better: >> >> N> add_include('h1.hpp', 'h2.hpp') add_code(MODULE, ''' >> N> class_< std::vector > ("VectorBool") >> N> .def(vector_indexing_suite< std::vector, >> N> true> ());''') >> >>Thats fine too but will there be a problem with ordering of the code >>if the interface is functional? i.e. if I have a class('A', 'h.hpp') >>and then want to add the user defined code after this, is it possible >>to do with this approach? I also thought that the UserDefined >>approach would be easier to implement. >> > > Yeah, no problem. The ordering is kept, since the exporters are kept > in a list. > > So, how about this interface: > > add_include('header1', 'header2', 'header3') > add_code(MODULE, ) > add_code(DECLARATION, ) > add_code(GLOBAL_DECLARATION, ) # outside the namespace What about, simply: include('header1', 'header2', 'header3') code(MODULE, ) code(DECLARATION, ) code(GLOBAL_DECLARATION, ) # outside the namespace Or: include('header1', 'header2', 'header3') inline(MODULE, ) inline(DECLARATION, ) inline(GLOBAL_DECLARATION, ) # outside the namespace But what are those ALL_CAPS names? -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Sun Aug 17 00:08:16 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Sat, 16 Aug 2003 23:08:16 +0100 Subject: [C++-sig] Re: Doubts with wrapping/using abstract bases. References: <16182.38270.865264.267282@monster.linux.in> <3F36BC58.4020106@globalite.com.br> <16183.45238.143458.663526@monster.linux.in> <16187.11659.666491.946542@monster.linux.in> Message-ID: Prabhu Ramachandran writes: >>>>>> "RG" == Raoul Gough writes: > > [snip explanation by RG of how test_holder.py works] > > Thanks for the explanation, it confirmed my understanding! Well, I'm glad to hear that it made sense! I wasn't too sure about the details myself, before I started my previous post. > > RG> BTW, have you considered using boost::shared_ptr? I wouldn't > RG> trust std::auto_ptr with this kind of stuff. Also, storing raw > RG> pointers in a vector is just asking for trouble if you ask me. > > Dave enlightened me on the advantages of using boost::shared_ptr a > month or so back. Unfortunately I am not in a position to change my > code at this time for two reasons: (a) I'll need to investigate if > there is a performance hit for my kind of code (b) I don't have the > time to change the interface in my code right now and carefully > eliminate cyclic reference loops etc. I see. Cyclic references would mean that you can't blindly replace everything with shared_ptr, so you'd have to decide on using some kind of weak pointer (e.g. raw pointers or boost::weak_ptr) at strategic locations. BTW, I once wrote a checked pointer that detects mis-uses in debug builds, but can be compiled away in release builds (similar to an assert macro). Details at http://home.clara.net/raoulgough/weak_ptr/, but it is more theoretical exercise than production-strength code. > > Storing pointers in a vector is asking for trouble? It might be true > in general but I'd say using pointers carefully is not bad. It has > worked well for me so far. Well, I was thinking specifically about mixing raw pointers in a container with std::auto_ptr pointers elsewhere. I'd be worried about the chances of an auto_ptr deciding to delete a pointer that is still stored in the vector. That's apart from the usual risk of memory leaks, of course. I'm not saying it can't be done, just that I wouldn't find it particularly easy. OTOH, I can understand why changing over wouldn't be feasible in an existing development process - it might end up costing you more time to switch over than it would save in debugging. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From nicodemus at globalite.com.br Sun Aug 17 03:32:45 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 16 Aug 2003 22:32:45 -0300 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> Message-ID: <3F3EDB3D.9040808@globalite.com.br> Hi David, David Abrahams wrote: >Nicodemus writes: > > >>Yeah, no problem. The ordering is kept, since the exporters are kept >>in a list. >> >>So, how about this interface: >> >>add_include('header1', 'header2', 'header3') >>add_code(MODULE, ) >>add_code(DECLARATION, ) >>add_code(GLOBAL_DECLARATION, ) # outside the namespace >> > >What about, simply: > > include('header1', 'header2', 'header3') > code(MODULE, ) > code(DECLARATION, ) > code(GLOBAL_DECLARATION, ) # outside the namespace > >Or: > > include('header1', 'header2', 'header3') > inline(MODULE, ) > inline(DECLARATION, ) > inline(GLOBAL_DECLARATION, ) # outside the namespace > >But what are those ALL_CAPS names? > Hmm, agreed, those "add" are redundant anyway, and I like "code" better than "include". 8) The names in caps indicates the sections in the source file where the code should go: #include namespace { } BOOST_PYTHON_MODULE(module) { } I think it is interesting to let the user add code arbitrarly in the source file, but I might be wrong. Thanks for the input! Nicodemus. From prabhu at aero.iitm.ernet.in Sun Aug 17 05:36:09 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sun, 17 Aug 2003 09:06:09 +0530 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: <3F3EDB3D.9040808@globalite.com.br> References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> Message-ID: <16190.63529.917784.961054@monster.linux.in> >>>>> "N" == nicodemus writes: N> Hmm, agreed, those "add" are redundant anyway, and I like N> "code" better than "include". 8) N> The names in caps indicates the sections in the source file N> where the code should go: Rather than using the special all caps MODULE etc. why not just do this: add_header(...) add_declaration(...) add_module(...) or code_header(...) ... or header_code() declaration_code() module_code() I'd prefer any of these to code(MODULE, ) etc. since it looks much cleaner. Thanks! cheers, prabhu From s_sourceforge at nedprod.com Sun Aug 17 17:50:03 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 17 Aug 2003 16:50:03 +0100 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <3F3E8B56.7000402@globalite.com.br> References: <16189.42079.420614.256221@monster.linux.in> Message-ID: <3F3FB23B.17679.567FFD5@localhost> On 16 Aug 2003 at 16:51, Nicodemus wrote: > add_include('header1', 'header2', 'header3') > add_code(MODULE, ) > add_code(DECLARATION, ) > add_code(GLOBAL_DECLARATION, ) # outside the namespace > generated by pyste. > # Any suggestions for a better > name? > > Does it cover all the needs, or am I missing something? 8) > > I plan to work on this tomorrow, or perhaps a little today. Any > suggestions are appreciated!! This seems to me to add complexity where you don't need it. You should have an "Include()" directive which lets you place includes before at the top, after that, module definitions etc. Then you place all the relevent code you want to insert into .cpp files which are then #include'd by the Include() in the right place. This makes keeping bits separate and maintainable much easier. It's what I use myself here using a python script to postprocess the pyste output. Cheers, Niall From s_sourceforge at nedprod.com Sun Aug 17 17:58:54 2003 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 17 Aug 2003 16:58:54 +0100 Subject: (Fwd) Re: [C++-sig] Re: Twas a bug in MSVC7.1 Message-ID: <3F3FB44E.25442.5701A99@localhost> > >Nicodemus: In light of this could you fix pyste so that it never > >generates an unnamed namespace? > > Ouch, sorry for have missed that! Niall, there's an option in pyste > named --pyste-ns=, where you can specify the namespace > where the declarations are written. You could try --pyste-ns=pyste > or something, that should solve your problem. I did try that but it was unsuitable for my needs. Really, the two line alteration I made to pyste to not generate an unnamed namespace seems much easier. Cheers, Niall From prabhu at aero.iitm.ernet.in Sun Aug 17 20:09:57 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sun, 17 Aug 2003 23:39:57 +0530 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <3F3FB23B.17679.567FFD5@localhost> References: <16189.42079.420614.256221@monster.linux.in> <3F3FB23B.17679.567FFD5@localhost> Message-ID: <16191.50421.105446.33049@monster.linux.in> >>>>> "ND" == Niall Douglas writes: ND> On 16 Aug 2003 at 16:51, Nicodemus wrote: >> add_include('header1', 'header2', 'header3') add_code(MODULE, [snip] ND> This seems to me to add complexity where you don't need ND> it. You should have an "Include()" directive which lets you ND> place includes before at the top, after that, module ND> definitions etc. ND> Then you place all the relevent code you want to insert into ND> .cpp files which are then #include'd by the Include() in the ND> right place. ND> This makes keeping bits separate and maintainable much ND> easier. It's what I use myself here using a python script to ND> postprocess the pyste output. I beg to differ. 1. In the suggested case (add_header, add_code etc.) the source for the generated .cpp file is *already* in one easy to maintain place viz the .pyste file. So I see no maintainability issue here since the source is in one place already. Splitting already well organized bits into smaller pieces leads to confusion since code fragments that are logically related are now spread over several files. 2. The current approach allows users to do exactly what they want. In fact, you can still include whatever files you want to in the relevant sections. So while the "include" approach straight jackets the user, the more generic approach is totally flexible and will also work for you. 3. Splitting files into smaller bits is possible when you have a few files. When you already have several .pyste files (around 40 in my case) adding two or three more files per pyste file just to expose a std::vector or add user defined code leads to an unmanageable number of files. cheers, prabhu From nicodemus at globalite.com.br Sun Aug 17 20:34:40 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 17 Aug 2003 15:34:40 -0300 Subject: [C++-sig] Pyste: support for user defined code. In-Reply-To: <16191.50421.105446.33049@monster.linux.in> References: <16189.42079.420614.256221@monster.linux.in> <3F3FB23B.17679.567FFD5@localhost> <16191.50421.105446.33049@monster.linux.in> Message-ID: <3F3FCAC0.1030001@globalite.com.br> Prabhu Ramachandran wrote: >>>>>>"ND" == Niall Douglas writes: >>>>>> >>>>>> > > ND> On 16 Aug 2003 at 16:51, Nicodemus wrote: > >> add_include('header1', 'header2', 'header3') add_code(MODULE, > >[snip] > > ND> This seems to me to add complexity where you don't need > ND> it. You should have an "Include()" directive which lets you > ND> place includes before at the top, after that, module > ND> definitions etc. > > ND> Then you place all the relevent code you want to insert into > ND> .cpp files which are then #include'd by the Include() in the > ND> right place. > > ND> This makes keeping bits separate and maintainable much > ND> easier. It's what I use myself here using a python script to > ND> postprocess the pyste output. > >I beg to differ. > > 1. In the suggested case (add_header, add_code etc.) the source for > the generated .cpp file is *already* in one easy to maintain place > viz the .pyste file. So I see no maintainability issue here since > the source is in one place already. Splitting already well > organized bits into smaller pieces leads to confusion since code > fragments that are logically related are now spread over several > files. > > 2. The current approach allows users to do exactly what they want. > In fact, you can still include whatever files you want to in the > relevant sections. So while the "include" approach straight > jackets the user, the more generic approach is totally flexible > and will also work for you. > > 3. Splitting files into smaller bits is possible when you have a few > files. When you already have several .pyste files (around 40 in > my case) adding two or three more files per pyste file just to > expose a std::vector or add user defined code leads to an > unmanageable number of files. > > I agree with Prabhu, specially because with this approach you can do what you want, Niall: code_module('#include "my_header.h"') It's not that much complexity added, in my opinion. 8) From nicodemus at globalite.com.br Sun Aug 17 20:36:56 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 17 Aug 2003 15:36:56 -0300 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: <16190.63529.917784.961054@monster.linux.in> References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> Message-ID: <3F3FCB48.2060708@globalite.com.br> Prabhu Ramachandran wrote: >>>>>>"N" == nicodemus writes: >>>>>> >>>>>> > > N> Hmm, agreed, those "add" are redundant anyway, and I like > N> "code" better than "include". 8) > > N> The names in caps indicates the sections in the source file > N> where the code should go: > >Rather than using the special all caps MODULE etc. why not just do >this: > > add_header(...) > add_declaration(...) > add_module(...) > >or > > code_header(...) > ... > >or > > header_code() > declaration_code() > module_code() > >I'd prefer any of these to code(MODULE, ) etc. since it looks >much cleaner. > > Agreed. There's not enough cases to justify the use of constants. I think: header_code() declaration_code() global_declaration_code() module_code() read nice. From nicodemus at globalite.com.br Sun Aug 17 21:34:18 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 17 Aug 2003 16:34:18 -0300 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: <3F3FCB48.2060708@globalite.com.br> References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> <3F3FCB48.2060708@globalite.com.br> Message-ID: <3F3FD8BA.50303@globalite.com.br> Nicodemus wrote: > Agreed. There's not enough cases to justify the use of constants. I > think: > > header_code() > declaration_code() > global_declaration_code() > module_code() > > read nice. It is in CVS now. Thanks for the input everyone! Regards, Nicodemus. From dave at boost-consulting.com Sun Aug 17 22:06:22 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 17 Aug 2003 16:06:22 -0400 Subject: [C++-sig] Re: Pyste: support for user defined code. References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> <3F3FCB48.2060708@globalite.com.br> Message-ID: Nicodemus writes: > Prabhu Ramachandran wrote: > >>>>>>>"N" == nicodemus writes: >>>>>>> >> >> N> Hmm, agreed, those "add" are redundant anyway, and I like >> N> "code" better than "include". 8) >> >> N> The names in caps indicates the sections in the source file >> N> where the code should go: >> >>Rather than using the special all caps MODULE etc. why not just do >>this: >> >> add_header(...) >> add_declaration(...) >> add_module(...) >> >> or code_header(...) >> ... >> >>or >> >> header_code() >> declaration_code() >> module_code() >> >>I'd prefer any of these to code(MODULE, ) etc. since it looks >>much cleaner. >> > > Agreed. There's not enough cases to justify the use of constants. I think: > > header_code() include('foo.hpp') > declaration_code() > global_declaration_code() These two names are not very distinct. What's the difference? > module_code() hello.inject(''' // my C++ code here ''') hello.World.inject(''' // my C++ code here ''') -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sun Aug 17 23:16:51 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 17 Aug 2003 18:16:51 -0300 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> <3F3FCB48.2060708@globalite.com.br> Message-ID: <3F3FF0C3.8050206@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>Agreed. There's not enough cases to justify the use of constants. I think: >> >>header_code() >> >> > > include('foo.hpp') > > Agreed, actually, I forgot such a function already exists, it is named Include. So, header_code was removed. 8) >>declaration_code() >>global_declaration_code() >> >> > > These two names are not very distinct. What's the difference? > > declaration goes inside the empty namespace, together with the wrapper classes for instance. global declaration goes outside this namespace. >>module_code() >> >> > > hello.inject(''' > // my C++ code here > ''') > > > hello.World.inject(''' > // my C++ code here > ''') > > I assume "hello" is the module name. That doesn't work because a Pyste file doesn't know in which module it will generate the code (this is given in the command line). Assuming "hello.World" is a class, then "inject" will put the code before or after the class? I find that a code() call more clear than an inject method. From dave at boost-consulting.com Sun Aug 17 23:50:08 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 17 Aug 2003 17:50:08 -0400 Subject: [C++-sig] Re: Pyste: support for user defined code. References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> <3F3FCB48.2060708@globalite.com.br> <3F3FF0C3.8050206@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>Nicodemus writes: >> >> >>>Agreed. There's not enough cases to justify the use of constants. I think: >>> >>>header_code() >>> >> >> include('foo.hpp') >> > > Agreed, actually, I forgot such a function already exists, it is named > Include. So, header_code was removed. 8) > >>>declaration_code() >>>global_declaration_code() >>> >> >> These two names are not very distinct. What's the difference? >> > > declaration goes inside the empty namespace, together with the wrapper > classes for instance. global declaration goes outside this namespace. That seems very redundant. global_declaration_code(''' namespace { ... } ''') >>>module_code() >>> >> >> hello.inject(''' >> // my C++ code here >> ''') >> >> hello.World.inject(''' >> // my C++ code here >> ''') >> > > I assume "hello" is the module name. That doesn't work because a Pyste > file doesn't know in which module it will generate the code (this is > given in the command line). I based the suggestion on your example from the Pyste docs. > Assuming "hello.World" is a class, then "inject" will put the code > before or after the class? Within? hello.World.inject('.def("foo", ...)') > I find that a code() call more clear than an inject method. "declaration_code" seems a little redundant to me. Aren't all declarations code? -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Aug 18 00:22:35 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 17 Aug 2003 19:22:35 -0300 Subject: [C++-sig] Re: Pyste: support for user defined code. In-Reply-To: References: <16188.42320.282016.867488@monster.linux.in> <3F3D5D0A.5090703@globalite.com.br> <16189.42079.420614.256221@monster.linux.in> <3F3E8B56.7000402@globalite.com.br> <3F3EDB3D.9040808@globalite.com.br> <16190.63529.917784.961054@monster.linux.in> <3F3FCB48.2060708@globalite.com.br> <3F3FF0C3.8050206@globalite.com.br> Message-ID: <3F40002B.7020106@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > >>declaration goes inside the empty namespace, together with the wrapper >>classes for instance. global declaration goes outside this namespace. >> >> > >That seems very redundant. > > global_declaration_code(''' > namespace { > ... > } > ''') > Agreed, no need for two kinds of declarations... it will only add to the confusion. >>>>module_code() >>>> >>>> >>>> >>> hello.inject(''' >>> // my C++ code here >>> ''') >>> >>> hello.World.inject(''' >>> // my C++ code here >>> ''') >>> >>> >>> >>I assume "hello" is the module name. That doesn't work because a Pyste >>file doesn't know in which module it will generate the code (this is >>given in the command line). >> >> > >I based the suggestion on your example from the Pyste docs. > > Oh, then you meant a header file. Yeah, it is possible, although I prefer the code() functions... but that's me. >>Assuming "hello.World" is a class, then "inject" will put the code >>before or after the class? >> >> > >Within? > > hello.World.inject('.def("foo", ...)') > > Oh, haven't thought about that. Seems useful, but to keep consistency we should make that a free function, not a method, because that is the syntax used to access World members (for instance, if the class World had a method "inject" that the user wants to exclude, the syntax would be "exclude(World.inject)"). I propose: inject(, ) inject_code(, ) Althought I preffer the latter. >>I find that a code() call more clear than an inject method. >> >> > >"declaration_code" seems a little redundant to me. Aren't all >declarations code? > That is to keep similar to "module_code", but I agree it is a little redundant. Opinions? Thanks for the feedback Dave! Regards, Nicodemus. From qinlj at solidshare.com Mon Aug 18 11:04:05 2003 From: qinlj at solidshare.com (Lijun Qin) Date: Mon, 18 Aug 2003 17:04:05 +0800 Subject: [C++-sig] Some patches to make the "Automatic PyUnicode to 'const char*'" possible, and make __stdcall function bindable Message-ID: <005701c36567$b3511c20$0200a8c0@barrack> Hi, I have some patches to make the "Automatic PyUnicode to 'const char*'" possible (please see http://mail.python.org/pipermail/c++-sig/2003-August/004997.html for details) and make the export of '__stdcall' function possible. In addition to the changes in the boost.python source, the file also need to changed to add some lines to match the (__stdcall T::*) functions, many lines in this file seemed were generated by the compile through defining something I don't known, maybe Mr. David Abrahams can make these changes (it exists in another library) #ifdef BOOST_MEM_FN_ENABLE_STDCALL template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; ... ... lots of lines similar to this ... #endif Lijun Qin http://www.solidshare.com --------------------------------------------------------------------------- p.s. Use the convert_unicode_policy like this: .def("SetWindowText", convert_unicode_policy >()) Then you can pass both PyString and PyUnicode to your method, without the explicit str() call. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: patch.txt URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: unicode_converter.h URL: From RaoulGough at yahoo.co.uk Mon Aug 18 14:49:46 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 18 Aug 2003 13:49:46 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: [cc'd to Joel in the hope that he will help out] David Abrahams writes: > Raoul Gough writes: [snip] >> OK, I've added len and read-only indexing to boost::python::range, >> dependant on iterator type. I've posted my current progress to >> http://home.clara.net/raoulgough/boost/ - any comments are >> welcome. There is a test script (currently stand-alone) and no docs >> yet. I'll wait a few days to see if anybody suggests any changes >> before advancing. > > One other point: I notice you're wondering whether to support slices; > probably you should have a look at Joel's recent indexing suite work. > Maybe once we start to get into range-as-iterable instead of > -as-iterator we should also be handling some of the object lifetime > and iterator validity issues. If this seems reasonable to you, you > probably ought to talk it over with Joel. I've had a chance to look at Joel's indexing_suite, and there should be quite a lot of overlap in the functionality between indexing_suite and the extended iterator_range. I've been thinking about how to provide the range-as-iterable support within the indexing_suite framework, but it looks like there would have to be some changes to the base classes. I'm basically considering an indexing_suite-derived class template that would use two iterators for construction and provide only the relevant support functions (from __iter__ alone for input_iterators through to __getitem__ and __setitem__ for random access iterators with non-const value types). The problem is that the indexing_suite base classes assume that all container functionality is always present, all the way up to __delitem__ (impossible for iterators). Thus, it is currently unsuitable for use with iterator pairs, especially if one considers const_iterators. For instance, the following doesn't come close to compiling: boost::python::class_ > ("Vector") .def (boost::python::vector_indexing_suite const>()); For obvious reasons (note the const qualifier). I haven't got far enough to see how many changes it would require to allow containers with less functionality than is currently assumed. Maybe Joel has some comments about the feasibility of this idea? -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From djowel at gmx.co.uk Mon Aug 18 17:27:50 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Mon, 18 Aug 2003 23:27:50 +0800 Subject: [C++-sig] Re: Adding __len__ to range objects References: Message-ID: <021801c3659d$5190a290$64646464@godzilla> Raoul Gough wrote: > I've had a chance to look at Joel's indexing_suite, and there should > be quite a lot of overlap in the functionality between indexing_suite > and the extended iterator_range. I've been thinking about how to > provide the range-as-iterable support within the indexing_suite > framework, but it looks like there would have to be some changes to > the base classes. Right. This is one of the things that's holding me back to formally announcing the suite. It isn't as simple as it started out to be anymore. It is very useful as it is, but the bottomline is that more experience with the sub-framework is needed to ascertain that the interface will hold. Sure enough, when I added the map-indexing suite (just recently), the interface needed to be changed. > I'm basically considering an indexing_suite-derived class template > that would use two iterators for construction and provide only the > relevant support functions (from __iter__ alone for input_iterators > through to __getitem__ and __setitem__ for random access iterators > with non-const value types). The problem is that the indexing_suite > base classes assume that all container functionality is always > present, all the way up to __delitem__ (impossible for > iterators). Thus, it is currently unsuitable for use with iterator > pairs, especially if one considers const_iterators. For instance, the > following doesn't come close to compiling: > > boost::python::class_ > ("Vector") > .def (boost::python::vector_indexing_suite const>()); > > For obvious reasons (note the const qualifier). I haven't got far > enough to see how many changes it would require to allow containers > with less functionality than is currently assumed. Maybe Joel has some > comments about the feasibility of this idea? I've already considered wrapping iterator ranges. I would appreciate it a lot if you are interested to help. As to how many changes it would require to allow containers with less functionality, not much. Right now, I have factored out 1) proxyability and 2) slicability protocols. I think what needs to be factored out, in addition to above are 3) resizability and perhaps 4) mutability (constness). You can see the factored out code in (see no_proxy_helper, proxy_helper, slice_helper and no_slice_helper). The indexing suite chooses the appropriate handler based on some flags and the types involved. The same system will need to be set in place to support resizability and mutability. Is it feasible? Of course ;-) Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From benny at coca-kohler.de Mon Aug 18 17:55:21 2003 From: benny at coca-kohler.de (benny at coca-kohler.de) Date: Mon, 18 Aug 2003 17:55:21 +0200 Subject: [C++-sig] using msvc lib in python Message-ID: <004201c365a1$215a6c60$0d00a8c0@maitai> hi everybody, i?m a newbie in extending python. i?ve got the following problem: i?ve got a library created with visual c++ and some functions in a sample program which use this library. everything is fine when i compile the library(altough i?m not an expert in creating libraries) and my sample program also runs. now i want to expose the functions from my sample program, so that i can use them in python. therefore i?m using bjam. when i run bjam i get some errors from the headerfiles. Some Datatypes in the library defined with "typedef" are unknown. The "typedef" definition is inside a "ifdef" prepocessor statement. this is my jamfile: subproject libs/python/example/tutorial ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; extension piplib # Declare a Python extension called hello : piplib.cpp # source ../../build/boost_python # dependencies # flags : E:\openpip\lib E:\openpip\lib\oplib_Debug oplib Can anybody help me? Is it possible to create the pyd-file using the Visual Studio??? i dont wanT to use the command line. thankz, ben From mike at nospam.com Mon Aug 18 19:50:32 2003 From: mike at nospam.com (Mike Rovner) Date: Mon, 18 Aug 2003 10:50:32 -0700 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: David Abrahams wrote: > "Mike Rovner" writes: > > Sorry, Mike. Too much missing detail and too confusing. Ouh, I appologize for disturbing. The error was mine. I was confused with the error message: Boost.Python.ArgumentError: Python argument types in Scheme.ishintable(Scheme, Layer, int) did not match C++ signature: ishintable(class Tcn::DerivationScheme const *, class Tcn::LayerDef const *) I overlooked extra parameter in Python args and tried to fix immaginable bug in Scheme pointer. Scheme is mentioned twice and that probably confused me. Thanks for replying, it actualy helped me to find my bug by kicking in right direction ;) Regards, Mike From sam at gabrielinteractive.com Mon Aug 18 21:14:12 2003 From: sam at gabrielinteractive.com (Sam Bloomquist) Date: Mon, 18 Aug 2003 14:14:12 -0500 Subject: [C++-sig] class data members Message-ID: I have an update to the question I posted earlier, shown below. It turns out that my crash only happens when the string I am trying to set is longer than 15 characters. Anyone have any guesses where the 15 character limit came from? I am currently working on moving an application from visual studio 6.0 to visual studio .net 2003 and boost 1.29.0 to boost 1.30.0 and am having a few problems with class data members. My c++ struct and python wrapper are as follows: struct JunkObject { bool operator == (JunkObject& jo); std::string m_sName; int m_iID; }; class_("JunkObject") .def_readwrite("name", &JunkObject::m_sName) .def_readwrite("id", &JunkObject::m_iID); # Then in python when I do this... obj = plus.JunkObject() obj.id = 5 # where "plus" is my boost python module, everthing is fine. But if I do... obj.name = "Bob went for a walk in the park." # my program crashes. Does anyone see something I'm missing? This worked fine in msvs 6.0 and boost 1.29. -Sam Bloomquist Gabriel Interactive, Inc. -------------- next part -------------- A non-text attachment was scrubbed... Name: winmail.dat Type: application/ms-tnef Size: 2056 bytes Desc: not available URL: From dave at boost-consulting.com Mon Aug 18 22:01:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 18 Aug 2003 16:01:29 -0400 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: "Mike Rovner" writes: > David Abrahams wrote: >> "Mike Rovner" writes: >> >> Sorry, Mike. Too much missing detail and too confusing. > > Ouh, I appologize for disturbing. The error was mine. > I was confused with the error message: > > Boost.Python.ArgumentError: Python argument types in > Scheme.ishintable(Scheme, Layer, int) > did not match C++ signature: > ishintable(class Tcn::DerivationScheme const *, class Tcn::LayerDef > const *) > > I overlooked extra parameter in Python args and tried to fix immaginable bug > in Scheme pointer. See what I get for providing readable error messages? More support requests! ;-> > Scheme is mentioned twice and that probably confused me. That's the "self" object, I bet. > Thanks for replying, it actualy helped me to find my bug by kicking > in right direction ;) I'll always be glad to tell you I don't understand ;o) -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 18 22:24:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 18 Aug 2003 16:24:53 -0400 Subject: [C++-sig] Re: class data members References: Message-ID: "Sam Bloomquist" writes: > I have an update to the question I posted earlier, shown below. It turns > out that my crash only happens when the string I am trying to set is longer > than 15 characters. Anyone have any guesses where the 15 character limit > came from? > > I am currently working on moving an application from visual studio 6.0 to > visual studio .net 2003 and boost 1.29.0 to boost 1.30.0 and am having a few > problems with class data members. My c++ struct and python wrapper are as > follows: > > struct JunkObject > { > bool operator == (JunkObject& jo); > std::string m_sName; > int m_iID; > }; > > class_("JunkObject") > .def_readwrite("name", &JunkObject::m_sName) > .def_readwrite("id", &JunkObject::m_iID); > > # Then in python when I do this... > > obj = plus.JunkObject() > obj.id = 5 > > # where "plus" is my boost python module, everthing is fine. But if I do... > > obj.name = "Bob went for a walk in the park." > > # my program crashes. Does anyone see something I'm missing? This worked > fine in msvs 6.0 and boost 1.29. Sam, Your example (well, if I fill in the missing details like BOOST_PYTHON_MODULE, etc.) works fine with the current Boost CVS and MSVC 6.5 for me. I bet you haven't really reduced this to a minimal example, have you? I'm fairly certain you'll find your bug if you do that. The Jamfile I used to test it was: ------- subproject libs/python/user ; # bring in the rules for python SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; extension foo_ext : foo.cpp ../../.. ; boost-python-runtest foo : foo.py foo_ext ; ------ I placed it in a subdirectory "user" of $BOOST_ROOT/libs/python along with the enclosed: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: foo.cpp URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: foo.py Type: application/octet-stream Size: 499 bytes Desc: not available URL: -------------- next part -------------- HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Tue Aug 19 00:29:04 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Mon, 18 Aug 2003 18:29:04 -0400 Subject: [C++-sig] argument_error Message-ID: <3F415330.1E4122E1@sitius.com> Hi, In occasion I do argument validation, like checking if sequence elements are all of some type(s), and with 1_29_0 I was throwing python::argument_error if the validation fails. In the CVS argument_error is not in the headers. What would be the proper way of doing this now? Regards, Nikolay From dave at boost-consulting.com Tue Aug 19 03:11:48 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 18 Aug 2003 21:11:48 -0400 Subject: [C++-sig] Re: argument_error References: <3F415330.1E4122E1@sitius.com> Message-ID: Nikolay Mladenov writes: > Hi, > > In occasion I do argument validation, like checking if sequence elements > are all of some type(s), > and with 1_29_0 I was throwing python::argument_error if the validation > fails. That was never the right thing to do since Boost.Python v1. > In the CVS argument_error is not in the headers. What would be the > proper way of doing this now? Do you just want to report an error or do you want overload resolution to continue to search for a match? If you just want to report an error, you can throw any C++ exception you like, or raise a Python TypeError: PyErr_SetString(PyExc_TypeError, "blah blah"); python::throw_error_already_set(); -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Tue Aug 19 03:33:48 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Mon, 18 Aug 2003 21:33:48 -0400 Subject: [C++-sig] Re: argument_error References: <3F415330.1E4122E1@sitius.com> Message-ID: <3F417E7C.AA72B460@sitius.com> What should it be if I want it to search for better match? Thanks. David Abrahams wrote: > > Nikolay Mladenov ?nickm at sitius.com? writes: > > ? Hi, > ? > ? In occasion I do argument validation, like checking if sequence elements > ? are all of some type(s), > ? and with 1_29_0 I was throwing python::argument_error if the validation > ? fails. > > That was never the right thing to do since Boost.Python v1. > > ? In the CVS argument_error is not in the headers. What would be the > ? proper way of doing this now? > > Do you just want to report an error or do you want overload resolution > to continue to search for a match? If you just want to report an > error, you can throw any C++ exception you like, or raise a Python > TypeError: > > PyErr_SetString(PyExc_TypeError, "blah blah"); > python::throw_error_already_set(); > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com From dave at boost-consulting.com Tue Aug 19 04:03:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 18 Aug 2003 22:03:35 -0400 Subject: [C++-sig] Re: argument_error References: <3F415330.1E4122E1@sitius.com> <3F417E7C.AA72B460@sitius.com> Message-ID: Nikolay Mladenov writes: > What should it be if I want it to search for better match? I think wrapping a function which returns a PyObject*, NULL only if the overload resolution fails, might work. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nickm at sitius.com Tue Aug 19 04:15:31 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Mon, 18 Aug 2003 22:15:31 -0400 Subject: [C++-sig] class/struct def_visitor Message-ID: <3F418843.8CCD79C1@sitius.com> I just updated from the boost-consulting cvs and I got the following error: D:\Shared\boost_1_31_0\boost\boost/python/class.hpp(62) : warning C4099: 'def_visitor' : type name first seen using 'class' now seen using 'struct' D:\Shared\boost_1_31_0\boost\boost/python/def_visitor.hpp(83) : see declaration of 'def_visitor' From djowel at gmx.co.uk Tue Aug 19 04:23:45 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Tue, 19 Aug 2003 10:23:45 +0800 Subject: [C++-sig] class/struct def_visitor References: <3F418843.8CCD79C1@sitius.com> Message-ID: <011201c365f8$eda7fc90$64646464@godzilla> Nikolay Mladenov wrote: > I just updated from the boost-consulting cvs and I got the following > error: > > D:\Shared\boost_1_31_0\boost\boost/python/class.hpp(62) : warning C4099: > 'def_visitor' : type name first seen using 'class' now seen using > 'struct' > D:\Shared\boost_1_31_0\boost\boost/python/def_visitor.hpp(83) : > see declaration of 'def_visitor' Fixed in CVS. Thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From prabhu at aero.iitm.ernet.in Tue Aug 19 04:49:43 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Tue, 19 Aug 2003 08:19:43 +0530 Subject: [C++-sig] Bugs with Pyste and vector_indexing_suite. Message-ID: <16193.36935.903426.126230@monster.linux.in> Hi, Three bugs. 1. The issue with vector_indexing_suite and exposing std::vector still remains. I've patched my local copy with the fix that Joel posted but this is not yet in CVS. Would appreciate if this could be fixed in CVS. Thanks! 2. Pyste from CVS has problems I have not had the time to track it down and reduce it to a small problem but the problem is with the declarations.py. Some of the methods do not appear to have the 'throws' attribute. I get errors like this: Traceback (most recent call last): File "/usr/local/bin/pyste.py", line 5, in ? pyste.main() File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/pyste.py", line 367, in main status = Begin() File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/pyste.py", line 213, in Begin return GenerateCode(parser, module, out, interfaces, multiple) File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/pyste.py", line 334, in GenerateCode export.GenerateCode(codeunit, exported_names) File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/Exporter.py", li ne 45, in GenerateCode self.Export(codeunit, exported_names) File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/ClassExporter.py ", line 88, in Export self.InheritMethods(exported_names) File "/usr/local/stow/pyste/lib/python2.2/site-packages/Pyste/ClassExporter.py ", line 116, in InheritMethods pointers = [x.PointerDeclaration(True) for x in self.class_ if isinstance(x, Method)] File "./declarations.py", line 313, in PointerDeclaration File "./declarations.py", line 213, in Exceptions AttributeError: 'Method' object has no attribute 'throws' I quietly fixed them (without looking for the cause) by changing this in declarations.py: 212 def Exceptions(self): 213 if self.throws is None: 214 return "" to: 212 def Exceptions(self): 213 if not hasattr(self, 'throws') or self.throws is None: 214 return "" It seems to work fine with this. Sorry, I can't give you a specific test case. 3. Pyste also has problems with Include and Import used together. I again don't have a small test case but perhaps Nicodemus will be able to figure this one out. Essentially if I add an Include(...) after an Import(...) nothing gets included. However if I place the Include before the Import, everything seems to work OK. Thanks and sorry for the lack of specific test cases. I'm really short on time now. cheers, prabhu From djowel at gmx.co.uk Tue Aug 19 05:25:07 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Tue, 19 Aug 2003 11:25:07 +0800 Subject: [C++-sig] Bugs with Pyste and vector_indexing_suite. References: <16193.36935.903426.126230@monster.linux.in> Message-ID: <015f01c36601$8f8def30$64646464@godzilla> Prabhu Ramachandran wrote: > > 1. The issue with vector_indexing_suite and exposing > std::vector still remains. I've patched my local copy with > the fix that Joel posted but this is not yet in CVS. Would > appreciate if this could be fixed in CVS. Thanks! Fixed in CVS. Thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From nickm at sitius.com Tue Aug 19 06:32:09 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 19 Aug 2003 00:32:09 -0400 Subject: [C++-sig] Re: Question regarding objects of enums References: <43342072.1060896519@[10.0.0.6]> Message-ID: <3F41A849.7D2FEB84@sitius.com> Dave Unfortunately I don't understand the solution to the problem, but I need something similar to be done in the value_holder.hpp( probably the BOOST_PYTHON_UNFORWARD_LOCAL macro) since I am getting: D:\Shared\boost_1_31_0\boost\boost/python/object/forward.hpp(175) : error C2893: Failed to specialize function template 'const T &__cdecl boost::python::objects::do_unforward(const T &,...)' With the following template arguments: 'enum View::Display::Option' D:\Shared\boost_1_31_0\boost\boost/python/object/make_holder.hpp(82) : see reference to function template instantiation '__thiscall boost::python::objects::value_holder::boost::python::objects::value_holder(struct _object *,enum View::Display::Option)' being compiled D:\Shared\boost_1_31_0\boost\boost/python/object/forward.hpp(175) : error C2784: 'T &__cdecl boost::python::objects::do_unforward(const class boost::reference_wrapper &,int)' : could not deduce template argument for 'const class boost::reference_wrapper &' from 'enum View::Display::Option' David Abrahams wrote: > > gideon may ?gideon at computer.org? writes: > > ? Hi Dave, > ? > ? I tried to compile my library with the current cvs version and > ? stumbled on a problem with enums. The following worked with > ? boost 1.30.0 but fails with the cvs version (using MSVC 7): > ? > ? class MyClass { > ? public: > ? enum Direction { > ? UP, DOWN > ? }; > ? }; > ? > ? enum Color { > ? RED, GREEN, BLUE > ? }; > ? > ? > ? void make_object() > ? { > ? object o1 = object(RED); // Works > ? object o2 = object(MyClass::UP); // Fails > ? } > ? > ? TIA, > ? > ? Gideon > > VC7 bug. Fixed in CVS with enclosed patch. > > ------------------------------------------------------------------------ > > object_core.patchName: object_core.patch > Type: text/x-patch > > ------------------------------------------------------------------------ > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > ------------------------------------------------------------------------ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From nickm at sitius.com Tue Aug 19 06:43:46 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 19 Aug 2003 00:43:46 -0400 Subject: [C++-sig] Re: Question regarding objects of enums References: <43342072.1060896519@[10.0.0.6]> <3F41A849.7D2FEB84@sitius.com> Message-ID: <3F41AB02.AC3B896@sitius.com> Try this with MSVC (6.5): /////////////////////////// class OBJ{ public : enum PROP{ p }; OBJ(PROP p){} }; #include using namespace boost::python; BOOST_PYTHON_MODULE(obj) { scope s( class_("OBJ", init() ) ); enum_ ("PROP"); } //////////////////////////////// From RaoulGough at yahoo.co.uk Tue Aug 19 14:05:28 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Tue, 19 Aug 2003 13:05:28 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> Message-ID: "Joel de Guzman" writes: > Raoul Gough wrote: > >> I've had a chance to look at Joel's indexing_suite, and there >> should be quite a lot of overlap in the functionality between >> indexing_suite and the extended iterator_range. I've been thinking >> about how to provide the range-as-iterable support within the >> indexing_suite framework, but it looks like there would have to be >> some changes to the base classes. > > Right. This is one of the things that's holding me back to formally > announcing the suite. It isn't as simple as it started out to be > anymore. It is very useful as it is, but the bottomline is that more > experience with the sub-framework is needed to ascertain that the > interface will hold. Sure enough, when I added the map-indexing > suite (just recently), the interface needed to be changed. I see - so the slicing had to be factored out, because you can't slice an associative container. In theory you could use lower_bound and upper_bound to do some kind of slicing using the key type rather than positional indexing. The Python mapping types don't seem to support this, though (I guess the Python dictionary type is hash-based, so it couldn't easily support this idea). Actually, that's a whole other kettle of fish, looking at the Python mapping functions! > >> I'm basically considering an indexing_suite-derived class template >> that would use two iterators for construction and provide only the >> relevant support functions (from __iter__ alone for input_iterators >> through to __getitem__ and __setitem__ for random access iterators >> with non-const value types). The problem is that the indexing_suite >> base classes assume that all container functionality is always >> present, all the way up to __delitem__ (impossible for >> iterators). Thus, it is currently unsuitable for use with iterator >> pairs, especially if one considers const_iterators. For instance, >> the following doesn't come close to compiling: >> >> boost::python::class_ > ("Vector") >> .def (boost::python::vector_indexing_suite const>()); >> >> For obvious reasons (note the const qualifier). I haven't got far >> enough to see how many changes it would require to allow containers >> with less functionality than is currently assumed. Maybe Joel has >> some comments about the feasibility of this idea? > > I've already considered wrapping iterator ranges. I would appreciate > it a lot if you are interested to help. As to how many changes it > would require to allow containers with less functionality, not > much. Right now, I have factored out 1) proxyability and 2) > slicability protocols. I think what needs to be factored out, in > addition to above are 3) resizability and perhaps 4) mutability > (constness). Well, I wonder about taking the same approach further, e.g. with any iterator range extensions - it seems like a lot of complexity involved in *removing* expected functionality. Maybe it would be possible to split the base class into separate functional units which can be recombined as appropriate, rather than having an all-in-one base class? I used something like that approach in my iterator_range extensions (at http://home.clara.net/raoulgough/boost/). Basically, I use the MPL to choose what def() functions to call, and rely on the compiler not instantiating unused templated functions. e.g. template<> struct maybe_add_len { template static void apply (class_ &class_) { // Specialized version *does* add __len__ class_.def ("__len__", &distance); } }; // ... in the main class_ setup function: maybe_add_len ::value> ::apply (result); This only does the class_.def() for __len__ when the iterator is (at least) a forward_iterator. The unspecialized maybe_add_len has an empty apply function, so if the specialization is not used: 1. In Python, len() automatically produces "TypeError: len() of unsized object" 2. distance is never used (i.e. its address is never taken) and won't even be instantiated. This could be extended using a traits class that defined things like has_len, has_slicing, has_append, etc... I vaguely remember reading something about over-zealous compilers that instantiate things when they shouldn't, but I would count that as too broken to work with :-) > > You can see the factored out code in > (see no_proxy_helper, proxy_helper, slice_helper and > no_slice_helper). The indexing suite chooses the appropriate > handler based on some flags and the types involved. The same system > will need to be set in place to support resizability and mutability. Could you explain the role of the element proxy vectors (proxy_group)? I wrote a test case which echoes construction and destruction of contained elements to stdout, and it looks to me like the elements are being copied even when the proxy is in use (i.e. a copy happens if I do "print vector[0]" from Python). Initially, I thought the proxy was some way to avoid extra copying of UDTs, but I guess that isn't it. > > Is it feasible? Of course ;-) I thought the same thing about extending iterator_range to support len and getitem, and look where that got me! (I tried three separate implementations before arriving at the current one). Maybe it was *too* feasible :-) -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Tue Aug 19 14:35:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Aug 2003 08:35:46 -0400 Subject: [C++-sig] Re: Question regarding objects of enums References: <43342072.1060896519@[10.0.0.6]> <3F41A849.7D2FEB84@sitius.com> <3F41AB02.AC3B896@sitius.com> Message-ID: Nikolay Mladenov writes: > Try this with MSVC (6.5): > > /////////////////////////// > class OBJ{ > public : > enum PROP{ p }; > OBJ(PROP p){} > }; > > #include > > using namespace boost::python; > > BOOST_PYTHON_MODULE(obj) > { > scope s( > class_("OBJ", init() ) > ); > enum_ ("PROP"); > > } > //////////////////////////////// Try this patch. FYI, I'm not sure how many of these I can actually work around, or how much energy I'm willing to put into it. VC7 and VC6 especially seem to be really broken when it comes to instantiating templates on enums nested in classes. -------------- next part -------------- A non-text attachment was scrubbed... Name: forward.patch Type: text/x-patch Size: 886 bytes Desc: not available URL: -------------- next part -------------- -- Dave Abrahams Boost Consulting www.boost-consulting.com From Giulio.Eulisse at cern.ch Tue Aug 19 16:39:25 2003 From: Giulio.Eulisse at cern.ch (Giulio Eulisse) Date: Tue, 19 Aug 2003 14:39:25 -0000 Subject: [C++-sig] building libpython without libutil Message-ID: <1061310621.15845.115.camel@lxcms25.cern.ch> Because of problems not depending on my will, I need to compile libpython2.2.so so that it does not link against libutil. Is there a way to force the openpty/forkpty test in ./configure to fail? Thanks in advance. Ciao, Giulio From sam at gabrielinteractive.com Tue Aug 19 17:21:31 2003 From: sam at gabrielinteractive.com (Sam Bloomquist) Date: Tue, 19 Aug 2003 10:21:31 -0500 Subject: [C++-sig] RE: class data members and boost::python::detail::init_module() In-Reply-To: Message-ID: > "Sam Bloomquist" writes: > > > I have an update to the question I posted earlier, shown below. > It turns > > out that my crash only happens when the string I am trying to > set is longer > > than 15 characters. Anyone have any guesses where the 15 > character limit > > came from? > > > > I am currently working on moving an application from visual > studio 6.0 to > > visual studio .net 2003 and boost 1.29.0 to boost 1.30.0 and am > having a few > > problems with class data members. My c++ struct and python > wrapper are as > > follows: > > > > struct JunkObject > > { > > bool operator == (JunkObject& jo); > > std::string m_sName; > > int m_iID; > > }; > > > > class_("JunkObject") > > .def_readwrite("name", &JunkObject::m_sName) > > .def_readwrite("id", &JunkObject::m_iID); > > > > # Then in python when I do this... > > > > obj = plus.JunkObject() > > obj.id = 5 > > > > # where "plus" is my boost python module, everthing is fine. > But if I do... > > > > obj.name = "Bob went for a walk in the park." > > > > # my program crashes. Does anyone see something I'm missing? > This worked > > fine in msvs 6.0 and boost 1.29. > > Sam, > > Your example (well, if I fill in the missing details like > BOOST_PYTHON_MODULE, etc.) works fine with the current Boost CVS and > MSVC 6.5 for me. I bet you haven't really reduced this to a minimal > example, have you? I'm fairly certain you'll find your bug if you do > that. The Jamfile I used to test it was: > > ------- > subproject libs/python/user ; > > # bring in the rules for python > SEARCH on python.jam = $(BOOST_BUILD_PATH) ; > include python.jam ; > > extension foo_ext : foo.cpp ../../.. ; > boost-python-runtest foo : foo.py foo_ext ; > ------ > > I placed it in a subdirectory "user" of $BOOST_ROOT/libs/python along > with the enclosed: > > -------------- next part -------------- > #include > > struct JunkObject > { > bool operator == (JunkObject& jo); > std::string m_sName; > int m_iID; > }; > > using namespace boost::python; > BOOST_PYTHON_MODULE(foo_ext) > { > class_("JunkObject") > .def_readwrite("name", &JunkObject::m_sName) > .def_readwrite("id", &JunkObject::m_iID); > } > > #include "../test/module_tail.cpp" David, Thanks for the help. As far as a minimal example goes, the example I gave is directly from my code (though I've now taken out the operator ==, but it wasn't causing any problems). For setting up my module I'm using boost::python::detail::init_module("plus", &Setup); where Setup is just a function that contains the wrapper class definitions... class_("JunkObject") .def_readwrite("name", &JunkObject::m_sName) .def_readwrite("id", &JunkObject::m_iID); Is this way of initializing the module still used? I can't find much in the way of documentation on the init_module function. Also, this problem didn't show up for me until switching to vc7, so I'm not surprised that it works with 6.5. I do appreciate the help, though, and if I need to change the way I'm initializing my module so that I use BOOST_PYTHON_MODULE, that's fine. -Sam From dave at boost-consulting.com Tue Aug 19 17:49:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Aug 2003 11:49:23 -0400 Subject: [C++-sig] Re: building libpython without libutil References: <1061310621.15845.115.camel@lxcms25.cern.ch> Message-ID: Giulio Eulisse writes: > Because of problems not depending on my will, I need to compile > libpython2.2.so so that it does not link against libutil. > Is there a way to force the openpty/forkpty test in ./configure to fail? > Thanks in advance. I think you're in the wrong group; that's a question for comp.lang.python or something. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 19 17:52:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Aug 2003 11:52:35 -0400 Subject: [C++-sig] Re: class data members and boost::python::detail::init_module() References: Message-ID: "Sam Bloomquist" writes: > > David, > > Thanks for the help. As far as a minimal example goes, the example I gave > is directly from my code That doesn't make it minimal. To produce a minimal example you prune out irrelevant parts until you can't prune any more without making the error go away. > (though I've now taken out the operator ==, but it > wasn't causing any problems). For setting up my module I'm using > > boost::python::detail::init_module("plus", &Setup); Do not use undocumented functions from the detail namespace. I make *no* guarantees about the behavior if you do that. > where Setup is just a function that contains the wrapper class > definitions... > class_("JunkObject") > .def_readwrite("name", &JunkObject::m_sName) > .def_readwrite("id", &JunkObject::m_iID); > > Is this way of initializing the module still used? It was never used, by users anyway. > I can't find much in the way of documentation on the init_module > function. That's because it's not for you; it's for the library. > Also, this problem didn't show up for me until switching > to vc7, so I'm not surprised that it works with 6.5. Next time you report a problem, please supply information about which compiler you're using along with the minimal example. > I do appreciate the help, though, and if I need to change the way > I'm initializing my module so that I use BOOST_PYTHON_MODULE, that's > fine. That's a start. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Giulio.Eulisse at cern.ch Tue Aug 19 18:06:35 2003 From: Giulio.Eulisse at cern.ch (Giulio Eulisse) Date: Tue, 19 Aug 2003 16:06:35 -0000 Subject: [C++-sig] Re: building libpython without libutil In-Reply-To: References: <1061310621.15845.115.camel@lxcms25.cern.ch> Message-ID: <1061315863.15845.136.camel@lxcms25.cern.ch> > > Because of problems not depending on my will, I need to compile > > libpython2.2.so so that it does not link against libutil. > > Is there a way to force the openpty/forkpty test in ./configure to fail? > > Thanks in advance. > I think you're in the wrong group; that's a question for > comp.lang.python or something. Since the problem I have (clashing library name between two libraries named "util") occurs while embedding python interpreter into C++ I thought the question would have been appropriate and that someone else in here could have had the same problem. Sorry and thanks anyway, Giulio From nickm at sitius.com Tue Aug 19 23:41:54 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 19 Aug 2003 17:41:54 -0400 Subject: [C++-sig] this used to work? Message-ID: <3F4299A2.3C4964FB@sitius.com> Hi, This code used to work before (1_29_0), but now(boost-consulting:cvs from yesterday) it does not: ////////////////////////////////////////// class OBJ{ public : virtual int f()=0; }; #include using namespace boost::python; BOOST_PYTHON_MODULE(obj) { class_("OBJ", no_init ); } //////////////////////////////////////////// MSVC 6.5 complains D:\shared\boost_1_31_0\boost\boost\python\object\value_holder.hpp(54) : error C2259: 'OBJ' : cannot instantiate abstract class due to following members: s:\temp\inner.cpp(1) : see declaration of 'OBJ' d:\projects\boost_1_31_0\boost\boost\python\class.hpp(589) : see reference to class template instantiation 'boost::python::objects::value_holder' being compiled d:\projects\stlport-4.5.3\stlport\stl\_alloc.h(349) : while compiling class-template member function 'void __thiscall boost::python::class_::register_(void) const' d:\projects\boost_1_31_0\boost\boost\python\object\value_holder.hpp(54) : warning C4259: 'int __thiscall OBJ::f(void)' : pure virtual function was not defined s:\temp\inner.cpp(5) : see declaration of 'f' d:\projects\boost_1_31_0\boost\boost\python\class.hpp(589) : see reference to class template instantiation 'boost::python::objects::value_holder' being compiled d:\projects\stlport-4.5.3\stlport\stl\_alloc.h(349) : while compiling class-template member function 'void __thiscall boost::python::class_::register_(void) const' From djowel at gmx.co.uk Tue Aug 19 20:47:29 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Wed, 20 Aug 2003 02:47:29 +0800 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> Message-ID: <003d01c36682$5ec55c40$0100a8c0@godzilla> Raoul Gough wrote: > "Joel de Guzman" writes: > > I see - so the slicing had to be factored out, because you can't slice > an associative container. In theory you could use lower_bound and > upper_bound to do some kind of slicing using the key type rather than > positional indexing. Yes, that occured to me. > The Python mapping types don't seem to support > this, though (I guess the Python dictionary type is hash-based, so it > couldn't easily support this idea). Exactly. > Actually, that's a whole other > kettle of fish, looking at the Python mapping functions! > > Well, I wonder about taking the same approach further, e.g. with any > iterator range extensions - it seems like a lot of complexity involved > in *removing* expected functionality. Maybe it would be possible to > split the base class into separate functional units which can be > recombined as appropriate, rather than having an all-in-one base > class? That's a possibility, yes. We can contain the functionality into a couple of protocol groups. Making the suite finer-grained, but not too much. Can you think of a nice way to group the existing and future functionality? As it is, the protocols I outlined (proxyability, slicability, resizability and mutability) are somewhat implementation-centric. > I used something like that approach in my iterator_range extensions > (at http://home.clara.net/raoulgough/boost/). Basically, I use the MPL > to choose what def() functions to call, and rely on the compiler not > instantiating unused templated functions. e.g. [snip] > This only does the class_.def() for __len__ when the iterator is (at > least) a forward_iterator. The unspecialized maybe_add_len has an > empty apply function, so if the specialization is not used: > > 1. In Python, len() automatically produces "TypeError: len() of > unsized object" > > 2. distance is never used (i.e. its address is never taken) and > won't even be instantiated. > > This could be extended using a traits class that defined things like > has_len, has_slicing, has_append, etc... In some cases, hard-coding the enabling/disabling of features to types is not desireable. Sometimes, for example, you don't want proxying for vectors, even if it can. I opt for more user control over which is and which is not enabled. >> You can see the factored out code in >> (see no_proxy_helper, proxy_helper, slice_helper and >> no_slice_helper). The indexing suite chooses the appropriate >> handler based on some flags and the types involved. The same system >> will need to be set in place to support resizability and mutability. > > Could you explain the role of the element proxy vectors (proxy_group)? > I wrote a test case which echoes construction and destruction of > contained elements to stdout, and it looks to me like the elements are > being copied even when the proxy is in use (i.e. a copy happens if I > do "print vector[0]" from Python). Initially, I thought the proxy was > some way to avoid extra copying of UDTs, but I guess that isn't it. Following Pythion semantics, basically, we want this: val = c[i] c[i].m() val == c[i] where m is a non-const (mutating) member function (method). Yet, we also want this: val = c[i] del c[i] # do something with val No dangling references == no return_internal_reference A proxy is basically a smart-pointer that has a reference to a container and an index. When *attached*, dereferencing the proxy will index the container. A proxy can be detached from the container. In the *detached* state, it holds the actual object which it returns when dereferenced. A proxy will be detached whenever you remove or replace that element from the container (e.g. del C[I], C[0:I] = [a,b,c], C[I] = x). The proxy_group manages the proxies and is responsible for detaching a proxy appropriately when necessary. >> Is it feasible? Of course ;-) > > I thought the same thing about extending iterator_range to support len > and getitem, and look where that got me! (I tried three separate > implementations before arriving at the current one). Maybe it was > *too* feasible :-) Haha! ;-) -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From wl at flexis.de Thu Aug 21 16:20:12 2003 From: wl at flexis.de (Wolfgang Langner) Date: Thu, 21 Aug 2003 16:20:12 +0200 Subject: [C++-sig] Argument handling, char** in constructor Message-ID: Hello, I use boost.python 1.30 with python 2.2.3 under Windows (VC6). My python module interfaces to a C++ class that has the following constructor: MyClass(int* argc = 0, char** argv = 0); In boost.python I exposed it with: ... .def(init >()) This works only if I have no arguments. The problem is, I have to pass arguments from the command line (called python programm) to the C++ class. (same as in main()) First I tried to solve it with a small wrapper class that inherits from the C++ class and maps a python list of strings to that interface. But that don't work because the C++ class is a singleton. Are ther any suggestions to expose this class to python ? Thank you. bye by Wolfgang From benny at coca-kohler.de Thu Aug 21 15:07:55 2003 From: benny at coca-kohler.de (benny kohler) Date: Thu, 21 Aug 2003 15:07:55 +0200 Subject: [C++-sig] boost: printf and cout dont work Message-ID: <002e01c367e5$3e793b50$0d00a8c0@maitai> hi everybody, i want to expose some c++ classes and functions using boost. what about "printf" and "cout", when i use them in my functions they are not printed on the display. it seems that they arent exposed to python. can anybody help me? thanks, benny From mike at nospam.com Wed Aug 20 21:09:03 2003 From: mike at nospam.com (Mike Rovner) Date: Wed, 20 Aug 2003 12:09:03 -0700 Subject: [C++-sig] Re: arg type equivivalence (constness) Message-ID: > David Abrahams wrote: >> "Mike Rovner" writes: > >>> Boost.Python.ArgumentError: Python argument types in >>> Scheme.ishintable(Scheme, Layer, int) >>> did not match C++ signature: >>> ishintable(class Tcn::DerivationScheme const *, class >>> Tcn::LayerDef const *) >>> >>> I overlooked extra parameter in Python args and tried to fix >>> immaginable bug in Scheme pointer. >> >> See what I get for providing readable error messages? More support >> requests! ;-> >> >>> Scheme is mentioned twice and that probably confused me. >> >> That's the "self" object, I bet. What do you think about reporting object instances as "Name()" (i.e. Scheme.ishintable(Scheme(), Layer(), int) in previous example) I can do that. ;) (add PyInstance_Check to reporting routine) Mike PS. Seems it was not posted. From nicodemus at globalite.com.br Wed Aug 20 03:25:52 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 19 Aug 2003 22:25:52 -0300 Subject: [C++-sig] Bugs with Pyste and vector_indexing_suite. In-Reply-To: <16193.36935.903426.126230@monster.linux.in> References: <16193.36935.903426.126230@monster.linux.in> Message-ID: <3F42CE20.6060401@globalite.com.br> Hi Prabhu! Prabhu Ramachandran wrote: >Hi, > >Three bugs. > > > 2. Pyste from CVS has problems I have not had the time to track it > down and reduce it to a small problem but the problem is with the > declarations.py. Some of the methods do not appear to have the > 'throws' attribute. I get errors like this: > > > File "./declarations.py", line 213, in Exceptions >AttributeError: 'Method' object has no attribute 'throws' > > I quietly fixed them (without looking for the cause) by changing > this in declarations.py: > > 212 def Exceptions(self): > 213 if self.throws is None: > 214 return "" > > to: > > 212 def Exceptions(self): > 213 if not hasattr(self, 'throws') or self.throws is None: > 214 return "" > > Looking at the sources, I can't figure out how that is possible, since Method is derived from Function, which in turn creates a instance attribute named "throws", with the value None, and Method calls Function constructor. But I think your problem is related to the cache: you probably pickled an old instance, without this attribute (the "throw" declaration support has been recently added, thanks to a patch by Gottfried! 8) ), and pickled objects are not initialized via __init__. Try to rebuild your cache and see if the problem goes away. 8) > 3. Pyste also has problems with Include and Import used together. I > again don't have a small test case but perhaps Nicodemus will be > able to figure this one out. Essentially if I add an > Include(...) after an Import(...) nothing gets included. However > if I place the Include before the Import, everything seems to > work OK. > > Unfortunately, I couldn't reproduce this... placing Include before or after an Import works fine in my tests. When you have time, could you please produce a small test case, or perhaps explain the problem in more detail? >Thanks and sorry for the lack of specific test cases. I'm really >short on time now. > > No problem, that's understandable. Thanks to take your time to report this problems! 8) Regards, Nicodemus. From jacek.generowicz at cern.ch Fri Aug 22 04:20:59 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: Fri, 22 Aug 2003 02:20:59 -0000 Subject: [C++-sig] Interchanging SWIG & Boost bindings. Message-ID: [I tried posting this earlier via gmane.org, but the latter seems to send everything I submit to /dev/null, in recent times. Apologies if you receive this more than once.] I'm looking into the possibility of making bindings generated by Boost and SWIG, to be interchangable. Here is some code to illustrate what (I think) I mean. Suppose I have some classes written in C++: ======= simple.cpp ==============================================<<< class foo { int n; public: foo(int N):n(N){} int square() const { return n*n; } }; class bar { int n; public: bar(int N):n(N){} int baz(const foo & f) const { return n + f.square(); } }; >>>================================================================= and I create an isomorphic set of classes in pure Python: ======= puresimple.py ===========================================<<< class foo: def __init__ (self, n): self.n = n def square (self): return self.n * self.n class bar: def __init__ (self, n): self.n = n def baz (self, f): return self.n + f.square() >>>================================================================== I create Python extension modules by Boostifying and SWIGifying simple.cpp (calling them boostsimple and swigsimple, respectively), and then run the following test program: ======== test.py =================================================<<< # Implement a pair of simple test classes (foo and bar) both in C++ # and in Python. Wrap the C++ version using both Boost and SWIG. import boostsimple as boost import swigsimple as swig import puresimple as pure # Hold instances of different implementations in separate namespaces class namespace: def __init__ (self, name, implementation, fooinit, barinit): self.name = name self.foo = implementation.foo(fooinit) self.bar = implementation.bar(barinit) b = namespace("Boost", boost, 2, 3) s = namespace("SWIG ", swig , 4, 5) p = namespace("pure ", pure , 6, 7) # The test consists of passing a foo object to the the baz method of a # bar object. The test_pass function takes, as arguments, the # namespaces (implementations) from which the foo and bar objects # should be taken, and performs the test, reporting on its actions. def test_pass(receiver, argument): try: print "Passing %s to %s:" % (argument.name, receiver.name), print receiver.bar.baz(argument.foo) except TypeError, datum: print datum # First, test the self-consistency of each implementation test_pass(b, b) # 7 = 3 + 4 test_pass(s, s) # 21 = 5 + 16 test_pass(p, p) # 43 = 7 + 36 print # Now try "cross-calling": passing arguments created in one # implementation to methods created by a different implementation # Pure python as receiver test_pass(p, s) # 23 = 7 + 16 test_pass(p, b) # 11 = 7 + 4 print # Pure python as argument test_pass(b, p) # 39 = 3 + 36 test_pass(s, p) # 40 = 4 + 36 print # Cross-call between different extension implementations test_pass(b, s) # 19 = 3 + 16 test_pass(s, b) # 9 = 5 + 4 >>>================================================================= Clearly, the first block of tests (self-consistency) just works. The second block (pure Python as receiver) also works, because the Python implementation of the bar.baz method is happy to receive and use _any_ object which responds to the "square()" message (signature polymorphism). The remaining blocks fail, however, because the Boost and SWIG implementations of bar.baz only accept objects of type "C++ foo wrapped by Boost" and "C++ foo wrapped by SWIG", respectively. There are two different issues at play; two different levels at which one can approach the problem. The first is that the Boost and SWIG wrappings do not recognize that they are actually wrapping the _same_ underlying C++ class. Would it be possible to make a Boost-wrapped foo look sufficiently like a SWIG-wrapped foo, in order for the SWIG-wrapped bar.baz to accept it as an argument, and to know how to access the underlying C++ object (and vice versa)? I'm thinking along the lines of some converter utility which takes Boost/SWIG-wrapped objects and transforms them into ones which look like SWIG/Boost-wrapped ones, _without_ need to re-create the original bindings. The second, more general, approach could be to try to loosen the type checking in the Boost and SWIG wrapped versions, in order to make them respect signature polymorphism. The latter is of less direct interest to me, but I suspect that it might provide a simpler and more general way of achieving the former. In particular, if we (see below for a brief discussion of what "we" means) can agree, a priori, on a recommended way of creating Boost and SWIG bindings in a way that makes them respect signature polymorphism, later interchangeability comes for free. The broader context of my question is the following: It has been agreed[+] that Python should be used as the scripting language, glue language, and "softawre bus" of the physics applications used in the LHC[*] computing project. The number of developers involved is huge; numerous Python bindings already exist in both Boost and SWIG, as do long-established (and often unshakeable :-) preferences for one or other of the two packages. We expect (numerous developers) to create many new bindings in the near future (using both Boost and SWIG), and we expect the underlying implementations of these packages to overlap in some (many) places. The end-user Physicists are being encouraged to drive their applications in Python, with the selling point that they will be able to access, interactively, all the software that they need, via the bindings which are being made, and make various disjoint packages talk to eachother. What we are trying to anticipate (and avoid) is the situation where an end-user is happily playing with his data in an interactive session, suddenly to be confronted with the message: Type error: Expected _p_Histogram when he is passing a histogram to a function which expects a histogram. If at this point he asks the developers for advice and gets told that "If you want to get histograms out of package FOO and use them in package BAR, then you have to wait for the authors of FOO to to make a second binding of FOO in SWIG ..." (by this time he has fallen asleep and doesn't hear the rest of the explanation), then that would be a BAD THING (TM). However, if we can offer the response "Just convert your histogram with the function Boost_to_SWIG before you pass it in" (or, better still, prevent the situation from arising in the first place), then the incident does not throw a huge spanner in the works. So, my questions are (sorry it took so long to get to the point!), is there any prior art in this area? Do you foresee any show-stopping problems? Do you see any obvious ways of doing it? (I haven't looked into the grubby details myself in depth yet, but I didn't want to find myself re-inventing the wheel, so I thought I'd ask a broad question early on.) (If you've got this far :-) Thanks for your time ! [+] To a first-order approximation :-) [*] http://cern.ch/lhc From jacek.generowicz at cern.ch Fri Aug 22 04:52:11 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: Fri, 22 Aug 2003 02:52:11 -0000 Subject: [C++-sig] Interchanging SWIG & Boost bindings. Message-ID: I'm looking into the possibility of making bindings generated by Boost and SWIG, to be interchangable. Here is some code to illustrate what (I think) I mean. Suppose I have some classes written in C++: ======= simple.cpp ==============================================<<< class foo { int n; public: foo(int N):n(N){} int square() const { return n*n; } }; class bar { int n; public: bar(int N):n(N){} int baz(const foo & f) const { return n + f.square(); } }; >>>================================================================= and I create an isomorphic set of classes in pure Python: ======= puresimple.py ===========================================<<< class foo: def __init__ (self, n): self.n = n def square (self): return self.n * self.n class bar: def __init__ (self, n): self.n = n def baz (self, f): return self.n + f.square() >>>================================================================== I create Python extension modules by Boostifying and SWIGifying simple.cpp (calling them boostsimple and swigsimple, respectively), and then run the following test program: ======== test.py =================================================<<< # Implement a pair of simple test classes (foo and bar) both in C++ # and in Python. Wrap the C++ version using both Boost and SWIG. import boostsimple as boost import swigsimple as swig import puresimple as pure # Hold instances of different implementations in separate namespaces class namespace: def __init__ (self, name, implementation, fooinit, barinit): self.name = name self.foo = implementation.foo(fooinit) self.bar = implementation.bar(barinit) b = namespace("Boost", boost, 2, 3) s = namespace("SWIG ", swig , 4, 5) p = namespace("pure ", pure , 6, 7) # The test consists of passing a foo object to the the baz method of a # bar object. The test_pass function takes, as arguments, the # namespaces (implementations) from which the foo and bar objects # should be taken, and performs the test, reporting on its actions. def test_pass(receiver, argument): try: print "Passing %s to %s:" % (argument.name, receiver.name), print receiver.bar.baz(argument.foo) except TypeError, datum: print datum # First, test the self-consistency of each implementation test_pass(b, b) # 7 = 3 + 4 test_pass(s, s) # 21 = 5 + 16 test_pass(p, p) # 43 = 7 + 36 print # Now try "cross-calling": passing arguments created in one # implementation to methods created by a different implementation # Pure python as receiver test_pass(p, s) # 23 = 7 + 16 test_pass(p, b) # 11 = 7 + 4 print # Pure python as argument test_pass(b, p) # 39 = 3 + 36 test_pass(s, p) # 40 = 4 + 36 print # Cross-call between different extension implementations test_pass(b, s) # 19 = 3 + 16 test_pass(s, b) # 9 = 5 + 4 >>>================================================================= Clearly, the first block of tests (self-consistency) just works. The second block (pure Python as receiver) also works, because the Python implementation of the bar.baz method is happy to receive and use _any_ object which responds to the "square()" message (signature polymorphism). The remaining blocks fail, however, because the Boost and SWIG implementations of bar.baz only accept objects of type "C++ foo wrapped by Boost" and "C++ foo wrapped by SWIG", respectively. There are two different issues at play; two different levels at which one can approach the problem. The first is that the Boost and SWIG wrappings do not recognize that they are actually wrapping the _same_ underlying C++ class. Would it be possible to make a Boost-wrapped foo look sufficiently like a SWIG-wrapped foo, in order for the SWIG-wrapped bar.baz to accept it as an argument, and to know how to access the underlying C++ object (and vice versa)? I'm thinking along the lines of some converter utility which takes Boost/SWIG-wrapped objects and transforms them into ones which look like SWIG/Boost-wrapped ones, _without_ need to re-create the original bindings. The second, more general, approach could be to try to loosen the type checking in the Boost and SWIG wrapped versions, in order to make them respect signature polymorphism. The latter is of less direct interest to me, but I suspect that it might provide a simpler and more general way of achieving the former. In particular, if we (see below for a brief discussion of what "we" means) can agree, a priori, on a recommended way of creating Boost and SWIG bindings in a way that makes them respect signature polymorphism, later interchangeability comes for free. The broader context of my question is the following: It has been agreed[+] that Python should be used as the scripting language, glue language, and "softawre bus" of the physics applications used in the LHC[*] computing project. The number of developers involved is huge; numerous Python bindings already exist in both Boost and SWIG, as do long-established (and often unshakeable :-) preferences for one or other of the two packages. We expect (numerous developers) to create many new bindings in the near future (using both Boost and SWIG), and we expect the underlying implementations of these packages to overlap in some (many) places. The end-user Physicists are being encouraged to drive their applications in Python, with the selling point that they will be able to access, interactively, all the software that they need, via the bindings which are being made, and make various disjoint packages talk to eachother. What we are trying to anticipate (and avoid) is the situation where an end-user is happily playing with his data in an interactive session, suddenly to be confronted with the message: Type error: Expected _p_Histogram when he is passing a histogram to a function which expects a histogram. If at this point he asks the developers for advice and gets told that "If you want to get histograms out of package FOO and use them in package BAR, then you have to wait for the authors of FOO to to make a second binding of FOO in SWIG ..." (by this time he has fallen asleep and doesn't hear the rest of the explanation), then that would be a BAD THING (TM). However, if we can offer the response "Just convert your histogram with the function Boost_to_SWIG before you pass it in" (or, better still, prevent the situation from arising in the first place), then the incident does not throw a huge spanner in the works. So, my questions are (sorry it took so long to get to the point!), is there any prior art in this area? Do you foresee any show-stopping problems? Do you see any obvious ways of doing it? (I haven't looked into the grubby details myself in depth yet, but I didn't want to find myself re-inventing the wheel, so I thought I'd ask a broad question early on.) (If you've got this far :-) Thanks for your time ! [+] To a first-order approximation :-) [*] http://cern.ch/lhc From dave at boost-consulting.com Wed Aug 20 01:15:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Aug 2003 19:15:43 -0400 Subject: [C++-sig] Re: this used to work? References: <3F4299A2.3C4964FB@sitius.com> Message-ID: Nikolay Mladenov writes: > Hi, > > This code used to work before (1_29_0), but now(boost-consulting:cvs > from yesterday) it does not: > > > ////////////////////////////////////////// > class OBJ{ > public : > virtual int f()=0; > }; > > #include > > using namespace boost::python; > > BOOST_PYTHON_MODULE(obj) > { > class_("OBJ", no_init ); > } > //////////////////////////////////////////// > Clearly you need today's snapshot then ;-> This problem was recently fixed. -- Dave Abrahams Boost Consulting www.boost-consulting.com From mike at nospam.com Wed Aug 20 00:59:07 2003 From: mike at nospam.com (Mike Rovner) Date: Tue, 19 Aug 2003 15:59:07 -0700 Subject: [C++-sig] Re: using msvc lib in python References: <004201c365a1$215a6c60$0d00a8c0@maitai> Message-ID: benny at coca-kohler.de wrote: > Is it possible to create the pyd-file using the > Visual Studio??? i dont wanT to use the command line. It's pretty easy - I use it. First .pyd is a plain .dll file. - Make a project "Dynamic library", - In Linker General tab -- name the linker Output File "your_module_name.pyd", -- put in Additional Library Directories like Python22\libs;\boost\libs\python\build\VisualStudio\bin (yes, I use to build BPL with VS also) - In Linker Input -- put in Additional Dependencies boost_python.lib (or boost_python_d.lib for debug) Add you modules/libraries and build solution will give you module for Python importing. I even debug it from VS using Debugging Command "python.exe" with my script name (which imports the extension module) as argument. Enjoy, Mike From mike at nospam.com Wed Aug 20 00:45:26 2003 From: mike at nospam.com (Mike Rovner) Date: Tue, 19 Aug 2003 15:45:26 -0700 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: David Abrahams wrote: > "Mike Rovner" writes: >> Boost.Python.ArgumentError: Python argument types in >> Scheme.ishintable(Scheme, Layer, int) >> did not match C++ signature: >> ishintable(class Tcn::DerivationScheme const *, class >> Tcn::LayerDef const *) >> >> I overlooked extra parameter in Python args and tried to fix >> immaginable bug in Scheme pointer. > > See what I get for providing readable error messages? More support > requests! ;-> > >> Scheme is mentioned twice and that probably confused me. > > That's the "self" object, I bet. What do you think about reporting object instances as "Name()" (i.e. Scheme.ishintable(Scheme(), Layer(), int) in previous example) I can do that. ;) (add PyInstance_Check to reporting routine) Mike From prabhu at aero.iitm.ernet.in Wed Aug 20 05:23:10 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Wed, 20 Aug 2003 08:53:10 +0530 Subject: [C++-sig] Problem: held type, std::auto_ptr, ReferenceErrors. Message-ID: <16194.59806.222843.766321@monster.linux.in> Hi, I'm running into problems again. This time its related to pointers, std::auto_ptr and possibly call policies. I'm using gcc (2.95.4). The code is a little long winded since I'm experimenting with a couple of problems in one shot. // holder.hpp ----------------------------------------- #include #include struct A { virtual ~A() {} virtual void f() = 0; }; struct B: A{ void f() {std::cout << "B::f\n";} }; struct HBase { virtual ~HBase() {} virtual std::size_t size() const = 0; virtual A* get(const std::size_t n) = 0; }; struct Holder : HBase { Holder() {} ~Holder() {for (std::size_t i=0; i arr; }; void func(A* a) {a->f();} void f(HBase* h) { std::cout << h->size() << std::endl; for (std::size_t i=0; isize(); ++i) h->get(i)->f(); } -------------------------------------------------- I wrap this with Pyste using std::auto_ptr as the holder using a Pyste file like so: -------------------------------------------------- A = Class('A', 'holder.hpp') B = Class('B', 'holder.hpp') def held_type_func(name): return 'std::auto_ptr< %s >'%name holder(A, held_type_func) holder(B, held_type_func) HBase = Class('HBase', 'holder.hpp') set_policy(HBase.get, return_value_policy(reference_existing_object)) Holder = Class('Holder', 'holder.hpp') set_policy(Holder.get, return_value_policy(reference_existing_object)) add_wrapper = Wrapper('add_wrapper', """ void add_wrapper(Holder* c, std::auto_ptr< B> o) { c->add(o.get()); o.release(); } """) set_wrapper(Holder.add, add_wrapper) module_code(''' implicitly_convertible, std::auto_ptr > ();\n''') func = Function('func', 'holder.hpp') f = Function('f', 'holder.hpp') -------------------------------------------------- I can attach the resulting cpp file if needed but using this Pyste file I generate a holder.so module and test it like so: -------------------------------------------------- from holder import * b = B() print "b.f():" b.f() print "func(b):" func(b) h = Holder() h.add(b) x = h.get(0) print "x.f():" x.f() print "func(x):" func(x) print "f(h):" f(h) -------------------------------------------------- Problem 1: ^^^^^^^^^^ First spot of trouble is here: b.f(): B::f func(b): B::f x.f(): B::f func(x): Traceback (most recent call last): File "test_holder.py", line 13, in ? func(x) Boost.Python.ArgumentError: Python argument types in B.f(B) did not match C++ signature: f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue}) f(1B {lvalue}) If I remove the HeldType and leave it as it is, everything works fine upto the func(x) call that is. I also tried by specifying a boost::shared_ptr as the held type. I did not need to use the add_wrapper in these two cases. That also seems to work just fine. So this looks to be a bug similar to the one earlier where x.f() used to fail when the held type was std::auto_ptr. AFAIK, this does not look to be a problem with Pyste. Problem 2: ^^^^^^^^^^ The second problem is with the f(h) call. I get the following error when I use either std::auto_ptr or boost::shared_ptr as the held type or use no held type at all. f(h): 1 Traceback (most recent call last): File "test_holder.py", line 15, in ? f(h) ReferenceError: Attempt to return dangling pointer to object of type: 1A I also tried to use a return_internal_reference<1>(); instead of the return_value_policy(reference_existing_object)) and get the same results. I also changed the HBase* argument to a Holder* argument with the same results. I'd appreciate very much if someone can tell me what I am doing wrong here or if this is a bug. Thanks! prabhu From mike at nospam.com Wed Aug 20 21:09:52 2003 From: mike at nospam.com (Mike Rovner) Date: Wed, 20 Aug 2003 12:09:52 -0700 Subject: [C++-sig] Re: using msvc lib in python Message-ID: Mike Rovner wrote: (repost) > benny at coca-kohler.de wrote: >> Is it possible to create the pyd-file using the >> Visual Studio??? i dont wanT to use the command line. > > It's pretty easy - I use it. > First .pyd is a plain .dll file. > - Make a project "Dynamic library", > - In Linker General tab > -- name the linker Output File "your_module_name.pyd", > -- put in Additional Library Directories like > Python22\libs;\boost\libs\python\build\VisualStudio\bin > (yes, I use to build BPL with VS also) > - In Linker Input > -- put in Additional Dependencies boost_python.lib (or > boost_python_d.lib for debug) > > Add you modules/libraries and build solution will give you module for > Python importing. > I even debug it from VS using Debugging Command "python.exe" with my > script name > (which imports the extension module) as argument. > > Enjoy, > Mike From nickm at sitius.com Wed Aug 20 20:23:27 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Wed, 20 Aug 2003 14:23:27 -0400 Subject: [C++-sig] Re: this used to work? References: <3F4299A2.3C4964FB@sitius.com> Message-ID: <3F43BC9F.99E5CFA7@sitius.com> This seems to be working again. Thanks! But there is a small error in object_core.hpp 221c221 < # if BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION --- > # if defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION From mike at bindkey.com Thu Aug 21 01:17:55 2003 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Aug 2003 16:17:55 -0700 Subject: [C++-sig] Fw: arg type equivivalence (constness) Message-ID: <000b01c36771$49825730$1500a8c0@elf.bindkey.com> Mike Rovner wrote: >> David Abrahams wrote: >>> "Mike Rovner" writes: >> >>>> Boost.Python.ArgumentError: Python argument types in >>>> Scheme.ishintable(Scheme, Layer, int) >>>> did not match C++ signature: >>>> ishintable(class Tcn::DerivationScheme const *, class >>>> Tcn::LayerDef const *) >>>> >>>> I overlooked extra parameter in Python args and tried to fix >>>> immaginable bug in Scheme pointer. >>> >>> See what I get for providing readable error messages? More support >>> requests! ;-> >>> >>>> Scheme is mentioned twice and that probably confused me. >>> >>> That's the "self" object, I bet. > > What do you think about reporting object instances as "Name()" > (i.e. Scheme.ishintable(Scheme(), Layer(), int) in previous example) > > I can do that. ;) (add PyInstance_Check to reporting routine) > > Mike > > PS. Seems it was not posted. PPS. My news.gmane.org interface seems not to work :( From prabhu at aero.iitm.ernet.in Fri Aug 22 18:21:55 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Fri, 22 Aug 2003 21:51:55 +0530 Subject: [C++-sig] Problem: held type, std::auto_ptr, ReferenceErrors. Message-ID: <16198.17187.178637.207575@monster.linux.in> [ I sent this on 20 Aug 2003 08:53:10 +0530 and it probably got eaten up somewhere. Apologies if this appears twice. ] Hi, I'm running into problems again. This time its related to pointers, std::auto_ptr and possibly call policies. I'm using gcc (2.95.4). The code is a little long winded since I'm experimenting with a couple of problems in one shot. // holder.hpp ----------------------------------------- #include #include struct A { virtual ~A() {} virtual void f() = 0; }; struct B: A{ void f() {std::cout << "B::f\n";} }; struct HBase { virtual ~HBase() {} virtual std::size_t size() const = 0; virtual A* get(const std::size_t n) = 0; }; struct Holder : HBase { Holder() {} ~Holder() {for (std::size_t i=0; i arr; }; void func(A* a) {a->f();} void f(HBase* h) { std::cout << h->size() << std::endl; for (std::size_t i=0; isize(); ++i) h->get(i)->f(); } -------------------------------------------------- I wrap this with Pyste using std::auto_ptr as the holder using a Pyste file like so: -------------------------------------------------- A = Class('A', 'holder.hpp') B = Class('B', 'holder.hpp') def held_type_func(name): return 'std::auto_ptr< %s >'%name holder(A, held_type_func) holder(B, held_type_func) HBase = Class('HBase', 'holder.hpp') set_policy(HBase.get, return_value_policy(reference_existing_object)) Holder = Class('Holder', 'holder.hpp') set_policy(Holder.get, return_value_policy(reference_existing_object)) add_wrapper = Wrapper('add_wrapper', """ void add_wrapper(Holder* c, std::auto_ptr< B> o) { c->add(o.get()); o.release(); } """) set_wrapper(Holder.add, add_wrapper) module_code(''' implicitly_convertible, std::auto_ptr > ();\n''') func = Function('func', 'holder.hpp') f = Function('f', 'holder.hpp') -------------------------------------------------- I can attach the resulting cpp file if needed but using this Pyste file I generate a holder.so module and test it like so: -------------------------------------------------- from holder import * b = B() print "b.f():" b.f() print "func(b):" func(b) h = Holder() h.add(b) x = h.get(0) print "x.f():" x.f() print "func(x):" func(x) print "f(h):" f(h) -------------------------------------------------- Problem 1: ^^^^^^^^^^ First spot of trouble is here: b.f(): B::f func(b): B::f x.f(): B::f func(x): Traceback (most recent call last): File "test_holder.py", line 13, in ? func(x) Boost.Python.ArgumentError: Python argument types in B.f(B) did not match C++ signature: f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue}) f(1B {lvalue}) If I remove the HeldType and leave it as it is, everything works fine upto and including the func(x) call. I also tried by specifying a boost::shared_ptr as the held type. I did not need to use the add_wrapper in these two cases. That also seems to work just fine. So this looks to be a bug similar to the one earlier where x.f() used to fail when the held type was std::auto_ptr. AFAIK, this does not look to be a problem with Pyste. Problem 2: ^^^^^^^^^^ The second problem is with the f(h) call. I get the following error when I use either std::auto_ptr or boost::shared_ptr as the held type or use no held type at all. f(h): 1 Traceback (most recent call last): File "test_holder.py", line 15, in ? f(h) ReferenceError: Attempt to return dangling pointer to object of type: 1A I also tried to use a return_internal_reference<1>(); instead of the return_value_policy(reference_existing_object)) and get the same results. I also changed the HBase* argument to a Holder* argument with the same results. I'd appreciate very much if someone can tell me what I am doing wrong here or if this is a bug. Thanks! prabhu From nicodemus at globalite.com.br Fri Aug 22 15:24:59 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 22 Aug 2003 10:24:59 -0300 Subject: [C++-sig] Bugs with Pyste and vector_indexing_suite. In-Reply-To: <16193.36935.903426.126230@monster.linux.in> References: <16193.36935.903426.126230@monster.linux.in> Message-ID: <3F4619AB.6030904@globalite.com.br> (Sorry if this post appears twice: I post the first message two days ago, and still didn't see it get to the list) Hi Prabhu! Prabhu Ramachandran wrote: >Hi, > >Three bugs. > > > 2. Pyste from CVS has problems I have not had the time to track it > down and reduce it to a small problem but the problem is with the > declarations.py. Some of the methods do not appear to have the > 'throws' attribute. I get errors like this: > > > File "./declarations.py", line 213, in Exceptions >AttributeError: 'Method' object has no attribute 'throws' > > I quietly fixed them (without looking for the cause) by changing > this in declarations.py: > > 212 def Exceptions(self): > 213 if self.throws is None: > 214 return "" > > to: > > 212 def Exceptions(self): > 213 if not hasattr(self, 'throws') or self.throws is None: > 214 return "" > > Looking at the sources, I can't figure out how that is possible, since Method is derived from Function, which in turn creates a instance attribute named "throws", with the value None, and Method calls Function constructor. But I think your problem is related to the cache: you probably pickled an old instance, without this attribute (the "throw" declaration support has been recently added, thanks to a patch by Gottfried! 8) ), and pickled objects are not initialized via __init__. Try to rebuild your cache and see if the problem goes away. 8) > 3. Pyste also has problems with Include and Import used together. I > again don't have a small test case but perhaps Nicodemus will be > able to figure this one out. Essentially if I add an > Include(...) after an Import(...) nothing gets included. However > if I place the Include before the Import, everything seems to > work OK. > > Unfortunately, I couldn't reproduce this... placing Include before or after an Import works fine in my tests. When you have time, could you please produce a small test case, or perhaps explain the problem in more detail? >Thanks and sorry for the lack of specific test cases. I'm really >short on time now. > > No problem, that's understandable. Thanks to take your time to report this problems! 8) Regards, Nicodemus. From ozhmuds at tulane.edu Fri Aug 22 23:44:30 2003 From: ozhmuds at tulane.edu (Oleksandr) Date: Fri, 22 Aug 2003 16:44:30 -0500 Subject: [C++-sig] Question about linking Message-ID: <3F468EBE.81F8FA30@tulane.edu> Dear Marc, My name is Oleksandr. I have found your letter "Problem building boost.python for Cygwin". As I think my problem is close to yours. I have a problem with Extending Python when I try to use GNU software. I installed Cygwin shell on PC and try to repeat example from Mark Lutz's book (p, 1089-1100): Mark Lutz. Programming Python, O'REILLY. Second Edition. At the bottom of this message you can see these programs for your convenience. The only difference is that path to the Python folder is changed. This example is working Ok on Unix machine (IRIX 6.5) after the next two steps: 1. gcc -g -c hello.c -I/usr/local/include/python2.2 -o hello.o 2. ld -shared hello.o -o hello.so Here I deliberately use command line (not Makefile) in order to simplify the question. At the first step file hello.o is created and on the second one file hello.so. And everything is working. Under the Cygwin shell on PC the first step is Ok: gcc hello.c -g -c -I/usr/include/python2.3/ -shared -o hello.o And I have object file hello.o but the second step gives me mistakes like this: $ ld hello.o -g -I/usr/include/python2.3/ -shared -o hello.so hello.o(.text+0x2a): In function `message':/home/AAZH/MarkLutz/hello.c:14: undefined reference to `PyArg_Parse' hello.o(.text+0x4a):/home/AAZH/MarkLutz/hello.c:17: undefined reference to `strcpy' hello.o(.text+0x5c):/home/AAZH/MarkLutz/hello.c:18: undefined reference to `strcat' hello.o(.text+0x6f):/home/AAZH/MarkLutz/hello.c:19: undefined reference to `Py_BuildValue' hello.o(.text+0xb8): In function `inithello':/home/AAZH/MarkLutz/hello.c:32: undefined reference to `Py_InitModule4' I checked that on PC folder /usr/include/python2.3/ contains the whole list of all hider files and the function names are in the corresponding files. Also I spend a lot of time trying to solve this problem but ... I hope that you know the answer. Please let me know if so. Thank you beforehand. Sincerely, O. Zhmudsky ************************************************************** import hello print hello.message('C') print hello.message('module ' + hello.__file__) for i in range(3): print hello.message(str(i)) ************************************************************** #include #include /* module functions */ static PyObject * /* returns object */ message(PyObject *self, PyObject *args) /* self unused in modules */ { /* args from python call */ char *fromPython, result[64]; if (! PyArg_Parse(args, "(s)", &fromPython)) /* convert Python -> C */ return NULL; /* null=raise exception */ else { strcpy(result, "Hello, "); /* build up C string */ strcat(result, fromPython); /* add passed Python string */ return Py_BuildValue("s", result); /* convert C -> Python */ } } /* registration table */ static struct PyMethodDef hello_methods[] = { {"message", message, 1}, /* method name, C func ptr, always-tuple */ {NULL, NULL} /* end of table marker */ }; /* module initializer */ void inithello() /* called on first import */ { /* name matters if loaded dynamically */ (void) Py_InitModule("hello", hello_methods); /* mod name, table ptr */ } From prabhu at aero.iitm.ernet.in Sun Aug 24 07:31:15 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sun, 24 Aug 2003 11:01:15 +0530 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. In-Reply-To: References: <16198.17187.178637.207575@monster.linux.in> Message-ID: <16200.19875.951364.329065@monster.linux.in> Hi Dave, >>>>> "DA" == David Abrahams writes: DA> The following message is a courtesy copy of an article that DA> has been posted to gmane.comp.python.c++ as well. Thanks for the followup and the CC! >> Problem 1: DA> If you pass this through c++filt you'll see that it has a DA> Python object of type (Python) B but can't match it to a C++ DA> function requiring a (C++) B lvalue argument. That can only DA> mean that there's no C++ B object in the Python B object. DA> Given that you're holding these things by auto_ptr, which DA> gives up ownership when copied, it's a strong hint that the DA> object has been passed where a C++ std::auto_ptr object was DA> expected, e.g. to your add_wrapper function. IIUC, you are saying that the object was not held correctly by std::auto_ptr? I can confirm that add_wrapper was indeed being called because I added a print statement after that. Boost.Python (correctly) complains if I pass the object itself to add_wrapper so I can't see how the object itself was passed to add_wrapper and that the h.add(b) call worked. I probably am not understanding what you mean but please do read on, I have another example (hopefully simpler). >> If I remove the HeldType and leave it as it is, everything >> works fine upto the func(x) call that is. DA> And then... what? And then problem 2. >> I also tried by specifying a boost::shared_ptr as the held >> type. I did not need to use the add_wrapper in these two >> cases. That also seems to work just fine. DA> It sounds like you're very confused about object ownership DA> issues in all these cases. Well, I was giving you as many data points as I could in order that you might get a clearer picture of what is going on. Here is what I understand of the object ownership issues. I could be wrong but I guess its best that I get it cleared up at the earliest. [ example based on code posted in last email ] >>> b = B() The Python object b holds a pointer to a B_Wrapper instance via std::auto_ptr. >>> h = Holder() >>> h.add(b) h.add calls the defined add_wrapper which expects a std::auto_ptr. Since I've declared std::auto_ptr to be implicitly convertible to std::auto_ptr, when 'b' is passed to the add_wrapper function, the add_wrapper gets the pointer to the B_Wrapper, and releases b's auto_ptr that holds B_Wrapper. So the b object will not be useable anymore. However h.get gets me the pointer that is stored in h: >>> x = h.get(0) >>> x.f() B::f Which clearly appears to work confirming what I was saying above. However I thought that func(x) should also work, but it does not and produced the error I showed earlier. This is what I think is going on. I could certainly be wrong and would appreciate if you can clarify where I am wrong. >> So this looks to be a bug similar to the one earlier where >> x.f() used to fail when the held type was std::auto_ptr. >> AFAIK, this does not look to be a problem with Pyste. DA> If you really think this is a bug in Boost.Python itself then DA> please reduce the Pyste-generated code and associated Python DA> to a minimal case so we can see what's really going on. OK, I just did that. Here is an example. // ----- bug1.hpp ----- #include #include struct B { virtual void f() {std::cout << "B::f\n";} }; struct Holder { Holder() {} ~Holder() {for (std::size_t i=0; i arr; }; void func(B* a) {a->f();} // ----- bug1.hpp ----- // ----- bug1.pyste ----- def held_type_func(name): return 'std::auto_ptr< %s >'%name B = Class('B', 'bug1.hpp') holder(B, held_type_func) Holder = Class('Holder', 'bug1.hpp') set_policy(Holder.get, return_internal_reference()) add_wrapper = Wrapper('add_wrapper', """ void add_wrapper(Holder* c, std::auto_ptr< B > o) { std::cout << "In add_wrapper\n"; c->add(o.get()); o.release(); } """) set_wrapper(Holder.add, add_wrapper) module_code(''' implicitly_convertible, std::auto_ptr > ();\n''') func = Function('func', 'bug1.hpp') // ----- bug1.pyste ----- Now I build the generated code to get the following problem: >>> from bug1 import * >>> b = B() >>> h = Holder() >>> h.add(b) In add_wrapper >>> del b >>> x = h.get(0) >>> func(x) pure virtual method called Aborted This does not happen if B::f is not virtual. Also, if I do not 'del b' then I get the following error when I call func(x). Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in B.f(B) did not match C++ signature: f(Q225_GLOBAL_.N.bug1.cppBVtXka9B_Wrapper {lvalue}) f(1B {lvalue}) I'd appreciate clarifications on what I'm doing wrong. Thanks! >> Problem 2: [snip] >> I also tried to use a return_internal_reference<1>(); instead >> of the return_value_policy(reference_existing_object)) and get >> the same results. I also changed the HBase* argument to a >> Holder* argument with the same results. DA> Sounds like you're just flailing about here; think about what DA> actually goes on instead. The HBase* passed to f actually Sorry, my intent was to give you as much information as I could. DA> points to a Holder_Wrapper generated by Pyste so that you can DA> override a Holder's virtual functions in Python. Its get() DA> implementation looks up a Python get method and calls that. DA> Holder's get() function returns a new Python object (which DA> simply points at the referenced object), to which there is DA> only one reference. The dangling reference detector doesn't DA> know anything about the fact that this object is merely DA> pointing at some existing object - it assumes the Python DA> object has ownership of the C++ object it holds, and that C++ DA> object will die when the Python object does. Many thanks for the clarification! I still have doubts, sorry, please bear with me. All this happens at the h->get(i)->f() call. So h->get(i) gives me this new Python object that points to the referenced object. The lifetime of this new Python object is guaranteed till the end of the statement h->get(i)->f(), so why should this be an error? The Python object goes away only at the end of the statement. Also how is this different from doing this on the Python interpreter? >>> print h.size() 1 >>> for i in range(h.size()): ... h.get(i).f() ... B::f If this is legal, why is it illegal when a function does the exact same thing in C++? >> I'd appreciate very much if someone can tell me what I am doing >> wrong here or if this is a bug. DA> Well, I don't know if this latter thing is a bug or a missing DA> feature exactly... but clearly something ought to be done DA> about it. I'm not really sure what the best general solution DA> is, though. There are lots of ways the dangling reference DA> detector can be too conservative. For example, if the C++ DA> object is held by shared_ptr, there may be other shared_ptr DA> copies keeping it alive. I don't really want to try to solve DA> the problem until I understand what the right solution might DA> be. One thought is that when objects are returned via a return value policy you could tag it as such and be a little more lenient on these or handle these specially. However, I am not sure of what I'm talking about anymore given my flaky understanding of various things. BTW, SWIG, provides a lower level interface (in that you can trigger a segfault on the interpreter if you know what to do) but it does work nicely with code like the above. It leaves memory management issues to the user which is why you can shoot yourself. However, the user can also change the shadow classes so that the interface is much cleaner and memory management issues can be handled quite safely by changing the thisown attribute appropriately. Thanks! cheers, prabhu From prabhu at aero.iitm.ernet.in Sat Aug 23 05:21:24 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Sat, 23 Aug 2003 08:51:24 +0530 Subject: [C++-sig] Bugs with Pyste and vector_indexing_suite. In-Reply-To: <3F4619AB.6030904@globalite.com.br> References: <16193.36935.903426.126230@monster.linux.in> <3F4619AB.6030904@globalite.com.br> Message-ID: <16198.56756.390259.294685@monster.linux.in> Hi Nicodemus, >>>>> "N" == nicodemus writes: >> 212 def Exceptions(self): 213 if self.throws is None: 214 >> return "" >> to: >> 212 def Exceptions(self): 213 if not hasattr(self, 'throws') or >> self.throws is None: 214 return "" N> Looking at the sources, I can't figure out how that is N> possible, since Method is derived from Function, which in turn N> creates a instance attribute named "throws", with the value N> None, and Method calls Function constructor. But I think your N> problem is related to the cache: you probably pickled an old N> instance, without this attribute (the "throw" declaration N> support has been recently added, thanks to a patch by N> Gottfried! 8) ), and pickled objects are not initialized via N> __init__. Try to rebuild your cache and see if the problem N> goes away. 8) Yes, that did it. I completely forgot to rebuild the cache when I ran into this problem. Perhaps something needs to be done about this? If Pyste changes internally then somehow the cache needs to be rebuilt. >> 3. Pyste also has problems with Include and Import used >> together. I >> again don't have a small test case but perhaps Nicodemus will >> be able to figure this one out. Essentially if I add an >> Include(...) after an Import(...) nothing gets included. >> However if I place the Include before the Import, everything >> seems to work OK. N> Unfortunately, I couldn't reproduce this... placing Include N> before or after an Import works fine in my tests. When you have N> time, could you please produce a small test case, or perhaps N> explain the problem in more detail? OK, I managed to get a minimal (more or less) example. // ---- bug0.hpp ---- #include class Base { public: virtual ~Base() {} virtual void f() {std::cout << "Base::f()\n";} virtual void f(int n) {std::cout << "Base::f(int)\n";} }; // ---- bug0.hpp ---- // ---- bug.hpp ---- #include "bug0.hpp" class Derived : public Base { public: ~Derived(){} virtual void f() {std::cout << "Derived::f\n";} }; // ---- bug.hpp ---- // ---- bug0.pyste ---- Base = Class('Base', 'bug0.hpp') Include('boost/python/suite/indexing/vector_indexing_suite.hpp') // ---- bug0.pyste ---- // ---- bug.pyste ---- Import('bug0.pyste') Derived = Class('Derived', 'bug.hpp') Include('boost/python/suite/indexing/vector_indexing_suite.hpp') // ---- bug.pyste ---- Note that you must include the same file in both pyste files and in bug.pyste if the Include goes above the Import it works but as it is shown above it does not. The Pyste generated code will compile, but take a look at the generated headers section and you will see the problem. Hope this helps. Thanks! prabhu From dave at boost-consulting.com Sat Aug 23 13:41:13 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Aug 2003 07:41:13 -0400 Subject: [C++-sig] Re: this used to work? References: <3F4299A2.3C4964FB@sitius.com> <3F43BC9F.99E5CFA7@sitius.com> Message-ID: Nikolay Mladenov writes: > This seems to be working again. Thanks! > > But there is a small error in object_core.hpp > > 221c221 > < # if BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION > --- >> # if defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Thanks, the fix was sitting on my disk but not checked in for some reason! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 23 13:42:21 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Aug 2003 07:42:21 -0400 Subject: [C++-sig] Re: Fw: arg type equivivalence (constness) References: <000b01c36771$49825730$1500a8c0@elf.bindkey.com> Message-ID: "Mike Rovner" writes: >> >> PS. Seems it was not posted. > PPS. My news.gmane.org interface seems not to work :( P.P.P.S. Relax everybody, and stop reposting. The SOBIG virus screwed up all internet communications for a few days. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 23 13:37:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Aug 2003 07:37:33 -0400 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. References: <16198.17187.178637.207575@monster.linux.in> Message-ID: [My followup was this] Prabhu Ramachandran writes: > Problem 1: > ^^^^^^^^^^ > First spot of trouble is here: > > b.f(): > B::f > func(b): > B::f > x.f(): > B::f > func(x): > Traceback (most recent call last): > File "test_holder.py", line 13, in ? > func(x) > Boost.Python.ArgumentError: Python argument types in > B.f(B) > did not match C++ signature: > f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue}) > f(1B {lvalue}) If you pass this through c++filt you'll see that it has a Python object of type (Python) B but can't match it to a C++ function requiring a (C++) B lvalue argument. That can only mean that there's no C++ B object in the Python B object. Given that you're holding these things by auto_ptr, which gives up ownership when copied, it's a strong hint that the object has been passed where a C++ std::auto_ptr object was expected, e.g. to your add_wrapper function. > If I remove the HeldType and leave it as it is, everything works fine > upto the func(x) call that is. And then... what? > I also tried by specifying a boost::shared_ptr as the held type. > I did not need to use the add_wrapper in these two cases. That also > seems to work just fine. It sounds like you're very confused about object ownership issues in all these cases. > So this looks to be a bug similar to the one earlier where x.f() > used to fail when the held type was std::auto_ptr. AFAIK, this > does not look to be a problem with Pyste. If you really think this is a bug in Boost.Python itself then please reduce the Pyste-generated code and associated Python to a minimal case so we can see what's really going on. > > Problem 2: > ^^^^^^^^^^ > > The second problem is with the f(h) call. I get the following error > when I use either std::auto_ptr or boost::shared_ptr as the held > type or use no held type at all. > > f(h): > 1 > Traceback (most recent call last): > File "test_holder.py", line 15, in ? > f(h) > ReferenceError: Attempt to return dangling pointer to object of type: 1A > > > I also tried to use a return_internal_reference<1>(); instead of the > return_value_policy(reference_existing_object)) and get the same > results. I also changed the HBase* argument to a Holder* argument > with the same results. Sounds like you're just flailing about here; think about what actually goes on instead. The HBase* passed to f actually points to a Holder_Wrapper generated by Pyste so that you can override a Holder's virtual functions in Python. Its get() implementation looks up a Python get method and calls that. Holder's get() function returns a new Python object (which simply points at the referenced object), to which there is only one reference. The dangling reference detector doesn't know anything about the fact that this object is merely pointing at some existing object - it assumes the Python object has ownership of the C++ object it holds, and that C++ object will die when the Python object does. > I'd appreciate very much if someone can tell me what I am doing wrong > here or if this is a bug. Well, I don't know if this latter thing is a bug or a missing feature exactly... but clearly something ought to be done about it. I'm not really sure what the best general solution is, though. There are lots of ways the dangling reference detector can be too conservative. For example, if the C++ object is held by shared_ptr, there may be other shared_ptr copies keeping it alive. I don't really want to try to solve the problem until I understand what the right solution might be. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 23 04:19:27 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Aug 2003 22:19:27 -0400 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: "Mike Rovner" writes: > What do you think about reporting object instances as "Name()" > (i.e. Scheme.ishintable(Scheme(), Layer(), int) in previous example) > > I can do that. ;) (add PyInstance_Check to reporting routine) Why would that be an improvement? Scheme() might not even be a valid call (its __init__ may require more parameters). -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 23 04:17:01 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Aug 2003 22:17:01 -0400 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. References: <16194.59806.222843.766321@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Problem 1: > ^^^^^^^^^^ > First spot of trouble is here: > > b.f(): > B::f > func(b): > B::f > x.f(): > B::f > func(x): > Traceback (most recent call last): > File "test_holder.py", line 13, in ? > func(x) > Boost.Python.ArgumentError: Python argument types in > B.f(B) > did not match C++ signature: > f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue}) > f(1B {lvalue}) If you pass this through c++filt you'll see that it has a Python object of type (Python) B but can't match it to a C++ function requiring a (C++) B lvalue argument. That can only mean that there's no C++ B object in the Python B object. Given that you're holding these things by auto_ptr, which gives up ownership when copied, it's a strong hint that the object has been passed where a C++ std::auto_ptr object was expected, e.g. to your add_wrapper function. > If I remove the HeldType and leave it as it is, everything works fine > upto the func(x) call that is. And then... what? > I also tried by specifying a boost::shared_ptr as the held type. > I did not need to use the add_wrapper in these two cases. That also > seems to work just fine. It sounds like you're very confused about object ownership issues in all these cases. > So this looks to be a bug similar to the one earlier where x.f() > used to fail when the held type was std::auto_ptr. AFAIK, this > does not look to be a problem with Pyste. If you really think this is a bug in Boost.Python itself then please reduce the Pyste-generated code and associated Python to a minimal case so we can see what's really going on. > > Problem 2: > ^^^^^^^^^^ > > The second problem is with the f(h) call. I get the following error > when I use either std::auto_ptr or boost::shared_ptr as the held > type or use no held type at all. > > f(h): > 1 > Traceback (most recent call last): > File "test_holder.py", line 15, in ? > f(h) > ReferenceError: Attempt to return dangling pointer to object of type: 1A > > > I also tried to use a return_internal_reference<1>(); instead of the > return_value_policy(reference_existing_object)) and get the same > results. I also changed the HBase* argument to a Holder* argument > with the same results. Sounds like you're just flailing about here; think about what actually goes on instead. The HBase* passed to f actually points to a Holder_Wrapper generated by Pyste so that you can override a Holder's virtual functions in Python. Its get() implementation looks up a Python get method and calls that. Holder's get() function returns a new Python object (which simply points at the referenced object), to which there is only one reference. The dangling reference detector doesn't know anything about the fact that this object is merely pointing at some existing object - it assumes the Python object has ownership of the C++ object it holds, and that C++ object will die when the Python object does. > I'd appreciate very much if someone can tell me what I am doing wrong > here or if this is a bug. Well, I don't know if this latter thing is a bug or a missing feature exactly... but clearly something ought to be done about it. I'm not really sure what the best general solution is, though. There are lots of ways the dangling reference detector can be too conservative. For example, if the C++ object is held by shared_ptr, there may be other shared_ptr copies keeping it alive. I don't really want to try to solve the problem until I understand what the right solution might be. -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Fri Aug 22 21:27:16 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Fri, 22 Aug 2003 20:27:16 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> Message-ID: "Joel de Guzman" writes: > Raoul Gough wrote: >> "Joel de Guzman" writes: [snip digression into associative mappings] >> Well, I wonder about taking the same approach further, e.g. with >> any iterator range extensions - it seems like a lot of complexity >> involved in *removing* expected functionality. Maybe it would be >> possible to split the base class into separate functional units >> which can be recombined as appropriate, rather than having an >> all-in-one base class? > > That's a possibility, yes. We can contain the functionality into a > couple of protocol groups. Making the suite finer-grained, but not > too much. Can you think of a nice way to group the existing and > future functionality? As it is, the protocols I outlined > (proxyability, slicability, resizability and mutability) are > somewhat implementation-centric. The more I think about, the more I see this as two separate domains of freedom. Firstly, there is the raw functionality of the C++ container (e.g. random access indexing, resizability, etc.) and then there are the Python interfacing aspects (i.e. proxies and return policies). For the container functionality aspects, we could probably break the suite up simply in terms of what Python methods are implemented (like the maybe_define_len, maybe_define_getitem functions I wrote for iterator_range). A likely problem with this approach is achieving good reuse of common code, but maybe extending the existing container_utils could provide an answer. Take the __len__ method for example. There are probably only two different implementations of this on the C++ side - either using the container::size member function, or std::distance(begin_iter, end_iter). This could mean something like: template struct memfn_len { typename Container::size_type static apply (call_traits::param_type c) { return c.size(); } }; template struct iterator_len { typename Iterator::difference_type static apply (iterator_pair const &c) { return std::distance (c.begin(), c.end()); } }; This still requires some glue to choose the right version and convert the return value to Python. In general, there may also need to be glue to extract parameters from Python. [snip] >> This could be extended using a traits class that defined things >> like has_len, has_slicing, has_append, etc... > > In some cases, hard-coding the enabling/disabling of features to > types is not desireable. Sometimes, for example, you don't want > proxying for vectors, even if it can. I opt for more user control > over which is and which is not enabled. This ties in with what I was thinking about the separation of container functionality from the interfacing aspects of the parameterization. Using a traits class doesn't necessarily hard-code the determination of what features to provide, it just alters the packaging of that information. My personal preference is to package the information into as few template parameters as possible. For example, template , bool UseProxy = Traits::default_use_proxy> class indexing_suite { /*... */ } The client code could always substitute custom_indexing_traits for the second parameter (possibly deriving the custom traits from an existing traits instance). I guess I would still keep the proxy parameter separate, since to proxy or not is somewhat orthogonal to the features of the container type itself (which is what you were getting at, I think). Some of the advantages for traits over multiple parameters are (IMO) 1. the traits class provides the parameters as named constants, rather than having bare true/false values in client code. 2. it removes any particular ordering of the parameters, so you don't have to provide explicitly all parameters up to the one you want to override. Basically, I think a traits class scales better as the number of parameters grows. It also might provide some support functions (I'm wondering about the kind of functions that std::char_traits has, like compare and find). >>> You can see the factored out code in >>> (see no_proxy_helper, proxy_helper, slice_helper and >>> no_slice_helper). The indexing suite chooses the appropriate >>> handler based on some flags and the types involved. The same >>> system will need to be set in place to support resizability and >>> mutability. >> >> Could you explain the role of the element proxy vectors >> (proxy_group)? I wrote a test case which echoes construction and >> destruction of contained elements to stdout, and it looks to me >> like the elements are being copied even when the proxy is in use >> (i.e. a copy happens if I do "print vector[0]" from >> Python). Initially, I thought the proxy was some way to avoid extra >> copying of UDTs, but I guess that isn't it. > > Following Pythion semantics, basically, we want this: > > val = c[i] > c[i].m() > val == c[i] > > where m is a non-const (mutating) member function (method). Yet, we > also want this: > > val = c[i] > del c[i] > # do something with val > > No dangling references == no return_internal_reference > > > A proxy is basically a smart-pointer that has a reference to a > container and an index. When *attached*, dereferencing the proxy > will index the container. A proxy can be detached from the > container. In the *detached* state, it holds the actual object which > it returns when dereferenced. A proxy will be detached whenever you > remove or replace that element from the container (e.g. del C[I], > C[0:I] = [a,b,c], C[I] = x). > > The proxy_group manages the proxies and is responsible for detaching > a proxy appropriately when necessary. Well, I've got to admire that for dedication to Python semantics! I can think of an alternative, though, that would simplify the suite considerably: document a requirement that if the client code wants Python-style semantics it should use a container of shared_ptr. This obviously has some disadvantages over the proxies, but I think it achieves the same semantics without any additional complexity in the indexing suite. > >>> Is it feasible? Of course ;-) >> >> I thought the same thing about extending iterator_range to support >> len and getitem, and look where that got me! (I tried three >> separate implementations before arriving at the current one). Maybe >> it was *too* feasible :-) > > Haha! ;-) I guess my suggestions so far as still fairly abstract, but what I *have* done is try to figure out a matrix of Python functionality versus STL container type (and iterator category). You can see the results on my site for now (http://home.clara.net/raoulgough/boost/), but maybe we should create a directory in the sandbox CVS if we're really going to work on this? Any comments on my ramblings up until now are welcome, of course. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From arnaud.picard at edfgdf.fr Mon Aug 25 09:43:35 2003 From: arnaud.picard at edfgdf.fr (Arnaud PICARD) Date: Mon, 25 Aug 2003 09:43:35 +0200 Subject: [C++-sig] Boost & cross module definitions Message-ID: Hi, I'm using boost.python to wrap C++ classes. All I've done as of now is efficient, yet I do have one question. I've had to define, for a number of various modules, the same identical class, let's call it data. The problem is, when I want to use methods in python that use the wrapped C++ data class from these differents modules, it won't work ; basically they are not considered the same class. Before I switched from v1.26 to v1.30, the class was wrapped in its own module and then I used import_converters(...) for cross-module definitions. However I cannot do so any more. Does any one has an idea ? BTW I've looked through the archives but all significant messages seem to refer to a now defunct (or at least older) version of boost.python. Any help ? Arnaud From djowel at gmx.co.uk Mon Aug 25 09:29:11 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Mon, 25 Aug 2003 15:29:11 +0800 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> Message-ID: <00d101c36adb$0087aea0$64646464@godzilla> Raoul Gough wrote: > "Joel de Guzman" writes: Hi Raoul, I'll reply to your other "ramblings" (;-) later. For now the most easiest to reply to: >> Following Pythion semantics, basically, we want this: >> >> val = c[i] >> c[i].m() >> val == c[i] >> >> where m is a non-const (mutating) member function (method). Yet, we >> also want this: >> >> val = c[i] >> del c[i] >> # do something with val >> >> No dangling references == no return_internal_reference >> >> >> A proxy is basically a smart-pointer that has a reference to a >> container and an index. When *attached*, dereferencing the proxy >> will index the container. A proxy can be detached from the >> container. In the *detached* state, it holds the actual object which >> it returns when dereferenced. A proxy will be detached whenever you >> remove or replace that element from the container (e.g. del C[I], >> C[0:I] = [a,b,c], C[I] = x). >> >> The proxy_group manages the proxies and is responsible for detaching >> a proxy appropriately when necessary. > > Well, I've got to admire that for dedication to Python semantics! I > can think of an alternative, though, that would simplify the suite > considerably: document a requirement that if the client code wants > Python-style semantics it should use a container of shared_ptr. This > obviously has some disadvantages over the proxies, but I think it > achieves the same semantics without any additional complexity in the > indexing suite. Can't do. Remember, one of the main objectives of BPL is to (quoting the manual): " It is designed to wrap C++ interfaces non-intrusively, so that you should not have to change the C++ code at all in order to wrap it, making Boost Python ideal for exposing 3rd-party libraries to Python.". Forcing the client to wrap containers of shared_ptr goes against this goal. As a matter of fact, what actually spurred the development of the indexing suite was because I needed to wrap some special vectors of objects. It is out of the question to go modifying the C++ code. Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From RaoulGough at yahoo.co.uk Mon Aug 25 14:04:58 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 25 Aug 2003 13:04:58 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> <00d101c36adb$0087aea0$64646464@godzilla> Message-ID: "Joel de Guzman" writes: > Raoul Gough wrote: >> "Joel de Guzman" writes: > > Hi Raoul, > > I'll reply to your other "ramblings" (;-) later. For now the most easiest > to reply to: > >>> Following Pythion semantics, basically, we want this: >>> >>> val = c[i] >>> c[i].m() >>> val == c[i] >>> >>> where m is a non-const (mutating) member function (method). Yet, we >>> also want this: >>> >>> val = c[i] >>> del c[i] >>> # do something with val >>> >>> No dangling references == no return_internal_reference >>> >>> >>> A proxy is basically a smart-pointer that has a reference to a >>> container and an index. When *attached*, dereferencing the proxy >>> will index the container. A proxy can be detached from the >>> container. In the *detached* state, it holds the actual object which >>> it returns when dereferenced. A proxy will be detached whenever you >>> remove or replace that element from the container (e.g. del C[I], >>> C[0:I] = [a,b,c], C[I] = x). >>> >>> The proxy_group manages the proxies and is responsible for detaching >>> a proxy appropriately when necessary. >> >> Well, I've got to admire that for dedication to Python semantics! I >> can think of an alternative, though, that would simplify the suite >> considerably: document a requirement that if the client code wants >> Python-style semantics it should use a container of shared_ptr. This >> obviously has some disadvantages over the proxies, but I think it >> achieves the same semantics without any additional complexity in the >> indexing suite. > > Can't do. Remember, one of the main objectives of BPL is to (quoting the > manual): > > " It is designed to wrap C++ interfaces non-intrusively, so that you should > not have to change the C++ code at all in order to wrap it, making Boost > Python ideal for exposing 3rd-party libraries to Python.". Personally, I prefer the smart pointer approach - "as safe as possible, but no safer" :-) I take your point, though. > > Forcing the client to wrap containers of shared_ptr goes against this goal. > As a matter of fact, what actually spurred the development of the indexing > suite was because I needed to wrap some special vectors of objects. It is > out of the question to go modifying the C++ code. Well, my concern is to do with the complexity of the support - it seems to require hooks throughout all of the code that modifies the container. Maybe it would be possible to create a "container proxy" that emulates the vector interface, and use: indexing_suite > > Thus encapsulating the proxy code. I think this would localize the code much better, if it is possible to do. Another concern about this - have you considered cases where C++ code accesses the raw container (i.e. without going via the indexing suite)? e.g. val = c[i] cxx_function(c) val == c[i] # ?? where cxx_function might (from C++) insert something into the container. If I understand correctly, doing an insertion via the indexing suite would notify the proxy when it needs to update its index. I think that means that raw C++ code that modifies the container would cause problems. So what do you think of the idea of providing a proxy-container- wrapper, instead of integrating the proxy support directly into the indexing suite? C++ code would then be aware (and have direct access to) the wrapped container, and it might significantly simplify the internals of the indexing suite. -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Mon Aug 25 14:53:05 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 08:53:05 -0400 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Hi Dave, > >>>>>> "DA" == David Abrahams writes: > > DA> The following message is a courtesy copy of an article that > DA> has been posted to gmane.comp.python.c++ as well. > > Thanks for the followup and the CC! > > >> Problem 1: > > DA> If you pass this through c++filt you'll see that it has a > DA> Python object of type (Python) B but can't match it to a C++ > DA> function requiring a (C++) B lvalue argument. That can only > DA> mean that there's no C++ B object in the Python B object. > DA> Given that you're holding these things by auto_ptr, which > DA> gives up ownership when copied, it's a strong hint that the > DA> object has been passed where a C++ std::auto_ptr object was > DA> expected, e.g. to your add_wrapper function. > > IIUC, you are saying that the object was not held correctly by > std::auto_ptr? What do you mean by "correctly?" I was suggesting that it was held (correctly), and then the object's ownership was (correctly?) passed off to the auto_ptr which was used as an argument to a function. Ownership passing when auto_ptrs are copied is a feature of auto_ptr, so in that sense it's "correct" to pass ownership. But I can't say whether that's the behavior you wanted. > I can confirm that add_wrapper was indeed being called > because I added a print statement after that. Boost.Python > (correctly) complains if I pass the object itself ^^^^^^^^^^^^^^^^^ you have to be more specific; there are lots of objects flying around. The C++ object? The Python object? From C++ or from Python? A code example helps. > to add_wrapper so I can't see how the object itself was passed to > add_wrapper and that the h.add(b) call worked. I probably am not > understanding what you mean but please do read on, I have another > example (hopefully simpler). > > >> If I remove the HeldType and leave it as it is, everything > >> works fine upto the func(x) call that is. > > DA> And then... what? > > And then problem 2. > > >> I also tried by specifying a boost::shared_ptr as the held > >> type. I did not need to use the add_wrapper in these two > >> cases. That also seems to work just fine. > > DA> It sounds like you're very confused about object ownership > DA> issues in all these cases. > > Well, I was giving you as many data points as I could in order that > you might get a clearer picture of what is going on. If you want help, the best strategy is to give as few data points as possible, i.e. reduce each distinct problem to a separate minimal test case. > Here is what I understand of the object ownership issues. I could > be wrong but I guess its best that I get it cleared up at the > earliest. > > [ example based on code posted in last email ] >>>> b = B() > > The Python object b holds a pointer to a B_Wrapper instance via > std::auto_ptr. I would say that the Python object b holds a std::auto_ptr which holds a B_Wrapper instance. >>>> h = Holder() >>>> h.add(b) > > h.add calls the defined add_wrapper which expects a std::auto_ptr. > Since I've declared std::auto_ptr to be implicitly > convertible to std::auto_ptr, when 'b' is passed to the add_wrapper > function, the add_wrapper gets the pointer to the B_Wrapper, and > releases b's auto_ptr that holds B_Wrapper. So the b object will not > be useable anymore. Good so far. > However h.get gets me the pointer that is stored in h: > >>>> x = h.get(0) >>>> x.f() > B::f Well, it gets you a Python 'A' object which "holds" its C++ object with a raw pointer (i.e. no ownership). > Which clearly appears to work confirming what I was saying above. > However I thought that func(x) should also work, but it does not and > produced the error I showed earlier. It looks as though that should work, to me. But I can't see the wrapping code. > This is what I think is going on. I could certainly be wrong and > would appreciate if you can clarify where I am wrong. I can't tell much without the wrapping code. > >> So this looks to be a bug similar to the one earlier where > >> x.f() used to fail when the held type was std::auto_ptr. > >> AFAIK, this does not look to be a problem with Pyste. > > DA> If you really think this is a bug in Boost.Python itself then > DA> please reduce the Pyste-generated code and associated Python > DA> to a minimal case so we can see what's really going on. > > OK, I just did that. Here is an example. > // ----- bug1.pyste ----- > def held_type_func(name): > return 'std::auto_ptr< %s >'%name This is not minimal. I want to see the C++ wrapping code. Believe it or not I have never even run Pyste. > >> Problem 2: > [snip] > >> I also tried to use a return_internal_reference<1>(); instead > >> of the return_value_policy(reference_existing_object)) and get > >> the same results. I also changed the HBase* argument to a > >> Holder* argument with the same results. > > DA> Sounds like you're just flailing about here; think about what > DA> actually goes on instead. The HBase* passed to f actually > > Sorry, my intent was to give you as much information as I could. I don't mind having the information; I'm just saying that you appear to be trying changes to the code somewhat at random, which seldom produces good results even when it appears to "work". > DA> points to a Holder_Wrapper generated by Pyste so that you can > DA> override a Holder's virtual functions in Python. Its get() > DA> implementation looks up a Python get method and calls that. > DA> Holder's get() function returns a new Python object (which > DA> simply points at the referenced object), to which there is > DA> only one reference. The dangling reference detector doesn't > DA> know anything about the fact that this object is merely > DA> pointing at some existing object - it assumes the Python > DA> object has ownership of the C++ object it holds, and that C++ > DA> object will die when the Python object does. > > Many thanks for the clarification! I still have doubts, sorry, please > bear with me. > > All this happens at the h->get(i)->f() call. So h->get(i) gives me > this new Python object that points to the referenced object. Ahh, no. h->get(i) is C++ syntax, so it doesn't give you a Python object... unless it returns python::object (which it doesn't). h->get(i) returns a pointer to a bare A* object. > The lifetime of this new Python object is guaranteed till the end of > the statement h->get(i)->f() No, the lifetime of the A* ("pa") is guaranteed to the end of the statement, but that doesn't mean the *pa is valid. > , so why should this be an error? I think you'll need to look at the Pyste-generated code to understand what's happening. > The Python object goes away only at the end of the statement. Nope. > Also how is this different from doing this on the Python > interpreter? In too many ways to describe. >>>> print h.size() > 1 >>>> for i in range(h.size()): > ... h.get(i).f() > ... > B::f > > If this is legal, why is it illegal when a function does the exact > same thing in C++? Here's a near-minimal case which I hope will illustrate: struct Foo { virtual Foo* f() // 4. wrapped as "Foo.f" { return &foo; } // 5. Wrapper using reference_existing_object // builds a new Python Foo object with one // reference count static Foo foo; }; Foo Foo::foo; struct Foo_Wrapper : Foo { Foo_Wrapper(PyObject* self) : m_self(self) {} Foo* f() { // 3. calls into Python return call_method(m_self, "f"); // 6. call_method looks at the Python Foo object it just got // and says "I know you're about to access a pointer into // this object. How many references does it have? Oh, 1? // In that case it will be destroyed before I return. // Sorry, that pointer will be invalid. Exception!" } PyObject* m_self; }; void func(Foo* x) // 1. x actually will point to a Foo_Wrapper { x.f(); // 2. calls Foo_Wrapper::f } BOOST_PYTHON_MODULE(foo) { def("func", func); class_("Foo") .def( "f" , &Foo::f , &Foo_Wrapper::f , return_value_policy() ) ; } Python: >>> fu = Foo() >>> fu2 = fu.f() >>> func(fu2) > One thought is that when objects are returned via a return value > policy you could tag it as such and be a little more lenient on > these or handle these specially. Yes, it's a possibility. > However, I am not sure of what I'm talking about anymore given my > flaky understanding of various things. If you weren't using Pyste, you could do something like: struct Foo_Wrapper : Foo { Foo_Wrapper(PyObject* self) : m_self(self) {} Foo* f() { object self(handle<>(borrowed(m_self))); return extract(self.attr("f")()); } PyObject* m_self; }; > BTW, SWIG, provides a lower level interface (in that you can trigger > a segfault on the interpreter if you know what to do) but it does > work nicely with code like the above. It leaves memory management > issues to the user which is why you can shoot yourself. Yeah, letting a C++ user shoot himself is fine, but letting a Python user shoot himself goes against the Boost.Python philosophy. > However, the user can also change the shadow classes so that the > interface is much cleaner and memory management issues can be > handled quite safely by changing the thisown attribute > appropriately. Sure, you can do almost anything you want with Boost.Python by writing C++ wrapper layers over your code, too. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Aug 25 14:54:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 08:54:46 -0400 Subject: [C++-sig] Re: Boost & cross module definitions References: Message-ID: "Arnaud PICARD" writes: > Hi, > > I'm using boost.python to wrap C++ classes. All I've done as of now is > efficient, yet I do have one question. > > I've had to define, for a number of various modules, the same identical > class, let's call it data. The problem is, when I want to use methods in > python that use the wrapped C++ data class from these differents modules, > it won't work ; basically they are not considered the same class. That's because you defined the class multiple times. > Before I switched from v1.26 to v1.30, the class was wrapped in its > own module and then I used import_converters(...) for > cross-module definitions. However I cannot do so any more. Does any > one has an idea ? Just wrap it once and everything should work. No importing needed. -- Dave Abrahams Boost Consulting www.boost-consulting.com From djowel at gmx.co.uk Mon Aug 25 15:26:27 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Mon, 25 Aug 2003 21:26:27 +0800 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> <00d101c36adb$0087aea0$64646464@godzilla> Message-ID: <004a01c36b0c$cf71b0e0$50a245ca@godzilla> Raoul Gough wrote: > "Joel de Guzman" writes: > Well, my concern is to do with the complexity of the support - it > seems to require hooks throughout all of the code that modifies the > container. Maybe it would be possible to create a "container proxy" > that emulates the vector interface, and use: > > indexing_suite > > > > Thus encapsulating the proxy code. I think this would localize the > code much better, if it is possible to do. A possibility, yes, nice idea. > Another concern about this - have you considered cases where C++ code > accesses the raw container (i.e. without going via the indexing > suite)? e.g. > > val = c[i] > cxx_function(c) > val == c[i] # ?? > > where cxx_function might (from C++) insert something into the > container. If I understand correctly, doing an insertion via the > indexing suite would notify the proxy when it needs to update its > index. I think that means that raw C++ code that modifies the > container would cause problems. Yes, I am aware of that. That's a caveat. Before, the indexing_suite goes public, I have to provide a notification function that one needs to call in such cases. Right now, I am not sure about its interface. > So what do you think of the idea of providing a proxy-container- > wrapper, instead of integrating the proxy support directly into the > indexing suite? C++ code would then be aware (and have direct access > to) the wrapped container, and it might significantly simplify the > internals of the indexing suite. Looks like a good idea. Feel free to try it out. I'm all for further refactoring. Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From RaoulGough at yahoo.co.uk Mon Aug 25 15:46:27 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Mon, 25 Aug 2003 14:46:27 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> <00d101c36adb$0087aea0$64646464@godzilla> <004a01c36b0c$cf71b0e0$50a245ca@godzilla> Message-ID: "Joel de Guzman" writes: > Raoul Gough wrote: [snip] >> So what do you think of the idea of providing a proxy-container- >> wrapper, instead of integrating the proxy support directly into the >> indexing suite? C++ code would then be aware (and have direct access >> to) the wrapped container, and it might significantly simplify the >> internals of the indexing suite. > > Looks like a good idea. Feel free to try it out. I'm all for further > refactoring. I won't get to look at this any further today, but it's probably a two or three day (part-time) job anyway. I'll have a go at it, unless you decide to work on it yourself (please let me know if you do, though!) -- Raoul Gough "Let there be one measure for wine throughout our kingdom, and one measure for ale, and one measure for corn" - Magna Carta From dave at boost-consulting.com Mon Aug 25 15:58:18 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 09:58:18 -0400 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> <00d101c36adb$0087aea0$64646464@godzilla> Message-ID: Raoul Gough writes: >> " It is designed to wrap C++ interfaces non-intrusively, so that you should >> not have to change the C++ code at all in order to wrap it, making Boost >> Python ideal for exposing 3rd-party libraries to Python.". > > Personally, I prefer the smart pointer approach - "as safe as > possible, but no safer" :-) I take your point, though. Compromises are possible. I think it's reasonable for someone to want a safe container which doesn't provide the illusion of value independence: >>> c = get_container() >>> x = c[0] >>> print x 'foo' >>> c[0] = 'bar' >>> print x 'bar' But the full illusion should be an option, IMO. >> Forcing the client to wrap containers of shared_ptr goes against >> this goal. As a matter of fact, what actually spurred the >> development of the indexing suite was because I needed to wrap some >> special vectors of objects. It is out of the question to go >> modifying the C++ code. > > Well, my concern is to do with the complexity of the support - it > seems to require hooks throughout all of the code that modifies the > container. Maybe it would be possible to create a "container proxy" > that emulates the vector interface, and use: > > indexing_suite > > > > Thus encapsulating the proxy code. I think this would localize the > code much better, if it is possible to do. > > Another concern about this - have you considered cases where C++ code > accesses the raw container (i.e. without going via the indexing > suite)? e.g. > > val = c[i] > cxx_function(c) > val == c[i] # ?? > > where cxx_function might (from C++) insert something into the > container. If I understand correctly, doing an insertion via the > indexing suite would notify the proxy when it needs to update its > index. I think that means that raw C++ code that modifies the > container would cause problems. We're aware of this. In that case we at least do range checking to make sure it can't crash. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Mon Aug 25 17:43:39 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 25 Aug 2003 08:43:39 -0700 (PDT) Subject: [C++-sig] Re: Boost & cross module definitions In-Reply-To: Message-ID: <20030825154339.62980.qmail@web20201.mail.yahoo.com> --- David Abrahams wrote: > Just wrap it once and everything should work. No importing needed. But there is something to watch out for. Say you have a module A and another module B. Let A have a class_ statement. Let B have a .def statement for a function with the signature foo(const X&); Before you call this function foo() from Python, module A has to be imported from somewhere. Otherwise the converters for X will not be available. The reason is that Boost.Python V2 (unlike V1) has a global converter registry. Each module registers its converters in the global registry when it is imported the first time. From that point on the converters are available in any other Boost.Python extension module. Ralf __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com From mike at nospam.com Mon Aug 25 18:54:08 2003 From: mike at nospam.com (Mike Rovner) Date: Mon, 25 Aug 2003 09:54:08 -0700 Subject: [C++-sig] Re: arg type equivivalence (constness) References: Message-ID: David Abrahams wrote: > "Mike Rovner" writes: > >> What do you think about reporting object instances as "Name()" >> (i.e. Scheme.ishintable(Scheme(), Layer(), int) in previous example) >> >> I can do that. ;) (add PyInstance_Check to reporting routine) > > Why would that be an improvement? Scheme() might not even be a valid > call (its __init__ may require more parameters). I was looking for easy way for distigush two Scheme's. Can't come up with better solution. :( Mike From dave at boost-consulting.com Mon Aug 25 20:42:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 14:42:46 -0400 Subject: [C++-sig] Re: pure virtual methods with pyste References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>David Abrahams writes: >> >> >>> BOOST_PYTHON_MODULE(test) >>> { >>> class_("Abstract") >>> .def("a", &Abstract::a) >>> .def("a", &AbstractWrap::default_a) >>> ; >>> >>> def("call", call); >>> } >>> >>>I just wish I knew a way to detect that a function was pure-virtual so >>>we could have Boost.Python generate that default_a automatically. >>> >> >>Perhaps this interface would be nice: >> >> BOOST_PYTHON_MODULE(test) >> { >> class_("Abstract") >> .def("a", pure_virtual(&Abstract::a)) >> ; >> >> def("call", call); >> } >> >>?? >> > > Seems nice enough for me. 8) OK, done; see . Perhaps you should change Pyste to use this facility. -- Dave Abrahams Boost Consulting www.boost-consulting.com From prabhu at aero.iitm.ernet.in Mon Aug 25 22:19:04 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Tue, 26 Aug 2003 01:49:04 +0530 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. In-Reply-To: References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> Message-ID: <16202.28472.943168.78625@monster.linux.in> Hi Dave, Thank you *very* much for the detailed and patient clarifications! If it will help other users in the future I will try and summarize this discussion and put it together so it can be part of the docs. I personally feel that a high level "how it works - with examples" kind of write up would make it easier for characters like me to understand what is going on without having to dive into the code. If you think this is a good idea, I'll try and work on something when I get the time. >>>>> "DA" == David Abrahams writes: >> >> Problem 1: >> DA> If you pass this through c++filt you'll see that it has a DA> Python object of type (Python) B but can't match it to a C++ DA> function requiring a (C++) B lvalue argument. That can only DA> mean that there's no C++ B object in the Python B object. DA> Given that you're holding these things by auto_ptr, which DA> gives up ownership when copied, it's a strong hint that the DA> object has been passed where a C++ std::auto_ptr object was DA> expected, e.g. to your add_wrapper function. >> >> IIUC, you are saying that the object was not held correctly by >> std::auto_ptr? DA> What do you mean by "correctly?" I meant that the C++ object B_Wrapper was not being held by std::auto_ptr. Sorry about the loose terminology. DA> I was suggesting that it was held (correctly), and then the DA> object's ownership was (correctly?) passed off to the auto_ptr DA> which was used as an argument to a function. Ownership DA> passing when auto_ptrs are copied is a feature of auto_ptr, so DA> in that sense it's "correct" to pass ownership. But I can't DA> say whether that's the behavior you wanted. Yes, I do want the object ownership to pass to the holder. >> I can confirm that add_wrapper was indeed being called because >> I added a print statement after that. Boost.Python (correctly) >> complains if I pass the object itself DA> ^^^^^^^^^^^^^^^^^ DA> you have to be more specific; there are lots of objects flying DA> around. The C++ object? The Python object? From C++ or from DA> Python? A code example helps. Well, if I did something like this: >>> x = h.get(0) >>> h.add(x) Boost.Python does not allow it. Yes, I know this is a horrible thing to do but I just tested to see if the wrapper would accept it, it did not. This is what I meant by "... I pass the object". However it seems irrelevant now that you have clarified several things, I'll try and give you a minimal test case. [ PR's understanding of the ownership issues ] >> h.add calls the defined add_wrapper which expects a >> std::auto_ptr. Since I've declared std::auto_ptr >> to be implicitly convertible to std::auto_ptr, when 'b' is >> passed to the add_wrapper function, the add_wrapper gets the >> pointer to the B_Wrapper, and releases b's auto_ptr that holds >> B_Wrapper. So the b object will not be useable anymore. DA> Good so far. Great! I got atleast something right! :) >> However h.get gets me the pointer that is stored in h: >> >>>>> x = h.get(0) x.f() >> B::f DA> Well, it gets you a Python 'A' object which "holds" its C++ DA> object with a raw pointer (i.e. no ownership). Yes, h::get() (i.e. the C++ code) returns a pointer to A. IIUC, there is no ownership for the Python 'A' object because of the return value policy that I choose. So if I choose return_internal _reference<1>() as the return value policy it ties the lifetime of the returned Python A object to the lifetime of the Holder, h, and if h is deleted ('del h') the reference to the C++ object is still 'safe' (in that it won't crash the interpreter) to use since its a weak reference. >> Which clearly appears to work confirming what I was saying >> above. However I thought that func(x) should also work, but it >> does not and produced the error I showed earlier. DA> It looks as though that should work, to me. But I can't see DA> the wrapping code. [snip] DA> This is not minimal. I want to see the C++ wrapping code. DA> Believe it or not I have never even run Pyste. Ahh, OK. Thanks for letting me know. Next time I'll also attach the C++ code. As an aside, I think Nicodemus and I would be happy if you did run Pyste sometime. :) Anyway, here is hopefully a minimal test case for "Problem 1". // ---- bug.cpp ------------------------------------ #include #include #include struct B { virtual void f() {std::cout << "B::f\n";} }; struct Holder { Holder() {} ~Holder() {for (std::size_t i=0; i arr; }; void func(B* a) {a->f();} // ------------ Wrapper code ------------------------ using namespace boost::python; struct B_Wrapper: B { B_Wrapper(PyObject* self_, const B& p0): B(p0), self(self_) {} B_Wrapper(PyObject* self_): B(), self(self_) {} void f() {call_method< void >(self, "f");} void default_f() {B::f();} PyObject* self; }; void add_wrapper(Holder* c, std::auto_ptr< B > o) { std::cout << "In add_wrapper\n"; c->add(o.get()); o.release(); } BOOST_PYTHON_MODULE(bug) { class_< B, std::auto_ptr< B_Wrapper > >("B", init< >()) .def(init< const B& >()) .def("f", &B::f, &B_Wrapper::default_f) ; class_< Holder >("Holder", init< >()) .def(init< const Holder& >()) .def("add", &add_wrapper) .def("get", &Holder::get, return_internal_reference< 1 >()) ; implicitly_convertible, std::auto_ptr > (); def("func", &func); } // ---- bug.cpp ------------------------------------ I built the module with gcc 2.95.4 (Debian, Woody) and tested using this script. // --- test_bug.py --- from bug import * b = B() h = Holder() h.add(b) del b x = h.get(0) func(x) # this tends to guarantee a segfault for me. for i in range(9): h.add(B()) for i in range(10): func(h.get(i)) // ------------ $ python test_bug.py In add_wrapper Segmentation fault IIUC, x is a Python object that holds a pointer to the A* inside h. This A* actually points to the B_Wrapper object that was created by 'b = B()'. This has a valid default_f so should not func(x) work? Also note that 'x.f()' works perfectly fine. Its the func(x) that seems to fail. >> >> Problem 2: [snip] >> Many thanks for the clarification! I still have doubts, sorry, >> please bear with me. >> >> All this happens at the h->get(i)->f() call. So h->get(i) >> gives me this new Python object that points to the referenced >> object. DA> Ahh, no. h->get(i) is C++ syntax, so it doesn't give you a DA> Python object... unless it returns python::object (which it DA> doesn't). h-> get(i) returns a pointer to a bare A* object. Indeed, I have no idea how I got the idea that h->get(i) will give me a Python object. The A* object actually points to the B_Wrapper object. [ snip PR's absurd statements based on the above mistake ] >>>>> print h.size() >> 1 >>>>> for i in range(h.size()): >> ... h.get(i).f() ... B::f >> >> If this is legal, why is it illegal when a function does the >> exact same thing in C++? DA> Here's a near-minimal case which I hope will illustrate: [ snip very illustrative example! ] Many thanks for the example! I think I understand the problem now. >> One thought is that when objects are returned via a return >> value policy you could tag it as such and be a little more >> lenient on these or handle these specially. DA> Yes, it's a possibility. OK. >> However, I am not sure of what I'm talking about anymore given >> my flaky understanding of various things. DA> If you weren't using Pyste, you could do something like: DA> struct Foo_Wrapper : Foo { DA> Foo_Wrapper(PyObject* self) DA> : m_self(self) {} DA> Foo* f() { DA> object self(handle<>(borrowed(m_self))); DA> return extract(self.attr("f")()); DA> } DA> PyObject* m_self; DA> }; Yes, that is possible but I'm using Pyste. Maybe we need another hook to insert code there? Is there an easier way that Boost.Python could handle this better? Any other alternatives I have? >> BTW, SWIG, provides a lower level interface (in that you can >> trigger a segfault on the interpreter if you know what to do) >> but it does work nicely with code like the above. It leaves >> memory management issues to the user which is why you can shoot >> yourself. DA> Yeah, letting a C++ user shoot himself is fine, but letting a DA> Python user shoot himself goes against the Boost.Python DA> philosophy. Yes, I understand. I was just saying how SWIG approaches the issue. >> However, the user can also change the shadow classes so that >> the interface is much cleaner and memory management issues can >> be handled quite safely by changing the thisown attribute >> appropriately. DA> Sure, you can do almost anything you want with Boost.Python by DA> writing C++ wrapper layers over your code, too. Indeed. Many thanks again for the answers! cheers, prabhu From dave at boost-consulting.com Tue Aug 26 01:16:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 19:16:40 -0400 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> <16202.28472.943168.78625@monster.linux.in> Message-ID: Prabhu Ramachandran writes: > Hi Dave, > > Thank you *very* much for the detailed and patient clarifications! Sure; you're worth it ;-) > If it will help other users in the future I will try and summarize > this discussion and put it together so it can be part of the docs. I > personally feel that a high level "how it works - with examples" kind > of write up would make it easier for characters like me to understand > what is going on without having to dive into the code. If you think > this is a good idea, I'll try and work on something when I get the > time. Yes, please! BTW, I've had several promises of such documentation efforts but so far nobody has had the fortitude to turn my ramblings into a real document... so you could distinguish yourself by following through! For example, here's something which was supposed to become real documentation: http://www.boost-consulting.com/boost/libs/python/doc/internals.html (it's in your CVS tree). >>>>>> "DA" == David Abrahams writes: > > >> >> Problem 1: > >> > DA> If you pass this through c++filt you'll see that it has a > DA> Python object of type (Python) B but can't match it to a C++ > DA> function requiring a (C++) B lvalue argument. That can only > DA> mean that there's no C++ B object in the Python B object. > DA> Given that you're holding these things by auto_ptr, which > DA> gives up ownership when copied, it's a strong hint that the > DA> object has been passed where a C++ std::auto_ptr object was > DA> expected, e.g. to your add_wrapper function. > >> > >> IIUC, you are saying that the object was not held correctly by > >> std::auto_ptr? > > DA> What do you mean by "correctly?" > > I meant that the C++ object B_Wrapper was not being held by > std::auto_ptr. Sorry about the loose terminology. > > DA> I was suggesting that it was held (correctly), and then the > DA> object's ownership was (correctly?) passed off to the auto_ptr > DA> which was used as an argument to a function. Ownership > DA> passing when auto_ptrs are copied is a feature of auto_ptr, so > DA> in that sense it's "correct" to pass ownership. But I can't > DA> say whether that's the behavior you wanted. > > Yes, I do want the object ownership to pass to the holder. > > >> I can confirm that add_wrapper was indeed being called because > >> I added a print statement after that. Boost.Python (correctly) > >> complains if I pass the object itself > DA> ^^^^^^^^^^^^^^^^^ > DA> you have to be more specific; there are lots of objects flying > DA> around. The C++ object? The Python object? From C++ or from > DA> Python? A code example helps. > > Well, if I did something like this: > >>>> x = h.get(0) >>>> h.add(x) > > Boost.Python does not allow it. Yes, I know this is a horrible thing > to do but I just tested to see if the wrapper would accept it, it did > not. This is what I meant by "... I pass the object". However it > seems irrelevant now that you have clarified several things, I'll try > and give you a minimal test case. > > [ PR's understanding of the ownership issues ] > > >> h.add calls the defined add_wrapper which expects a > >> std::auto_ptr. Since I've declared std::auto_ptr > >> to be implicitly convertible to std::auto_ptr, when 'b' is > >> passed to the add_wrapper function, the add_wrapper gets the > >> pointer to the B_Wrapper, and releases b's auto_ptr that holds > >> B_Wrapper. So the b object will not be useable anymore. > > DA> Good so far. > > Great! I got atleast something right! :) > > >> However h.get gets me the pointer that is stored in h: > >> > >>>>> x = h.get(0) x.f() > >> B::f > > DA> Well, it gets you a Python 'A' object which "holds" its C++ > DA> object with a raw pointer (i.e. no ownership). > > Yes, h::get() (i.e. the C++ code) returns a pointer to A. IIUC, there > is no ownership for the Python 'A' object because of the return value > policy that I choose. Right. > So if I choose return_internal _reference<1>() as the return value > policy it ties the lifetime of the returned Python A object to the > lifetime of the Holder, h, and if h is deleted ('del h') the > reference to the C++ object is still 'safe' (in that it won't crash > the interpreter) to use since its a weak reference. Right, at least until some C++ code invalidates that pointer in some other way. You might look at the indexing suite stuff Joel has checked in for ways to make this sort of thing even safer. > >> Which clearly appears to work confirming what I was saying > >> above. However I thought that func(x) should also work, but it > >> does not and produced the error I showed earlier. > > DA> It looks as though that should work, to me. But I can't see > DA> the wrapping code. > > [snip] > > DA> This is not minimal. I want to see the C++ wrapping code. > DA> Believe it or not I have never even run Pyste. > > Ahh, OK. Thanks for letting me know. Next time I'll also attach the > C++ code. > > As an aside, I think Nicodemus and I would be happy if you did run > Pyste sometime. :) Yes, so much to do; so little time. I'm interested, but I don't see that there would be huge benefits to the community if I did that. > Anyway, here is hopefully a minimal test case for "Problem 1". > > > $ python test_bug.py > In add_wrapper > Segmentation fault Hmm, for me, in full Python debug mode with most compilers, I get [3821 refs] In add_wrapper B::f In add_wrapper In add_wrapper In add_wrapper In add_wrapper In add_wrapper In add_wrapper In add_wrapper In add_wrapper In add_wrapper B::f B::f B::f B::f B::f B::f B::f B::f B::f B::f Hmm, but with gcc-2.95.3, I get: In add_wrapper Traceback (most recent call last): File "foo.py", line 12, in ? func(x) AttributeError: 'wrapper_descriptor' object has no attribute 'f' [5464 refs] Hmm, the latter are using Python 2.3; the former using 2.2.2. Which version of Python are you using? Ouch; when I upgrade the other compilers to use Python 2.3, I get AttributeError: 'WeakRef' object has no attribute 'f' Ick. Here's the problem: the "self" pointer is dangling by the time B_Wrapper::f is invoked. This just reinforces my previous conclusion that we need a more formalized way to handle these Wrapper classes, e.g. with a common base class something like this one: namespace boost { namespace python { class VirtualDispatcher { VirtualDispatcher(PyObject* self) : m_detached(false), m_self(self) {} ~VirtualDispatcher() { if (m_detached) Py_DECREF(m_self); } void detach() { Py_INCREF(m_self); m_detached = true; } object self() const { return object(handle<>(borrowed(m_self))); } private: bool m_detached; PyObject* m_self; }; }} And then we need an adopt policy something like what Daniel Wallin has in luabind, but which is smart enough to detach() all VirtualDispatcher objects. > IIUC, x is a Python object that holds a pointer to the A* inside h. > This A* actually points to the B_Wrapper object that was created by 'b > = B()'. This has a valid default_f so should not func(x) work? Also > note that 'x.f()' works perfectly fine. Sure; that looks up the f attribute and calls it, while func(x) goes through a few more layers. > Its the func(x) that seems to fail. > DA> struct Foo_Wrapper : Foo { > DA> Foo_Wrapper(PyObject* self) > DA> : m_self(self) {} > > DA> Foo* f() { > DA> object self(handle<>(borrowed(m_self))); > DA> return extract(self.attr("f")()); > DA> } > DA> PyObject* m_self; > DA> }; > > Yes, that is possible but I'm using Pyste. Maybe we need another hook > to insert code there? I guess that's up to Nicodemus. > Is there an easier way that Boost.Python could handle this better? Easier for you; harder for me. I don't have time to solve these problems quickly at a deep level in Boost.Python, at least, not for free ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Aug 26 02:27:09 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 25 Aug 2003 21:27:09 -0300 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. In-Reply-To: References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> <16202.28472.943168.78625@monster.linux.in> Message-ID: <3F4AA95D.4020709@globalite.com.br> David Abrahams wrote: >Prabhu Ramachandran writes: > > >> DA> struct Foo_Wrapper : Foo { >> DA> Foo_Wrapper(PyObject* self) >> DA> : m_self(self) {} >> >> DA> Foo* f() { >> DA> object self(handle<>(borrowed(m_self))); >> DA> return extract(self.attr("f")()); >> DA> } >> DA> PyObject* m_self; >> DA> }; >> >>Yes, that is possible but I'm using Pyste. Maybe we need another hook >>to insert code there? >> >> > >I guess that's up to Nicodemus. > > You can do that already, you just have to write a wrapper for f. Here's an example: ---------------- foo.h: struct Foo { virtual int f() { return 0; } }; --------------- foo.pyste Include('iostream') f_wrapper = Wrapper('f_wrapper', ''' int f_wrapper(Foo *foo) { std::cout << "f!" << std::endl; return foo->Foo::f(); } ''') Foo = Class('Foo', 'foo.h') set_wrapper(Foo.f, f_wrapper) Will generate this: int f_wrapper(Foo *foo) { std::cout << "f!" << std::endl; return foo->Foo::f(); } namespace { struct Foo_Wrapper: Foo { ... int f() { return call_method< int >(self, "f"); } int default_f() { return f_wrapper(this); } ... }; But perhaps this is not enough, since the method in the original post needed to access the PyObject* of the Wrapper class. Is it possible to get the PyObject* given a Foo instance? Regards, Nicodemus. From nicodemus at globalite.com.br Tue Aug 26 02:48:08 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 25 Aug 2003 21:48:08 -0300 Subject: [C++-sig] Re: pure virtual methods with pyste In-Reply-To: References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> Message-ID: <3F4AAE48.8010604@globalite.com.br> David Abrahams wrote: >OK, done; see . Perhaps you should >change Pyste to use this facility. > I did, but I am getting this compiler error: pure.cpp d:/programming/libraries/boost-cvs/boost/boost/python/detail/nullary_function_ad aptor.hpp(33): catastrophic error: expected a file name # include BOOST_PP_LOCAL_ITERATE() ^ Perhaps I am missing something? Here is the code: // Includes ==================================================================== #include #include #include // Using ======================================================================= using namespace boost::python; // Declarations ================================================================ namespace { struct A_Wrapper: A { A_Wrapper(PyObject* self_, const A& p0): A(p0), self(self_) {} A_Wrapper(PyObject* self_): A(), self(self_) {} void foo() { call_method< void >(self, "foo"); } PyObject* self; }; }// namespace // Module ====================================================================== BOOST_PYTHON_MODULE(pure) { class_< A, boost::noncopyable, A_Wrapper >("A", init< >()) .def("foo", pure_virtual(&A::foo), &A_Wrapper::default_foo) ; } From dave at boost-consulting.com Tue Aug 26 04:22:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 22:22:34 -0400 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> <16202.28472.943168.78625@monster.linux.in> <3F4AA95D.4020709@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>Prabhu Ramachandran writes: >> >>> DA> struct Foo_Wrapper : Foo { >>> DA> Foo_Wrapper(PyObject* self) >>> DA> : m_self(self) {} >>> >>> DA> Foo* f() { >>> DA> object self(handle<>(borrowed(m_self))); >>> DA> return extract(self.attr("f")()); >>> DA> } DA> PyObject* m_self; >>> DA> }; >>> >>>Yes, that is possible but I'm using Pyste. Maybe we need another hook >>> to insert code there? >> >>I guess that's up to Nicodemus. >> > > You can do that already, you just have to write a wrapper for > f. Here's an example: > > ---------------- foo.h: > > struct Foo > { > virtual int f() { return 0; } > }; > > > --------------- foo.pyste > > Include('iostream') > f_wrapper = Wrapper('f_wrapper', > ''' > int f_wrapper(Foo *foo) { > std::cout << "f!" << std::endl; > return foo->Foo::f(); > } > ''') > > Foo = Class('Foo', 'foo.h') > set_wrapper(Foo.f, f_wrapper) Will generate this: > > int f_wrapper(Foo *foo) { > std::cout << "f!" << std::endl; > return foo->Foo::f(); > } > > namespace { > > struct Foo_Wrapper: Foo > { > ... > > int f() { > return call_method< int >(self, "f"); > } > > int default_f() { > return f_wrapper(this); > } > > ... > }; But perhaps this is not enough, since the > method in the original post needed to access the PyObject* of the > Wrapper class. Is it possible to get the PyObject* given a Foo > instance? No, but you can use a back_reference or shared_ptr argument and pass it to object() to get the PyObject*. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 26 04:25:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Aug 2003 22:25:33 -0400 Subject: [C++-sig] Re: pure virtual methods with pyste References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> <3F4AAE48.8010604@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>OK, done; see . Perhaps you should >>change Pyste to use this facility. >> > > I did, but I am getting this compiler error: > > pure.cpp > d:/programming/libraries/boost-cvs/boost/boost/python/detail/nullary_function_ad > aptor.hpp(33): catastrophic error: expected a file name > # include BOOST_PP_LOCAL_ITERATE() > ^ > > > Perhaps I am missing something? Here is the code: I just checked in some missing #includes. Please try again. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Aug 26 05:14:02 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 26 Aug 2003 00:14:02 -0300 Subject: [C++-sig] Re: pure virtual methods with pyste In-Reply-To: References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> <3F4AAE48.8010604@globalite.com.br> Message-ID: <3F4AD07A.5000209@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>David Abrahams wrote: >> >> >> >>>OK, done; see . Perhaps you should >>>change Pyste to use this facility. >>> >>> >>> >>I did, but I am getting this compiler error: >> >>pure.cpp >>d:/programming/libraries/boost-cvs/boost/boost/python/detail/nullary_function_ad >>aptor.hpp(33): catastrophic error: expected a file name >> # include BOOST_PP_LOCAL_ITERATE() >> ^ >> >> >>Perhaps I am missing something? Here is the code: >> >> > >I just checked in some missing #includes. Please try again. > Thanks for the quick fix! I am still getting errors thought: pure.cpp d:/programming/libraries/boost-cvs/boost/boost/preprocessor/iteration/detail/rlo cal.hpp(779): error: identifier "BOOST_PP_ENUM_BINARY_PARAMS_Z" is undefined BOOST_PP_LOCAL_MACRO(1) ^ d:/programming/libraries/boost-cvs/boost/boost/preprocessor/iteration/detail/rlo cal.hpp(779): error: expected a ")" BOOST_PP_LOCAL_MACRO(1) ^ d:/programming/libraries/boost-cvs/boost/boost/preprocessor/iteration/detail/rlo cal.hpp(779): error: expected a type specifier BOOST_PP_LOCAL_MACRO(1) ^ d:/programming/libraries/boost-cvs/boost/boost/preprocessor/iteration/detail/rlo cal.hpp(779): error: parameter of abstract class type "A" is not allowed: function "A::foo" is a pure virtual function BOOST_PP_LOCAL_MACRO(1) ^ d:/programming/libraries/boost-cvs/boost/boost/preprocessor/iteration/detail/rlo cal.hpp(779): error: expected a ";" BOOST_PP_LOCAL_MACRO(1) ^ Also, shouldn't be included by ? Thanks, Nicodemus. From benny at coca-kohler.de Tue Aug 26 10:00:37 2003 From: benny at coca-kohler.de (benny kohler) Date: Tue, 26 Aug 2003 10:00:37 +0200 Subject: [C++-sig] extended c++ - socket connection doesnt work Message-ID: <001701c36ba8$22be23f0$0d00a8c0@maitai> hi, i?m using a c++ lib, which i want to use in python. so i extended it for python using boost bjam. within the lib there is a function doing a socket connect. so if i try to do the socket-connect in python, the connection doesnt work. however i dont get any errors or exceptions that the "connect" failed. the next step was that i tried to use the c++ lib within c++. when i use the lib within c++ the socket connection worked. i dont know what im doing wrong. can anybody help me??? greetings benny From evgeny at digitalfun.ru Tue Aug 26 12:28:24 2003 From: evgeny at digitalfun.ru (Evgeny O. Kochenyuk) Date: Tue, 26 Aug 2003 14:28:24 +0400 Subject: [C++-sig] call_method and reference_existing_object results in "Attempt to return dangling pointer..." Message-ID: <19310635140.20030826142824@digitalfun.ru> Hello c++-sig, I've got a python class method that wraps a c++ function returning class reference(as "reference_existing_object"). When using call_method on it this error message shown: Traceback (most recent call last): File "test_xxx.py", line 6, in ? xxx.call_getValue(T()) ReferenceError: Attempt to return dangling reference to object of type: struct C Here's the code: (Surely a reference on object such as "static C c" can't be "dangling"?) #test_xxx.py#################### import xxx class T: def getValue(self): return xxx.createC() xxx.call_getValue(T()) ##################### //xxx.cpp/////////////// #include using namespace boost::python; struct C{ }; C& createC(){ static C c; return c; } void call_getValue(object o){ call_method(o.ptr(), "getValue"); } BOOST_PYTHON_MODULE(xxx) { class_("C", no_init); def("createC", createC, return_value_policy()); def("call_getValue", call_getValue); } /////////////// -- Best regards, Evgeny mailto:evgeny at digitalfun.ru From dave at boost-consulting.com Tue Aug 26 13:45:56 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Aug 2003 07:45:56 -0400 Subject: [C++-sig] Re: pure virtual methods with pyste References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> <3F4AAE48.8010604@globalite.com.br> <3F4AD07A.5000209@globalite.com.br> Message-ID: Nicodemus writes: > Thanks for the quick fix! > > I am still getting errors thought: > > > Also, shouldn't be included by > ? Please try again, again. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 26 13:51:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Aug 2003 07:51:33 -0400 Subject: [C++-sig] Re: call_method and reference_existing_object results in "Attempt to return dangling pointer..." References: <19310635140.20030826142824@digitalfun.ru> Message-ID: "Evgeny O. Kochenyuk" writes: > Hello c++-sig, > > I've got a python class method that wraps a c++ function returning > class reference(as "reference_existing_object"). When using > call_method on it this error message shown: > > Traceback (most recent call last): > File "test_xxx.py", line 6, in ? > xxx.call_getValue(T()) > ReferenceError: Attempt to return dangling reference to object of type: struct C > > > Here's the code: > (Surely a reference on object such as "static C c" can't be > "dangling"?) It's the enclosing Python object which would be dangling. This is a limitation of Boost.Python at the moment. Please see http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1781761 and http://mail.python.org/pipermail/c++-sig/2003-August/005288.html for a workaround. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Aug 26 17:51:22 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Aug 2003 11:51:22 -0400 Subject: [C++-sig] TODO list Message-ID: I've just checked in a TODO list; see http://www.boost-consulting.com/boost/libs/python/todo.html within the hour. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Aug 27 00:57:58 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 26 Aug 2003 19:57:58 -0300 Subject: [C++-sig] Re: pure virtual methods with pyste In-Reply-To: References: <5999.1059397727@www46.gmx.net> <3F253336.1020806@globalite.com.br> <3F25CC5D.1020800@globalite.com.br> <3F4AAE48.8010604@globalite.com.br> <3F4AD07A.5000209@globalite.com.br> Message-ID: <3F4BE5F6.4030903@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>Thanks for the quick fix! >> >>I am still getting errors thought: >> >> >> > > > >>Also, shouldn't be included by >>? >> >> > >Please try again, again. > Working just fine, thanks! I am about to commit the necessary changes to make Pyste use this facility. Regards, Nicodemus. From dave at boost-consulting.com Wed Aug 27 01:16:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Aug 2003 19:16:12 -0400 Subject: [C++-sig] Re: Interchanging SWIG & Boost bindings. References: Message-ID: Jacek Generowicz writes: > Clearly, the first block of tests (self-consistency) just works. > > The second block (pure Python as receiver) also works, because the > Python implementation of the bar.baz method is happy to receive and > use _any_ object which responds to the "square()" message (signature > polymorphism). > > The remaining blocks fail, however, because the Boost and SWIG > implementations of bar.baz only accept objects of type "C++ foo > wrapped by Boost" and "C++ foo wrapped by SWIG", respectively. > > There are two different issues at play; two different levels at which > one can approach the problem. > > The first is that the Boost and SWIG wrappings do not recognize that > they are actually wrapping the _same_ underlying C++ class. Would it > be possible to make a Boost-wrapped foo look sufficiently like a > SWIG-wrapped foo, in order for the SWIG-wrapped bar.baz to accept it > as an argument, and to know how to access the underlying C++ object You've got to ask the SWIG guys about that part. > (and vice versa)? Yes, the vice versa one we can cover. You just need to register an appropriate lvalue from-Python converter. > I'm thinking along the lines of some converter utility which takes > Boost/SWIG-wrapped objects and transforms them into ones which look > like SWIG/Boost-wrapped ones, _without_ need to re-create the > original bindings. That sentence is meaningless to me, sorry. What's the difference between a Boost/SWIG-wrapped object and a SWIG/Boost-wrapped one? What does "re-create the original bindings" mean? > The second, more general, approach could be to try to loosen the type > checking in the Boost and SWIG wrapped versions, in order to make them > respect signature polymorphism. If you want full signature polymorphism, you should just re-code your C++ functions to use boost::python::object arguments. > The latter is of less direct interest to me, but I suspect that it > might provide a simpler and more general way of achieving the > former. In particular, if we (see below for a brief discussion of > what "we" means) can agree, a priori, on a recommended way of > creating Boost and SWIG bindings in a way that makes them respect > signature polymorphism, later interchangeability comes for free. > > The broader context of my question is the following: It has been > agreed[+] that Python should be used as the scripting language, glue > language, and "softawre bus" of the physics applications used in the > LHC[*] computing project. The number of developers involved is huge; > numerous Python bindings already exist in both Boost and SWIG, as do > long-established (and often unshakeable :-) preferences for one or > other of the two packages. We expect (numerous developers) to create > many new bindings in the near future (using both Boost and SWIG), and > we expect the underlying implementations of these packages to overlap > in some (many) places. > > The end-user Physicists are being encouraged to drive their > applications in Python, with the selling point that they will be able > to access, interactively, all the software that they need, via the > bindings which are being made, and make various disjoint packages talk > to eachother. What we are trying to anticipate (and avoid) is the > situation where an end-user is happily playing with his data in an > interactive session, suddenly to be confronted with the message: > > Type error: Expected _p_Histogram > > when he is passing a histogram to a function which expects a > histogram. If at this point he asks the developers for advice and gets > told that "If you want to get histograms out of package FOO and use > them in package BAR, then you have to wait for the authors of FOO to > to make a second binding of FOO in SWIG ..." (by this time he has > fallen asleep and doesn't hear the rest of the explanation), then that > would be a BAD THING (TM). Understood. > However, if we can offer the response "Just convert your histogram > with the function Boost_to_SWIG before you pass it in" Unlikely to be possible in that direction, unfortunately (though I'm not familiar with SWIG internals). SWIG_to_Boost is not really possible as a Python function either, at least, not without additional arguments. > (or, better still, prevent the situation from arising in the first > place) That one seems more likely to be plausible. > then the incident does not throw a huge spanner in the works. > > So, my questions are (sorry it took so long to get to the point!), is > there any prior art in this area? Not that I know of. > Do you foresee any show-stopping problems? Only the obvious one: we have two really big somewhat independent projects already and those of us who are responsible for them may not have the free time and/or energy to integrate them. > Do you see any obvious ways of doing it? (I haven't looked into the > grubby details myself in depth yet, but I didn't want to find myself > re-inventing the wheel, so I thought I'd ask a broad question early > on.) No, this isn't simple. I can't speak for what it would take to get SWIG to accept Boost.Python-wrapped classes. I can imagine what it would take to get Boost.Python to accept SWIG-wrapped classes; there are a few possible approaches but they'd all require a little research into SWIG. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Aug 27 01:31:22 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Aug 2003 19:31:22 -0400 Subject: [C++-sig] Re: Argument handling, char** in constructor References: Message-ID: Wolfgang Langner writes: > Hello, > > I use boost.python 1.30 with python 2.2.3 under Windows (VC6). > > My python module interfaces to a C++ class that has the following > constructor: > > MyClass(int* argc = 0, char** argv = 0); > > In boost.python I exposed it with: > ... > .def(init >()) > > This works only if I have no arguments. > The problem is, I have to pass arguments from the command line > (called python programm) to the C++ class. (same as in main()) > > First I tried to solve it with a small wrapper class that > inherits from the C++ class and maps a python list of strings > to that interface. But that don't work because the C++ class > is a singleton. > > > Are ther any suggestions to expose this class to python ? Well, what do you expect to be able to pass to this class from Python? There are no built-in conversions from Python to char**. I'm guessing you'd like to write: >>> MyClass(['arg1', 'arg2']) ?? I have an item on the TODO list which should address that need (http://www.boost-consulting.com/boost/libs/python/todo.html#injected-constructors) but I am not precisely sure that it will work for you because of the "singleton" issue. What does that mean in your case? Can MyClass instances be allocated on the heap? -- Dave Abrahams Boost Consulting www.boost-consulting.com From qinlj at solidshare.com Wed Aug 27 04:44:39 2003 From: qinlj at solidshare.com (Lijun Qin) Date: Wed, 27 Aug 2003 02:44:39 -0000 Subject: [C++-sig] Patch to add thread support to invoke function. Message-ID: <001c01c39c31$a36f0b40$0200a8c0@barrack> Hi, I have made some changes to the invoke.hpp file, to add Py_UNBLOCK_THREADS result = f(...); Py_BLOCK_THREADS pair, this is need for too reasons: First, if the f(...) is a lengthy operation, it'll block all Python code to execute, this is not good, second, if f(...) function call some functions that will acquire the python global lock, it'll deadlock, one example is the COM inproc server using Pythoncom22.dll, every COM interface method will first call PyEval_AcquireThread, but the global lock has been held, so deadlock occur. Lijun Qin http://www.solidshare.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: invoke.hpp URL: From wl at flexis.de Wed Aug 27 09:41:39 2003 From: wl at flexis.de (Wolfgang Langner) Date: Wed, 27 Aug 2003 09:41:39 +0200 Subject: [C++-sig] Re: Argument handling, char** in constructor In-Reply-To: References: Message-ID: <3F4C60B3.1060201@flexis.de> David Abrahams wrote: > Wolfgang Langner writes: >>I use boost.python 1.30 with python 2.2.3 under Windows (VC6). >> >>My python module interfaces to a C++ class that has the following >>constructor: >> >>MyClass(int* argc = 0, char** argv = 0); >> >>In boost.python I exposed it with: >> ... >>.def(init >()) >> >>This works only if I have no arguments. >>The problem is, I have to pass arguments from the command line >>(called python programm) to the C++ class. (same as in main()) >> >>First I tried to solve it with a small wrapper class that >>inherits from the C++ class and maps a python list of strings >>to that interface. But that don't work because the C++ class >>is a singleton. >> >> >>Are ther any suggestions to expose this class to python ? > > > Well, what do you expect to be able to pass to this class from Python? > There are no built-in conversions from Python to char**. > > I'm guessing you'd like to write: > > >>> MyClass(['arg1', 'arg2']) > > ?? Yes, that's right. So I have an easy to use interface for the python class. > I have an item on the TODO list which should address that need > (http://www.boost-consulting.com/boost/libs/python/todo.html#injected-constructors) > but I am not precisely sure that it will work for you because of the > "singleton" issue. What does that mean in your case? Can MyClass > instances be allocated on the heap? The item on the TODO list seems to bee usefull for me. I investigate it and read more about the thread. For the singelton issue, I need more time to look at it. It's also possible for me to change the C++ class, because I have the full code (but it's still closed source). The heap allocation is a good idea, I try it. Next days I'm not at work so it can take some time to my next mail. But if there are solutions I mail them. Thank you for your help. bye by Wolfgang From jacek.generowicz at cern.ch Wed Aug 27 10:22:45 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: Wed, 27 Aug 2003 08:22:45 -0000 Subject: [C++-sig] Re: Interchanging SWIG & Boost bindings. References: Message-ID: David Abrahams writes: > Jacek Generowicz writes: > > > The first is that the Boost and SWIG wrappings do not recognize that > > they are actually wrapping the _same_ underlying C++ class. Would it > > be possible to make a Boost-wrapped foo look sufficiently like a > > SWIG-wrapped foo, in order for the SWIG-wrapped bar.baz to accept it > > as an argument, and to know how to access the underlying C++ object > > You've got to ask the SWIG guys about that part. SWIG guys ... I'm asking y'all ! :-) (Yes, I'll approach the SWIG list directly, if there is no response here.) > > (and vice versa)? > > Yes, the vice versa one we can cover. You just need to register an > appropriate lvalue from-Python converter. > > > I'm thinking along the lines of some converter utility which takes > > Boost/SWIG-wrapped objects and transforms them into ones which look > > like SWIG/Boost-wrapped ones, _without_ need to re-create the > > original bindings. > > That sentence is meaningless to me, sorry. What's the difference > between a Boost/SWIG-wrapped object and a SWIG/Boost-wrapped one? Apologies. It's a shorthand which turns out to be useless :-) I meant: ... some converter utility which takes Boost wrapped objects and transforms them into ones which look like SWIG wrapped ones, and vice versa ... > What does "re-create the original bindings" mean? It means, to modify the configuration files (be it SWIG .i files, or the C++ source files which contain boost::python "instructions"), and rebuild the Python extension module. > > However, if we can offer the response "Just convert your histogram > > with the function Boost_to_SWIG before you pass it in" > > Unlikely to be possible in that direction, unfortunately (though I'm > not familiar with SWIG internals). SWIG_to_Boost is not really > possible as a Python function either, at least, not without > additional arguments. And the extra arguments are unlikely to be obvious to your average end-user, I guess ? > > (or, better still, prevent the situation from arising in the first > > place) > > That one seems more likely to be plausible. Would it be based on the principle of "Thou shalt create thy Boost and SWIG bindings according to these guidelines"? or do you imagine it would be possible to provide some means of automatically making existing modules conformant? > > Do you foresee any show-stopping problems? > > Only the obvious one: we have two really big somewhat independent > projects already Actually, _we_ have three projects: we have a "dictionary" package, which fakes-up introspection capablilities in C++, by parsing header files with GCC-XML; via a Python binding to the dictionary we can give Python users access to any C++ objects for which they generate the dictionary. It may not give you the prettiest interface, but you get it almost for free, so it serves a purpose. We'd need this to inteproperate with the other two, but as it is relatively young, we have a fair amount of freedom to adapt it to the demands of Boost and SWIG. From prabhu at aero.iitm.ernet.in Wed Aug 27 10:47:13 2003 From: prabhu at aero.iitm.ernet.in (Prabhu Ramachandran) Date: Wed, 27 Aug 2003 14:17:13 +0530 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. In-Reply-To: References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> <16202.28472.943168.78625@monster.linux.in> Message-ID: <16204.28689.630246.960039@monster.linux.in> >>>>> "DA" == David Abrahams writes: >> If it will help other users in the future I will try and >> summarize this discussion and put it together so it can be part >> of the docs. I personally feel that a high level "how it works >> - with examples" kind of write up would make it easier for >> characters like me to understand what is going on without >> having to dive into the code. If you think this is a good >> idea, I'll try and work on something when I get the time. DA> Yes, please! BTW, I've had several promises of such DA> documentation efforts but so far nobody has had the fortitude DA> to turn my ramblings into a real document... so you could DA> distinguish yourself by following through! OK, I have three hard deadlines coming up so time is short right now (as can be seen from my delayed response) *but* I hope to get something going by September end and something reasonable by mid Oct. One of those deadlines I mentioned above is a lightning talk (10 minutes) I'm planning on giving at SciPy'03 on "Wrapping with SWIG and Boost.Python: a comparison". The emphasis is to provide a basic comparison and feel for wrapping with either tool (nothing too deep or advanced). I'll make those slides also available to the general public once the talk is over. I will also show you the slides *before* I present it so that I don't say something incorrect about Boost.Python. I think that might also prove useful to some users. I know I'm no expert on either tool but I have used both to wrap some non-trivial code. DA> For example, here's something which was supposed to become DA> real documentation: DA> http://www.boost-consulting.com/boost/libs/python/doc/internals.html DA> (it's in your CVS tree). Yes, I looked at it and noticed the messages on the list. My plan is not to go into such depth but to provide a higher level overview. It might even be a repetition of the tutorial with a little more detail but I hope re-reading similar material from different angles with more examples will give users a clearer understanding. [snip] >> As an aside, I think Nicodemus and I would be happy if you did >> run Pyste sometime. :) DA> Yes, so much to do; so little time. I'm interested, but I ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Amen to that! DA> don't see that there would be huge benefits to the community DA> if I did that. Yes, I understand. >> Anyway, here is hopefully a minimal test case for "Problem 1". DA> >> $ python test_bug.py In add_wrapper Segmentation fault [snip] DA> Hmm, but with gcc-2.95.3, I get: DA> In add_wrapper Traceback (most recent call last): DA> File "foo.py", line 12, in ? DA> func(x) DA> AttributeError: 'wrapper_descriptor' object has no attribute DA> 'f' [5464 refs] DA> Hmm, the latter are using Python 2.3; the former using 2.2.2. DA> Which version of Python are you using? Python 2.2.1 (Debian GNU/Linux stable). [snip] DA> Ick. Here's the problem: the "self" pointer is dangling by DA> the time B_Wrapper::f is invoked. This just reinforces my DA> previous conclusion that we need a more formalized way to DA> handle these Wrapper classes, e.g. with a common base class DA> something like this one: [snip] DA> And then we need an adopt policy something like what Daniel DA> Wallin has in luabind, but which is smart enough to detach() DA> all VirtualDispatcher objects. Ahh, I see. So, I'll go over this again. When I do: b = B() h.add(b) del b the Python object holding the B_Wrapper is gone (del b). So B_Wrapper's 'self' member is garbage. This is why I needed to do 'del b' or use 'h.add(B())' to run into the problem. Hmm, I think I can use the VirtualDispatcher idea in my case since AFAIK I simply need to add a detach() call inside the add_wrapper where the ownership is transferred. I'll also have to make the wrapper accept a std::auto_ptr instead of std::auto_ptr. Am I missing a subtle issue here? From what I understand the "adopt policy" will do this in a transparent way at the Boost.Python level. [ call_method and dangling reference problem ] >> Is there an easier way that Boost.Python could handle this >> better? DA> Easier for you; harder for me. I don't have time to solve DA> these problems quickly at a deep level in Boost.Python, at DA> least, not for free ;-) I understand. :) Anyway, I'm not in a big hurry and am hoping these issues will be solved sometime in the future. Till then *my* Boost.Python wrappers will be non-optimal. The trouble is that I have quite a few classes that need to hand off the ownership to a class that looks like the Holder shown in the above. I also will run into problems with the call_method dangling reference problem. Essentially I have about 70 odd classes to wrap (not all of them have the problem, of course!) and don't have the time to hand wrap them all. Yes, I can generate basic wrappers with Pyste and modify them suitably and use the modified wrappers. However, I would like to do this whole thing using Pyste alone which is why I've been banging away at Pyste and bothering Nicodemus so much. This is also a way for me to contribute back to you guys. Essentially, from my efforts so far I have pretty much everything else working except for these two problems (VirtualDispatcher and the call_method dangling reference issue). I might run into more problems but I can't predict those. None of this stuff is urgent, so I can wait. So a humble request. Is there some kind of *approximate* time frame when these two particular issues will be solved? If its not too long I'll wait. If not I'll simply use the current Pyste generated files, modify them by hand (based on your hints) and use the modified files to generate the wrappers. Thanks once again for everything Dave! Nicodemus, thanks for the Pyste support! cheers, prabhu From dave at boost-consulting.com Wed Aug 27 12:55:36 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 27 Aug 2003 06:55:36 -0400 Subject: [C++-sig] Re: Argument handling, char** in constructor References: <3F4C60B3.1060201@flexis.de> Message-ID: Wolfgang Langner writes: > David Abrahams wrote: >> Wolfgang Langner writes: > >>>I use boost.python 1.30 with python 2.2.3 under Windows (VC6). >>> >>>My python module interfaces to a C++ class that has the following >>>constructor: >>> >>>MyClass(int* argc = 0, char** argv = 0); >>> >>>In boost.python I exposed it with: >>> ... >>>.def(init >()) >>> >>>This works only if I have no arguments. >>>The problem is, I have to pass arguments from the command line >>>(called python programm) to the C++ class. (same as in main()) >>> >>>First I tried to solve it with a small wrapper class that >>>inherits from the C++ class and maps a python list of strings >>>to that interface. But that don't work because the C++ class >>>is a singleton. >>> >>> >>>Are ther any suggestions to expose this class to python ? >> Well, what do you expect to be able to pass to this class from >> Python? >> There are no built-in conversions from Python to char**. >> I'm guessing you'd like to write: >> >>> MyClass(['arg1', 'arg2']) >> ?? > Yes, that's right. So I have an easy to use interface for the python class. > >> I have an item on the TODO list which should address that need >> (http://www.boost-consulting.com/boost/libs/python/todo.html#injected-constructors) >> but I am not precisely sure that it will work for you because of the >> "singleton" issue. What does that mean in your case? Can MyClass >> instances be allocated on the heap? > > The item on the TODO list seems to bee usefull for me. > I investigate it and read more about the thread. > > For the singelton issue, I need more time to look at it. > It's also possible for me to change the C++ class, because I have > the full code (but it's still closed source). > The heap allocation is a good idea, I try it. It wasn't a suggestion; I don't see how you'd take advantage of it. I wanted to know because if someone implements the TODO item and you want to use it, you'd need to be able to allocate your class on the heap. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Aug 27 15:22:28 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 27 Aug 2003 10:22:28 -0300 Subject: [C++-sig] Re: Problem: held type, std::auto_ptr, ReferenceErrors. In-Reply-To: <16204.28689.630246.960039@monster.linux.in> References: <16198.17187.178637.207575@monster.linux.in> <16200.19875.951364.329065@monster.linux.in> <16202.28472.943168.78625@monster.linux.in> <16204.28689.630246.960039@monster.linux.in> Message-ID: <3F4CB094.50300@globalite.com.br> Hi Prabhu, Prabhu Ramachandran wrote: >... However, I would like to do >this whole thing using Pyste alone which is why I've been banging away >at Pyste and bothering Nicodemus so much. This is also a way for me >to contribute back to you guys. > Hehehe, please continue to bother me! You've contributed *a lot* to Pyste, and I am thankful for that! ;) Thanks! Nicodemus. From dave at boost-consulting.com Wed Aug 27 16:45:04 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 27 Aug 2003 10:45:04 -0400 Subject: [C++-sig] Re: Interchanging SWIG & Boost bindings. References: Message-ID: Jacek Generowicz writes: >> > Do you foresee any show-stopping problems? >> >> Only the obvious one: we have two really big somewhat independent >> projects already > > Actually, _we_ have three projects: we have a "dictionary" package, > which fakes-up introspection capablilities in C++, by parsing header > files with GCC-XML; via a Python binding to the dictionary we can give > Python users access to any C++ objects for which they generate the > dictionary. It may not give you the prettiest interface, but you get > it almost for free, so it serves a purpose. We'd need this to > inteproperate with the other two, but as it is relatively young, we > have a fair amount of freedom to adapt it to the demands of Boost and > SWIG. Given that we already have Pyste which uses the same strategy perhaps this provides an interesting focal point for integration... -- Dave Abrahams Boost Consulting www.boost-consulting.com From Nedelescu.Marian at draexlmaier.de Thu Aug 28 08:03:59 2003 From: Nedelescu.Marian at draexlmaier.de (Nedelescu Marian PIT) Date: Thu, 28 Aug 2003 08:03:59 +0200 Subject: [C++-sig] Question Message-ID: Hi, Please tell me how can I access (in C++) information from the traceback object obtain after a call of PyErr_Fetch function ? Many thanks, Marian From mike.thompson at day8.com.au Thu Aug 28 10:07:30 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Thu, 28 Aug 2003 18:07:30 +1000 Subject: [C++-sig] STLPort problems Message-ID: I'm getting compile time errors when building Boost.Python using STLport. I'm using the following combination: Python 2.3 Boost 1.30.2 STLport 4.5.3 VC++ 6 on Windows XP Pro These compile time problems (see below) do NOT happen if I remove use of STLport and just use the VC++6 standard libs. When I do that I get a clean compile. To get around the problem, I have tried overnight cvs and I've also tried using the VC6 projects supplied in the distribution. Exactly the same problem each time. No difference. The compile errors occurs on some, but not all, files. Here are the first few error lines when I use 1.30.2 and the supplied VC6 projects: --------------------Configuration: boost_python - Win32 Debug-------------------- Compiling... builtin_converters.cpp C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\../include/new(35) : warning C4290: C++ Exception Specification ignored C:\MEDIAWISE\LIBS\STLPORT-4.5.3\STLPORT\wrap_std/complex(41) : error C2039: 'tan' : is not a member of 'std' C:\MEDIAWISE\LIBS\STLPORT-4.5.3\STLPORT\wrap_std/complex(41) : error C2873: 'tan' : symbol cannot be used in a using-declaration C:\MEDIAWISE\LIBS\STLPORT-4.5.3\STLPORT\wrap_std/complex(42) : error C2039: 'tanh' : is not a member of 'std' C:\MEDIAWISE\LIBS\STLPORT-4.5.3\STLPORT\wrap_std/complex(42) : error C2873: 'tanh' : symbol cannot be used in a using-declaration ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2146: syntax error : missing ',' before identifier 'LONG_LONG' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2065: 'LONG_LONG' : undeclared identifier ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2059: syntax error : '>' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2143: syntax error : missing ';' before '{' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2146: syntax error : missing ',' before identifier 'LONG_LONG' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2144: syntax error : missing ',' before type 'const int' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2990: 'to_python_value' : non-template class has already been defined as a template class ../../../../boost/python/converter/builtin_converters.hpp(33) : see declaration of 'to_python_value' ../../../../boost/python/converter/builtin_converters.hpp(106) : error C2913: explicit specialization; 'struct boost::python::arg_to_python boost::python::arg_to_python' is not a class template ../../../../boost/python/converter/builtin_converters.hpp(106) : see declaration of 'arg_to_python' ../../../../boost/python/converter/builtin_converters.hpp(107) : error C2146: syntax error : missing ',' before identifier 'LONG_LONG' ../../../../boost/python/converter/builtin_converters.hpp(107) : error C2059: syntax error : '>' ../../../../boost/python/converter/builtin_converters.hpp(107) : error C2143: syntax error : missing ';' before '{' ../../../../boost/python/converter/builtin_converters.hpp(107) : error C2146: syntax error : missing ',' before identifier 'LONG_LONG' ...... etc I will now delve deeper, but wanted to make sure I'm not making an obvious mistake. To build, I'm using a batch file like this: rem Get environment right for compiler -- comment out after first run rem "C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" rem Setup for Boost.Python set PYTHON_ROOT=C:\Python23 set PYTHON_VERSION=2.3 rem Setup for Boost 'toolset' set STLPORT_PATH=C:\proj\libs set STLPORT_4.5.3_PATH=C:\proj\libs\STLport-4.5.3 set STLPORT_VERSION=4.5.3 bin.ntx86\bjam "-sTOOLS=msvc-stlport" -- Mike From romany at actimize.com Thu Aug 28 15:39:18 2003 From: romany at actimize.com (Roman Yakovenko) Date: Thu, 28 Aug 2003 16:39:18 +0300 Subject: [C++-sig] Pyste small bug ( very small :-) ). Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0C@exchange.adrembi.com> Hi. Where: file - FunctionExporter class FunctionExporter function GenerateOverloads decl_.maxArgs must be decl.maxArgs Suggestion: PyChecker Roman. From dave at boost-consulting.com Thu Aug 28 16:39:06 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 28 Aug 2003 10:39:06 -0400 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" writes: > To get around the problem, I have tried overnight cvs and I've also tried using > the VC6 projects supplied in the distribution. Exactly the same problem each > time. No difference. > > The compile errors occurs on some, but not all, files. I believe this is an stlport bug. Have you tried with the stlport-0119 "beta"? Boris recommends that one. -- Dave Abrahams Boost Consulting www.boost-consulting.com From romany at actimize.com Thu Aug 28 17:03:27 2003 From: romany at actimize.com (Roman Yakovenko) Date: Thu, 28 Aug 2003 18:03:27 +0300 Subject: [C++-sig] module too big. Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020632@exchange.adrembi.com> Hi. Using Pyste I succedded to generate wrapper for my library. The file I got is 4000 lines. My question is how can I devide this file to a few small ones ? Thanks. Roman From romany at actimize.com Thu Aug 28 17:32:33 2003 From: romany at actimize.com (Roman Yakovenko) Date: Thu, 28 Aug 2003 18:32:33 +0300 Subject: [C++-sig] Pyste - wrong code generation - maybe Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0D@exchange.adrembi.com> Hi. I use Pyste from CVS. I use VC++ 6.0, SP5 The following code produce error on my machine. ( Pyste generates code like this on generating wrappers (in my case). ) I don't know whether it ligal error from compiler or not. I think Dave Abrahams will give the answer in a second. If this legal error then we need to fix pyste. Also I think I can try to fix this. namespace ns { class A { public: virtual int s(){ return 1; } }; } class B : public ns::A { public: virtual int s() { return ns::A::s(); } //<-- error must be A::s }; Roman From romany at actimize.com Thu Aug 28 20:00:49 2003 From: romany at actimize.com (Roman Yakovenko) Date: Thu, 28 Aug 2003 21:00:49 +0300 Subject: [C++-sig] HeldType - class has only non trivial constructor Message-ID: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0E@exchange.adrembi.com> Hi. After a few hours of fight I decided - I need help. Sorry for long posting. Reference to previous thread or solution would be great. In two words the problem is simple. I have based and derived classes with only non trivial constructor( for factory method ). Base class is pure virtual so I have to wrape it and Derived class. And after I do this I've got a compilation error. Here is the code ( after all my English is not my native language ): struct K{}; struct MyBase { MyBase( const K& _k) : {} virtual ~MyBase(){} }; struct MyDerived : public MyBase{ MyDerived( const K& k) : MyBase(k) {} ~MyDerived(){} }; struct MyBase_Wrapper: MyBase { MyBase_Wrapper(PyObject* self_, const K& p0) : MyBase(p0), self(self_) {} PyObject* self; }; struct MyDerived_Wrapper : MyDerived { MyDerived_Wrapper(PyObject* self_, const K& p0) : MyDerived(p0), self(self_) {} PyObject* self; }; BOOST_PYTHON_MODULE(PyDataTypesLib_generated) { class_< K >( "K" )(); class_< MyBase, bases<>, MyBase_Wrapper, boost::noncopyable >("Base", init< const K& >() ); class_< MyDerived, bases< MyBase > , MyDerived_Wrapper >("Derived", init< const K& >() ); } As you may guess I can't compile this code ( MSVC 6.0 SP5 ). The error is: cannot convert parameter 2 from 'const struct MyDerived' to 'const struct K &' The struct make_instance is instantiated (in case MyDerived ) with arguments MyDerived and MyDerived_Wrapper. I just do know what I have to do in order write the wrapper. Some hint ? Thanks for the help. Roman From dave at boost-consulting.com Thu Aug 28 20:58:47 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 28 Aug 2003 14:58:47 -0400 Subject: [C++-sig] Re: HeldType - class has only non trivial constructor References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0E@exchange.adrembi.com> Message-ID: "Roman Yakovenko" writes: > As you may guess I can't compile this code ( MSVC 6.0 SP5 ). > The error is: cannot convert parameter 2 from 'const struct MyDerived' to 'const struct K &' > The struct make_instance is instantiated (in case MyDerived ) with arguments > MyDerived and MyDerived_Wrapper. I just do know what I have to do in order > write the wrapper. Some hint ? MyDerived needs boost::noncopyable as it is, well, non-copyable. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Fri Aug 29 00:28:30 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 28 Aug 2003 19:28:30 -0300 Subject: [C++-sig] Pyste small bug ( very small :-) ). In-Reply-To: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0C@exchange.adrembi.com> References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0C@exchange.adrembi.com> Message-ID: <3F4E820E.7030305@globalite.com.br> Roman Yakovenko wrote: >Hi. > >Where: file - FunctionExporter > class FunctionExporter > function GenerateOverloads > decl_.maxArgs must be decl.maxArgs > > > Thanks for the report Roman, sorry about that. ;) Regards, Nicodemus. From nicodemus at globalite.com.br Fri Aug 29 01:05:30 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 28 Aug 2003 20:05:30 -0300 Subject: [C++-sig] module too big. In-Reply-To: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020632@exchange.adrembi.com> References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5020632@exchange.adrembi.com> Message-ID: <3F4E8ABA.4090208@globalite.com.br> Hi Roman, Roman Yakovenko wrote: >Hi. Using Pyste I succedded to generate wrapper for my library. >The file I got is 4000 lines. My question is how can I devide >this file to a few small ones ? > > The support for big wrappers has improved a lot in the last few weeks, thanks to a combinated effort of Prabhu Ramachandran and myself. We discussed a lot, shared lots of code, and came up with a solution that he and I are quite happy with it. 8) I didn't write the documentation about it, thought, so I will describe the procedure here. Let's use this class hierarchy as an example: // A.h struct A { /* ... */ }; // B.h #include "A.h" struct B: A { /* ... */ }; // C.h #include "B.h" struct C: B { /* ... */ }; First thing, you must divide your classes in multiple Pyste files. Mind you, Boost.Python needs base classes to be instantiated before derived classes, and Pyste did that automatically for you, but not anymore, so you have to do it by hand. Let's write one Pyste file for our library then: # mylib.pyste Class("A", "A.h") Class("B", "B.h") Class("C", "C.h") Notice that the base class, A, has been declared first. This is the simplest usage. We use this command line: pyste.py --module=mylib mylib.pyste This will generate a file named "mylib.cpp" in the current directory with all the classes exported. Now suppose this file is too big (as is your case) and it takes ages to compile, plus after any little change you do in both your code or the Pyste file you will have to re-generate the wrapper code (which can take a while) and recompile it (which taks *quite* a while 8) ). The first step to solve this problem is to split your classes in multiple Pyste files. Here, let's put A and B in their own Pyste file (AB.pyste), and put C in another (C.pyste). But we have to declare also that C.pyste depends on AB.pyste, so that Pyste knows that A and B are also being exported to generate the correct code. Here are the contents of then: # AB.pyste Class("A", "A.h") Class("B", "B.h") # C.pyste Import("AB.pyste") # that's how we declare the dependency Class("C", "C.h") Ok, now we have to generate the code. You use the --multiple flag to specify that your are sharing your wrapping code across multiple cpp files: pyste.py --multiple --module=mylib AB.pyste This will generate the file mylib/_AB.cpp. pyste.py --multiple --module=mylib C.pyste This will generate the file mylib/_C.cpp. Those files contain the definition of the classes, but they don't declare BOOST_PYTHON_MODULE. This is done in a separate file, that you create with this command line: pyste.py --multiple --module=mylib --generate-main AB.pyste C.pyste This will generate the file mylib/_main.cpp. To correctly generate it, you have to pass in the command line *all* the Pyste files of your library. Fortunately, the generation of this file is almost instantly. ;) Now, we have in the mylib folder all the files needed by our library: _AB.cpp _C.cpp _main.cpp You now just compile them all normaly to object files, and link them all together. You will have an extension module as before, but with a few advantages: * If you change a header file used by a Pyste file, only the corresponding cpp of that Pyste file will have to be regenerated and recompiled, the rest stays intact. * Compile time will normally be reduced, since with very big files the memory consumption by the compiler gets out of hand. There's a feature that will also speed-up the re-generation of the wrappers (not compilation), the possibility to create Pyste caches. You just have to add a new option to the command lines above: "--cache-dir=". In the directory specified, Pyste will cache the output by GCCXML, which should give a boost of about 3 to 4 times over the normal usage. Example: pyste.py --multiple --module=mylib --cache-dir=cache C.pyste This will generate, besides mylib/_C.cpp, a file named cache/C.pystec. The next time you run this same command, it should create the wrappers much quicker than before. But note that C.pystec depends on all the headers of the declarations in C.pyste, so if you change C.h, you should re-generate the cache. You can either delete C.pystec, or run: pyste.py --multiple --module=mylib --cache-dir=cache --only-create-cache C.pyste This will recreate the C.pystec file, but will not generate any wrapper code. Whew! Hope that gets you moving! 8) Feel free to ask any questions you may have! Regards, Nicodemus. From nicodemus at globalite.com.br Fri Aug 29 01:29:15 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 28 Aug 2003 20:29:15 -0300 Subject: [C++-sig] Pyste - wrong code generation - maybe In-Reply-To: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0D@exchange.adrembi.com> References: <91BFE89EFFA2904E9A4C3ACB4E5F2DF5027B0D@exchange.adrembi.com> Message-ID: <3F4E904B.4050309@globalite.com.br> Roman Yakovenko wrote: >Hi. I use Pyste from CVS. I use VC++ 6.0, SP5 > >The following code produce error on my machine. >( Pyste generates code like this on generating wrappers (in my case). ) > >I don't know whether it ligal error from compiler or not. >I think Dave Abrahams will give the answer in a second. >If this legal error then we need to fix pyste. >Also I think I can try to fix this. > > >namespace ns >{ > >class A >{ >public: > virtual int s(){ return 1; } > >}; > >} > >class B : public ns::A >{ >public: > virtual int s() > { return ns::A::s(); } //<-- error must be A::s >}; > > Works fine for me with Intel C++ 6. I think it is a bug with VC 6, because the code seems legal. I'm sure Dave can supply more info. Regards, Nicodemus. From mike.thompson at day8.com.au Fri Aug 29 06:36:44 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Fri, 29 Aug 2003 14:36:44 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "David Abrahams" wrote in message news:uhe41n8xh.fsf at boost-consulting.com... > "Mike Thompson" writes: > > > To get around the problem, I have tried overnight cvs and I've also tried using > > the VC6 projects supplied in the distribution. Exactly the same problem each > > time. No difference. > > > > The compile errors occurs on some, but not all, files. > > I believe this is an stlport bug. Have you tried with the > stlport-0119 "beta"? Boris recommends that one. > Okay, I've download STLport-4.5-0119 and while it takes away the first (tan() and tanh() issues), there are still other problems. I've made some adjustments to the overnight cvs HEAD of boost, so I can get a clean compile. Here's what I had to do: 1. python\src\converter\builtin_converters.hpp I had to add a new #define for LONG_LONG at line 106. Code now looks like this: // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. # ifdef HAVE_LONG_LONG #define LONG_LONG PY_LONG_LONG // <------ ADDED THIS LINE ------------ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x)) # endif The missing definition of LONG_LONG caused compile time errors in builtin_converters.cpp at lines 174 and 353. Because HAVE_LONG_LONG is defined in PyConfig.h, I've defined LONG_LONG using Python's concept of long long from the same PyConfig.h. I have no idea if that's correct and general. 2. python\src\object\enum.cpp Under VC6 and STLport, fprintf() ends up in the global namespace, so line 48 becomes: fprintf(fp, text); instead of: BOOST_CSTD_::fprintf(fp, text); 3. python\src\object\function.cpp Under VC6 and STLport, strcmp() ends up in the global namespace, so line 20 becomes: return strcmp(x,y) < 0; instead of: return BOOST_CSTD_::strcmp(x,y) < 0; Hacks 2 and 3 above are obviously not general solutions, but I'd be very happy to test any changes you want to make to CVS HEAD. I'm now going to figure out how to run the unit tests, to check if I've broken anything. HTH -- Mike From mike.thompson at day8.com.au Fri Aug 29 06:48:59 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Fri, 29 Aug 2003 14:48:59 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" wrote: > > I've made some adjustments to the overnight cvs HEAD of boost, so I can get a > clean compile. > I mean, of course, that I've made changes to MY local copy. -- Mike From mike.thompson at day8.com.au Fri Aug 29 10:20:10 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Fri, 29 Aug 2003 18:20:10 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" wrote in message news:biml94$f9q$1 at sea.gmane.org... > > "David Abrahams" wrote in message > news:uhe41n8xh.fsf at boost-consulting.com... > > "Mike Thompson" writes: > > > > > To get around the problem, I have tried overnight cvs and I've also tried > using > > > the VC6 projects supplied in the distribution. Exactly the same problem > each > > > time. No difference. > > > > > > The compile errors occurs on some, but not all, files. > > > > I believe this is an stlport bug. Have you tried with the > > stlport-0119 "beta"? Boris recommends that one. > > > > Okay, I've download STLport-4.5-0119 and while it takes away the first (tan() > and tanh() issues), there are still other problems. > > I've made some adjustments to the overnight cvs HEAD of boost, so I can get a > clean compile. > > Here's what I had to do: > > 1. python\src\converter\builtin_converters.hpp > > I had to add a new #define for LONG_LONG at line 106. Code now looks > like this: > // using Python's macro instead of Boost's - we don't seem to > get the > // config right all the time. > # ifdef HAVE_LONG_LONG > #define LONG_LONG PY_LONG_LONG // > <------ ADDED THIS LINE ------------ > BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, > PyLong_FromLongLong(x)) > BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, > PyLong_FromUnsignedLongLong(x)) > # endif > > The missing definition of LONG_LONG caused compile time errors in > builtin_converters.cpp at lines 174 and 353. > > Because HAVE_LONG_LONG is defined in PyConfig.h, I've defined > LONG_LONG using > Python's concept of long long from the same PyConfig.h. I have no > idea if that's correct and general. > > 2. python\src\object\enum.cpp > > Under VC6 and STLport, fprintf() ends up in the global namespace, so > line 48 becomes: > fprintf(fp, text); > instead of: > BOOST_CSTD_::fprintf(fp, text); > > > 3. python\src\object\function.cpp > > Under VC6 and STLport, strcmp() ends up in the global namespace, so > line 20 becomes: > return strcmp(x,y) < 0; > instead of: > return BOOST_CSTD_::strcmp(x,y) < 0; > > > Hacks 2 and 3 above are obviously not general solutions, but I'd be very happy > to test any changes you want to make to CVS HEAD. > More information: 1. There is a new beta release of SLTport - version 4.5-0725. Its not shown on their home page but its announced and is available at http://www.stlport.com/beta/ I'm now using this version. 2. Ignore hack #1 above. I was, in fact, working with boost 1.30.2 when I made these changes and when I realised this and went to work with overnight cvs, I found this problem had already been fixed. 3. Problems 2 and 3 arise because I've choosen to use STLport with the native VC6 iostreams library. I.e. I've got the following major configuration switch set (in stl_user_config.h) #define _STLP_NO_OWN_IOSTREAMS 1 When I disable this switch (and use STLport's iostream implementation) then no compilation problems at all. Everything is fine. However, if I use native (VC6) iostream and STLPort then I get problems 2 and 3 described before PLUS some new compilation erros because I'm now actually using boost HEAD (and not 1.30.2). These new compilation problems all relate to the used of 'complex' and Boost.Python's belief that its in std. I'll detail them soon. I just wanted to write a quick update before dinner, just in case anyone spend any time on this. -- Mike From mike.thompson at day8.com.au Fri Aug 29 14:18:36 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Fri, 29 Aug 2003 22:18:36 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" wrote: > I'm getting compile time errors when building Boost.Python > using STLport. > Okay. After far too long, this all seems to be down to two isses: 1. A problem with Python2.3 and Boost 1.30.2 which now appears fixed in cvs HEAD. See my previous posts for details of the missing #define for LONG_LONG. 2. As suggested by David, there is an STLport bug. Its been around for a while but has not been fixed in the latest beta snapshots. I've raised the following bug report as a further prompter: http://www.stlport.com/dcforum/DCForumID6/1364.html NB: The bug is ONLY triggered when you use STLport with the "I'll use native iostream library" switch on STLport. -- Mike From dave at boost-consulting.com Fri Aug 29 14:43:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 29 Aug 2003 08:43:35 -0400 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" writes: > "Mike Thompson" wrote: >> I'm getting compile time errors when building Boost.Python >> using STLport. >> > > Okay. After far too long, this all seems to be down to two isses: > > 1. A problem with Python2.3 and Boost 1.30.2 which now appears > fixed in cvs HEAD. See my previous posts for details of the > missing #define for LONG_LONG. > > 2. As suggested by David, there is an STLport bug. Its been around > for a while but has not been fixed in the latest beta snapshots. > I've raised the following bug report as a further prompter: > http://www.stlport.com/dcforum/DCForumID6/1364.html > > NB: The bug is ONLY triggered when you use STLport with the "I'll > use > native iostream library" switch on STLport. Mike, STLPort "native iostreams" are a hack, and I'm inclined not to support them. Lots of subtle things don't work right because you can't make the fact that they're in a different namespace truly invisible. If there's a small patch needed to get your stuff going, and you post it, I'll probably be willing to apply it. Can you use STLPort iostreams instead? -- Dave Abrahams Boost Consulting www.boost-consulting.com From mike.thompson at day8.com.au Fri Aug 29 14:52:23 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Fri, 29 Aug 2003 22:52:23 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" wrote in message news:bingb7$39a$1 at sea.gmane.org... > > "Mike Thompson" wrote: > > I'm getting compile time errors when building Boost.Python > > using STLport. > > > > Okay. After far too long, this all seems to be down to two isses: > > 1. A problem with Python2.3 and Boost 1.30.2 which now appears > fixed in cvs HEAD. See my previous posts for details of the > missing #define for LONG_LONG. > > 2. As suggested by David, there is an STLport bug. Its been around > for a while but has not been fixed in the latest beta snapshots. > I've raised the following bug report as a further prompter: > http://www.stlport.com/dcforum/DCForumID6/1364.html > > NB: The bug is ONLY triggered when you use STLport with the "I'll > use > native iostream library" switch on STLport. > Arrgh. Its getting late and I'm getting forgetful. This post was mean to be a summary but I forgot to mention in point 2. that strcpy() and fprintf() do not end up in std:: either and are put in global namespace. I had to hack Python.Boost to get this to work with STLport. (see previous post) AND .... I also had problems trying to use a version of STLport other than 4.5.3. I followed all the instructions I swear, but the build system always wanted to #include from the folder stlport4.5.3\stlport (rather than from a sister folder like stlport4.5-0725). I tried to track this down through the jam files but they meant little to me and I gave up. -- Mike From dave at boost-consulting.com Fri Aug 29 18:13:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 29 Aug 2003 12:13:38 -0400 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" writes: > "Mike Thompson" wrote in message > news:bingb7$39a$1 at sea.gmane.org... >> >> "Mike Thompson" wrote: >> > I'm getting compile time errors when building Boost.Python >> > using STLport. >> > >> >> Okay. After far too long, this all seems to be down to two isses: >> >> 1. A problem with Python2.3 and Boost 1.30.2 which now appears >> fixed in cvs HEAD. See my previous posts for details of the >> missing #define for LONG_LONG. >> >> 2. As suggested by David, there is an STLport bug. Its been around >> for a while but has not been fixed in the latest beta snapshots. >> I've raised the following bug report as a further prompter: >> http://www.stlport.com/dcforum/DCForumID6/1364.html >> >> NB: The bug is ONLY triggered when you use STLport with the "I'll >> use >> native iostream library" switch on STLport. >> > > Arrgh. Its getting late and I'm getting forgetful. > > This post was mean to be a summary but I forgot to mention in point 2. that > strcpy() and fprintf() do not end up in std:: either and are put in global > namespace. I had to hack Python.Boost to get this to work with STLport. (see > previous post) > > AND .... > > I also had problems trying to use a version of STLport other than 4.5.3. I > followed all the instructions I swear, but the build system always wanted to > #include from the folder stlport4.5.3\stlport (rather than from a sister folder > like stlport4.5-0725). I tried to track this down through the jam files but > they meant little to me and I gave up. Mike, This stuff all works fine for me with no patches to anythin. My relevant settings are: set STLPORT_PATH=c:\src\STLPort set STLPORT_4.5.3_PATH=c:\src\STLPort\STLPort-4.5-0119 I invoke bjam with "-sBUILD=debug-python on" when I run the tests. Everything gets put/accessed in the appropriate namespace(s). -- Dave Abrahams Boost Consulting www.boost-consulting.com From langston at SLAC.Stanford.EDU Sat Aug 30 01:53:50 2003 From: langston at SLAC.Stanford.EDU (Langston, Matthew David) Date: Fri, 29 Aug 2003 16:53:50 -0700 Subject: [C++-sig] undefined symbol "typeinfo for boost::python::instance_holder" un der Linux/RH9 Message-ID: <26E3EC48949D134C94A1574B2C89466117546B@exchange2.slac.stanford.edu> I've built a Boost.Python module (from boost 1.30.0) that I want to link statically against libboost_python.a. This works fine under Windows and cl, but doesn't work under Linux (RedHat 9) and gcc 3.2.2. When I import my statically linked module under python (i.e. "import ntuple"), I get this error: ImportError: /work/langston/projects/build/NTuple_static/NTuple/.libs/ntuplemodule.so: undefined symbol: _ZTIN5boost6python15instance_holderE The gcc demangler (c++filt) says this symbol is: "typeinfo for boost::python::instance_holder" FYI, I am defining BOOST_PYTHON_STATIC_LIB when try to statically link to Boost.Python. Also, when I dynamically link to Boost.Python everything works fine (on both Windows and Linux). Why doesn't statically linking to Boost.Python work under Linux/gcc? Thank you for your help. Warmest regards, Matt -- Matthew D. Langston, Ph.D. GLAST, Stanford Linear Accelerator Center langston at SLAC.Stanford.EDU From patrick at vrac.iastate.edu Sat Aug 30 04:37:18 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 29 Aug 2003 21:37:18 -0500 Subject: [C++-sig] Unresolved external symbols with Visual C++ 7.0 and 7.1 Message-ID: <3F500DDE.4050404@vrac.iastate.edu> I am having a really hard time trying to get my Boost.Python-based module to compile on Windows using Visual C++ 7.0 or 7.1. Everything is fine with GCC and MIPSpro, but with Visual C++, I get linker errors about three missing symbols. I have attached a file that demonstrates the linker error, but it only shows one of the unresolved symbols: test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::python::api::object __cdecl boost::python::objects::function_object(class boost::function2 > const &,unsigned int,struct std::pair const &)" (__imp_?function_object at objects@python at boost@@YA?AVobject at api@23 at ABV?$function2 at PAU_object@@PAU1 at PAU1@V?$allocator at Vfunction_base@boost@@@std@@@3 at IABU?$pair at PBUkeyword@detail at python@boost@@PBU1234@@std@@@Z) referenced in function "class boost::python::api::object __cdecl boost::python::detail::make_function_aux,struct boost::mpl::int_<0> >(void (__cdecl*)(struct _object *),struct boost::python::default_call_policies const &,struct boost::python::detail::args_from_python const &,struct boost::mpl::list2 const &,struct std::pair const &,struct boost::mpl::int_<0>)" (??$make_function_aux at P6AXPAU_object@@@ZUdefault_call_policies at python@boost@@Uargs_from_python at detail@34 at U?$list2 at XPAU_object@@@mpl at 4@U?$int_@$0A@@84@@detail at python@boost@@YA?AVobject at api@12 at P6AXPAU_object@@@ZABUdefault_call_policies at 12@ABUargs_from_python at 012@ABU?$list2 at XPAU_object@@@mpl at 2@ABU?$pair at PBUkeyword@detail at python@boost@@PBU1234@@std@@U?$int_@$0A@@92@@Z) If I defined and expose methods from the class to Python, I could get the number of unresolved symbols goes up to three. However, I suspect that if I can figure out what is going wrong that causes the above error, I will be able to fix the other two unresolved symbols as well. I based my compiler and linker commands on the output from running jam with the -n option, as suggested by the documentation: cl /nologo /TP /Zm800 /GR /GX /Z7 /Od /Ob0 /GX /GR /MDd /IC:\cygwin\home\patrick\bpl-vc71\include /IC:\Python22\include /I. /c test.cpp link /nologo/DEBUG /subsystem:console /incremental:no /dll /out:test.pyd /implib:test.lib /LIBPATH:C:\cygwin\home\patrick\bpl-vc71\lib /LIBPATH:C\Python22\libs boost_python.lib test.obj What I am missing or doing wrong? -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.cpp URL: From dave at boost-consulting.com Sat Aug 30 04:44:21 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 29 Aug 2003 22:44:21 -0400 Subject: [C++-sig] Re: Unresolved external symbols with Visual C++ 7.0 and 7.1 References: <3F500DDE.4050404@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > I based my compiler and linker commands on the output from running jam > with the -n option, as suggested by the documentation: > > cl /nologo /TP /Zm800 /GR /GX /Z7 /Od /Ob0 /GX /GR /MDd > /IC:\cygwin\home\patrick\bpl-vc71\include /IC:\Python22\include /I. /c > test.cpp > > link /nologo/DEBUG /subsystem:console /incremental:no /dll > /out:test.pyd /implib:test.lib > /LIBPATH:C:\cygwin\home\patrick\bpl-vc71\lib /LIBPATH:C\Python22\libs > boost_python.lib test.obj > > What I am missing or doing wrong? Probably just that you're not precisely duplicating what bjam does. Have you checked that carefully? I can't imagine it failing to make a module that simple work, since I do it just about every day. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Aug 30 04:47:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 29 Aug 2003 22:47:53 -0400 Subject: [C++-sig] Re: undefined symbol "typeinfo for boost::python::instance_holder" un der Linux/RH9 References: <26E3EC48949D134C94A1574B2C89466117546B@exchange2.slac.stanford.edu> Message-ID: "Langston, Matthew David" writes: > Why doesn't statically linking to Boost.Python work under Linux/gcc? > Thank you for your help. Not using bjam is usually the explanation for this sort of problem, but it could just as easily be a compiler bug. How are you doing the build? Did you build a static version of Boost.Python to link to (libboost_python.a)? -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Sat Aug 30 15:17:45 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Sat, 30 Aug 2003 14:17:45 +0100 Subject: [C++-sig] Re: Adding __len__ to range objects References: <021801c3659d$5190a290$64646464@godzilla> <003d01c36682$5ec55c40$0100a8c0@godzilla> <00d101c36adb$0087aea0$64646464@godzilla> <004a01c36b0c$cf71b0e0$50a245ca@godzilla> Message-ID: "Joel de Guzman" writes: > Raoul Gough wrote: [snip] >> I think that means that raw C++ code that modifies the container >> would cause problems. > > Yes, I am aware of that. That's a caveat. Before, the indexing_suite > goes public, I have to provide a notification function that one needs > to call in such cases. Right now, I am not sure about its interface. Maybe using the container wrapper (below) would solve this problem fairly neatly, since the C++ code has full access to the wrapped container. > >> So what do you think of the idea of providing a proxy-container- >> wrapper, instead of integrating the proxy support directly into the >> indexing suite? C++ code would then be aware (and have direct >> access to) the wrapped container, and it might significantly >> simplify the internals of the indexing suite. > > Looks like a good idea. Feel free to try it out. I'm all for further > refactoring. Well, I've had a go anyway. I've produced a container_proxy template that wraps a random-access container and provides access via element proxies. The element proxies provide an implicit conversion to the raw value type, and also a constructor from the raw value type, which means that it works with an unchanged[*1] vector_indexing_suite as follows: vector_indexing_suite, true> i.e. the wrapped vector with no proxy. This is functionally more or less equivalent to vector_indexing_suite, i.e. the raw vector *with* the proxy helper. [*1] Actually, it does require a minor patch to make vector_indexing_suite use the container's reference typedef rather than data_type & Note that I say "more or less" equivalent, since there seems to be a bug in the existing proxy support. Using vector, where IntWrapper is a simple int holder with optional tracing, the following snippet doesn't work correctly: copy = v[1] print "copy is %s, v[1] is %s" % (copy, v[1]) v[1] = IntWrapper (5) print "copy is %s, v[1] is %s" % (copy, v[1]) Sample output: copy is 3, v[1] is 3 copy is 5, v[1] is 5 # Wrong - copy should remain unchanged The container_proxy wrapper fixes that problem (whatever it is, probably minor) but doesn't fix the following additional problem, that both versions exhibit: slice = v[1:2] print "slice[0] is %s, v[1] is %s" % (slice[0], v[1]) v[1].increment() print "slice[0] is %s, v[1] is %s" % (slice[0], v[1]) Sample output: slice[0] is 5, v[1] is 5 slice[0] is 5, v[1] is 6 # Should be slice[0] is 6, v[1] is 6 This may be a fundamental problem with how slices are returned. Compiler is gcc 3.3.1 (mingw special 20030804-1). Anyway, new code is available from my website: http://home.clara.net/raoulgough/boost/release.tar.gz I'll have another go at updating the boost-sandbox when possible (forgetting about my earlier botched attempts). Ultimately, it would be good to do away with the implicit conversions that the element proxy provides, but I'm not sure that this is doable (and would certainly require special case code in the interfacing suite). -- Raoul Gough. (setq dabbrev-case-fold-search nil) From patrick at vrac.iastate.edu Sat Aug 30 17:32:36 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Sat, 30 Aug 2003 10:32:36 -0500 Subject: [C++-sig] Re: Unresolved external symbols with Visual C++ 7.0 and 7.1 In-Reply-To: References: <3F500DDE.4050404@vrac.iastate.edu> Message-ID: <3F50C394.1020401@vrac.iastate.edu> David Abrahams wrote: > Patrick Hartling writes: > > >>I based my compiler and linker commands on the output from running jam >>with the -n option, as suggested by the documentation: >> >>cl /nologo /TP /Zm800 /GR /GX /Z7 /Od /Ob0 /GX /GR /MDd >>/IC:\cygwin\home\patrick\bpl-vc71\include /IC:\Python22\include /I. /c >>test.cpp >> >>link /nologo/DEBUG /subsystem:console /incremental:no /dll >>/out:test.pyd /implib:test.lib >>/LIBPATH:C:\cygwin\home\patrick\bpl-vc71\lib /LIBPATH:C\Python22\libs >>boost_python.lib test.obj >> >>What I am missing or doing wrong? > > > Probably just that you're not precisely duplicating what bjam does. > Have you checked that carefully? Upon closer inspection, I found that, in spite of my best efforts, there was a mismatch between the compiler versions. That is, Visual C++ 7.1 was being used to link against a Boost.Python build created with Visual C++ 7.0. There is some path mangling happening somewhere that I need to track down. Sorry for the noise. > I can't imagine it failing to make a module that simple work, since I > do it just about every day. That's why I've been feeling so frustrated. :) -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ From langston at SLAC.Stanford.EDU Sun Aug 31 02:59:17 2003 From: langston at SLAC.Stanford.EDU (Langston, Matthew David) Date: Sat, 30 Aug 2003 17:59:17 -0700 Subject: [C++-sig] RE: undefined symbol "typeinfo for boost::python::instance_holder " under Linux/RH9 Message-ID: <26E3EC48949D134C94A1574B2C89466117546D@exchange2.slac.stanford.edu> Hi Dave, Under Linux I simply did a bjam "-sTOOLS=gcc", which created boost/libs/python/build/bin-stage/libboost_python.a which bjam appears to have copied (based on file sizes) from boost/libs/python/build/bin/libboost_python.a/gcc/release/runtime-link-dynamic/libboost_python.a So, I assume bjam built everything properly. What else to try? Are you saying that statically linking to libboost_python.a on linux/gcc should work? I am using boost 1.30.0, so would upgrading to 1.30.2 maybe help? -Matt "Langston, Matthew David" writes: > Why doesn't statically linking to Boost.Python work under Linux/gcc? > Thank you for your help. Not using bjam is usually the explanation for this sort of problem, but it could just as easily be a compiler bug. How are you doing the build? Did you build a static version of Boost.Python to link to (libboost_python.a)? From mike.thompson at day8.com.au Sun Aug 31 15:46:19 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Sun, 31 Aug 2003 23:46:19 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "David Abrahams" wrote: > > "Mike Thompson" wrote: > > > > I also had problems trying to use a version of STLport other than 4.5.3. I > > followed all the instructions I swear, but the build system always wanted to > > #include from the folder stlport4.5.3\stlport (rather than from a sister folder > > like stlport4.5-0725). I tried to track this down through the jam files but > > they meant little to me and I gave up. > > > Mike, > > This stuff all works fine for me with no patches to anythin. My > relevant settings are: > > set STLPORT_PATH=c:\src\STLPort > set STLPORT_4.5.3_PATH=c:\src\STLPort\STLPort-4.5-0119 > > I invoke bjam with "-sBUILD=debug-python on" when I > run the tests. Everything gets put/accessed in the appropriate > namespace(s). > Sorry David, I fear I've wasted your time here. I was using the latest STLport beta snapshot (version 4.5-0725), and I believe my settings were: set STLPORT_PATH=C:\proj\libs set STLPORT_4.5-0725_PATH=C:\proj\libs\STLport-4.5-0725 set STLPORT_VERSION=4.5-0725 Except, of course, now I find that this arrangement works just fine. So, after a bit of thought ..... I'm thinking that perhaps my problem was caused by the collision of the following: 1. Perhaps I didn't have STLPORT_VERSION set (meaning it defaulted to 4.5.3) 2. I had one piece of residual environment hanging around from earlier experiements with version 4.5.3 viz: set STLPORT_4.5.3_PATH=C:\proj\libs\STLport-4.5.3 in that case the: set STLPORT_4.5-0725_PATH=C:\proj\libs\STLport-4.5-0725 would not get used and instead bjam would used the residual: set STLPORT_4.5.3_PATH=C:\proj\libs\STLport-4.5.3 All seems so clear now. Arrgh. Sorry again to send you on a wild goose chase. I did notice one further thing in all this experiementing though. Even when the stlport version was set at 4.5-0725, the library was created in a folder with the name 'stlport-version-4.5.3'. I.e. something like ........\libs\python\build\bin\libboost_python.lib\msvc-stlport\debug\runtime-l ink-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5. 3 Is this correct? I would have expected it to be a folder called 'stlport-version-4.5-0725' -- Mike From mike.thompson at day8.com.au Sun Aug 31 15:54:15 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Sun, 31 Aug 2003 23:54:15 +1000 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "David Abrahams" wrote in message news:usmnkeirs.fsf at boost-consulting.com... > "Mike Thompson" writes: > > > "Mike Thompson" wrote: > >> I'm getting compile time errors when building Boost.Python > >> using STLport. > >> > > > > Okay. After far too long, this all seems to be down to two isses: > > > > 1. A problem with Python2.3 and Boost 1.30.2 which now appears > > fixed in cvs HEAD. See my previous posts for details of the > > missing #define for LONG_LONG. > > > > 2. As suggested by David, there is an STLport bug. Its been around > > for a while but has not been fixed in the latest beta snapshots. > > I've raised the following bug report as a further prompter: > > http://www.stlport.com/dcforum/DCForumID6/1364.html > > > > NB: The bug is ONLY triggered when you use STLport with the "I'll > > use > > native iostream library" switch on STLport. > > Mike, > > STLPort "native iostreams" are a hack, and I'm inclined not to support > them. Lots of subtle things don't work right because you can't make > the fact that they're in a different namespace truly invisible. If > there's a small patch needed to get your stuff going, and you post it, > I'll probably be willing to apply it. Can you use STLPort iostreams > instead? > I can't see any quick patch which might get STLport "native iostreams" working with Boost.Python. A broken in STLport breaks a bit too much of boost, and fixing doesn't look easy. I'll now investigate using STLPort iostreams instead. Many thanks. P.S. If its not supported -- and I can now see why -- I wonder if Boost.Python should produce an #error if someone (like me) tries to go down the "native iostreams" path? -- Mike From dave at boost-consulting.com Sun Aug 31 21:49:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 31 Aug 2003 15:49:35 -0400 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" writes: > "David Abrahams" wrote in message > news:usmnkeirs.fsf at boost-consulting.com... >> "Mike Thompson" writes: >> >> > "Mike Thompson" wrote: >> >> I'm getting compile time errors when building Boost.Python >> >> using STLport. >> >> >> > >> > Okay. After far too long, this all seems to be down to two isses: >> > >> > 1. A problem with Python2.3 and Boost 1.30.2 which now appears >> > fixed in cvs HEAD. See my previous posts for details of the >> > missing #define for LONG_LONG. >> > >> > 2. As suggested by David, there is an STLport bug. Its been around >> > for a while but has not been fixed in the latest beta snapshots. >> > I've raised the following bug report as a further prompter: >> > http://www.stlport.com/dcforum/DCForumID6/1364.html >> > >> > NB: The bug is ONLY triggered when you use STLport with the > "I'll >> > use >> > native iostream library" switch on STLport. >> >> Mike, >> >> STLPort "native iostreams" are a hack, and I'm inclined not to support >> them. Lots of subtle things don't work right because you can't make >> the fact that they're in a different namespace truly invisible. If >> there's a small patch needed to get your stuff going, and you post it, >> I'll probably be willing to apply it. Can you use STLPort iostreams >> instead? >> > > I can't see any quick patch which might get STLport "native iostreams" working > with Boost.Python. A broken in STLport breaks a bit too much of > boost, and fixing doesn't look easy. > > I'll now investigate using STLPort iostreams instead. > > Many thanks. > > P.S. If its not supported -- and I can now see why -- I wonder if Boost.Python > should produce an #error if someone (like me) tries to go down the "native > iostreams" path? The build system does that already; you only miss the error if you subvert Boost.Build. OTOH if you want to submit a patch which will work, I'll gladly fold it into the codebase. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sun Aug 31 21:51:04 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 31 Aug 2003 15:51:04 -0400 Subject: [C++-sig] Re: STLPort problems References: Message-ID: "Mike Thompson" writes: > I did notice one further thing in all this experiementing though. Even when > the stlport version > was set at 4.5-0725, the library was created in a folder with the name > 'stlport-version-4.5.3'. > I.e. something like > ........\libs\python\build\bin\libboost_python.lib\msvc-stlport\debug\runtime-l > ink-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5. > 3 > > Is this correct? Yeah, unfortunately. only has a few preset values. You can find the feature declaration for stlport-version and add new values to it if you need them. > I would have expected it to be a folder called > 'stlport-version-4.5-0725' -- Dave Abrahams Boost Consulting www.boost-consulting.com