From djowel at gmx.co.uk Tue Dec 24 21:54:22 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Wed, 25 Dec 2002 04:54:22 +0800 Subject: [C++-sig] Tutorial References: <3DB8311C.299058B5@llnl.gov> Message-ID: <005a01c2ab8e$a7985800$16be8aca@kim> Hi, As for the const in std::string const name, Dave has fixed the code in the CVS, AFAIK. see http://mail.python.org/pipermail/c++-sig/2002-October/002284.html As for the other mistake, it is my fault. Corrected in CVS. Regards, --Joel ----- Original Message ----- From: "chuzo okuda" > I read some of the tutorial. > > I cannot make it work without eliminating "const" in Class Data Members > topic. > How to make it work with const? > > struct Var { > Var(std::string name) : name(name), value() {} > std::string const name; > float value; > }; > > BOOST_PYTHON_MODULE_INIT(mytest3) > { > using namespace boost::python; > > class_("Var", init()) > .def_readonly("name", &Var::name) > .def_readwrite("value", &Var::value) > ; > } > > *** snips *** > "boost::python::detail::copy_non_const_reference_expects_a_non_const_ > reference_return_type thon::objects::make_holder<1>::apply select_value_holder::type, > *** snips *** > > Also, on the next topic, Class Property, I see: > > class_("Num") > .add_property("rovalue", &Var::get) > .add_property("value", &Var::get, &Var::set); > > It should be &Num::get and &Num::set. > > Additionally, I would like to have a index page that can quickly find > information such as "add_property", "def_readonly", etc. > It would be very much helpful like python web page. > Cheers! > Chuzo > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From djowel at gmx.co.uk Tue Dec 24 23:45:45 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Wed, 25 Dec 2002 06:45:45 +0800 Subject: [C++-sig] Tutorial References: <3DB8311C.299058B5@llnl.gov> Message-ID: <00ed01c2ab9e$3548c860$16be8aca@kim> ----- Original Message ----- From: "David Abrahams" > > > > class_("Num") > > .add_property("rovalue", &Var::get) > > .add_property("value", &Var::get, &Var::set); > > > > It should be &Num::get and &Num::set. > > Thanks. Joel, would you make this fix? Done. Plus some more. Please check the stuff in the CVS if it is up to your standards :-) --Joel PS> Is there a target date for boost 1.29.1 ? From jeff.holle at verizon.net Mon Dec 2 01:01:31 2002 From: jeff.holle at verizon.net (Jeff Holle) Date: Sun, 01 Dec 2002 16:01:31 -0800 Subject: [C++-sig] class_::add_property flexiablity Message-ID: <3DEAA2DB.6000100@verizon.net> I'm using gcc 3.2 and boost 1.29.0 on Mandrake Linux 9.0. I'm wondering if its possible to use add_property with an accessor that returns a reference. The following code compiles, but if I change the Widget::getName method to return a "const std::string&" it produces a lot of compiler errors.... #include #include #include #include using namespace boost::python; class Widget { public: Widget() {;} const std::string getName(void) const { return m_Name;} private: std::string m_Name; }; BOOST_PYTHON_MODULE(TestAddProperty) { class_("Widget") .add_property("Name",&Widget::getName); } From dave at boost-consulting.com Mon Dec 2 01:27:54 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 01 Dec 2002 19:27:54 -0500 Subject: [C++-sig] class_::add_property flexiablity In-Reply-To: <3DEAA2DB.6000100@verizon.net> (Jeff Holle's message of "Sun, 01 Dec 2002 16:01:31 -0800") References: <3DEAA2DB.6000100@verizon.net> Message-ID: Jeff Holle writes: > I'm using gcc 3.2 and boost 1.29.0 on Mandrake Linux 9.0. > > I'm wondering if its possible to use add_property with an accessor that returns a reference. > > The following code compiles, but if I change the Widget::getName method to return a "const > std::string&" it produces a lot of compiler errors.... > > #include > #include > #include > #include > > using namespace boost::python; > > class Widget { > public: > Widget() {;} > const std::string getName(void) const { return m_Name;} > private: > std::string m_Name; > }; > > > BOOST_PYTHON_MODULE(TestAddProperty) > { > class_("Widget") > .add_property("Name",&Widget::getName); > > } Sure. The add_property docs at http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers say: 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 object under construction with the given attribute name. So fget can be an instance of object already. How do you make a callable Python object which wraps a C++ function returning by reference? See http://www.boost.org/libs/python/doc/v2/make_function.html#make_function-spec. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Dec 2 03:00:26 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 01 Dec 2002 21:00:26 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: (David Abrahams's message of "Tue, 12 Nov 2002 13:46:23 -0500") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> Message-ID: David Abrahams writes: > "Peter Dimov" writes: > >>> I'd like to explore a few refinements with you. For example, it may >>> be possible to get real shared_ptr interoperability by deriving >>> py_counted_base from counted_base. Maybe we should ask Peter to >>> weigh in on this. Peter, Brett's code is attached to this page: >>> http://aspn.activestate.com/ASPN/Mail/Message/1430235 >> >> I don't really understand what the code is about ;-) > > Here's the quick skinny: > > - Boost.Python allows you to specify how Python objects will hold the > C++ objects they wrap. You can specify that they be held by > shared_ptr (or any other smart pointer), in which case the > library will generate converters to/from Python for > shared_ptr. The to_python converters will simply build a new > Python object around the shared_ptr<>. > > - If you have virtual functions you want to ``override in Python'', > you actually have to hold the T object with a derived class U which > overrides the virtual functions to dispatch back to Python. In this > case, class U naturally has to have access to the Python object > (that's the pyobj_ member you see in Brett's code). > > - You can further specify that your C++ object is held by > shared_ptr, which is what Brett is doing. That allows you to hold > a U object for dispatching, yet still pass shared_ptrs around in > your C++ code. > > There are several problems with the above arrangement, but the most > important one is that if you keep the shared_ptr alive longer than > its corresponding Python object, calls to the Python-overridable > virtual functions will crash, because they'll try to call through an > invalid pointer. That's what Brett is trying to address with his crazy > pointer. > >> but I'm leaning towards moving counted_base back to boost::detail >> and removing the intrusive counting "feature" of shared_ptr. >> >> The interoperability/shared_from_this problems have alternate solutions as >> described in the techniques "document". > > Hmm. I guess that rules out that option. > >> I'm not sure whether this helps or not, but it's also possible to have a >> shared_ptr to PyObject, by using Py_DECREF as the deleter (also described in >> the attached file). > > Now /that's/ starting to sound intriguing. I wonder if it's possible > to derive our U class from boost::python::objects::instance<>, and > automatically generate shared_ptr<> converters for it. > > Maybe the whole idea of holding a shared_ptr is bogus from the get-go. OK, I've implemented the first part of this change in the CVS. The current status is: * Any Python object wrapping a C++ object of type T can be converted to a shared_ptr, where U is T or any of its publicly-accessible base classes and U has been exposed with class_ * There is no need to explicitly specify shared_ptr as the holder in class_ * The shared_ptr actually manages the lifetime of the Python object, so it will never be destroyed before the corresponding C++ object is destroyed. Not implemented yet: * Automatic conversion of shared_ptr to python (e.g. when used as a return type). For that, you still need to pass shared_ptr to class_<...> as the holder, and since the old mechanism doesn't take advantage of the new shared_ptr deleter introspection feature yet, you always get a new Python object. Open questions: * There is some cost in code and compilation time associated with these automatic conversions for each class_<...> instance. Should users really be forced to pay for these conversions, or should they be explicitly requested, e.g. register_shared_ptr(); Such a function may be needed anyway, since classes that are exposed other than via class_<> (see, e.g. class Simple in libs/python/test/m1.cpp) may want to be managed via shared_ptr<>. * Can we do better for "callback classes" which dispatch virtual functions to Python (like BaseWrap at http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html) than to ask users to store their own PyObject* "self" reference? Some opportunities we may be missing by not providing a nice base class: 1. The ability to prevent users from copying, or even creating these objects - which is dangerous because of the weak PyObject* reference. 2. The ability to relieve users from having to touch the self pointer when implementing virtual function overrides (call_method could be a member of the base class) 3. The ability to convert shared_ptrs, references, and pointers to these classes into Python objects without creating a new Python object - instead we could just use the stored self pointer if we can detect derivationj from our special base class. I'm not very convinced this is useful for shared_ptr, since deleter introspection will allow us to retrieve the PyObject* if the object came from Python -- and shared_ptr shouldn't arise otherwise if we implement #1. However, it might be useful for regular pointers and references. * And now, a radical notion: should we ban the use of shared_ptr as an argument to class_<...> ? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From warkid at hotbox.ru Mon Dec 2 10:20:21 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Mon, 2 Dec 2002 12:20:21 +0300 Subject: [C++-sig] Can't convert from class_ to scope in latest CVS! Message-ID: <1007068437.20021202122021@hotbox.ru> Hello , i've checked out the CVS recently and found this strange bug(?) with scope: cannot convert from 'boost::python::class_::self' to 'boost::python::scope' here's the code: #include #include #include using namespace boost::python; struct C{ }; BOOST_PYTHON_MODULE(hello) { scope s= class_("C"); } Best regards, Kerim mailto:warkid at hotbox.ru From dave at boost-consulting.com Mon Dec 2 13:51:29 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 02 Dec 2002 07:51:29 -0500 Subject: [C++-sig] Can't convert from class_ to scope in latest CVS! In-Reply-To: <1007068437.20021202122021@hotbox.ru> (Kerim Borchaev's message of "Mon, 2 Dec 2002 12:20:21 +0300") References: <1007068437.20021202122021@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello , > > i've checked out the CVS recently and found this strange bug(?) with > scope: > > cannot convert from 'boost::python::class_::self' to 'boost::python::scope' > > here's the code: > > #include > #include > #include > using namespace boost::python; > > struct C{ > }; > > BOOST_PYTHON_MODULE(hello) > { > scope s= class_("C"); > } > > Best regards, > Kerim mailto:warkid at hotbox.ru http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1444827 explains all. However, I think I'll take out the explicit constructor, and maybe even add an assignment operator, so that we don't have to go through this again ;-/ -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Dec 2 15:20:35 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 02 Dec 2002 09:20:35 -0500 Subject: [C++-sig] Can't convert from class_ to scope in latest CVS! In-Reply-To: (David Abrahams's message of "Mon, 02 Dec 2002 07:51:29 -0500") References: <1007068437.20021202122021@hotbox.ru> Message-ID: David Abrahams writes: > However, I think I'll take out the explicit constructor, and maybe > even add an assignment operator, so that we don't have to go through > this again ;-/ Done. No assignment operator though; it's not appropriate. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From jeff.holle at verizon.net Tue Dec 3 05:50:54 2002 From: jeff.holle at verizon.net (Jeff Holle) Date: Mon, 02 Dec 2002 20:50:54 -0800 Subject: [C++-sig] class_::add_property flexiablity References: <20021202170006.11898.53067.Mailman@mail.python.org> Message-ID: <3DEC382E.7040801@verizon.net> c++-sig-request at python.org wrote: >Send C++-sig mailing list submissions to > c++-sig at python.org > >To subscribe or unsubscribe via the World Wide Web, visit > http://mail.python.org/mailman/listinfo/c++-sig >or, via email, send a message with subject or body 'help' to > c++-sig-request at python.org > >You can reach the person managing the list at > c++-sig-admin at python.org > >When replying, please edit your Subject line so it is more specific >than "Re: Contents of C++-sig digest..." > > >Today's Topics: > > 1. class_::add_property flexiablity (Jeff Holle) > 2. Re: class_::add_property flexiablity (David Abrahams) > 3. Re: call_method (David Abrahams) > 4. Can't convert from class_ to scope in latest CVS! (Kerim Borchaev) > 5. Re: Can't convert from class_ to scope in latest CVS! (David Abrahams) > 6. Re: Can't convert from class_ to scope in latest CVS! (David Abrahams) > >--__--__-- > >Message: 1 >Date: Sun, 01 Dec 2002 16:01:31 -0800 >From: Jeff Holle >To: c++-sig at python.org >Subject: [C++-sig] class_::add_property flexiablity >Reply-To: c++-sig at python.org > >I'm using gcc 3.2 and boost 1.29.0 on Mandrake Linux 9.0. > >I'm wondering if its possible to use add_property with an accessor that >returns a reference. > >The following code compiles, but if I change the Widget::getName method >to return a "const std::string&" it produces a lot of compiler errors.... > > #include > #include > #include > #include > > using namespace boost::python; > > class Widget { > public: > Widget() {;} > const std::string getName(void) const { return m_Name;} > private: > std::string m_Name; > }; > > > BOOST_PYTHON_MODULE(TestAddProperty) > { > class_("Widget") > .add_property("Name",&Widget::getName); > > } > > >In reading your referenced html doc pages, I "fell into" this attempt: > >--__--__-- > >Message: 2 >To: c++-sig at python.org >Subject: Re: [C++-sig] class_::add_property flexiablity >From: David Abrahams >Date: Sun, 01 Dec 2002 19:27:54 -0500 >Reply-To: c++-sig at python.org > >Jeff Holle writes: >In reading your referenced html pages, I "fell into" this: > .add_property("Name",make_function(&Widget::getName, return_value_policy())); It compiles without errors, but produces unacceptable runtime behaviours. Amongest them is that this doesn't produce an error: import TestAddProperty widget = TestAddProperty.Widget widget.Name = "this is a test" print widget.Name Note that I haven't provided a mutator. I've subsequently investigated enough to know that my C++ method is not being called. What is the correct thing to do? The other question is why did this obviously incorrect thing compile? Given this behaviour, the documentation needs to be much better... >>I'm using gcc 3.2 and boost 1.29.0 on Mandrake Linux 9.0. >> >>I'm wondering if its possible to use add_property with an accessor that returns a reference. >> >>The following code compiles, but if I change the Widget::getName method to return a "const >>std::string&" it produces a lot of compiler errors.... >> >> #include >> #include >> #include >> #include >> >> using namespace boost::python; >> >> class Widget { >> public: >> Widget() {;} >> const std::string getName(void) const { return m_Name;} >> private: >> std::string m_Name; >> }; >> >> >> BOOST_PYTHON_MODULE(TestAddProperty) >> { >> class_("Widget") >> .add_property("Name",&Widget::getName); >> >> } >> >> > >Sure. The add_property docs at >http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers >say: > > 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 object under construction > with the given attribute name. > >So fget can be an instance of object already. How do you make a >callable Python object which wraps a C++ function returning by >reference? See >http://www.boost.org/libs/python/doc/v2/make_function.html#make_function-spec. > > > From dave at boost-consulting.com Tue Dec 3 06:17:42 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 03 Dec 2002 00:17:42 -0500 Subject: [C++-sig] class_::add_property flexiablity In-Reply-To: <3DEC382E.7040801@verizon.net> (Jeff Holle's message of "Mon, 02 Dec 2002 20:50:54 -0800") References: <20021202170006.11898.53067.Mailman@mail.python.org> <3DEC382E.7040801@verizon.net> Message-ID: Jeff, 1. Please post a reproducible C++ test case, with Python code which demonstrates the problem 2. Please try to limit the amount of quoted text in replies. In particular, please don't quote the digest header ;-) Jeff Holle writes: > c++-sig-request at python.org wrote: > >>Send C++-sig mailing list submissions to >> c++-sig at python.org >> >>To subscribe or unsubscribe via the World Wide Web, visit >> http://mail.python.org/mailman/listinfo/c++-sig >>or, via email, send a message with subject or body 'help' to >> c++-sig-request at python.org >> >>You can reach the person managing the list at >> c++-sig-admin at python.org >> >>When replying, please edit your Subject line so it is more specific >>than "Re: Contents of C++-sig digest..." >> >> >>Today's Topics: >> >> 1. class_::add_property flexiablity (Jeff Holle) >> 2. Re: class_::add_property flexiablity (David Abrahams) >> >>Jeff Holle writes: >>In reading your referenced html pages, I "fell into" this: >> > .add_property("Name",make_function(&Widget::getName, > return_value_policy())); > > It compiles without errors, but produces unacceptable runtime behaviours. > Amongest them is that this doesn't produce an error: > > import TestAddProperty > widget = TestAddProperty.Widget > widget.Name = "this is a test" > print widget.Name > Note that I haven't provided a mutator. > > I've subsequently investigated enough to know that my C++ method is > not being called. > > What is the correct thing to do? > > The other question is why did this obviously incorrect thing compile? > Given this behaviour, the documentation needs to be much better... > > -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Dec 3 16:14:39 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 03 Dec 2002 10:14:39 -0500 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: (Dirk Gerrits's message of "Mon, 25 Nov 2002 22:27:51 +0100") References: <3DDE85C6.3060005@gerrits.homeip.net> <3DDFA61B.1070402@gerrits.homeip.net> Message-ID: Dirk Gerrits writes: >> If you could write up a short HTML page in the documentation >> describing what people need to know in order to embed Boost.Python >> extensions, that would be hugely appreciated as well. > > Sure! I have prelims though. This will have to wait till the > weekend. ;) Should it be in QuickDoc format for the Tutorial or should > it be more of a HTML FAQ entry? I think it sounds like tutorial material... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From jeff.holle at verizon.net Tue Dec 3 19:15:20 2002 From: jeff.holle at verizon.net (Jeff Holle) Date: Tue, 03 Dec 2002 10:15:20 -0800 Subject: [C++-sig] class_::add_property flexiablity No. 2 Message-ID: <3DECF4B8.80506@verizon.net> I'm using gcc 3.2 and boost 1.29.0 on Mandrake Linux 9.0. I'm attempting to employ Boost.Python to wrap an accessor method that returns a reference employing the class_.add_property method. The following C++ code compiles and links without error: #include #include #include #include #include using namespace boost::python; class Widget { public: Widget() : m_Name("Initial Value") {;} const std::string& getName(void) const { return m_Name;} private: std::string m_Name; }; BOOST_PYTHON_MODULE(TestAddProperty) { class_("Widget") .add_property("Name",make_function(&Widget::getName, return_value_policy())); } It does not work however. The following are two python scripts that demonstrates this. import TestAddProperty widget = TestAddProperty.Widget print widget.Name Prints "" If it worked I'd expect it to print "Initial Value". import TestAddProperty widget = TestAddProperty.Widget widget.Name = "This is a test" print widget.Name This prints "This is a test". If it worked, I'd expect a run-time error executing line number 3 because I have not exposed a mutator in the TestAddProperty module. From thor.arne.johansen at ibas.no Tue Dec 3 19:28:32 2002 From: thor.arne.johansen at ibas.no (thor.arne.johansen at ibas.no) Date: Tue, 3 Dec 2002 19:28:32 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) Message-ID: Hello, I'm trying to use Boost.Python to embedd and extend Python. After a little but of struggling and some help from Dave (thanx Dave), I've been able to write a small example. The example embedds Python in a console application, and exposes a C++ class and object instances to the Python script. I'm sure there are issues with my implementation, and I'm escpecially interested in getting tips/comments on the error/exception handling. I'm wondering if it is appropriate to post the example here for review or a (reasonable?) example of embedding with Boost.Python. The example is about 350 lines (including the test script)? -- Thor Arne Johansen Dept. Manager R&D Ibas AS From jeff.holle at verizon.net Wed Dec 4 01:35:13 2002 From: jeff.holle at verizon.net (Jeff Holle) Date: Tue, 03 Dec 2002 16:35:13 -0800 Subject: [C++-sig] class_::add_property flexiablity No. 2 Message-ID: <3DED4DC1.3020507@verizon.net> Problem fixed. It was a python booboo. The correct code is: import TestAddProperty widget = TestAddProperty.Widget() print widget.Name Note the "()" in line 2. From dave at boost-consulting.com Wed Dec 4 01:55:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 03 Dec 2002 19:55:53 -0500 Subject: [C++-sig] class_::add_property flexiablity No. 2 In-Reply-To: <3DED4DC1.3020507@verizon.net> (Jeff Holle's message of "Tue, 03 Dec 2002 16:35:13 -0800") References: <3DED4DC1.3020507@verizon.net> Message-ID: Jeff Holle writes: > Problem fixed. > > It was a python booboo. The correct code is: > > import TestAddProperty > widget = TestAddProperty.Widget() > print widget.Name Nasty. Oh, for a statically-checked language irony-served-lukewarm-ly y'rs, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Wed Dec 4 11:02:00 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Wed, 4 Dec 2002 23:02:00 +1300 Subject: [C++-sig] Re: call_method In-Reply-To: References: <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> Message-ID: <20021204100200.GB1468@HARE> On Dec 01 21:00, David Abrahams wrote: > > OK, I've implemented the first part of this change in the CVS. > The current status is: > > * Any Python object wrapping a C++ object of type T can be converted > to a shared_ptr, where U is T or any of its publicly-accessible > base classes and U has been exposed with class_ > > * There is no need to explicitly specify shared_ptr as the holder > in class_ > > * The shared_ptr actually manages the lifetime of the Python object, > so it will never be destroyed before the corresponding C++ object is > destroyed. Very cool. > > Not implemented yet: > > * Automatic conversion of shared_ptr to python (e.g. when used as a > return type). For that, you still need to pass shared_ptr to > class_<...> as the holder, and since the old mechanism doesn't take > advantage of the new shared_ptr deleter introspection feature yet, > you always get a new Python object. You could roll your own for the moment with a ustom to_python convertor - right? > > Open questions: > > * There is some cost in code and compilation time associated with > these automatic conversions for each class_<...> instance. Should > users really be forced to pay for these conversions, or should they > be explicitly requested, e.g. > > register_shared_ptr(); > > Such a function may be needed anyway, since classes that are exposed > other than via class_<> (see, e.g. class Simple in > libs/python/test/m1.cpp) may want to be managed via shared_ptr<>. Anything to ease the strain on our poor compilers would be good :) Of course, I'll be using it all the time. > > * Can we do better for "callback classes" which dispatch virtual > functions to Python (like BaseWrap at > http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html) > than to ask users to store their own PyObject* "self" reference? > Some opportunities we may be missing by not providing a nice base > class: > > 1. The ability to prevent users from copying, or even creating these > objects - which is dangerous because of the weak PyObject* > reference. > > 2. The ability to relieve users from having to touch the self > pointer when implementing virtual function overrides (call_method > could be a member of the base class) > > 3. The ability to convert shared_ptrs, references, and pointers to > these classes into Python objects without creating a new Python > object - instead we could just use the stored self pointer if we > can detect derivationj from our special base class. I'm not very > convinced this is useful for shared_ptr, since deleter > introspection will allow us to retrieve the PyObject* if the > object came from Python -- and shared_ptr shouldn't > arise otherwise if we implement #1. However, it might be useful > for regular pointers and references. I've just got the latest cvs source and I'm getting my head back into this -- give me a little time to play and I'll try and say something sensible. > > * And now, a radical notion: should we ban the use of shared_ptr as > an argument to class_<...> ? > As above.. Thanks for the new funkiness. Cheers, Brett From dirk at gerrits.homeip.net Wed Dec 4 11:34:45 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Wed, 04 Dec 2002 11:34:45 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: References: Message-ID: thor.arne.johansen at ibas.no wrote: > Hello, > > I'm trying to use Boost.Python to embedd and extend Python. After a little > but of struggling and some help from Dave (thanx Dave), I've been able to > write a small example. The example embedds Python in a console application, > and exposes a C++ class and object instances to the Python script. > > I'm sure there are issues with my implementation, and I'm escpecially > interested in getting tips/comments on the error/exception handling. Well I've rewritten the current /libs/python/test/embedding.cpp to use python::handle instead of PyObject*. This REALLY simplifies the reference counting, thanks for the tip Dave! :) > I'm wondering if it is appropriate to post the example here for review or a > (reasonable?) example of embedding with Boost.Python. The example is about > 350 lines (including the test script)? Not sure about that. I'm no moderator here. ;) Regards, Dirk Gerrits From dave at boost-consulting.com Wed Dec 4 14:18:55 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 08:18:55 -0500 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: (thor.arne.johansen@ibas.no's message of "Tue, 3 Dec 2002 19:28:32 +0100") References: Message-ID: thor.arne.johansen at ibas.no writes: > Hello, > > I'm trying to use Boost.Python to embedd and extend Python. After a little > but of struggling and some help from Dave (thanx Dave), I've been able to > write a small example. The example embedds Python in a console application, > and exposes a C++ class and object instances to the Python script. > > I'm sure there are issues with my implementation, and I'm escpecially > interested in getting tips/comments on the error/exception handling. > > I'm wondering if it is appropriate to post the example here for review or a > (reasonable?) example of embedding with Boost.Python. The example is about > 350 lines (including the test script)? Sure! Maybe you and Dirk can collaborate over what makes a good embedding example. Two heads are better than one, as they say. You might consider getting Jeremy Siek to set you guys up with write access to the Boost CVS sandbox, so you can develop your code/docs there. However, if that's too much mental overhead, doing it on this list should be OK. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Dec 4 15:50:54 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 09:50:54 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <20021204100200.GB1468@HARE> (Brett Calcott's message of "Wed, 4 Dec 2002 23:02:00 +1300") References: <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <20021204100200.GB1468@HARE> Message-ID: Brett Calcott writes: >> Not implemented yet: >> >> * Automatic conversion of shared_ptr to python (e.g. when used as a >> return type). For that, you still need to pass shared_ptr to >> class_<...> as the holder, and since the old mechanism doesn't take >> advantage of the new shared_ptr deleter introspection feature yet, >> you always get a new Python object. > > You could roll your own for the moment with a ustom to_python convertor > - right? Right. >> Open questions: >> >> * There is some cost in code and compilation time associated with >> these automatic conversions for each class_<...> instance. Should >> users really be forced to pay for these conversions, or should they >> be explicitly requested, e.g. >> >> register_shared_ptr(); >> >> Such a function may be needed anyway, since classes that are exposed >> other than via class_<> (see, e.g. class Simple in >> libs/python/test/m1.cpp) may want to be managed via shared_ptr<>. > > Anything to ease the strain on our poor compilers would be good :) > Of course, I'll be using it all the time. If a guy who says he's going to use it all the time volunteers to have it be manual, I guess I'm sold on the idea that it should be manual. Do I hear any further objections? > Thanks for the new funkiness. Sure! bootsy-ly y'rs, dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Wed Dec 4 16:11:47 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 04 Dec 2002 10:11:47 -0500 Subject: [C++-sig] compile problem with stl list In-Reply-To: <20021114030026.22461.qmail@sina.com> Message-ID: Hello, I have a small test that mimicks what I want to do: #include typedef std::list stdlistSP; // Using typedef on STL list #include #include #include using namespace boost::python; BOOST_PYTHON_MODULE(simple) { class_("stdlistSP", init()) .def("push_back", &stdlistSP::push_back) ; } When I build this using MSVC++ V6 everything works fine, but when I try the same using Cygwin/GCC it produces the following error: simple.cpp: In function `void init_module_simple()': simple.cpp:13: no matching function for call to ` boost::python::class_ ::def(const char[10], )' If is switch from list to vector it again works just fine. Anyone know what I need to do? TIA, Scott From dave at boost-consulting.com Wed Dec 4 16:17:20 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 10:17:20 -0500 Subject: [C++-sig] compile problem with stl list In-Reply-To: ("Scott A. Smith"'s message of "Wed, 04 Dec 2002 10:11:47 -0500") References: Message-ID: "Scott A. Smith" writes: > Hello, > > I have a small test that mimicks what I want to do: > > > #include > typedef std::list stdlistSP; // Using typedef on STL list > > #include > #include > #include > using namespace boost::python; > > BOOST_PYTHON_MODULE(simple) > { > class_("stdlistSP", init()) > .def("push_back", &stdlistSP::push_back) > ; > } > > When I build this using MSVC++ V6 everything works fine, but when I try > the same using Cygwin/GCC it produces the following error: > > simple.cpp: In function `void init_module_simple()': > simple.cpp:13: no matching function for call to ` > boost::python::class_ boost::python::detail::not_specified, > boost::python::detail::not_specified> > ::def(const char[10], )' > > If is switch from list to vector it again works just fine. > Anyone know what I need to do? You're generally prohibited from taking the address of a standard library function, because it might be overloaded or have optional arguments. In this case I bet that list::push_back is overloaded. A thin forwarding function could be wrapped instead: void list_push_back(stdlistSP& l, double x) { l.push_back(x); } -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Wed Dec 4 17:03:38 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Wed, 04 Dec 2002 17:03:38 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: References: Message-ID: David Abrahams wrote: > Sure! Maybe you and Dirk can collaborate over what makes a good > embedding example. Two heads are better than one, as they say. Sounds like a plan to me. How about it Thor? > You might consider getting Jeremy Siek to set you guys up with write > access to the Boost CVS sandbox, so you can develop your code/docs > there. However, if that's too much mental overhead, doing it on this > list should be OK. I think that's a great idea. I'll contact him at once. I should have my first Boost.Python embedding tutorial draft done by tonight so it should be appearing in the sandbox soon if all goes well. I'll leave a link here when you (Dave, Thor, others who are interested) can check it out (and possibly improve upon it). Regards, Dirk Gerrits From thor.arne.johansen at ibas.no Wed Dec 4 17:18:25 2002 From: thor.arne.johansen at ibas.no (thor.arne.johansen at ibas.no) Date: Wed, 4 Dec 2002 17:18:25 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) Message-ID: >thor.arne.johansen at ibas.no writes: > > [Snip] > >> I'm wondering if it is appropriate to post the example here for review or a >> (reasonable?) example of embedding with Boost.Python. The example is about >> 350 lines (including the test script)? > >Sure! Maybe you and Dirk can collaborate over what makes a good >embedding example. Two heads are better than one, as they say. > >You might consider getting Jeremy Siek to set you guys up with write >access to the Boost CVS sandbox, so you can develop your code/docs >there. However, if that's too much mental overhead, doing it on this >list should be OK. I think I will stay out of the sandbox for now :), but I'm posting my example code below. The hope of course is that I will get some useful comments/tips (on error/exception handling??), and that the example might be useful to others: ***** Begin: main.cpp ***** // // Embedding and extending with Boost.Python example // By Thor Arne Johansen // #include #include #include #include #include #include #include #include #include #include #include // Error codes #define Success 0 #define PY_InitError -100 #define PY_ConvertError -101 #define PY_CallError -102 // Global module pointer boost::python::handle<> module; // Class definitions // // PythonException: Exception object thrown by Python interface (usually caused by an exception in Python interpreter) // class PythonException { std::string m_exception_type; std::string m_error_message; public: PythonException():m_exception_type(""),m_error_message(""){}; void setExceptionType(std::string msg) {m_exception_type = msg;} void setErrorMessage(std::string msg) {m_error_message = msg;} std::string getExceptionType() {return m_exception_type;} std::string getErrorMessage(void) {return m_error_message;} }; // // Test class which contain state // class MyClass { private: _int64 m_state; public: MyClass():m_state(0){} MyClass(_int64 st):m_state(st){} void setState(_int64 st) { m_state = st;} _int64 getState() { return m_state;} void printPtr() { printf("C++ : Ptr=0x%p", this); } }; // Function prototypes int initPython(std::string scriptName); int callPython(std::string func, std::string msg, boost::python::object& obj); void getExceptionDetail(PythonException& exc); // Convenience functions boost::python::handle<> import_module(std::string module_name) { using namespace boost::python; PyObject *module_ptr = PyImport_ImportModule(const_cast(module_name.c_str())); if( module_ptr == NULL) { PythonException exc; getExceptionDetail(exc); throw(exc); } return handle<>(module_ptr); } boost::python::object get_function(const char *func_name) { PyObject* dict = PyModule_GetDict(module.get()); // Borrowed reference boost::python::str funcName(func_name); return boost::python::object(boost::python::handle <>(PyDict_GetItem(dict, funcName.ptr()))); } // Python wrapper for MyClass BOOST_PYTHON_MODULE(myCppModule) { using namespace boost::python; class_("MyClass") .def("getState", &MyClass::getState) .def("setState", &MyClass::setState) .def("printPtr", &MyClass::printPtr) ; } // Call a function in module (ptrPyModule) with two arguments // func: Name of python function // msg: Message string // obj: Boost.Python object (an instance of a wrapped class) int callPython(const std::string funcStr, std::string msg, boost::python::object& obj) { int retv; PythonException p_exc; // Create empty exception object on stack try { boost::python::object func = get_function(const_cast(funcStr.c_str())); retv = boost::python::extract(func(msg, obj)); } catch(...) // What should we catch here?? { getExceptionDetail(p_exc); throw(p_exc); } return retv; } // // // Initialize Python interpreter // Initialize Extension module that expose C++ classes/objects to Python script // Set up sys.path to include script path (Where the python scripts can be found) // // int initPython(std::string scriptName) { if(scriptName.length() == 0 ) return PY_InitError; // Register the extension module PyImport_AppendInittab("myCppModule", initmyCppModule); // Initialize the Python interpreter Py_Initialize(); // Set up so sys.path contain our script path std::string pyinitstr( "import sys\n" "sys.path.append(\"##SCRIPTPATH##\")\n" "\n" ); // Build full path to scripts // For now, we hardcode the path where the scripts are located // Typically this would be read from a configuration file std::string scr_path = "d:/work/ExtendEmbedd2"; // Insert path into init string std::string placeHolder("##SCRIPTPATH##"); unsigned int pos = pyinitstr.find(placeHolder); if(pos!=std::string::npos) { pyinitstr.erase(pos, placeHolder.length()); pyinitstr.insert(pos, scr_path); } // Run the init script to set up sys.path if( PyRun_SimpleString(const_cast(pyinitstr.c_str())) != NULL ) std::cout << "C++ : Warning: Could not set up sys.path\n" << std::endl; // Import the module, storing the pointer in a handle<> try { module = import_module(const_cast(scriptName.c_str())); } catch(PythonException& exc) { std::cout << "\nC++ : Exception thrown when importing module in initPython():" << std::endl; std::cout << "C++ : " << exc.getExceptionType() << ": " << exc.getErrorMessage() << std::endl; return PY_InitError; } catch(...) { std::cout << "C++ : Unknown exception when importing module " << scriptName << std::endl; return PY_InitError; } return Success; } // Complete the exception object exc based on the exception thrown by the Python module // This was adopted from pyerrors.c found here: http://rmi.net/~lutz/errata-supplements.html void getExceptionDetail(PythonException& exc) { PyObject* exc_type; PyObject* exc_value; PyObject* exc_traceback; PyObject* pystring; PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); if( exc_type==0 && exc_value==0 && exc_traceback==0) { exc.setExceptionType("Strange: No Python exception occured"); exc.setErrorMessage("Strange: Nothing to report"); } else { pystring = NULL; if (exc_type != NULL && (pystring = PyObject_Str(exc_type)) != NULL && /* str(object) */ (PyString_Check(pystring)) ) exc.setExceptionType(PyString_AsString(pystring)); else exc.setExceptionType(""); Py_XDECREF(pystring); pystring = NULL; if (exc_value != NULL && (pystring = PyObject_Str(exc_value)) != NULL && /* str(object) */ (PyString_Check(pystring)) ) exc.setErrorMessage(PyString_AsString(pystring)); else exc.setErrorMessage(""); Py_XDECREF(pystring); Py_XDECREF(exc_type); Py_XDECREF(exc_value); /* caller owns all 3 */ Py_XDECREF(exc_traceback); /* already NULL'd out */ } } // // Initialize, and run some tests // int main(int argc, char *argv[]) { std::cout << "C++ : Initializing Python and loading script" << std::endl; int retv = initPython("myscript"); if( retv == Success ) { // Create a MyClass, and set some state information MyClass mc(10); // Show identity mc.printPtr(); std::cout << std::endl; // Show state std::cout << "C++ : mc.getState() in C++ before Python call: " << mc.getState() << std::endl; // Do some stuff to the object from Python // First wrap a reference to mc in an bpl object boost::python::object arg2(boost::ref(mc)); // Show identity of the wrapped object arg2.attr("printPtr")();std::cout << std::endl; // Alternative method to do the same thing boost::python::call_method(arg2.ptr(),"printPtr"); std::cout << std::endl; try { // Call Python, possibly changing the state of mc int retv = callPython("myTestFunc", "String argument from c++", arg2); std::cout << "C++ : callPython() returned: " << retv << std::endl; } catch(PythonException& exc) { std::cout << "\nC++ : Exception thrown in callPython():" << std::endl; std::cout << "C++ : " << exc.getExceptionType() << ": " << exc.getErrorMessage() << std::endl; retv = PY_CallError; } catch(...) { std::cout << "C++ : Unknown exception when calling callPython!" << std::endl; retv = PY_CallError; } // Show state std::cout << "C++ : mc.getState() after Python call: " << mc.getState() << std::endl; } else std::cout << "C++ : Failed to initialize!" << std::endl; std::cout << "C++ : Press any key to quit" << std::endl; getch(); return retv; } ***** End: main.cpp ***** ***** Begin: myscript.py ***** try: import myCppModule print "Python: Import SUCCEEDED!!!" except: print "Python: Import FAILED..." # # Test module # Illustrate both instatiation and use of already instantiated C++ objects # def myTestFunc(msg, cppObj): # Print message from C++ print "Python: msg = ", msg # Instantiate a MyClass object a = myCppModule.MyClass() # Show identity print "Python: Identity of 'local' MyClass object: ", a.printPtr() print # Change state of object print "Python: Current state:", a.getState() a.setState(1234) print "Python: New state :", a.getState() # Delete object del a # Test the object exposed from c++ (Passed as a formal parameter) # Show identify of cppObj print "Python: Identity of exposed cppObj: ", cppObj.printPtr() print # Show state of cppObj print "Python: cppObj.getState() on entry:", cppObj.getState() # Change state of object cppObj.setState(-9223000000000000000) # Test the limits of long long (or _int64 on msvc) # Show state of object print "Python: cppObj.getState() on exit :", cppObj.getState() return 999 ***** End: myscript.py ***** -- Thor Arne Johansen Dept. Manager R&D Ibas AS From ssmith at magnet.fsu.edu Wed Dec 4 18:50:12 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 04 Dec 2002 12:50:12 -0500 Subject: [C++-sig] Dissimilar Overloads In-Reply-To: Message-ID: Hi, If one has overloaded functions with dis-similar arguments, do they need to be wrapped separately? While I have been able to successfully use BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS when my functions have argument lists that are similar and/or use default values, I cannot figure out how to do something equally simple to get functions with different types of arguments exported. For example, is there something like the code below that can work? #include using namespace boost::python; int f(int x, int y, int z); void f(double d, complex z); BOOST_PYTHON_MODULE(xxx) { def("f", f, args("x", "y", "z")); def("f", f, args("d", "y")); } Or do I have to define new functions with different names then export them? Thanks, Scott From leo4ever22 at yahoo.com Wed Dec 4 20:50:43 2002 From: leo4ever22 at yahoo.com (Leonard Dick) Date: Wed, 4 Dec 2002 11:50:43 -0800 (PST) Subject: [C++-sig] Dissimilar Overloads In-Reply-To: Message-ID: <20021204195043.23193.qmail@web21306.mail.yahoo.com> Hi, thanx a lot for your mail, could you please break down you intepretations and languages more simpler, I couldn't figure out much from you mail. thanks Leo --- "Scott A. Smith" wrote: > Hi, > > If one has overloaded functions with dis-similar > arguments, > do they need to be wrapped separately? While I have > been able > to successfully use BOOST_PYTHON_FUNCTION_OVERLOADS > and > BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS when my > functions have > argument lists that are similar and/or use default > values, I cannot > figure out how to do something equally simple to get > functions with > different types of arguments exported. For example, > is there something > like the code below that can work? > > #include > using namespace boost::python; > > int f(int x, int y, int z); > void f(double d, complex z); > > BOOST_PYTHON_MODULE(xxx) > { > def("f", f, args("x", "y", "z")); > def("f", f, args("d", "y")); > } > > Or do I have to define new functions with different > names > then export them? > > Thanks, > Scott > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dave at boost-consulting.com Wed Dec 4 20:49:46 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 14:49:46 -0500 Subject: [C++-sig] Dissimilar Overloads In-Reply-To: ("Scott A. Smith"'s message of "Wed, 04 Dec 2002 12:50:12 -0500") References: Message-ID: "Scott A. Smith" writes: > Hi, > > If one has overloaded functions with dis-similar arguments, > do they need to be wrapped separately? While I have been able > to successfully use BOOST_PYTHON_FUNCTION_OVERLOADS and > BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS when my functions have > argument lists that are similar and/or use default values, I cannot > figure out how to do something equally simple to get functions with > different types of arguments exported. For example, is there something > like the code below that can work? > > #include > using namespace boost::python; > > int f(int x, int y, int z); > void f(double d, complex z); > > BOOST_PYTHON_MODULE(xxx) > { > def("f", f, args("x", "y", "z")); > def("f", f, args("d", "y")); int (&f1)(int,int,int) = f; def("f", f1, args("x", "y", "z")); void (&f2)(double,complex) = f; def("f", f2, args("d", "y")); is the easiest way. There are other hacks in this particular case, but I'd avoid them. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Wed Dec 4 21:06:29 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 04 Dec 2002 15:06:29 -0500 Subject: [C++-sig] Dissimilar Overloads In-Reply-To: <20021204195043.23193.qmail@web21306.mail.yahoo.com> Message-ID: > Leo wrote: > thanx a lot for your mail, could you please break > down you intepretations and languages more simpler, I > couldn't figure out much from you mail. Sure Leo. I have a C++ function, say f, that is overloaded: int f(int x, int y, int z); void f(double d, complex z); What is the easiest way to expose these using Boost.Python? I had hoped something like the following might work: > > #include > > using namespace boost::python; > > > > int f(int x, int y, int z); > > void f(double d, complex z); > > > > BOOST_PYTHON_MODULE(xxx) > > { > > def("f", f, args("x", "y", "z")); > > def("f", f, args("d", "y")); > > } But that doesn't work. Note that the function f is not part of any class. Thanks Scott From nicodemus at globalite.com.br Thu Dec 5 01:01:15 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 04 Dec 2002 21:01:15 -0300 Subject: [C++-sig] Boost.Python code generator Message-ID: <3DEE974B.3050009@globalite.com.br> Hail to all. A collegue and I are planning to port the C++ code base of our company to Python. After checking both swig and boost.python, we opted for boost, because of its flexibility and cleanness. 8) After various tests, we felt that we could automatize the process, using a boost.python code generator. I would like to present our ideas to the boost.python readers to gather comments and suggestions. We opted for the use of a "interface file" to expose the C++ class to our code generator. It's main design goals are: - Simplicity - Independent from header files (self-contained) - Export classes that: * are templates * have virtual functions * have functions with default arguments * enums Our motivations are: - The interface file is simplier than write boost code directly - It separates the code that exports the class from the module where the class will be exported (more on that later). - It is not intrusive to the library being exported (unlike other solutions, like the use of "tags" in the header for exposing the functions). We are planning to call it Pyste (Python Semiautomatic Type Exporter), but that can change in the future. 8) The usage process would be as follows: - The user creates a interface file for the header that he/she plans to export. So, for two header files declaring two classes, A.h and B.h, the user creates interface files A.pyi and B.pyi (examples later). - The user runs in the command line: pyste -module test A.pyi B.pyi This command generates one file, test.cpp, which contains boost code that exposes the test module and its classes to python. - The user compiles the generated test.cpp as a dynamic library, as he/she would do with boost.python. Here is a simple class to exemplify: file A.h ------------------------------------------------------------------------ #include #include "B.h" namespace test { class A: public B { public: virtual void foo( int x ); const std::string & getName() const; int value; private: std::string s; }; } ------------------------------------------------------------------------ The interface file would be as follows (the syntax is not fixed yet): file A.pyi ------------------------------------------------------------------------ include test/A.h # this will just change to '#include "test/A.h"' # in the generated code, ie, the header # will not be actually parsed by pyste class test.A(base test.B) def foo (virtual void-int) # specify the return value and the parameters def getName (return internal_reference) attr value ------------------------------------------------------------------------ What do you think? Would it be of use to other people, in your opinion? I would very much appreciate comments and suggestions. Farewell, Nicodemus. From rwgk at yahoo.com Thu Dec 5 00:45:19 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 4 Dec 2002 15:45:19 -0800 (PST) Subject: [C++-sig] Boost.Python code generator In-Reply-To: <3DEE974B.3050009@globalite.com.br> Message-ID: <20021204234519.14322.qmail@web20203.mail.yahoo.com> --- Nicodemus wrote: > The interface file would be as follows (the syntax is not fixed yet): > > file A.pyi > ------------------------------------------------------------------------ > include test/A.h # this will just change to '#include "test/A.h"' > # in the generated code, ie, the header > # will not be actually parsed by pyste > > class test.A(base test.B) > def foo (virtual void-int) # specify the return value and the parameters > def getName (return internal_reference) > > attr value > ------------------------------------------------------------------------ > This is very interesting, but I am wondering how much you could actually cut down on the typing. I believe David's restless mind has brought us already fairly close to a hypothetical "most concise" syntax for defining the bindings between a statically typed language and a dynamically typed language. If you cross this boarder you will have to make certain decisions that are not already encoded, you will have to specify additional information (i.e. which templates to instantiate, return policies, pickle support, etc.). Scanning through my source code I cannot identify too many places where one could hope for significantly improved convenience. An obvious exception is this trivial repetition: def("foo", foo) That you could take care of with a macro such as: #define DEF(function_name) def(# function_name, function_name) giving you: DEF(foo) Other than that you could maybe eliminate the need for certain punctuation such as parentheses and semicolons but you have to buy this for the price of having intermediate steps. On the other hand ... If you can identify a significant potential for cutting down on the typing you might be able to hide those intermediate steps almost completely: your pyste module could be a "Builder" in SCons (scons.sf.net). This is a fantastic build tool for anyone using Python anyway/already. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nicodemus at globalite.com.br Thu Dec 5 02:49:42 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 04 Dec 2002 22:49:42 -0300 Subject: [C++-sig] Boost.Python code generator In-Reply-To: <20021204234519.14322.qmail@web20203.mail.yahoo.com> References: <20021204234519.14322.qmail@web20203.mail.yahoo.com> Message-ID: <3DEEB0B6.2090102@globalite.com.br> Ralf W. Grosse-Kunstleve wrote: >This is very interesting, but I am wondering how much you could actually cut >down on the typing. I believe David's restless mind has brought us already >fairly close to a hypothetical "most concise" syntax for defining the bindings >between a statically typed language and a dynamically typed language. If you >cross this boarder you will have to make certain decisions that are not already >encoded, you will have to specify additional information (i.e. which templates >to instantiate, return policies, pickle support, etc.). Scanning through my >source code I cannot identify too many places where one could hope for >significantly improved convenience. An obvious exception is this trivial >repetition: > > def("foo", foo) > >That you could take care of with a macro such as: > Thanks a lot for your response! I understand your point and agree. For the simple "def" case, the advantage would be small. But the real benefits of pyste would be with more elaborated uses, like virtual methods for instance. For example, translate: ------ include test/A.h class test.A def foo (virtual void-int) def test.bar (rename MyBar, defaults 0-2) ------ Then, using "pyste -module test A.pyi", generate test.cpp: ------ #include struct A_Wrap: public test::A { A_Wrap( PyObject* p_Self ): m_Self( p_Self ) {} void foo( int x ) { return call_method( m_Self, "foo", x ); } void foo_default( int x ) { return test::A::foo( x ); } PyObject* m_Self; }; BOOST_PYTHON_FUNCTION_OVERLOADS(bar_overloads, bar, 0, 2); BOOST_PYTHON_MODULE(test) { class_( "A" ) .def( "foo", &A_Wrap::foo ) .def( "foo", &A_Wrap::foo_default ) ; def( "MyBar", &test::bar, bar_overloads() ); } ------ In this case I see a real benefit, if you consider that you have over 100+ classes to convert. 8) >If you can identify a significant potential for cutting down on the typing you >might be able to hide those intermediate steps almost completely: your pyste >module could be a "Builder" in SCons (scons.sf.net). This is a fantastic build >tool for anyone using Python anyway/already. > That would be great, but in the future only. SCons is really nice, and we use it extensively. 8) > >Ralf > Thanks again, Nicodemus From dave at boost-consulting.com Thu Dec 5 02:52:15 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 20:52:15 -0500 Subject: [C++-sig] Boost.Python code generator In-Reply-To: <3DEEB0B6.2090102@globalite.com.br> (Nicodemus's message of "Wed, 04 Dec 2002 22:49:42 -0300") References: <20021204234519.14322.qmail@web20203.mail.yahoo.com> <3DEEB0B6.2090102@globalite.com.br> Message-ID: Nicodemus writes: > I understand your point and agree. For the simple "def" case, the > advantage would be small. But the real benefits of pyste would be with > more elaborated uses, like virtual methods for instance. > > For example, translate: > > ------ > include test/A.h > > class test.A > def foo (virtual void-int) Why invent such radical new syntax? It's neither C++-like nor Python-like Wouldn't virtual void foo(int); work better? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Thu Dec 5 03:05:54 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 04 Dec 2002 21:05:54 -0500 Subject: [C++-sig] Static, again... In-Reply-To: <20021112100724.GA26115@vervet.localnet> Message-ID: I also have looked over the mailing list archives and still don't see how things work. The example given was > #include > #include > > struct Num { > Num() {} > ~Num() {} > static int getDims() {return 3;} > int dims() {return 5;} > }; > > BOOST_PYTHON_MODULE_INIT(numTest) > { > using namespace boost::python; > module numTestMod("numTest"); > numTestMod > .add > ( class_("Num") > .def_init() > .def("getDims",&Num::getDims) > .def("dims", &Num::dims) > ) > ; > } Was the conclusion in this discussion that one cannot use getDims with an instance of the class NOR with the class itself? That is neither X = Num() X.getDims() nor Num.getDims() will work? Neither works for me. David wrote that > We don't have a way to make true static methods yet. So, what ways are there for using the static method? As I recall, using the static method in Python via the class name worked OK in BPV1. I cannot get function getDims() working in V2 with anything I've tried. Can someone spell it out for me? Thanks, (and thanks to Dave twice over in a single day) Scott From nicodemus at globalite.com.br Thu Dec 5 04:19:52 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 05 Dec 2002 00:19:52 -0300 Subject: [C++-sig] Boost.Python code generator In-Reply-To: References: <20021204234519.14322.qmail@web20203.mail.yahoo.com> <3DEEB0B6.2090102@globalite.com.br> Message-ID: <3DEEC5D8.1050900@globalite.com.br> David Abrahams wrote: >Why invent such radical new syntax? It's neither C++-like nor >Python-like Wouldn't > > virtual void foo(int); > >work better? > > Hello David, Because it would break the C++ syntax in other cases. The simple "def" would have to change too, since now the user has to declare types: Instead of: def bar The user would now have to write: void bar(int x, double y, float z); To maintain consistency. Also, I want to add some other directives, like for example "rename", which lets the user rename a function. How do that in a syntax similar to C++? void bar(int x); rename MyBar; Seems weird, most likely to confuse. void bar(int x); // rename MyBar would be better, maybe. My idea is to include in the interface *only* the minimum that boost needs to generate the wrapper code. Using a different and consistent interface, seems to me a good idea in this case. But the objective of my post is to discuss the idea... the interface-file syntax is not definite, and will likely change. Best Regards, Nicodemus. From dave at boost-consulting.com Thu Dec 5 03:21:45 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 21:21:45 -0500 Subject: [C++-sig] Static, again... In-Reply-To: ("Scott A. Smith"'s message of "Wed, 04 Dec 2002 21:05:54 -0500") References: Message-ID: "Scott A. Smith" writes: > I also have looked over the mailing list archives and > still don't see how things work. The example given was > >> #include >> #include >> >> struct Num { >> Num() {} >> ~Num() {} >> static int getDims() {return 3;} >> int dims() {return 5;} >> }; >> >> BOOST_PYTHON_MODULE_INIT(numTest) >> { >> using namespace boost::python; >> module numTestMod("numTest"); >> numTestMod >> .add >> ( class_("Num") >> .def_init() >> .def("getDims",&Num::getDims) >> .def("dims", &Num::dims) >> ) >> ; >> } > > Was the conclusion in this discussion that one cannot > use getDims with an instance of the class NOR with the > class itself? That is neither > > X = Num() > X.getDims() > > nor > > Num.getDims() > > will work? I don't know if we concluded that, but it's correct. > Neither works for me. David wrote that > >> We don't have a way to make true static methods yet. > > So, what ways are there for using the static method? A static member function is just a regular function; you can add it at module scope: BOOST_PYTHON_MODULE_INIT(numTest) { def("getDims", &Num::getDims); ... } > As I recall, using the static method in Python via the class name > worked OK in BPV1. I think that's correct. > I cannot get function getDims() working in V2 with anything I've > tried. Can someone spell it out for me? See above. > Thanks, (and thanks to Dave twice over in a single day) If it's any consolation, I now know exactly what needs to be done to support static methods. It's just a matter of finding time and/or funding to do the work... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Dec 5 03:32:29 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Dec 2002 21:32:29 -0500 Subject: [C++-sig] Boost.Python code generator In-Reply-To: <3DEEC5D8.1050900@globalite.com.br> (Nicodemus's message of "Thu, 05 Dec 2002 00:19:52 -0300") References: <20021204234519.14322.qmail@web20203.mail.yahoo.com> <3DEEB0B6.2090102@globalite.com.br> <3DEEC5D8.1050900@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>Why invent such radical new syntax? It's neither C++-like nor >> Python-like Wouldn't virtual void foo(int); >> >>work better? >> > Hello David, > > Because it would break the C++ syntax in other cases. The simple "def" > would have to change too, since now the user has to declare types: > > Instead of: > > def bar > > The user would now have to write: > > void bar(int x, double y, float z); To maintain consistency. But your example declared types, if I'm not mistaken. Here it is again: def foo (virtual void-int) Why not dispense with "def" and let the user just write bar In the case where there's nothing to deduce? > Also, I want to add some other directives, like for example "rename", > which lets the user rename a function. How do that in a syntax similar > to C++? > > void bar(int x); rename MyBar; > > Seems weird, most likely to confuse. > > void bar(int x); // rename MyBar > > would be better, maybe. void bar(int x) as MyBar or bar as MyBar in the case where there are no overloads or default arguments has a nice ring to it. > My idea is to include in the interface *only* the minimum that boost > needs to generate the wrapper code. Using a different and consistent > interface, seems to me a good idea in this case. > > But the objective of my post is to discuss the idea... the > interface-file syntax is not definite, and will likely change. Brad King has been talking about extending CABLE using GCC_XML as a front-end and Boost.Python as a back end. I think I'd rather see the two of you cooperate on that direction... but don't let that thwart your enthusiasm, if you're really motivated to pursue this one! One wrapper generator is better than none. but-are-two-better-than-one-ly y'rs, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nicodemus at globalite.com.br Thu Dec 5 04:59:03 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 05 Dec 2002 00:59:03 -0300 Subject: [C++-sig] Boost.Python code generator In-Reply-To: References: <20021204234519.14322.qmail@web20203.mail.yahoo.com> <3DEEB0B6.2090102@globalite.com.br> <3DEEC5D8.1050900@globalite.com.br> Message-ID: <3DEECF07.2030605@globalite.com.br> David Abrahams wrote: >But your example declared types, if I'm not mistaken. Here it is >again: > > def foo (virtual void-int) > >Why not dispense with "def" and let the user just write > > bar >In the case where there's nothing to deduce? > The type declaration is only needed in the case where a function is virtual, to be able to generate the callbacks. The def keyword is needed because there are other things that a class can export, like attributes and operators: class test.A def bar def foo (virtual void-int) attr x operator == (param A) The philosofy here is that the statements are in the form: [(options)] Where options are in the form: (