From mgiger at lunarsoft.com Sat Mar 1 00:43:52 2003 From: mgiger at lunarsoft.com (Matt Giger) Date: Fri, 28 Feb 2003 15:43:52 -0800 Subject: [C++-sig] Inherited instance variables Message-ID: Hi, I just discovered Boost.Python and I am very impressed (as I am with most of Boost). I have embedded a Python interpreter in my project and would like to tie in some C++ classes but am having problems with inherited member variables. Here is my example: C++ --- struct foo { foo(void) {} virtual ~foo(void) {} virtual bool handle_evt(object event) { return false; } list children; } struct foowrap : foo { foowrap(PyObject* self) : self_(self) {} foowrap(PyObject* self, const foo& f) : foo(f), self_(self) {} bool handle_evt(object event) { return call_method(self_, "handle_evt", event); } static bool def_handle_evt(foo* f, object event) { return f->foo::handle_evt(event); } PyObject* const self_; }; BOOST_PYTHON_MODULE(foomod) { class("foo") .def("handle_evt", &foowrap::def_handle_evt) .def_readwrite("children", &widget::children); } Python ------ import foomod class subfoo(foomod.foo): def __init__(self, parent): self.parent = parent self.parent.children.append(self) def __del__(self) self.parent.children.remove(self) def handle_evt(self, event) print event for child in children: if handle_evt(event) return true else return false f = foo() # works fine g = subfoo(f) # works fine h = subfoo(g) # breaks Error: self.parent.children.append(self) TypeError: bad argument type for built-in operation # no children list available in the subfoo class instance 'g' print g.children TypeError: bad argument type for built-in operation It appears that the children list object is not visible from any subclasses of the foo class. I have tried changing the line: .def_readwrite("children", &widget::children) with .add_property("children", make_getter(&foo::children, return_internal_reference<>()), make_setter(&foo::children)) but still no luck...any help would be appreciated, thanks. -- Matt Giger Lunar Software, Inc. mgiger at lunarsoft.com From BPettersen at NAREX.com Sat Mar 1 19:11:42 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Sat, 1 Mar 2003 11:11:42 -0700 Subject: [C++-sig] BPL embedding tutorial updated. Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192022DD85F@admin56.narex.com> > From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] > > I've made some changes to my Boost.Python tutorial on embedding. [...] > If you find any errors or have any suggestions, I'd love to hear from you. Great work! A minor nit though, embedding doesn't require static libraries (you can even mix and match), static libs does make distribution easier. Am I to assume that there will eventually be e.g. (apologies for the incorrect syntax, I assume you get the idea): object py::import::AddModule(std::string const& name); dict py::module::GetDict(object moduleObj); object py::RunExpr(std::string const& code, dict globals, dict locals); object py::RunStmt(std::string const& code, dict globals, dict locals); object py::RunStmts(std::string const& code, dict globals, dict locals); or is there even thought about wrapping more of the Python object types, like e.g.: module mainModule = py::import::AddModule("__main__"); dict mainDict = mainModule.getDict(); interpreter interp(mainDict, mainDict); // globals, locals object res = interp.runExpr(std::string const& code); etc. Either way would be quite cool IMHO :-) If you allready have a design in mind, you should make it available in case someone has time to help you . -- bjorn From nicodemus at globalite.com.br Sat Mar 1 20:39:01 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 01 Mar 2003 16:39:01 -0300 Subject: [C++-sig] Support for member operators? Message-ID: <3E610C55.3080007@globalite.com.br> Hi! Suppose I have the following: struct C { C(int x_): x(x_) {} int x; const C operator+(int o) { return C(x + o); } }; const C operator*(const C& c, int o) { return C(c.x * o); } If I try to expose the operator+ like this: .def( self + other() ) I get a compiler error: "no operator "+" matches these operands", while the * operator works perfectly: .def( self * other() ) Does Boost.Python support member operators? For now, I'm exposing the operator + like this: .def("__add__", C::operator+) and it works, but I wonder if there's a better way. Thanks, Nicodemus. From dirk at gerrits.homeip.net Sat Mar 1 20:51:11 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Sat, 01 Mar 2003 20:51:11 +0100 Subject: [C++-sig] Re: BPL embedding tutorial updated. In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E20192022DD85F@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E20192022DD85F@admin56.narex.com> Message-ID: Bjorn Pettersen wrote: >>From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] >> >>I've made some changes to my Boost.Python tutorial on embedding. > > [...] > >>If you find any errors or have any suggestions, I'd love to hear from > > you. > > Great work! A minor nit though, embedding doesn't require static > libraries (you can even mix and match), static libs does make > distribution easier. I was unaware. If you have some specific changes to suggest to the tutorial, please do! They will probably be too late for the 1.30.0 release though, I'm afraid. > Am I to assume that there will eventually be e.g. (apologies for the > incorrect syntax, I assume you get the idea): > > object py::import::AddModule(std::string const& name); > dict py::module::GetDict(object moduleObj); > object py::RunExpr(std::string const& code, dict globals, dict > locals); > object py::RunStmt(std::string const& code, dict globals, dict > locals); > object py::RunStmts(std::string const& code, dict globals, dict > locals); > > or is there even thought about wrapping more of the Python object types, > like e.g.: > > module mainModule = py::import::AddModule("__main__"); > dict mainDict = mainModule.getDict(); > interpreter interp(mainDict, mainDict); // globals, locals > object res = interp.runExpr(std::string const& code); > > etc. > > Either way would be quite cool IMHO :-) If you allready have a design > in mind, you should make it available in case someone has time to help > you . There has been some discussion on a python::interpreter class. Nothing has really been decided, but I think it would look something like this: namespace boost { namespace python { class interpreter { interpreter(); interpreter(int argc, char* argv[]); ~interpreter(); void exec(char const* statements); void exec(char const* statements, dict& globals, dict& locals); object eval(char const* expression); object eval(char const* expression, dict& globals, dict& locals); dict& main_namespace(); object* main_module(); }; }} // namespace boost::python The call i.exec/eval(statements) would be the same as the call i.exec/eval(statements, i.main_namespace(), i.main_namespace()) But I must stress here that this is 'email client code' not 'IDE source editor code'. Also, as I said above, nothing has been agreed on, this is still open for discussion. Regards, Dirk Gerrits From rwgk at yahoo.com Sat Mar 1 21:13:53 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 1 Mar 2003 12:13:53 -0800 (PST) Subject: [C++-sig] Support for member operators? In-Reply-To: <3E610C55.3080007@globalite.com.br> Message-ID: <20030301201353.83610.qmail@web20205.mail.yahoo.com> --- Nicodemus wrote: > const C operator+(int o) > ... > > If I try to expose the operator+ like this: > > .def( self + other() ) > > I get a compiler error: "no operator "+" matches these operands" What happens if you change the member function signature to C operator+(int o) const > Does Boost.Python support member operators? I am pretty sure it does, but your placement of "const" seems very unusual. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From nicodemus at globalite.com.br Sat Mar 1 21:32:25 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 01 Mar 2003 17:32:25 -0300 Subject: [C++-sig] Support for member operators? In-Reply-To: <20030301201353.83610.qmail@web20205.mail.yahoo.com> References: <20030301201353.83610.qmail@web20205.mail.yahoo.com> Message-ID: <3E6118D9.8030103@globalite.com.br> Thanks for the reply Ralf, Ralf W. Grosse-Kunstleve wrote: >--- Nicodemus wrote: > > >> const C operator+(int o) >>... >> >>If I try to expose the operator+ like this: >> >> .def( self + other() ) >> >>I get a compiler error: "no operator "+" matches these operands" >> >> > >What happens if you change the member function signature to > >C operator+(int o) const > > It works then. 8) But what if a class defines a operator + that is not const, ie., it changes an attribute of the class? Can Boost.Python export this, or a particular signature is required to expose operators? >>Does Boost.Python support member operators? >> >> > >I am pretty sure it does, but your placement of "const" seems very unusual. > > It means to return a "const C" object, not that the operator+ is const. Nicodemus. From brett.calcott at paradise.net.nz Sun Mar 2 12:24:03 2003 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Mon, 3 Mar 2003 00:24:03 +1300 Subject: [C++-sig] Re: Enhanced shared_ptr support References: Message-ID: This is very cool. Thanks... > > A few days ago I checked in some changes to the way shared_ptrs get > converted to Python. A while back I had added a special shared_ptr > deleter which caused all shared_ptr conversions from python to > maintain the lifetime of the owning Python object, not of the C++ > object. In other words, we'll have this: > > shared_ptr T > +------+------+ +------+ > | | | | | > | * | *------->| | > | || | | | | > +--||--+------+ +------+ > || /\ > \/ || > +-----------------+ || > | | || > | Python Object *======++ > | | > +-----------------+ > > The double lines represent ownership relationships. Now, when such a > shared_ptr is converted back to python, the owned Python object is > returned, rather than a new Python object being built around the > shared_ptr, sharing ownership of the T object with the Python object > above. > > -Dave > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com From Shayne.FLETCHER at rbos.com Sun Mar 2 14:18:57 2003 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Sun, 2 Mar 2003 13:18:57 -0000 Subject: [C++-sig] how to wrap this handle/body design? Message-ID: <5D6C430AF508AF4CB04061B775D23A7D0909F6@lon0748xns.fm.rbsgrp.net> Hi All, Apologies in advance for the length of the post. I have been trying to work out the details of how to reflect a handle/body with a clone semantics type design but am running in to diffuculties... The idea in the code that follows is that "functors" wrap polymorphic "functor implementations". Existing functor implementations are in C++ but we should like to be able to design new functor implementations in Python, wrap them up in C++ functors and use them both from C++ and Python. Functor implementations are created by "functor constructor" objects which are registered with a "functor factory". The basic problem is 'dangling references': // boost/libs/python/src/converter/from_python.cpp void* lvalue_result_from_python( PyObject* source , registration const& converters , char const* ref_type) { handle<> holder(source); if (source->ob_refcnt <= 2) { handle<> msg( ::PyString_FromFormat( "Attempt to return dangling %s to object of type: %s" , ref_type , converters.target_type.name())); PyErr_SetObject(PyExc_ReferenceError, msg.get()); throw_error_already_set(); } void* result = get_lvalue_from_python(source, converters); if (!result) (throw_no_lvalue_from_python)(source, converters, ref_type); return result; } } We are on boost 1.29.0. Most of the program follows - the troublesome methods are marked with "//???" (the most notable is the 'functor_constructor_wrapper::create_functor()' method). Any assistance will be most gratefully received: class functor_impl { public: virtual ~functor_impl(){} virtual void Attach() const = 0; virtual void Release() const = 0; virtual void perform() const = 0; virtual functor_impl* clone() const = 0; }; template inline T* cloned_impl_ptr(T** pp, T* lp) { T* pTemp = 0; if(lp) { pTemp = lp->clone(); pTemp->Attach(); } if(*pp) (*pp)->Release(); *pp = pTemp; return pTemp; } template class cloned_impl_ptr { public: T* p; cloned_impl_ptr() { p = 0L; } cloned_impl_ptr(T* lp) // takes ownership - does not clone()! { p = lp; if(p) { p->Attach(); } } cloned_impl_ptr(const cloned_impl_ptr& lp) { if(lp.p) { p = lp.p->clone(); p->Attach(); } else p = lp.p; } ~cloned_impl_ptr() { if(p) p->Release(); } T* operator->() const { assert(p!=0L); return p; } T* operator=(const cloned_impl_ptr& lp) { return cloned_impl_ptr_assign(&p, lp.p); } }; class functor { cloned_impl_ptr m_pimpl; public: functor() : m_pimpl(0) {} functor(functor_impl* pimpl) : m_pimpl(pimpl) {} void perform() const { m_pimpl->perform(); } }; class functor_constructor { public: virtual functor create_functor() = 0; virtual functor_impl* create_functor_impl() = 0; }; class functor_factory { private: std::map m_ctors; public: static functor_factory& instance() { static functor_factory ff; return ff; } void register_functor(std::string const& name , functor_constructor* p_functor_constructor) { m_ctors[name] = p_functor_constructor; } functor create_functor(std::string const& name) { functor_constructor* p_functor_constructor = m_ctors[name]; return p_functor_constructor->create_functor(); } functor_impl* create_functor_impl(std::string const& name) { functor_constructor* p_functor_constructor = m_ctors[name]; return p_functor_constructor->create_functor_impl(); } }; struct functor_impl_wrapper : functor_impl { PyObject* m_self; functor_impl_wrapper(PyObject* self) : m_self(self) {} functor_impl_wrapper(PyObject* self , functor_impl const& rhs) : m_self(self), functor_impl(rhs) {} void Attach() const { Py_INCREF(m_self); } void Release() const { Py_DECREF(m_self); } void perform() const { boost::python::call_method(m_self , "perform" , (boost::type*)0); } functor_impl* clone() const { // ??? // how should this be implemented? } }; functor* bind_functor_to_impl(functor_impl* p_impl) { return new functor(p_impl); } struct functor_constructor_wrapper : functor_constructor { PyObject* m_self; functor_constructor_wrapper(PyObject* self) : m_self(self) {} functor_constructor_wrapper(PyObject* self , functor_constructor const& rhs) : m_self(self), functor_constructor(rhs) {} functor_impl* create_functor_impl() { // how should this be implemented? } functor create_functor() { // ??? // how should this be implemented? // first cut was, // return boost::python::call_method(m_self // ,"create_functor" // , (boost::type*)0)); // but this gives rise to runtime errors due to // attempt to return a dangling reference } }; void invoke_functor_perform(functor const& f) { f.perform(); } void create_functor_and_perform(std::string const& which) { functor f = functor_factory::instance().create_functor(which); f.perform(); } BOOST_PYTHON_MODULE(isle) { class_("functor_impl", init<>()) .def(init()) ; class_("functor_constructor", init<>()) ; class_("functor", init<>()) .def(init()) .def(init()) .def("perform", &functor::perform) ; def("bind_functor_to_impl" , &bind_functor_to_impl , return_value_policy()) ; class_("functor_factory", no_init) .def("register_functor", &functor_factory::register_functor) .def("create_functor", &functor_factory::create_functor) ; def("functor_factory_instance" , &functor_factory::instance , return_value_policy()) ; def("invoke_functor_perform" , &invoke_functor_perform) ; def("create_functor_and_perform" , &create_functor_and_perform) ; } Then in Python, import unittest import isle class my_functor_impl(isle.functor_impl): def __init__(self, value=0): self.__value = value isle.functor_impl.__init__(self) def perform(self): print " invocation: my_functor_impl.perform ", self.__value def clone(self): print " invocation: my_functor_impl.clone" mfi = my_functor_impl() isle.functor_impl.__init__(mfi, self) mfi.__value = self.__value + 1 return mfi class my_functor_constructor(isle.functor_constructor): def __init__(self): isle.functor_constructor.__init__(self) def create_functor(self): return isle.bind_functor_to_impl(self.create_functor_impl()) def create_functor_impl(self): mfi = my_functor_impl(0) return mfi mfc = my_functor_constructor() isle.functor_factory_instance().register_functor("my_functor", mfc) print "\nTesting functors..." class functor_test_case(unittest.TestCase): """Tests for functors """ def setUp(self): """Initialize test case""" pass def tearDown(self): """Uninitialize test case""" pass def test(self): """Test functor creation & invocation of functors.""" print "\n Testing creation & invocation of python defined functor..." functor = isle.functor_factory_instance().create_functor("my_functor") print "\n Invoking perform on functor from python..." functor.perform() print "\n Invoking perform on functor from C++..." isle.invoke_functor_perform(functor) print "\n Invoking create & perform..." isle.create_functor_and_perform("my_functor") def testFunctor(self): pass *********************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority *********************************************************************** From nich at users.sourceforge.net Sun Mar 2 16:37:00 2003 From: nich at users.sourceforge.net (Nicholas Francis) Date: Sun, 2 Mar 2003 16:37:00 +0100 Subject: [C++-sig] Exporting references into python Message-ID: A newbie question regarding boost::python. I need to make a templatized function that returns a boost::python::object containing a reference to an object I already have. Basically: template object convertToPython (T &obj) { return object (obj) } All classes I pass through T are already wrapped (they are also not copy-constructible). I tried with the code found at python.orgs wiki: template T& identity(T& x) { return x; } template object get_object_reference (T& x) { object f = make_function (&identity, return_value_policy maps to void. I then tried to hardcode a type just to see if it worked at all: InputManager &identity (InputManager &x) { return x; } object get_object_reference (InputManager &x) { object f = make_function ( &identity, return_value_policy (Nicholas Francis's message of "Sun, 2 Mar 2003 16:37:00 +0100") References: Message-ID: Nicholas Francis writes: > A newbie question regarding boost::python. > > I need to make a templatized function that returns a > boost::python::object containing a reference to an object I already > have. Basically: > > template > object convertToPython (T &obj) { > return object (obj) > } > > All classes I pass through T are already wrapped (they are also not > copy-constructible). I tried with the code found at python.orgs wiki: > > template T& identity(T& x) { return x; } > template object get_object_reference (T& x) { > object f = make_function > (&identity, return_value_policy return f(x); > } > > this code gave me a compile error (on CW 8.3, Mac OS X). Apparently CW > is convinced that the &identity maps to void. Compiler bug. It confounds VC6 and VC7 also. The following works perfectly with cwpro8.3 and the others however: #include using namespace boost::python; template struct identity { static T& execute(T& x) { return x; } }; template object get_object_reference (T& x) { object f = make_function (&identity::execute, return_value_policy()); return f(x); } struct InputManager {}; InputManager x; object get_in_mgr() { return get_object_reference(x); } BOOST_PYTHON_MODULE_INIT(test_ext) { class_("InputManager"); def("get_in_mgr", get_in_mgr); } Maybe you could update the Wiki? > I then tried to hardcode a type just to see if it worked at all: > > InputManager &identity (InputManager &x) { return x; } > object get_object_reference (InputManager &x) { > object f = make_function ( > &identity, return_value_policy return f(x); > } > > This compiled, but gave me a typeerror at runtime: (No to_python > (by-value) converter found for c++ type: InputManager) Are you sure you know which Python code was causing that? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sun Mar 2 23:13:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 02 Mar 2003 17:13:35 -0500 Subject: [C++-sig] Support for member operators? In-Reply-To: <3E6118D9.8030103@globalite.com.br> (Nicodemus's message of "Sat, 01 Mar 2003 17:32:25 -0300") References: <20030301201353.83610.qmail@web20205.mail.yahoo.com> <3E6118D9.8030103@globalite.com.br> Message-ID: Nicodemus writes: >>I am pretty sure it does, but your placement of "const" seems very unusual. >> > > It means to return a "const C" object, not that the operator+ is const. > > Nicodemus. I just checked in some changes to libs/python/test/operators.[py/cpp] which demonstrate that this code compiles, but also that the resulting const object is mistakenly converted to an int(!?). Anyway, I have no time to debug that problem at the moment, but the fact that the test is failing should be a good reminder ;-). If anyone else wants to take a crack at it, I'd be most grateful. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nich at users.sourceforge.net Sun Mar 2 23:23:59 2003 From: nich at users.sourceforge.net (Nicholas Francis) Date: Sun, 2 Mar 2003 23:23:59 +0100 Subject: [C++-sig] Exporting references into python In-Reply-To: Message-ID: On s?ndag, mar 2, 2003, at 22:06 Europe/Copenhagen, David Abrahams wrote: > Nicholas Francis writes: > >> A newbie question regarding boost::python. >> >> I need to make a templatized function that returns a >> boost::python::object containing a reference to an object I already >> have. Basically: >> >> template >> object convertToPython (T &obj) { >> return object (obj) >> } >> >> All classes I pass through T are already wrapped (they are also not >> copy-constructible). I tried with the code found at python.orgs wiki: >> >> template T& identity(T& x) { return x; } >> template object get_object_reference (T& x) { >> object f = make_function >> (&identity, return_value_policy> return f(x); >> } >> >> this code gave me a compile error (on CW 8.3, Mac OS X). Apparently CW >> is convinced that the &identity maps to void. > > Compiler bug. It confounds VC6 and VC7 also. The following works > perfectly with cwpro8.3 and the others however: > > #include > > using namespace boost::python; > > template > struct identity > { > static T& execute(T& x) { return x; } > }; > > template object get_object_reference (T& x) > { > object f = make_function > (&identity::execute, > return_value_policy()); > return f(x); > } > > struct InputManager {}; > InputManager x; > > object get_in_mgr() > { > return get_object_reference(x); > } > > BOOST_PYTHON_MODULE_INIT(test_ext) > { > class_("InputManager"); > def("get_in_mgr", get_in_mgr); > } Thanks a lot for the help - I now got it to compile... > Maybe you could update the Wiki? I would be honored, but will wait untill all the problems are resolved (see below) However, it seems to me that the real problem here is that InputManager (indeed, all T's I will be using) are not copy-constructible. If I try this with InputManager, which is declared as: class_, boost::noncopyable> ("InputManager") ... ; It doesn't work. However, trying with a Vector3f (simple struct, 3 floats) that IS copyable, it works as expected > >> I then tried to hardcode a type just to see if it worked at all: >> >> InputManager &identity (InputManager &x) { return x; } >> object get_object_reference (InputManager &x) { >> object f = make_function ( >> &identity, return_value_policy> return f(x); >> } >> >> This compiled, but gave me a typeerror at runtime: (No to_python >> (by-value) converter found for c++ type: InputManager) > > Are you sure you know which Python code was causing that? It happens when i do f(x). I tried splitting it up into: object o = f(x) printf ("Got here\n"); return o; the Got here never was executed.... Here is a part of the stack trace when the exception was generated: (innermost calls last) TestExtract() _ZNK5boost6python3api16object_operatorsINS1_6objectEEclI12InputManagerEE NNS0_6detail9dependentIS3_T0_EE4typeERKT0_ _ZN5boost6python4callINS0_3api6objectE12InputManagerEENNS0_6detail10retu rnableIT_EE4typeEP7_objectRKT0_PNS_4typeIT_EE boost::python::converter::arg_to_python::arg_to_python(Inp utManager&) boost::python::converter::detail::value_arg_to_python::val ue_arg_to_python(InputManager&) boost::python::converter::detail::arg_to_python_base::arg_to_python_base (const volatile void*, boost::python::converter::registration&) boost::python::converter::registration::to_python(const volatile void*)const boost::python::throw_error_already_set() Cheers, Nicholas Francis From dave at boost-consulting.com Mon Mar 3 00:02:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 02 Mar 2003 18:02:19 -0500 Subject: [C++-sig] Exporting references into python In-Reply-To: (Nicholas Francis's message of "Sun, 2 Mar 2003 23:23:59 +0100") References: Message-ID: Nicholas Francis writes: > On s?ndag, mar 2, 2003, at 22:06 Europe/Copenhagen, David Abrahams > wrote: > >> Nicholas Francis writes: >> >>> A newbie question regarding boost::python. >>> >>> I need to make a templatized function that returns a >>> boost::python::object containing a reference to an object I already >>> have. Basically: >>> >>> template >>> object convertToPython (T &obj) { >>> return object (obj) >>> } >>> >>> All classes I pass through T are already wrapped (they are also not >>> copy-constructible). I tried with the code found at python.orgs wiki: >>> >>> template T& identity(T& x) { return x; } >>> template object get_object_reference (T& x) { >>> object f = make_function >>> (&identity, return_value_policy>> return f(x); >>> } >>> >>> this code gave me a compile error (on CW 8.3, Mac OS X). Apparently CW >>> is convinced that the &identity maps to void. >> >> Compiler bug. It confounds VC6 and VC7 also. The following works >> perfectly with cwpro8.3 and the others however: >> >> #include >> >> using namespace boost::python; >> >> template >> struct identity >> { >> static T& execute(T& x) { return x; } >> }; >> >> template object get_object_reference (T& x) >> { >> object f = make_function >> (&identity::execute, >> return_value_policy()); >> return f(x); >> } >> >> struct InputManager {}; >> InputManager x; >> >> object get_in_mgr() >> { >> return get_object_reference(x); >> } >> >> BOOST_PYTHON_MODULE_INIT(test_ext) >> { >> class_("InputManager"); >> def("get_in_mgr", get_in_mgr); >> } > > Thanks a lot for the help - I now got it to compile... > >> Maybe you could update the Wiki? > > I would be honored, but will wait untill all the problems are resolved > (see below) > > However, it seems to me that the real problem here is that > InputManager (indeed, all T's I will be using) are not > copy-constructible. If I try this with InputManager, which is > declared as: > > class_, boost::noncopyable> > ("InputManager") > ... > ; > > It doesn't work. However, trying with a Vector3f (simple struct, 3 > floats) that IS copyable, it works as expected. I forgot that objects are passed by-value to python functions by default unless you use boost::ref(...). #include using namespace boost::python; template struct identity { static T& execute(T& x) { return x; } }; template object get_object_reference (T& x) { object f = make_function (&identity::execute, return_value_policy()); return f(boost::ref(x)); } struct InputManager {}; InputManager x; object get_in_mgr() { return get_object_reference(x); } BOOST_PYTHON_MODULE_INIT(test_ext) { class_("InputManager"); def("get_in_mgr", get_in_mgr); } -- Dave Abrahams Boost Consulting www.boost-consulting.com From kylelin at gamania.com Mon Mar 3 08:01:52 2003 From: kylelin at gamania.com (=?big5?B?p96zTqzjtW+zoS1LdWxlIExpbiiqTKRsslcp?=) Date: Mon, 3 Mar 2003 15:01:52 +0800 Subject: [C++-sig] Quiz about Extending Python Message-ID: <5000C23E17ED6E4D9C501578674E6C4A156190@TP-EX-03.gamania.com> Hi all, Sorry to interrupt you a little bit, I have a question about extending python problem, could anyone please help me to get some idea about it? My question is that, I've created my Python own module ("pyArea"), a script file to call to the object and an application to call to the script file. Ok, let me show you the coding part~ 1. Python Script: import pyArea area = pyArea.CreateObject() # create a new object def Zoom() area.Zoom() 2. Application: Inside the Message Loop: if (g_pDict) pFunc = PyDict_GetItemString(g_pDict, "Zoom"); if (PyCallable_Check(pFunc)) { PyObject *objResult = PyObject_CallFunction(pFunc, NULL); } Well, my question is that, after I call the function PyObject_CallFunction for ?217? times the program just crash instantly( crashed in Python_d.dll : debug DLL ?Msg: First-chance exception in rwtest.exe (PYTHON22_D.DLL): 0xC0000005: Access Violation.? ), I've try to make my own module as simple as possible but the result would be somehow the same as before. Have you ever encounter the same problem as I do? Or I didn't release the memory properly, so the Python Interpreter may still trap some memory inside? However, if I discard of using my module in Python Script(without calling pyArea.Zoom()), the function call seems working alright. If you have any idea about it could you please help me~ thank you. =) Ps. My OS is Windows 2000, Python version: 2.2.2 Kyle Lin. -------------- next part -------------- An HTML attachment was scrubbed... URL: From achim.domma at syynx.de Mon Mar 3 16:24:23 2003 From: achim.domma at syynx.de (Achim Domma) Date: Mon, 3 Mar 2003 16:24:23 +0100 Subject: [C++-sig] implicitly_convertible with abstract class Message-ID: Hi, the following line generates some errors and has worked with earlier versions of boost.python, as far as I know. implicitly_convertible(); Any hint what's going wrong? VPathBase is an abstract base class, the error are attached. regards, Achim PythonMagick.cpp K:\cvsroot\boost\boost\python\detail\is_auto_ptr.hpp(18) : error C2259: 'Magick::VPathBase' : cannot instantiate abstract class due to following members: 'void Magick::VPathBase::operator ()(MagickLib::DrawContext) const' : pure virtual function was not defined j:\Program Files\PythonMagick-0.4\include\Magick++\Drawable.h(202) : see declaration of 'Magick::VPathBase::operator`()'' 'Magick::VPathBase *Magick::VPathBase::copy(void) const' : pure virtual function was not defined j:\Program Files\PythonMagick-0.4\include\Magick++\Drawable.h(205) : see declaration of 'Magick::VPathBase::copy' K:\cvsroot\boost\boost\python\detail\copy_ctor_mutates_rhs.hpp(17) : see reference to class template instantiation 'boost::python::detail::is_auto_ptr' being compiled with [ X_=Magick::VPathBase ] K:\cvsroot\boost\boost\mpl\if.hpp(109) : see reference to class template instantiation 'boost::python::detail::copy_ctor_mutates_rhs' being compiled with [ T=Magick::VPathBase ] K:\cvsroot\boost\boost\python\extract.hpp(61) : see reference to class template instantiation 'boost::mpl::if_' being compiled with [ C_=boost::python::detail::copy_ctor_mutates_rhs, T1=Magick::VPathBase &, T2=boost::call_traits::param_type ] K:\cvsroot\boost\boost\python\extract.hpp(115) : see reference to class template instantiation 'boost::python::converter::extract_rvalue' being compiled with [ T=Magick::VPathBase ] K:\cvsroot\boost\boost\python\converter\implicit.hpp(34) : see reference to class template instantiation 'boost::python::extract' being compiled with [ T=Magick::VPathBase ] K:\cvsroot\boost\boost\python\converter\implicit.hpp(31) : while compiling class-template member function 'void boost::python::converter::implicit::construct(PyObject *,boost::python::converter::rvalue_from_python_stage1_data *)' with [ Source=Magick::VPathBase, Target=Magick::VPath ] K:\cvsroot\boost\boost\python\implicit.hpp(21) : see reference to class template instantiation 'boost::python::converter::implicit' being compiled with [ Source=Magick::VPathBase, Target=Magick::VPath ] PythonMagick.cpp(45) : see reference to function template instantiation 'void boost::python::implicitly_convertible(boost::type *,boost::type *)' being compiled with [ T=Magick::VPathBase, Target=Magick::VPath ] K:\cvsroot\boost\boost\python\detail\is_auto_ptr.hpp(18) : error C2259: 'Magick::VPathBase' : cannot instantiate abstract class due to following members: 'void Magick::VPathBase::operator ()(MagickLib::DrawContext) const' : pure virtual function was not defined j:\Program Files\PythonMagick-0.4\include\Magick++\Drawable.h(202) : see declaration of 'Magick::VPathBase::operator`()'' 'Magick::VPathBase *Magick::VPathBase::copy(void) const' : pure virtual function was not defined j:\Program Files\PythonMagick-0.4\include\Magick++\Drawable.h(205) : see declaration of 'Magick::VPathBase::copy' "cl" /Zm800 -nologo -GX -c -DNDEBUG -DHAVE_IOSFWD -DBOOST_PYTHON_DYNAMIC_LIB /Ogity /O2 /Gs /Ob2 /GX /GR /MD /Op /Zc:wchar_t,forScope -I"..\..\..\libs\python\PythonMagick" -I"J:\Program Files\PythonMagick-0.4\include\Magick++\lib" -I"J:\Program Files\PythonMagick-0.4\include" -I"K:\cvsroot\boost" -I"c:\python22\include " -I"D:\Program Files\Microsoft Visual Studio ET\VC7\include" -Fo"..\..\..\libs\python\PythonMagick\bin\_PythonMagick.py d\vc7\release\runtime-link-dynamic\PythonMagick.obj" -Tp"PythonMagick.cpp" ...failed vc-C++ ..\..\..\libs\python\PythonMagick\bin\_PythonMagick.pyd\vc7\release\runtime- link-dynamic\PythonMagick.obj... From dave at boost-consulting.com Mon Mar 3 18:22:15 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 03 Mar 2003 12:22:15 -0500 Subject: [C++-sig] implicitly_convertible with abstract class In-Reply-To: ("Achim Domma"'s message of "Mon, 3 Mar 2003 16:24:23 +0100") References: Message-ID: "Achim Domma" writes: > Hi, > > the following line generates some errors and has worked with earlier > versions of boost.python, as far as I know. > > implicitly_convertible(); > > Any hint what's going wrong? VPathBase is an abstract base class, the error > are attached. This is a vc7 bug. A workaround has been checked into CVS. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 3 23:14:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 03 Mar 2003 17:14:53 -0500 Subject: [C++-sig] how to wrap this handle/body design? In-Reply-To: <5D6C430AF508AF4CB04061B775D23A7D0909F6@lon0748xns.fm.rbsgrp.net> ("FLETCHER, Shayne, FM"'s message of "Sun, 2 Mar 2003 13:18:57 -0000") References: <5D6C430AF508AF4CB04061B775D23A7D0909F6@lon0748xns.fm.rbsgrp.net> Message-ID: "FLETCHER, Shayne, FM" writes: > Hi All, > > Apologies in advance for the length of the post. I have been trying to work > out the details of how to reflect a handle/body with a clone semantics type > design but am running in to diffuculties... Well, I think I am able to understand the basic nature of your problem, but it would sure have helped if you had reduced it to a much smaller case. I think that's possible for you to do fairly easily and it would probably deepen your understanding of the problem as well. > The idea in the code that follows is that "functors" wrap polymorphic > "functor implementations". Existing functor implementations are in C++ but > we should like to be able to design new functor implementations in Python, > wrap them up in C++ functors and use them both from C++ and Python. Functor > implementations are created by "functor constructor" objects which are > registered with a "functor factory". > > The basic problem is 'dangling references': OK, do you understand what that means? The Python implementation of the virtual function is returning a new Python object which owns the object whose address you're trying to return. The inside of your virtual function overload contains the only reference to that new object. If the function returns the reference count will be decremented, the object will be destroyed, and the resulting pointer will dangle. There are several ways to approach this problem, and they all involve using smart pointers. I would strongly recommend that you recast your interface in terms of smart pointers anyway; it will help in so many ways. So: class functor_impl { public: virtual ~functor_impl(){} virtual void Attach() const = 0; virtual void Release() const = 0; virtual void perform() const = 0; virtual boost::shared_ptr clone() const = 0; }; I also recommend you get the latest CVS state or at least the RC_1_30_0 branch, since it has much better support for smart pointers than 1.29.0. HTH, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From Alexey.Goldin at jpl.nasa.gov Mon Mar 3 22:54:17 2003 From: Alexey.Goldin at jpl.nasa.gov (Alexey Goldin) Date: 03 Mar 2003 13:54:17 -0800 Subject: [C++-sig] Chaining methods in C++ and Python Message-ID: <1046728456.17607.1.camel@hobbit> I have (I believe) a fairly simple for experts question. I am trying to wrap a medium size high frequency circuit simulation package (Supermix, at http://www.submm.caltech.edu/supermix/default.html I encountered the following problem. Many class methods return reference to themself to allow chaining, something along the line class microstrip{ microstrip & top_strip(impedance & t); microstrip & ground_plane(impedance & g); microstrip & substrate(dielectric s); microstrip & superstrate(dielectric s) .................More stuff follows............. } These methods establish relationship between microstrip object and objects like length, width, substrate, etc... (yes, length is also an object --- it can be parameter dependent on other numbers) Naturally, to protect objects like substrate, superstrate, length, etc. from beeing freed by memory management, I am trying to use the following mechanism (fragment from my wrapper): class_ >("microstrip", init<>()) .def(init()) .def("substrate", µstrip::substrate, return_internal_reference<1,with_custodian_and_ward<1,2> >() ) .def("superstrate", µstrip::superstrate, return_internal_reference<1,with_custodian_and_ward<1,2> >() ) .def("top_strip", µstrip::top_strip, return_internal_reference<1,with_custodian_and_ward<1,2> >() ) .def("ground_plane",µstrip::ground_plane,return_internal_reference<1,with_custodian_and_ward<1,2> >() ); This is working fine, if I am using the following code (Python): SiO=const_diel(7.5,0.01) air=const_diel(1.0,0) line = microstrip() #line.top_strip(nb).ground_plane(nb).substrate(SiO) line.top_strip(nb) line.ground_plane(nb) line.substrate(SiO) return line However, if I try to replace the last three lines with one commented out line with chained calls, the first time I try to call microstrip methods I get error message: pure virtual method called Aborted This is the kind of message C++ runtime library is giving when I do not protect referenced objects with_custodian_and_ward. However, in this case the error is triggered by going to chained call. g++ -v Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.4/specs gcc version 2.95.4 20011002 (Debian prerelease) I am using Pyton 2.2.2, latest CVS boost. I'd really like to have Python very similar to one produced by C++ If the problem non-obvious, I will spend a day or two provide some test case that will fit in few pages. I' however, hope that the problem may be obvious to experts without it. My suspicion is that chained call is creating a temporary object (new one for each call of method like top_strip), the lifetime of referenced object is tied to lifetime of this temporary object, which is later destroyed. This does not happen If this is so, how can I bypass this problem? Thanks! -- Alexey Goldin From dave at boost-consulting.com Tue Mar 4 00:37:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 03 Mar 2003 18:37:12 -0500 Subject: [C++-sig] Chaining methods in C++ and Python In-Reply-To: <1046728456.17607.1.camel@hobbit> (Alexey Goldin's message of "03 Mar 2003 13:54:17 -0800") References: <1046728456.17607.1.camel@hobbit> Message-ID: Alexey Goldin writes: > If the problem non-obvious, I will spend a day or two provide some > test case that will fit in few pages. I' however, hope that the > problem may be obvious to experts without it. It's not obvious to me at first glance, but it should be easy to make a test case that fits comfortably in <50 lines of C++. If you can post that I'm sure I can answer your question. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Alexey.Goldin at jpl.nasa.gov Tue Mar 4 02:43:10 2003 From: Alexey.Goldin at jpl.nasa.gov (Alexey Goldin) Date: 03 Mar 2003 17:43:10 -0800 Subject: [C++-sig] Chaining methods in C++ and Python Message-ID: <1046742189.18231.2.camel@hobbit> >It's not obvious to me at first glance, but it should be easy to make >a test case that fits comfortably in <50 lines of C++. If you can >post that I'm sure I can answer your question. I will sure try, but so far I have not managed to reproduce it in small test case :-( Thanks! -- Alexey Goldin From sabbatini at deanovell.unian.it Tue Mar 4 10:29:56 2003 From: sabbatini at deanovell.unian.it (Massimo Sabbatini) Date: Tue, 4 Mar 2003 10:29:56 +0100 Subject: [C++-sig] boost::python - feeding C++ functions with Python Numeric arrays Message-ID: <006301c2e230$a46e12e0$044ca8c0@magellano> Dear SIG, I would like to use boost::python to feed my c++ numerical routines with Numeric arrays [ python 2.2, boost 1.30 (cvs), Numeric 22 ]. What I need is the following: 1) taking a Numeric object as an argument 2) extract shape information 3) extract values and fill c++ variables with those values I tried the following for 1D objects but I did not get anything out of it: /// Assign a grid from a 1D python Numeric object void set_asset_grid_py(boost::python::numeric::array& grid ) { int array_size = boost::python::extract(grid.attr("shape")()); m_asset_grid.resize( array_size ); for(int i=0; i(grid[ i ]); }; What am I missing? Any suggestion will be greatly appreciated. Regards, Massimo From ssmith at magnet.fsu.edu Tue Mar 4 14:25:00 2003 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Tue, 04 Mar 2003 08:25:00 -0500 Subject: [C++-sig] OSX darwin-tools glitch? In-Reply-To: Message-ID: Hello, For fun I have once again tried to build Boost.Python using OSX. Nothing worked well, so I decided I better follow the directions recently posted: http://cci.lbl.gov/boost/ (darwin_notes). I rebuilt gcc, rebuilt python, then tried BP w/ latest CVS. Although there are lots of warnings, everything proceeded up to the end of the BP build. Then I get these complaints: ld: can't open: /usr/local_cci/gcc-3.2.2/lib/libstdc++.a (No such file or directory, errno = 2) ld: can't open: /usr/local_cci/gcc-3.2.2/lib/gcc-lib/powerpc-apple-darwin6.4/3.2.2/libgcc.a (No such file or directory, Having a look in the darwin-tools.jam file in the boost/tools/build directory, I found that local-cci is explicitly used. My (plain) install of GCC put the libraries into /usr/local/lib rather that libstdc++.a /usr/local_cci/gcc-3.2.2/lib. I altered the darwin-tools.jam file to reflect this and the BP build then ran to completion and produced libboost_python.dylib. Am I doing something wrong or is there a glitch in the darwin-tools.jam file? I am not familiar with the directory /usr/local_cci, perhaps Nick just used that for his GCC install? Thanks & many thanks to Nick for putting up his build directions, Scott From Shayne.FLETCHER at rbos.com Tue Mar 4 15:03:22 2003 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 4 Mar 2003 14:03:22 -0000 Subject: [C++-sig] why does this produce a dangling reference? Message-ID: <5D6C430AF508AF4CB04061B775D23A7D090A00@lon0748xns.fm.rbsgrp.net> Hi All: Here's what seems to me to be a fairly simple use case that unfortunately suffers from the "attempt to return dangling reference" problem (using current CVS snapshot). Can anyone help me understand what I'm doing wrong and what I can do to overcome the problem? class period {}; class rate_impl{ private: period m_period; public: virtual ~rate_impl() {} virtual period const& get_floating_frequency() const { return m_period; } virtual void generate_dates() const { period p = get_floating_frequency(); // ! causes 'dangling reference' } }; struct rate_impl_wrapper : rate_impl{ PyObject* m_self; rate_impl_wrapper(PyObject* self) : m_self(self) {} period const& get_floating_frequency() const { return boost::python::call_method(m_self ,"get_floating_frequency" , (boost::type*)0); } period const& default_get_floating_frequency() const { return rate_impl::get_floating_frequency(); } void generate_dates() const { boost::python::call_method(m_self , "generate_dates" , (boost::type*)0); } void default_generate_dates() const { rate_impl::generate_dates(); } }; BOOST_PYTHON_MODULE(isle) { class_("period", init<>()) ; class_("rate_impl", init<>()) .def("get_floating_frequency" , &rate_impl::get_floating_frequency , &rate_impl_wrapper::default_get_floating_frequency , return_value_policy()) .def("generate_dates" , &rate_impl::generate_dates , &rate_impl_wrapper::default_generate_dates) ; } Then in Python, import isle rate = isle.rate_impl() rate.generate_dates() The end result is: Traceback (most recent call last): File "test_rate.py", line 3, in ? rate.generate_dates() ReferenceError: Attempt to return dangling reference to object of type: class period - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From Shayne.FLETCHER at rbos.com Tue Mar 4 17:38:00 2003 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 4 Mar 2003 16:38:00 -0000 Subject: [C++-sig] re: how to wrap this handle/body design? Message-ID: <5D6C430AF508AF4CB04061B775D23A7D090A01@lon0748xns.fm.rbsgrp.net> Dave: >> Apologies in advance for the length of the post. I have been trying to work >> out the details of how to reflect a handle/body with a clone semantics type >> design but am running in to diffuculties... >Well, I think I am able to understand the basic nature of your >problem, but it would sure have helped if you had reduced it to a much >smaller case. I think that's possible for you to do fairly easily and >it would probably deepen your understanding of the problem as well. Yes. Apologies for that... I am very keen to get to grips with the problem in it's entirety. >> The basic problem is 'dangling references': >OK, do you understand what that means? >The Python implementation of the virtual function is returning a new >Python object which owns the object whose address you're trying to >return. The inside of your virtual function overload contains the >only reference to that new object. If the function returns the >reference count will be decremented, the object will be destroyed, and >the resulting pointer will dangle. Indeed, I have got this. What has eluded me thus far (beyond artifically bumping up the PyObject's ref count) is how to avoid the situation. > There are several ways to approach this problem, and they all involve >using smart pointers. Can you point me at any documentation relating to these approaches? > I would strongly recommend that you recast >your interface in terms of smart pointers anyway; it will help in so >many ways. So: > class functor_impl > { > public: > virtual ~functor_impl(){} > virtual void Attach() const = 0; > virtual void Release() const = 0; > virtual void perform() const = 0; > virtual boost::shared_ptr clone() const = 0; > }; Thanks for the tip. > I also recommend you get the latest CVS state or at least the > RC_1_30_0 branch, since it has much better support for smart pointers > than 1.29.0. Done. > HTH, Well you have. In the first instance, mgt. have been persuaded that I may have a little more time on the problem and in the second I am confident that with a little more effort I will arrive at a satisfactory result. Thanks. - Shayne. *********************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority *********************************************************************** From Shayne.FLETCHER at rbos.com Tue Mar 4 19:21:42 2003 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 4 Mar 2003 18:21:42 -0000 Subject: [C++-sig] more on why does this produce a dangling reference? Message-ID: <5D6C430AF508AF4CB04061B775D23A7D090A02@lon0748xns.fm.rbsgrp.net> Dear All: Further to my earlier posting today http://mail.python.org/pipermail/c++-sig/2003-March/003504.html, I have found one way that seems to produce the required behaviour: period const& rate_impl_wrapper::get_floating_frequency() const { boost::python::object obj( boost::python::call_method(m_self ,"get_floating_frequency" , (boost::type*)0)); return boost::python::extract(obj)(); } This approach no longer gives rise to a dangling reference error and it appears to work, but, since obj refcnt is 1, surely this code is returning a reference to a temporary? - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From Alexey.Goldin at jpl.nasa.gov Tue Mar 4 18:47:01 2003 From: Alexey.Goldin at jpl.nasa.gov (Alexey Goldin) Date: 04 Mar 2003 09:47:01 -0800 Subject: [C++-sig] Chaining methods in C++ and Python Message-ID: <1046800021.19860.5.camel@hobbit> Here is a small test case which seems to reproduce the problem --- see attached files. Build test.so from test.cpp, then run python t.py Thanks! -- Alexey Goldin -------------- next part -------------- A non-text attachment was scrubbed... Name: test.cpp Type: text/x-c++ Size: 1172 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: t.py Type: text/x-python Size: 255 bytes Desc: not available URL: From NKSauter at lbl.gov Wed Mar 5 01:04:05 2003 From: NKSauter at lbl.gov (NKSauter at lbl.gov) Date: Tue, 04 Mar 2003 16:04:05 -0800 Subject: [C++-sig] OSX darwin-tools glitch? Message-ID: <11d52911c195.11c19511d529@lbl.gov> Glad to see the darwin_notes are of some interest. Scott is absolutely correct: /usr/local_cci/gcc-3.2.2 is my own installation-specific directory name, a result of installing gcc with "--prefix=". Perhaps someone could comment on the correct procedure for specifying a special -L path in the toolset darwin-tools.jam. I don't understand bjam usage well enough to prepend my special directory to the library search path. Nick Sauter ----- Original Message ----- From: "Scott A. Smith" Date: Tuesday, March 4, 2003 5:25 am Subject: [C++-sig] OSX darwin-tools glitch? > Hello, > > For fun I have once again tried to build Boost.Python using OSX. > Nothing worked well, so I decided I better follow the directions > recently posted: http://cci.lbl.gov/boost/ (darwin_notes). I > rebuilt gcc, rebuilt python, then tried BP w/ latest CVS. Although > there are > lots of warnings, everything proceeded up to the end of the BP > build. Then I get these complaints: > > ld: can't open: /usr/local_cci/gcc-3.2.2/lib/libstdc++.a (No such > file or > directory, errno = 2) > ld: can't open: > /usr/local_cci/gcc-3.2.2/lib/gcc-lib/powerpc-apple- > darwin6.4/3.2.2/libgcc.a(No such file or directory, > > Having a look in the darwin-tools.jam file in the boost/tools/build > directory, > I found that local-cci is explicitly used. My (plain) install of > GCC put the > libraries > into /usr/local/lib rather that libstdc++.a /usr/local_cci/gcc- > 3.2.2/lib. I > altered the > darwin-tools.jam file to reflect this and the BP build then ran to > completion and > produced libboost_python.dylib. > > Am I doing something wrong or is there a glitch in the darwin- > tools.jamfile? > I am not familiar with the directory /usr/local_cci, perhaps Nick > just used > that > for his GCC install? > > Thanks & many thanks to Nick for putting up his build directions, > Scott > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From dave at boost-consulting.com Wed Mar 5 03:13:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 04 Mar 2003 21:13:12 -0500 Subject: [C++-sig] why does this produce a dangling reference? In-Reply-To: <5D6C430AF508AF4CB04061B775D23A7D090A00@lon0748xns.fm.rbsgrp.net> ("FLETCHER, Shayne, FM"'s message of "Tue, 4 Mar 2003 14:03:22 -0000") References: <5D6C430AF508AF4CB04061B775D23A7D090A00@lon0748xns.fm.rbsgrp.net> Message-ID: "FLETCHER, Shayne, FM" writes: The problem is here: > period const& get_floating_frequency() const > { > return boost::python::call_method(m_self > ,"get_floating_frequency" > , (boost::type*)0); > } First, why are you using an _undocumented_ optional parameter of call_method that way? It's not causing your issue, but you're using an implementation detail of Boost.Python which could change at any moment, rendering your code invalid. The correct way to do this is: period const& get_floating_frequency() const { return boost::python::call_method( m_self,"get_floating_frequency"); } I guess I should stop using type<> and start using some other template that will cause an error if users try to touch it. :( Anyway, the problem here is exactly as the message says: ReferenceError: Attempt to return dangling reference to object of type: class period The Python method invoked by call_method constructs a new Python object. You're trying to return a reference to a C++ object (an instance of class period) contained within and owned by that Python object. However, but the last reference to the Python object is held by get_floating_frequency() above, and when the function returns, the Python object will be destroyed, destroying the instance of class period, and leaving the returned reference dangling. That's already undefined behavior, and will probably lead to a crash. That's what you're doing wrong. As to what you can do to overcome the problem, start by understanding the lifetimes of the objects you're working with... hopefully a workable approach will then be obvious to you. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 5 03:23:13 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 04 Mar 2003 21:23:13 -0500 Subject: [C++-sig] re: how to wrap this handle/body design? In-Reply-To: <5D6C430AF508AF4CB04061B775D23A7D090A01@lon0748xns.fm.rbsgrp.net> ("FLETCHER, Shayne, FM"'s message of "Tue, 4 Mar 2003 16:38:00 -0000") References: <5D6C430AF508AF4CB04061B775D23A7D090A01@lon0748xns.fm.rbsgrp.net> Message-ID: Wow, not even emacs was able to clean up the crazy line breaks in your message; I had to do this by hand... "FLETCHER, Shayne, FM" writes: > Dave: > > >> Apologies in advance for the length of the post. I have > >> been trying to work out the details of how to reflect a > >> handle/body with a clone semantics type design but am > >> running in to diffuculties... > > >Well, I think I am able to understand the basic nature of your > >problem, but it would sure have helped if you had reduced it to a > >much smaller case. I think that's possible for you to do fairly > >easily and it would probably deepen your understanding of the > >problem as well. > > Yes. Apologies for that... I am very keen to get to grips with the > problem in it's entirety. > > >> The basic problem is 'dangling references': > > >OK, do you understand what that means? > >The Python implementation of the virtual function is returning a > >new Python object which owns the object whose address you're > >trying to return. The inside of your virtual function overload > >contains the only reference to that new object. If the function > >returns the reference count will be decremented, the object will > >be destroyed, and the resulting pointer will dangle. > > Indeed, I have got this. What has eluded me thus far (beyond > artifically bumping up the PyObject's ref count) is how to avoid the > situation. "Don't try to return references to objects you own" is the basic approach. It's the same rule as you'd use for C++. IOW, you don't do this: X& f() { X x; return x; }; > > There are several ways to approach this problem, and they all > > involve using smart pointers. > > Can you point me at any documentation relating to these approaches? Sadly, no. However, if you take my advice about recasting the interface in terms of smart pointers, then you can return a smart pointer instead of a reference in this case. > > I would strongly recommend that you recast your interface in > >terms of smart pointers anyway; it will help in so many ways. > >So: > HTH again, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 5 03:25:02 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 04 Mar 2003 21:25:02 -0500 Subject: [C++-sig] more on why does this produce a dangling reference? In-Reply-To: <5D6C430AF508AF4CB04061B775D23A7D090A02@lon0748xns.fm.rbsgrp.net> ("FLETCHER, Shayne, FM"'s message of "Tue, 4 Mar 2003 18:21:42 -0000") References: <5D6C430AF508AF4CB04061B775D23A7D090A02@lon0748xns.fm.rbsgrp.net> Message-ID: "FLETCHER, Shayne, FM" writes: > Dear All: > > Further to my earlier posting today > http://mail.python.org/pipermail/c++-sig/2003-March/003504.html, I have > found one way that seems to produce the required behaviour: > > period const& rate_impl_wrapper::get_floating_frequency() const > { > boost::python::object obj( > boost::python::call_method(m_self > ,"get_floating_frequency" > , (boost::type*)0)); > return boost::python::extract(obj)(); > } > > This approach no longer gives rise to a dangling reference error and it > appears to work, but, since obj refcnt is 1, surely this code is returning a > reference to a temporary? Not a temporary in the sense the C++ standard uses the word, but yes, the effect is the same. You're still returning a dangling reference. You've just managed to subvert the protections Boost.Python gives you. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 5 12:36:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 05 Mar 2003 06:36:00 -0500 Subject: [C++-sig] Chaining methods in C++ and Python In-Reply-To: <1046800021.19860.5.camel@hobbit> (Alexey Goldin's message of "04 Mar 2003 09:47:01 -0800") References: <1046800021.19860.5.camel@hobbit> Message-ID: Alexey Goldin writes: > Here is a small test case which seems to reproduce the problem --- see attached files. > > Build test.so from test.cpp, then run python t.py > > > Thanks! This is a simple issue of lifetime management. The C++ 'a' objects created in mk_tst are owned by their corresponding Python objects, which get destroyed when mk_tst exits. The pointers you have stored in your 'tst' object are dangling thereafter. The Introduction section at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/with_custodian_and_ward.html#introduction explains this fairly well HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 5 15:57:02 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 05 Mar 2003 09:57:02 -0500 Subject: [C++-sig] Inherited instance variables In-Reply-To: (Matt Giger's message of "Fri, 28 Feb 2003 15:43:52 -0800") References: Message-ID: Matt Giger writes: > Hi, I just discovered Boost.Python and I am very impressed (as I am > with most of Boost). I have embedded a Python interpreter in my > project and would like to tie in some C++ classes but am having > problems with inherited member variables. Matt, are you using Boost 1.29.0 or the CVS? There have been some improvements in handling of mutable attributes. > Here is my example: > > C++ > --- > > struct foo { > foo(void) {} > virtual ~foo(void) {} > virtual bool handle_evt(object event) { return false; } > list children; > } > > struct foowrap : foo { > foowrap(PyObject* self) : self_(self) {} > foowrap(PyObject* self, const foo& f) : foo(f), self_(self) {} > bool handle_evt(object event) > { return call_method(self_, "handle_evt", event); } > static bool def_handle_evt(foo* f, object event) > { return f->foo::handle_evt(event); } > PyObject* const self_; > }; > > BOOST_PYTHON_MODULE(foomod) > { > class("foo") > .def("handle_evt", &foowrap::def_handle_evt) > .def_readwrite("children", &widget::children); > } This won't compile; where's widget? ... -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 5 16:22:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 05 Mar 2003 10:22:57 -0500 Subject: [C++-sig] OSX darwin-tools glitch? In-Reply-To: <11d52911c195.11c19511d529@lbl.gov> (NKSauter@lbl.gov's message of "Tue, 04 Mar 2003 16:04:05 -0800") References: <11d52911c195.11c19511d529@lbl.gov> Message-ID: NKSauter at lbl.gov writes: > Glad to see the darwin_notes are of some interest. Scott is > absolutely correct: /usr/local_cci/gcc-3.2.2 is my own > installation-specific directory name, a result of installing gcc with > "--prefix=". > > Perhaps someone could comment on the correct procedure for specifying > a special -L path in the toolset darwin-tools.jam. I don't understand > bjam usage well enough to prepend my special directory to the library > search path. [Boost.Build questions should go to the jamboost list] Anyway, is it a fixed directory that you want in the library search path, does it depend on the installation, or is it always someplace relative to the rest of the toolset installation? Should it always go in the library path for this toolset, or only when building Boost.Python targets? > ----- Original Message ----- From: "Scott A. Smith" > Date: Tuesday, March 4, 2003 5:25 am Subject: > [C++-sig] OSX darwin-tools glitch? > >> Hello, >> >> For fun I have once again tried to build Boost.Python using OSX. >> Nothing worked well, so I decided I better follow the directions >> recently posted: http://cci.lbl.gov/boost/ (darwin_notes). I rebuilt >> gcc, rebuilt python, then tried BP w/ latest CVS. Although there are >> lots of warnings, everything proceeded up to the end of the BP >> build. Then I get these complaints: >> >> ld: can't open: /usr/local_cci/gcc-3.2.2/lib/libstdc++.a (No such >> file or directory, errno = 2) ld: can't open: >> /usr/local_cci/gcc-3.2.2/lib/gcc-lib/powerpc-apple- >> darwin6.4/3.2.2/libgcc.a(No such file or directory, >> >> Having a look in the darwin-tools.jam file in the boost/tools/build >> directory, I found that local-cci is explicitly used. My (plain) >> install of GCC put the libraries into /usr/local/lib rather that >> libstdc++.a /usr/local_cci/gcc- 3.2.2/lib. I altered the >> darwin-tools.jam file to reflect this and the BP build then ran to >> completion and produced libboost_python.dylib. >> >> Am I doing something wrong or is there a glitch in the darwin- >> tools.jamfile? I am not familiar with the directory /usr/local_cci, >> perhaps Nick just used that for his GCC install? >> >> Thanks & many thanks to Nick for putting up his build directions, >> Scott >> >> >> _______________________________________________ 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 mgiger at lunarsoft.com Wed Mar 5 16:25:05 2003 From: mgiger at lunarsoft.com (Matt Giger) Date: Wed, 5 Mar 2003 07:25:05 -0800 Subject: [C++-sig] Inherited instance variables In-Reply-To: References: Message-ID: >Matt Giger writes: > >> Hi, I just discovered Boost.Python and I am very impressed (as I am >> with most of Boost). I have embedded a Python interpreter in my >> project and would like to tie in some C++ classes but am having >> problems with inherited member variables. > >Matt, are you using Boost 1.29.0 or the CVS? There have been some >improvements in handling of mutable attributes. > >> Here is my example: >> >> C++ >> --- >> >> struct foo { >> foo(void) {} >> virtual ~foo(void) {} >> virtual bool handle_evt(object event) { return false; } >> list children; >> } >> >> struct foowrap : foo { >> foowrap(PyObject* self) : self_(self) {} >> foowrap(PyObject* self, const foo& f) : foo(f), self_(self) {} >> bool handle_evt(object event) >> { return call_method(self_, "handle_evt", event); } >> static bool def_handle_evt(foo* f, object event) >> { return f->foo::handle_evt(event); } >> PyObject* const self_; >> }; >> >> BOOST_PYTHON_MODULE(foomod) >> { >> class("foo") >> .def("handle_evt", &foowrap::def_handle_evt) >> .def_readwrite("children", &widget::children); >> } > >This won't compile; where's widget? Yikes, sorry I did some simplification of the code and got caught by that old copy-paste bug creation technique, "widget::children" should read "foo::children". I'm using 1.29.0. BTW. Thank you for replying, your Boost.Python lib saves *a ton* of work and you seem tireless in your (free) help for people using it. I just wanted to thank you for your tremendous efforts. -- Matt Giger Lunar Software, Inc. mgiger at lunarsoft.com From Shayne.FLETCHER at rbos.com Wed Mar 5 18:29:53 2003 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Wed, 5 Mar 2003 17:29:53 -0000 Subject: [C++-sig] re: how to wrap this handle/body design? Message-ID: <5D6C430AF508AF4CB04061B775D23A7D090A03@lon0748xns.fm.rbsgrp.net> Dave: > The basic problem is 'dangling references': > I would strongly recommend that you recast your interface in > terms of smart pointers anyway; it will help in so many ways. > HTH again, You have - my problems are sorted. Thanks. I'm very grateful :-) - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From Alexey.Goldin at jpl.nasa.gov Wed Mar 5 18:19:53 2003 From: Alexey.Goldin at jpl.nasa.gov (Alexey Goldin) Date: 05 Mar 2003 09:19:53 -0800 Subject: [C++-sig] Chaining methods in C++ and Python In-Reply-To: References: <1046800021.19860.5.camel@hobbit> Message-ID: <1046884793.24480.9.camel@hobbit> > > This is a simple issue of lifetime management. The C++ 'a' objects > created in mk_tst are owned by their corresponding Python objects, > which get destroyed when mk_tst exits. The pointers you have stored > in your 'tst' object are dangling thereafter. > > The Introduction section at > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/with_custodian_and_ward.html#introduction > explains this fairly well > > HTH, Ok. This makes sense. However --- is it possible to do one of the following things in not too ugly way: 1) allow writing something like t.set_f1(a1).set_f2(a2) and make sure that pointers to both a1 and a2 are owned by t --- preferable solution 2) Making sure that t.set_f1(a1) does not return object of type tst, so calling t.set_f1(a1).set_f2(a2) and instead I have to call t.set_f1(a1) t.set_f2(a2) --- not so good, but at least making sure it is not easy to crash application? I can not change signature of method tst::set_f1 --- this is a library not under my control. Yes, I can write some wrappers but in my understanding this is what boost.python was created to avoid.... Thank you! boost.python is a wonderful tool, but sometimes as confusing as C++ :-) -- Alexey Goldin From cleung at eos.ubc.ca Wed Mar 5 19:45:58 2003 From: cleung at eos.ubc.ca (Charles Leung) Date: Wed, 5 Mar 2003 10:45:58 -0800 (PST) Subject: [C++-sig] boost::python - feeding C++ functions with Python Numeric arrays In-Reply-To: <006301c2e230$a46e12e0$044ca8c0@magellano> References: <006301c2e230$a46e12e0$044ca8c0@magellano> Message-ID: <32775.137.82.23.131.1046889958.squirrel@webmail.eos.ubc.ca> Hi Massimo, I noticed your message has been up for a while and not yet being replied, so I'm just going to give it a try here = ). I implemented a Numeric array interface on top of boost's using a combination of boost library methods and Python's C interface. As far as I can remember, some of boost's Numeric array member function didn't work directly with Numeric 22.0. You can probably find more information from the c-sig archive around October of last year. Again, this was done a while ago and boost library may be more supportive to Numeric array now. As an example, to get the size of a numeric array, I have something like... int size(boost::python::numeric::array arr) { if(!PyArray_Check(arr.ptr())){ PyErr_SetString(PyExc_ValueError, "Expect a PyArray Object"); throw_error_already_set(); } return PyArray_Size(arr.ptr()) } to extract values from a Numeric array, I first get the pointer referencing the data, cast it, and then do a memcpy. It will roughly look something like... double m_asset_grid[size] double* dataptr = (double*) ((PyArrayObject*) arr.ptr())->data; memcpy(&m_asset_grid[0], dataptr, 8*size) I hope this helps... Cheers, Charles > Dear SIG, > > I would like to use boost::python to feed my c++ numerical routines with > Numeric arrays [ python 2.2, boost 1.30 (cvs), Numeric 22 ]. > > What I need is the following: > 1) taking a Numeric object as an argument > 2) extract shape information > 3) extract values and fill c++ variables with those values > > I tried the following for 1D objects but I did not get anything out of > it: > > /// Assign a grid from a 1D python Numeric object > void set_asset_grid_py(boost::python::numeric::array& grid ) { > int array_size = boost::python::extract(grid.attr("shape")()); > m_asset_grid.resize( array_size ); > for(int i=0; i m_asset_grid[i] = boost::python::extract(grid[ i ]); > }; > > What am I missing? > Any suggestion will be greatly appreciated. > > Regards, > Massimo > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Wed Mar 5 20:14:49 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 05 Mar 2003 14:14:49 -0500 Subject: [C++-sig] Chaining methods in C++ and Python In-Reply-To: <1046884793.24480.9.camel@hobbit> (Alexey Goldin's message of "05 Mar 2003 09:19:53 -0800") References: <1046800021.19860.5.camel@hobbit> <1046884793.24480.9.camel@hobbit> Message-ID: Alexey Goldin writes: >> >> This is a simple issue of lifetime management. The C++ 'a' objects >> created in mk_tst are owned by their corresponding Python objects, >> which get destroyed when mk_tst exits. The pointers you have stored >> in your 'tst' object are dangling thereafter. >> >> The Introduction section at >> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/with_custodian_and_ward.html#introduction >> explains this fairly well >> >> HTH, > > Ok. This makes sense. Agh, no it doesn't, sorry. I mis-analyzed the actual problem. The deal is that the result of t.set_f1(a1) looks like this: result t2 a1 +-------+ +-------+ +-------+ Python | tst +===>| tst +===>| a | +-------+ +-------+ +-------+ C++ | * | | tst | | a | +---+---+ +-------+ +-------+ | ^ +------------+ Where double arrows are ownership, and the single arrow represents the reference to the C++ object inside of t2. then, result.set_f2(a2) causes something like this: ++==========================++ result2 result1 || t2 a1 || a2 +-------+ +-------+|| +-------+ +-------+ || +-------+ Python | tst +===>| tst +++=>| tst +===>| a | ++==>| a | +-------+ +-------+ +-------+ +-------+ +-------+ C++ | * | | * | | tst | | a | | a | +---+---+ +---+---+ +-------+ +-------+ +-------+ | | ^ +----------->+------------+ As you can see the lifetime of a2 isn't maintained by t2 when it is returned. The key is to somehow get the set_f1() and set_f2() to return the original Python tst object instead of a "shadow". There are lots of ways to do that, but probably the easiest is to use back_reference in a thin wrapper function: object set_f1(back_reference self, A & ff) { self.get().set_f1(ff); return self; }; ... .def("set_f1", set_f1, with_custodian_and_ward<1,2>() ) attached is a full demo. The question remains open as to whether Boost.Python should be doing something for you automatically here. I think return_internal_reference might include a test to see if it's the same object being returned, and handle this automatically. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.cpp URL: -------------- next part -------------- > However --- is it possible to do one of the > following things in not too ugly way: > > 1) allow writing something like t.set_f1(a1).set_f2(a2) and make sure > that pointers to both a1 and a2 are owned by t --- preferable solution > > 2) Making sure that t.set_f1(a1) does not return object of type tst, so > calling > t.set_f1(a1).set_f2(a2) and instead I have to call > > t.set_f1(a1) > t.set_f2(a2) > > --- not so good, but at least making sure it is not easy to crash > application? > > I can not change signature of method tst::set_f1 --- this is a library > not under my control. Yes, I can write some wrappers but in my > understanding this is what boost.python was created to avoid.... > > Thank you! boost.python is a wonderful tool, but sometimes as confusing > as C++ :-) > > -- > Alexey Goldin > > > _______________________________________________ > 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 Alexey.Goldin at jpl.nasa.gov Wed Mar 5 19:40:28 2003 From: Alexey.Goldin at jpl.nasa.gov (Alexey Goldin) Date: 05 Mar 2003 10:40:28 -0800 Subject: [C++-sig] Chaining methods in C++ and Python In-Reply-To: References: <1046800021.19860.5.camel@hobbit> <1046884793.24480.9.camel@hobbit> Message-ID: <1046889628.24481.22.camel@hobbit> Oh, this sounds good. Off to study manual.... Thanks a lot! On Wed, 2003-03-05 at 11:14, David Abrahams wrote: > There are lots of ways to do that, but probably the easiest is to use > back_reference in a thin wrapper function: > > object set_f1(back_reference self, A & ff) > { > self.get().set_f1(ff); > return self; > }; From mgiger at lunarsoft.com Thu Mar 6 18:09:29 2003 From: mgiger at lunarsoft.com (Matt Giger) Date: Thu, 6 Mar 2003 09:09:29 -0800 Subject: [C++-sig] Any Boost.Python equivalent to **keywords? Message-ID: I would like to construct a class with a **keywords construct: class tclass: def __init__(self, **keywords) for k in kw.keys() self.__dict__[k] = kw[k] >>> t = tclass(a = 1, b = 2, c = 3) >>> t.a, t.b, t.c 1, 2, 3 I realize that this sort of open-ended Python construct would probably be difficult to generate with templates. I've looked through the test cases in the 1_29_0 distribution and can't find anything to do this. It probably wouldn't be too hard to generate a helper function to turn a **keywords construct into a dictionary and use that to initialize a C++ defined class object, I was just wondering if there was a built in way... Many thanks. -- Matt Giger Lunar Software, Inc. mgiger at lunarsoft.com From nksauter at lbl.gov Thu Mar 6 21:00:15 2003 From: nksauter at lbl.gov (Nicholas K. Sauter) Date: Thu, 06 Mar 2003 12:00:15 -0800 Subject: [C++-sig] Boost.Python compiles & links on Darwin References: <3E5D7D33.7BC667CE@lbl.gov> Message-ID: <3E67A8CF.DD65F828@lbl.gov> David Abrahams wrote: > > Details are posted in the "darwin_notes" link presented on my > > Multi-platform build page: > > http://cci.lbl.gov/boost > > BTW, Nick, I never look at the build page; there's so much output > that it's almost impossible to find errors. I don't know if it's > useful to you, but I think you might run bjam with > bjam -d0 all > for that page so that the tests don't run. The test page can hold the > test run output. Just a suggestion. The build procedure has been updated as follows: "build" uses -d0 all "test" uses -sRUN_ALL_TESTS=1 -d0 test The web page presentation has also been cleaned up a bit. -- Nicholas K. Sauter, Ph.D. Lawrence Berkeley National Lab 1 Cyclotron Road, Bldg 4R0230 Berkeley, CA 94720-8235 nksauter at lbl.gov Voice: 510-486-5713 Fax: 510-486-5909 -------------- next part -------------- A non-text attachment was scrubbed... Name: nksauter.vcf Type: text/x-vcard Size: 354 bytes Desc: Card for Nicholas K. Sauter URL: From datafeed at SoftHome.net Thu Mar 6 21:40:47 2003 From: datafeed at SoftHome.net (M. Evans) Date: Thu, 6 Mar 2003 13:40:47 -0700 Subject: [C++-sig] Functional C++ and Exact Real Arithmetic Message-ID: <718963158.20030306134047@SoftHome.net> The awesome FC++ library, http://www.cc.gatech.edu/~yannis/fc++/ Related - exact real arithmetic in C++ and Python, http://more.btexact.com/people/briggsk2/XR.html M. From dave at boost-consulting.com Thu Mar 6 22:19:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 06 Mar 2003 16:19:46 -0500 Subject: [C++-sig] Boost.Python compiles & links on Darwin In-Reply-To: <3E67A8CF.DD65F828@lbl.gov> ("Nicholas K. Sauter"'s message of "Thu, 06 Mar 2003 12:00:15 -0800") References: <3E5D7D33.7BC667CE@lbl.gov> <3E67A8CF.DD65F828@lbl.gov> Message-ID: "Nicholas K. Sauter" writes: > David Abrahams wrote: > >> > Details are posted in the "darwin_notes" link presented on my >> > Multi-platform build page: >> > http://cci.lbl.gov/boost >> >> BTW, Nick, I never look at the build page; there's so much output >> that it's almost impossible to find errors. I don't know if it's >> useful to you, but I think you might run bjam with >> bjam -d0 all >> for that page so that the tests don't run. The test page can hold the >> test run output. Just a suggestion. > > The build procedure has been updated as follows: > > "build" uses -d0 all > "test" uses -sRUN_ALL_TESTS=1 -d0 test > > The web page presentation has also been cleaned up a bit. Thanks, that's nice! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Mar 6 22:24:52 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 06 Mar 2003 16:24:52 -0500 Subject: [C++-sig] Functional C++ and Exact Real Arithmetic In-Reply-To: <718963158.20030306134047@SoftHome.net> ("M. Evans"'s message of "Thu, 6 Mar 2003 13:40:47 -0700") References: <718963158.20030306134047@SoftHome.net> Message-ID: "M. Evans" writes: > The awesome FC++ library, > http://www.cc.gatech.edu/~yannis/fc++/ > > Related - exact real arithmetic in C++ and Python, > http://more.btexact.com/people/briggsk2/XR.html Nifty. Yannis is a lazy guy!** -Dave **a compliment, I assure you. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Mar 7 17:19:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 07 Mar 2003 11:19:38 -0500 Subject: [C++-sig] Any Boost.Python equivalent to **keywords? In-Reply-To: (Matt Giger's message of "Thu, 6 Mar 2003 09:09:29 -0800") References: Message-ID: Matt Giger writes: > I would like to construct a class with a **keywords construct: > > class tclass: > def __init__(self, **keywords) > for k in kw.keys() > self.__dict__[k] = kw[k] > > >>>> t = tclass(a = 1, b = 2, c = 3) >>>> t.a, t.b, t.c > 1, 2, 3 > > > I realize that this sort of open-ended Python construct would probably > be difficult to generate with templates. I've looked through the > test cases in the 1_29_0 distribution and can't find anything to do > this. > > It probably wouldn't be too hard to generate a helper function to turn > a **keywords construct into a dictionary and use that to initialize a > C++ defined class object, I was just wondering if there was a built in > way... I have some changes sitting on my disk that will allow you to do this; I'll try to check it in later today. -Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From harold at imb-jena.de Fri Mar 7 18:56:10 2003 From: harold at imb-jena.de (harold fellermann) Date: Fri, 7 Mar 2003 18:56:10 +0100 Subject: [C++-sig] iterate through boot::python::list In-Reply-To: Message-ID: <14649EF6-50C6-11D7-913A-000393DA32FA@imb-jena.de> Is there any possibility to iterate trough a boost::python::list (or dictionary) from within C++ ? I could not find anything in the documentation. thanks, - harold - -- Live in a world of your own. But always welcome visitors. -- From dave at boost-consulting.com Fri Mar 7 19:52:56 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 07 Mar 2003 13:52:56 -0500 Subject: [C++-sig] iterate through boot::python::list In-Reply-To: <14649EF6-50C6-11D7-913A-000393DA32FA@imb-jena.de> (harold fellermann's message of "Fri, 7 Mar 2003 18:56:10 +0100") References: <14649EF6-50C6-11D7-913A-000393DA32FA@imb-jena.de> Message-ID: harold fellermann writes: > Is there any possibility to iterate trough a boost::python::list (or > dictionary) > from within C++ ? I could not find anything in the documentation. Well, for a list you can call x.attr("__len__")() to get its length and index it. For a dictionary you can call items() and then do the same. However, it would be interesting to make a standard input_iterator that could iterate over the items, e.g.: for ( input_iterator i = begin(some_list_or_dict); i != end(some_list_or_dict); ++i) { whatever(*i); } Nice project for someone who wants to make a contribution. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Fri Mar 7 21:24:56 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 7 Mar 2003 12:24:56 -0800 (PST) Subject: [C++-sig] iterate through boot::python::list In-Reply-To: Message-ID: <20030307202456.33412.qmail@web20203.mail.yahoo.com> --- David Abrahams wrote: > harold fellermann writes: > > > Is there any possibility to iterate trough a boost::python::list (or > > dictionary) > > from within C++ ? I could not find anything in the documentation. > > Well, for a list you can call x.attr("__len__")() to get its length > and index it. You can also do this: #include int l = boost::python::len(some_list_or_dict); > Nice project for someone who wants to make a contribution. Expanding api_placeholder.hpp into a comprehensive solution constitutes another nice project for someone wanting to make a contribution. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From dave at boost-consulting.com Fri Mar 7 21:41:45 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 07 Mar 2003 15:41:45 -0500 Subject: [C++-sig] iterate through boot::python::list In-Reply-To: <20030307202456.33412.qmail@web20203.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Fri, 7 Mar 2003 12:24:56 -0800 (PST)") References: <20030307202456.33412.qmail@web20203.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > You can also do this: > > #include > > int l = boost::python::len(some_list_or_dict); > >> Nice project for someone who wants to make a contribution. > > Expanding api_placeholder.hpp into a comprehensive solution constitutes another > nice project for someone wanting to make a contribution. Absolutely, and I would support that idea. -- Dave Abrahams Boost Consulting www.boost-consulting.com From ostiguy at fnal.gov Sat Mar 8 00:34:22 2003 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Fri, 7 Mar 2003 17:34:22 -0600 (CST) Subject: [C++-sig] static class variables In-Reply-To: Message-ID: Hi - I recently experimented with the new "staticmethod" attribute to wrap static class methods. I works beautifully ... great work ! This leads me to ask: is there any existing/planned equally convenient way to wrap static class variables ? I am thinking of something along the lines of struct MyClass { double value1; double value2; } python::class_("MyClass") .def_readwrite("value2", &MyClass::value) .staticvariable("value2"); <<<<<< ????????? so that from python I could simply say MyClass.value2 = 2.0 As always, your help/comments/suggestions are greatly appreciated. -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From dave at boost-consulting.com Sat Mar 8 00:59:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 07 Mar 2003 18:59:50 -0500 Subject: [C++-sig] static class variables In-Reply-To: (Francois Ostiguy's message of "Fri, 7 Mar 2003 17:34:22 -0600 (CST)") References: Message-ID: Francois Ostiguy writes: > Hi - > > I recently experimented with the new "staticmethod" attribute to > wrap static class methods. I works beautifully ... great work ! Thanks go mostly to Nikolay Mladenov, who contributed it. > This leads me to ask: is there any existing/planned equally > convenient way to wrap static class variables ? See http://aspn.activestate.com/ASPN/Mail/Message/1547542, though I am now favoring option 2 at the end of that message over option 1. I don't have a plan to implement it soon unless someone hires me to do it, just because I have a lot on my plate already... but someone else may want to do it. > I am thinking of something along the lines of > > struct MyClass { > double value1; > double value2; I assume you meant to add a static data member called 'value' here?? > } > > > python::class_("MyClass") > .def_readwrite("value2", &MyClass::value) > .staticvariable("value2"); <<<<<< ????????? That syntax would not be neccessary; it would be enough to write: python::class_("MyClass") .def_readwrite("value2", &MyClass::value) ; ...since &MyClass::value is not a data member pointer, but a simple object pointer and thus we can deduce that it should act like a static data member. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Mar 8 04:55:51 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 07 Mar 2003 22:55:51 -0500 Subject: [C++-sig] Any Boost.Python equivalent to **keywords? In-Reply-To: (David Abrahams's message of "Fri, 07 Mar 2003 11:19:38 -0500") References: Message-ID: David Abrahams writes: >> It probably wouldn't be too hard to generate a helper function to turn >> a **keywords construct into a dictionary and use that to initialize a >> C++ defined class object, I was just wondering if there was a built in >> way... > > I have some changes sitting on my disk that will allow you to do this; > I'll try to check it in later today. OK, please check out the latest from CVS. You can find a description of how to use it in libs/python/doc/v2/raw_function.html. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Mar 8 16:31:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 08 Mar 2003 10:31:19 -0500 Subject: [C++-sig] New implementation for opaque_pointer_converter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A7F4@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Tue, 25 Feb 2003 12:58:53 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A7F4@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: >> >> Hi Gottfried, >> >> >> >> I have not forgotten about your patch. I don't think it >> can go into >> >> 1.30.0, as we plan to branch for release in a couple of days. >> > That's unfortunate :-( >> >> I had some concerns about it that I haven't had time to address with >> you. I want to be sure I know what we're getting ;-) > Sure. > >> >> >> However, I think we can do something to address your needs >> in the CVS >> >> shortly after the branch. Can you send me a link to the message >> >> where you posted the patch? I seem to have misplaced it. >> > Here you are: >> > http://article.gmane.org/gmane.comp.python.c%2B%2B/2420 Hi Gottfried, I was trying to apply your patch (which basically looks very good), and it seems there are some problems with NULL opaque pointer conversions. The enclosed test files demonstrate. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: opaque.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: opaque.py URL: -------------- next part -------------- If you can get this cleared up in the next couple of days, I'll merge it into the 1.30.0 branch. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Sun Mar 9 08:31:33 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 8 Mar 2003 23:31:33 -0800 (PST) Subject: [C++-sig] def_readwrite and custom rvalue converters Message-ID: <20030309073133.94327.qmail@web20207.mail.yahoo.com> Hi David, In December we had a conversation about the interaction of def_readonly()/def_readwrite() and my custom rvalue converters (container_conversions.h), leading to TypeError: No Python class registered for C++ class ... messages. After you gave me some advice I arrived at this replacement for def_readwrite(): typedef return_value_policy rbv; // ... .add_property("site", make_getter(&w_t::site, rbv()), make_setter(&w_t::site)) Is this still the best solution available? Thanks, Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From dave at boost-consulting.com Sun Mar 9 13:30:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 09 Mar 2003 07:30:41 -0500 Subject: [C++-sig] def_readwrite and custom rvalue converters In-Reply-To: <20030309073133.94327.qmail@web20207.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Sat, 8 Mar 2003 23:31:33 -0800 (PST)") References: <20030309073133.94327.qmail@web20207.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > Hi David, > > In December we had a conversation about the interaction of > def_readonly()/def_readwrite() and my custom rvalue converters > (container_conversions.h), leading to > > TypeError: No Python class registered for C++ class ... > > messages. After you gave me some advice I arrived at this > replacement for def_readwrite(): > > typedef return_value_policy rbv; > // ... > .add_property("site", make_getter(&w_t::site, rbv()), > make_setter(&w_t::site)) > > Is this still the best solution available? Sorry, I don't remember enough about the problem to be able to say. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at haufe.de Sun Mar 9 22:40:09 2003 From: Gottfried.Ganssauge at haufe.de (=?iso-8859-1?Q?Gottfried_Gan=DFauge?=) Date: Sun, 9 Mar 2003 22:40:09 +0100 Subject: [C++-sig] New implementation for opaque_pointer_converter References: <2040C0A1CA23D51181A30050BAAC990274A7F4@berexch.ber.haufemg.com> Message-ID: <001a01c2e684$7580ebd0$44a837c2@gieke> > Hi Gottfried, hi, > > I was trying to apply your patch (which basically looks very good), > and it seems there are some problems with NULL opaque pointer > conversions. The enclosed test files demonstrate. > If you can get this cleared up in the next couple of days, I'll merge > it into the 1.30.0 branch. The problem - as I see it - is the following There exists an arg_from_python-converter which - in it's convertible()-method - basically says: conversion of NULL-pointers is not valid. I see tow ways around that. The first one is fairly simple: just return Py_None from opaque_pointer_converter::convert() if a NULL-pointer is to be converted. It's drawback was already made obvious in your test case: the assertion (type(getnull()) == type(get()) won't hold. The second one is much more difficult (at least for me): We need a new type class which says: I'm a pointer but I have value semantics in the sense of arg_rvalue_from_python<>. This can be used in the select_arg_from_python<> template to select the proper converter for opaque pointers. What do you think? Cheers, Gottfried From dave at boost-consulting.com Mon Mar 10 01:35:18 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 09 Mar 2003 19:35:18 -0500 Subject: [C++-sig] New implementation for opaque_pointer_converter In-Reply-To: <001a01c2e684$7580ebd0$44a837c2@gieke> (Gottfried =?iso-8859-1?q?Gan=DFauge's?= message of "Sun, 9 Mar 2003 22:40:09 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A7F4@berexch.ber.haufemg.com> <001a01c2e684$7580ebd0$44a837c2@gieke> Message-ID: Gottfried Gan?auge writes: >> Hi Gottfried, > hi, >> >> I was trying to apply your patch (which basically looks very good), >> and it seems there are some problems with NULL opaque pointer >> conversions. The enclosed test files demonstrate. >> If you can get this cleared up in the next couple of days, I'll merge >> it into the 1.30.0 branch. > The problem - as I see it - is the following > There exists an arg_from_python-converter which - in it's > convertible()-method - basically says: conversion of NULL-pointers is not > valid. > I see tow ways around that. > The first one is fairly simple: just return Py_None from > opaque_pointer_converter::convert() if a NULL-pointer is to be >> converted. That's what Boost.Python does when converting NULL pointer values to_python, because it corresponds to peoples' expectations. > It's drawback was already made obvious in your test case: the assertion > (type(getnull()) == type(get()) won't hold. I added that assertion after trying assert getnull() is None expecting it to work. Probably it would be best to return something other than PyNone in this case, but it's not a big deal. > The second one is much more difficult (at least for me): > We need a new type class which says: I'm a pointer but I have value > semantics in the sense of arg_rvalue_from_python<>. This can be used in the > select_arg_from_python<> template to select the proper converter for opaque > pointers. > What do you think? You could always cause your macro to generate another specialization which does the conversion differently. However, I realize now that I have concerns about the current specialization macro: In order for this to work cross-module you'd need to invoke the macro in every translation unit which uses conversions to- or from- the raw pointer type. In the approach I was thinking of, we would just change type_id() to use typeid(add_pointer::type>::type) for _all_ T. We'd want some special code to strip the trailing '*' when printing these, and we'd need to carefully examine all of the places where a boost::python::type_info is constructed from a std::type_info. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Mon Mar 10 07:21:26 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sun, 9 Mar 2003 22:21:26 -0800 (PST) Subject: [C++-sig] def_readwrite and custom rvalue converters In-Reply-To: Message-ID: <20030310062126.5870.qmail@web20206.mail.yahoo.com> --- David Abrahams wrote: > > Is this still the best solution available? > > Sorry, I don't remember enough about the problem to be able to say. That strongly suggests the answer is "yes." FWIW: Say you have a custom rvalue converter which converts Python tuples to std::vector and a to_python converter for the opposite direction. Everything is fine for converting function arguments and return values. However, with Boost 1.30.0 def_readonly() and def_readwrite() do not work for that std::vector. In connection with this you pointed me to the following code: data_members.cpp contains: // If it's a regular class type (not an object manager or other // type for which we have to_python specializations, use // return_internal_reference so that we can do things like // x.y.z = 1 // and get the right result. template struct default_getter_policy You wrote further: > Which selects a policy to use for getters. The problem is that your > converter can't use return_internal_reference, because it's making a > list or tuple or something else which doesn't support weak references, > instead of an extension class instance. You told me that this can be used instead of def_readwrite(): typedef return_value_policy rbv; // ... .add_property("site", make_getter(&w_t::site, rbv()), make_setter(&w_t::site)) You thought it would be better to handle this situation automatically with some "not_exposed_as_class" specialization. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From Gottfried.Ganssauge at HAUFE.DE Mon Mar 10 08:56:28 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 10 Mar 2003 08:56:28 +0100 Subject: AW: [C++-sig] New implementation for opaque_pointer_converter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A851@berexch.ber.haufemg.com> Hi Dave, > Von: David Abrahams [mailto:dave at boost-consulting.com] > > I see tow ways around that. > > The first one is fairly simple: just return Py_None from > > opaque_pointer_converter::convert() if a NULL-pointer is to be > >> converted. > > That's what Boost.Python does when converting NULL pointer values > to_python, because it corresponds to peoples' expectations. After sleeping a night over it I realized that it's probably what I would expect as well, so I now tend to think that this implementation might be the best one. In addition all APIs I know using opaque pointers (like fopen()) use NULL-pointers for a failure return value so we would need some special value anyway to check for failures. > > > It's drawback was already made obvious in your test case: > the assertion > > (type(getnull()) == type(get()) won't hold. > > I added that assertion after trying > > assert getnull() is None > > expecting it to work. Probably it would be best to return something > other than PyNone in this case, but it's not a big deal. Probably not; as you already pointed out: people expect to get None for a NULL-pointer. ... > > However, I realize now that I have concerns about the current > specialization macro: In order for this to work cross-module you'd > need to invoke the macro in every translation unit which uses > conversions to- or from- the raw pointer type. > > In the approach I was thinking of, we would just change type_id() > to use typeid(add_pointer::type>::type) for _all_ > T. We'd want some special code to strip the trailing '*' when > printing these, and we'd need to carefully examine all of the places > where a boost::python::type_info is constructed from a std::type_info. I see what you mean. Cheers, Gottfried From sabbatini at deanovell.unian.it Mon Mar 10 11:54:17 2003 From: sabbatini at deanovell.unian.it (Massimo Sabbatini) Date: Mon, 10 Mar 2003 11:54:17 +0100 Subject: [C++-sig] Boost::Python and intel-win32 Message-ID: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> Dear SIG, I'm trying to export few classes with Boost::Python using bjam and the intel-win32 toolset. I first tried vc6 (toolset msvc) and while vc6 start compiling (but stops due to an internal error), intel-win32 (v.7) does not start compiling at all. It seems that bjam does not issue the proper command line. I enclose the output of my "bjam -sTOOLS=intel-win32" below. Any suggestions? P.S. paths are correctly set. Massimo D:\development\olg\export\python>d:\win_bin\bjam -sTOOLS=intel-win32 ...patience... ...found 1160 targets... ...updating 4 targets... vc-C++ bin\olg.pyd\intel-win32\debug\runtime-link-dynamic\olg.obj '/Zm800' is not recognized as an internal or external command, operable program or batch file. /Zm800 -nologo -GX -c -BOOST_PYTHON_DYNAMIC_LIB /Z7 /Od /Ob0 /GX /GR /MDd /Qwn5 /Qwd985 /Qansi_alias -I"." -I"d:\development\olg" -I"d:\development\bo ost" -I"d:\development\numerics" -I"d:\development\boost\tools\build\jam_src " -I "d:\development\hdf5-1.4.5-winInt\c\release\include" -I"c:\python22\include " -Fo"bin\olg.pyd\intel-win32\debug\runtime-link-dynamic\olg.obj" -Tp"olg.cpp " ...failed vc-C++ bin\olg.pyd\intel-win32\debug\runtime-link-dynamic\olg.obj... ...skipped olg.CMD for lack of < olg.pyd\intel-win32\debug\runtime-link-dynamic>olg.obj... ...skipped olg.lib for lack of < olg.pyd\intel-win32\debug\runtime-link-dynamic>olg.CMD... ...skipped olg.pyd for lack of < olg.pyd\intel-win32\debug\runtime-link-dynamic>olg.CMD... ...failed updating 1 target... ...skipped 3 targets... D:\development\olg\export\python> From dave at boost-consulting.com Mon Mar 10 12:32:48 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 06:32:48 -0500 Subject: [C++-sig] Boost::Python and intel-win32 In-Reply-To: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> ("Massimo Sabbatini"'s message of "Mon, 10 Mar 2003 11:54:17 +0100") References: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> Message-ID: "Massimo Sabbatini" writes: > Dear SIG, > > I'm trying to export few classes with Boost::Python using bjam and the > intel-win32 toolset. I first tried vc6 (toolset msvc) and while vc6 start > compiling (but stops due to an internal error), intel-win32 (v.7) does not > start compiling at all. It seems that bjam does not issue the proper command > line. I enclose the output of my "bjam -sTOOLS=intel-win32" below. > > Any suggestions? > > P.S. paths are correctly set. What, precisely, do you mean by "paths are correctly set"? Did you configure the toolset as described at http://www.boost.org/tools/build/intel-win32-tools.html? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 10 13:06:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 07:06:33 -0500 Subject: [C++-sig] def_readwrite and custom rvalue converters In-Reply-To: <20030310062126.5870.qmail@web20206.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Sun, 9 Mar 2003 22:21:26 -0800 (PST)") References: <20030310062126.5870.qmail@web20206.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> > Is this still the best solution available? >> >> Sorry, I don't remember enough about the problem to be able to say. > > That strongly suggests the answer is "yes." > > FWIW: Say you have a custom rvalue converter which converts Python tuples to > std::vector and a to_python converter for the opposite direction. > Everything is fine for converting function arguments and return values. > However, with Boost 1.30.0 def_readonly() and def_readwrite() do not work for > that std::vector. OK, I remember now. Yes, the answer is still "yes." > You thought it would be better to handle this situation automatically with some > "not_exposed_as_class" specialization. Probably. It wouldn't be too hard to add something like that which you could specialize. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at HAUFE.DE Mon Mar 10 14:04:21 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 10 Mar 2003 14:04:21 +0100 Subject: AW: [C++-sig] New implementation for opaque_pointer_converter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A853@berexch.ber.haufemg.com> Hi Dave, although I see your point regarding cross module compatibility i must confess that I don't really grasp all implications of the change you propose. On the other hand I figure that my opaque_pointer_converter might be useful for a lot of applications using only a single module (such as mine), so I just made the smaller change of returning None for a NULL-pointer. I changed your assertion accordingly such that it now asserts (getnull() is None). Here is the changed patch which I generated against the RC_1_30_0-Branch. Cheers, Gottfried > -----Urspr?ngliche Nachricht----- > Von: Gottfried.Ganssauge at HAUFE.DE > [mailto:Gottfried.Ganssauge at HAUFE.DE] > Gesendet: Montag, 10. M?rz 2003 08:56 > An: c++-sig at python.org > Betreff: AW: [C++-sig] New implementation for opaque_pointer_converter > > > Hi Dave, > > Von: David Abrahams [mailto:dave at boost-consulting.com] > > > I see tow ways around that. > > > The first one is fairly simple: just return Py_None from > > > opaque_pointer_converter::convert() if a NULL-pointer is to be > > >> converted. > > > > That's what Boost.Python does when converting NULL pointer values > > to_python, because it corresponds to peoples' expectations. > After sleeping a night over it I realized that it's probably > what I would > expect as well, > so I now tend to think that this implementation might be the best one. > In addition all APIs I know using opaque pointers (like fopen()) use > NULL-pointers for a failure return value so we would need > some special value > anyway to check for failures. > > > > > > It's drawback was already made obvious in your test case: > > the assertion > > > (type(getnull()) == type(get()) won't hold. > > > > I added that assertion after trying > > > > assert getnull() is None > > > > expecting it to work. Probably it would be best to return something > > other than PyNone in this case, but it's not a big deal. > Probably not; as you already pointed out: people expect to > get None for a > NULL-pointer. > > ... > > > > However, I realize now that I have concerns about the current > > specialization macro: In order for this to work cross-module you'd > > need to invoke the macro in every translation unit which uses > > conversions to- or from- the raw pointer type. > > > > In the approach I was thinking of, we would just change type_id() > > to use typeid(add_pointer::type>::type) > for _all_ > > T. We'd want some special code to strip the trailing '*' when > > printing these, and we'd need to carefully examine all of the places > > where a boost::python::type_info is constructed from a > std::type_info. > I see what you mean. > > Cheers, > > Gottfried > > _______________________________________________ > 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: opaque_pointer.patch.2 Type: application/octet-stream Size: 24111 bytes Desc: not available URL: From dave at boost-consulting.com Mon Mar 10 14:20:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 08:20:23 -0500 Subject: AW: [C++-sig] New implementation for opaque_pointer_converter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A853@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Mon, 10 Mar 2003 14:04:21 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A853@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: > Hi Dave, > > although I see your point regarding cross module compatibility i > must confess that I don't really grasp all implications of the > change you propose. Me neither, which is why I haven't tried to do it yet. > On the other hand I figure that my opaque_pointer_converter might be useful > for a lot of applications using only a single module (such as mine), so I > just made the smaller change of returning None for a NULL-pointer. > I changed your assertion accordingly such that it now asserts > (getnull() is None). Here is the changed patch which I generated > against the RC_1_30_0-Branch. If you update the docs to describe how to use your system in a cross-module context I will be happy to apply your patch to the release candidate. (Basically, any module that has to convert the opaque pointer to or from python must also have the specialization at the top). If you could just send me the files you changed since the original patch that would help me; I haven't figured out how to conveniently apply patches which span a directory tree. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dirk at gerrits.homeip.net Mon Mar 10 14:59:43 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Mon, 10 Mar 2003 14:59:43 +0100 Subject: [C++-sig] Re: Boost::Python and intel-win32 In-Reply-To: References: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> Message-ID: David Abrahams wrote: > "Massimo Sabbatini" writes: > > >>Dear SIG, >> >>I'm trying to export few classes with Boost::Python using bjam and the >>intel-win32 toolset. I first tried vc6 (toolset msvc) and while vc6 start >>compiling (but stops due to an internal error), intel-win32 (v.7) does not >>start compiling at all. It seems that bjam does not issue the proper command >>line. I enclose the output of my "bjam -sTOOLS=intel-win32" below. >> >> Any suggestions? >> >>P.S. paths are correctly set. > > > What, precisely, do you mean by "paths are correctly set"? > > Did you configure the toolset as described at > http://www.boost.org/tools/build/intel-win32-tools.html? > In particular, did you run Intel\Compiler70\IA32\Bin\iccvars.bat prior to bjam, and in the same DOS-box? Personally, I build Boost as a whole with the following batch script: @echo off D: cd \boost_cvs call "C:\Program Files\Intel\Compiler60\IA32\Bin\iccvars.bat" set PYTHON_ROOT=c:\python22 set PYTHON_VERSION=2.2 set INTELC="C:\Program Files\Intel\Compiler60\IA32" bjam "-sTOOLS=intel-win32" copy /y libs\python\build\bin-stage\*.dll c:\python22 (Boost is in D:\boost_cvs, Python in C:\python22 and the compiler has been installed in C:\Program Files. To use this on your machine, change the paths accordingly.) Regards, Dirk Gerrits From Gottfried.Ganssauge at HAUFE.DE Mon Mar 10 15:31:07 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 10 Mar 2003 15:31:07 +0100 Subject: AW: AW: [C++-sig] New implementation for opaque_pointer_converter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A854@berexch.ber.haufemg.com> > If you update the docs to describe how to use your system in a > cross-module context I will be happy to apply your patch to the > release candidate. (Basically, any module that has to convert the > opaque pointer to or from python must also have the specialization at > the top). I added a sentence to that effect to the macro's documentation. > > If you could just send me the files you changed since the original > patch that would help me; I haven't figured out how to conveniently > apply patches which span a directory tree. I'm using patch from the cygwin package; it works brilliant. Just cd to the top of your boost hierarchy and say "patch -p1 < opaque_pointer.patch" When I'm working on unix (most of the time) patch is available anyway. The files changed since my patch from January, 28 are as follows: boost/python/opaque_pointer_converter.h libs/python/doc/v2/opaque_pointer_converter.html libs/python/doc/v2/return_opaque_pointer.html (fixed a missing link) libs/python/test/opaque.cpp libs/python/test/opaque.py -------------- next part -------------- A non-text attachment was scrubbed... Name: opaque_pointer_converter.hpp Type: application/octet-stream Size: 3592 bytes Desc: not available URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: opaque.cpp Type: application/octet-stream Size: 1897 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: opaque.py Type: application/octet-stream Size: 1682 bytes Desc: not available URL: From dave at boost-consulting.com Mon Mar 10 15:36:36 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 09:36:36 -0500 Subject: [C++-sig] Re: Boost::Python and intel-win32 In-Reply-To: (Dirk Gerrits's message of "Mon, 10 Mar 2003 14:59:43 +0100") References: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> Message-ID: Dirk Gerrits writes: > David Abrahams wrote: >> "Massimo Sabbatini" writes: >> >>>Dear SIG, >>> >>>I'm trying to export few classes with Boost::Python using bjam and the >>>intel-win32 toolset. I first tried vc6 (toolset msvc) and while vc6 start >>>compiling (but stops due to an internal error), intel-win32 (v.7) does not >>>start compiling at all. It seems that bjam does not issue the proper command >>>line. I enclose the output of my "bjam -sTOOLS=intel-win32" below. >>> >>> Any suggestions? >>> >>>P.S. paths are correctly set. >> What, precisely, do you mean by "paths are correctly set"? >> Did you configure the toolset as described at >> http://www.boost.org/tools/build/intel-win32-tools.html? >> > > In particular, did you run Intel\Compiler70\IA32\Bin\iccvars.bat prior > to bjam, and in the same DOS-box? That's actually a different question. You can do it that way, but the configuration variables make it unneccessary to run the .bat file first. Either approach should work. > Personally, I build Boost as a whole with the following batch script: > > > @echo off > D: > cd \boost_cvs > > call "C:\Program Files\Intel\Compiler60\IA32\Bin\iccvars.bat" > > set PYTHON_ROOT=c:\python22 > set PYTHON_VERSION=2.2 > set INTELC="C:\Program Files\Intel\Compiler60\IA32" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This shouldn't be needed if you have run the .bat file. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 10 15:43:39 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 09:43:39 -0500 Subject: AW: AW: [C++-sig] New implementation for opaque_pointer_converter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A854@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Mon, 10 Mar 2003 15:31:07 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A854@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: >> If you update the docs to describe how to use your system in a >> cross-module context I will be happy to apply your patch to the >> release candidate. (Basically, any module that has to convert the >> opaque pointer to or from python must also have the specialization at >> the top). > I added a sentence to that effect to the macro's documentation. A favor: if you could leave a blank line before your reply it would enhance readability. >> If you could just send me the files you changed since the original >> patch that would help me; I haven't figured out how to conveniently >> apply patches which span a directory tree. > I'm using patch from the cygwin package; it works brilliant. Me too, but I didn't know the -p1 option. For some reason ediff-patch-files doesn't handle it either. > Just cd to the top of your boost hierarchy and say "patch -p1 < > opaque_pointer.patch" > When I'm working on unix (most of the time) patch is available anyway. > > The files changed since my patch from January, 28 are as follows: > boost/python/opaque_pointer_converter.h > libs/python/doc/v2/opaque_pointer_converter.html > libs/python/doc/v2/return_opaque_pointer.html (fixed a missing link) > libs/python/test/opaque.cpp > libs/python/test/opaque.py Agh, why don't you just send the patch then; I need to try this -p1 option. ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at HAUFE.DE Mon Mar 10 15:48:20 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 10 Mar 2003 15:48:20 +0100 Subject: AW: AW: AW: [C++-sig] New implementation for opaque_pointer_conve rter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A855@berexch.ber.haufemg.com> Hi Dave, > A favor: if you could leave a blank line before your reply it would > enhance readability. ... > Agh, why don't you just send the patch then; I need to try this -p1 > option. ;-) Nothing easier ... Here you are: my latest, greatest patch :-) Cheers, Gottfried -------------- next part -------------- A non-text attachment was scrubbed... Name: opaque_pointer.patch.3 Type: application/octet-stream Size: 24319 bytes Desc: not available URL: From dirk at gerrits.homeip.net Mon Mar 10 16:21:13 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Mon, 10 Mar 2003 16:21:13 +0100 Subject: [C++-sig] Re: Boost::Python and intel-win32 In-Reply-To: References: <002301c2e6f3$6e9ab7f0$044ca8c0@magellano> Message-ID: David Abrahams wrote: > Dirk Gerrits writes: > >>In particular, did you run Intel\Compiler70\IA32\Bin\iccvars.bat prior >>to bjam, and in the same DOS-box? > > > That's actually a different question. You can do it that way, but the > configuration variables make it unneccessary to run the .bat file > first. Either approach should work. Hmm, ok. >>Personally, I build Boost as a whole with the following batch script: >> >> >>@echo off >>D: >>cd \boost_cvs >> >>call "C:\Program Files\Intel\Compiler60\IA32\Bin\iccvars.bat" >> >>set PYTHON_ROOT=c:\python22 >>set PYTHON_VERSION=2.2 >>set INTELC="C:\Program Files\Intel\Compiler60\IA32" > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > This shouldn't be needed if you have run the .bat file. That may be so, but on my system, INTELC is not defined after running the .bat file. I see that I copy-pasted my old .bat file btw. I'm now using Intel\Compiler70. Dirk Gerrits From fxdirk at insanesoftware.de Mon Mar 10 17:22:17 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Mon, 10 Mar 2003 17:22:17 +0100 Subject: [C++-sig] call_method trouble? Message-ID: <000001c2e721$3bad10d0$0e01a8c0@dirkspc> Hello, first a big thank you to everone working on boost.python, this library rocks! However, I have come across a problem I just can not solve. I apologize for the length of the post, but in order to demonstrate the problem I had to include this code. This is the class I try to wrap: class FXObject { public: virtual long handle(FXObject* sender, FXSelector sel, void* ptr) { } }; FXObject::handle is a message dispatcher, it looks the message up in a message map and calls the associated method. I want to make this class available to python so that derived python classes can define their own message handlers: struct FXObjectWrap : public FXObject { public: FXObjectWrap(PyObject* self_) : self(self_) {} long handle(FXObject* sender,FXSelector sel,void* ptr) { // 1. check the python msg map, if not handled check c++ msg map if (canPythonHandle(self, sel)) { return pythonHandle(self, sender, sel, ptr); } else { ... } } long python_handle(FXObject* sender,FXSelector sel) { return handle(sender, sel, NULL); } PyObject* self; }; bool canPythonHandle(PyObject* o, FXSelector selector) { ... } long pythonHandle(PyObject* o,FXObject* sender, FXSelector selector, void * ptr) { handle<> ph(borrowed(o)); object obj(ph); extract msgmap_extractor(obj.attr("__msgmap__")); if (msgmap_extractor.check()) { list msgmap = msgmap_extractor(); int msgmap_len = extract(msgmap.attr("__len__")()); for (int i=0; i < msgmap_len; i++) { tuple t = extract(msgmap[i]); int sel = extract(t[0]); if (sel == SELTYPE(selector)) { int lo_id = extract(t[1]); int hi_id = extract(t[2]); if((lo_id <= SELID(selector)) && (SELID(selector) <= hi_id)) { char const* method_name = extract(t[3]); long res = call_method(o, method_name, boost::python::ptr(sender), sel); return res; } } } } return 0; } BOOST_PYTHON_MODULE(foxgui) { implicitly_convertible(); implicitly_convertible(); class_("FXObject") .def("handle", &FXObjectWrap::python_handle) ; } FXObject::handle now first examines the attribute __msgmap__ if a python handler is defined, and if none is found it continues with the c++ msg map. This is all working, but the following test case fails: from foxgui import * from unittest import * class FXObjectDerived2(FXObject): __msgmap__ = [(0,0,0,"onMessage")] def onMessage(self, sender, sel): return sender.handle(self, 0) + 7 class FXObjectTestCase(TestCase): def setUp(self): self.object = FXObject() self.derived2 = FXObjectDerived2() def tearDown(self): self.object = None self.derived2 = None def testMessages3(self): """Test message parameters""" self.failIf(self.derived2.handle(self.object, 0) <> 7) The line marked in red gives the following error: sender.handle(self, 0) bad argument type for built-in operation To me that means something is wrong with the arguments to the handle function. However, calling handle directly works fine: A = FXObject() A.handle(A, 0) Only calling sender.handle inside a message handler gives this error, so I think somethink is wrong with the way I used call_method in pythonHandle to call the python message handler, or I am doing some other stupid mistake. Any hints on what's going here are greatly appreciated, I've been trying to get this to work since hours without any success. Thanks, - Dirk Ulbricht -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Mon Mar 10 17:34:11 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 11:34:11 -0500 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e721$3bad10d0$0e01a8c0@dirkspc> ("Dirk Ulbricht"'s message of "Mon, 10 Mar 2003 17:22:17 +0100") References: <000001c2e721$3bad10d0$0e01a8c0@dirkspc> Message-ID: "Dirk Ulbricht" writes: > Only calling sender.handle inside a message handler gives this error, so I > think somethink is wrong with the way I used call_method in pythonHandle to > call the python message handler, or I am doing some other stupid mistake. > Any hints on what's going here are greatly appreciated, I've been trying to > get this to work since hours without any success. What do you see when you add this to onMessage: print 'self=', self print 'sender=', sender ?? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 10 17:46:45 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 11:46:45 -0500 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e721$3bad10d0$0e01a8c0@dirkspc> ("Dirk Ulbricht"'s message of "Mon, 10 Mar 2003 17:22:17 +0100") References: <000001c2e721$3bad10d0$0e01a8c0@dirkspc> Message-ID: Dirk, I think the fact that you are posting in HTML (I'm guessing) is causing your code to be formatted badly in the mail messages. Please try posting in Plaintext. It looks to me like FXObjectWrap::python_handle should be calling FXObject::handle rather than the unqualified handle, because it will cause an infinite recursion otherwise when invoked via the Python onMessage callback. Also, you should probably be using the "virtual function with default implementation" wrapping formula described at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/tutorial/doc/virtual_functions_with_default_implementations.html. One possible explanation for the problem is that type information is lost when converting your FXObject* to a Python object in this line: long res = call_method(o, method_name, boost::python::ptr(sender), sel); Are you using the latest CVS state or the 1.30.0 beta? These are way ahead of the 1.29.0 release in handling polymorphic classes. "Dirk Ulbricht" writes: > Hello, > > > > first a big thank you to everone working on boost.python, this library > rocks! However, I have come across a problem I just can not solve. I > apologize for the length of the post, but in order to demonstrate the > problem I had to include this code. This is the class I try to wrap: > > > > class FXObject > > { > > public: > > virtual long handle(FXObject* sender, FXSelector sel, void* ptr) > > { > > } > > }; -- Dave Abrahams Boost Consulting www.boost-consulting.com From fxdirk at insanesoftware.de Mon Mar 10 17:54:05 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Mon, 10 Mar 2003 17:54:05 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: Message-ID: <000001c2e725$ae131e90$0e01a8c0@dirkspc> Hi Dave, thanks for responding. This gives: self = obj.FXObjectDerived2 object at ... sender = foxgui.FXObject object at ... obj is the module the tests are located in. - Dirk -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Monday, March 10, 2003 5:34 PM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? "Dirk Ulbricht" writes: > Only calling sender.handle inside a message handler gives this error, so I > think somethink is wrong with the way I used call_method in pythonHandle to > call the python message handler, or I am doing some other stupid mistake. > Any hints on what's going here are greatly appreciated, I've been trying to > get this to work since hours without any success. What do you see when you add this to onMessage: print 'self=', self print 'sender=', sender ?? -- 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 fxdirk at insanesoftware.de Mon Mar 10 18:23:52 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Mon, 10 Mar 2003 18:23:52 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: Message-ID: <000001c2e729$d5f19550$0e01a8c0@dirkspc> Hi Dave, ok I'll be posting plain text. I use the 1.29.00 (download from the website). As I started working with boost.python, I tried the cvs version but at that time it didn't compile so I just sticked with the website download. I'll try again. The problem with the "virtual functions with default implementations" approach is that the virtual wrapper and the forwarder need to have the same method signature. However I couldn't find a way to wrap a method that takes a void* parameter, that doesn't make much sense anyway. Since this parameter is not needed in python I just omitted it. Also, FXObject::handle is not meant to be overridden in python, it is just a bit different for objects available to python. The infinite recursion could only happen if there are cycles in the "message sending chain", which should never happen. I'll try again with the latest cvs and let you know if that works better. Thank you for your time. - Dirk Ulbricht -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Monday, March 10, 2003 5:47 PM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? Dirk, I think the fact that you are posting in HTML (I'm guessing) is causing your code to be formatted badly in the mail messages. Please try posting in Plaintext. It looks to me like FXObjectWrap::python_handle should be calling FXObject::handle rather than the unqualified handle, because it will cause an infinite recursion otherwise when invoked via the Python onMessage callback. Also, you should probably be using the "virtual function with default implementation" wrapping formula described at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p ython/doc/tutorial/doc/virtual_functions_with_default_implementations.html. One possible explanation for the problem is that type information is lost when converting your FXObject* to a Python object in this line: long res = call_method(o, method_name, boost::python::ptr(sender), sel); Are you using the latest CVS state or the 1.30.0 beta? These are way ahead of the 1.29.0 release in handling polymorphic classes. "Dirk Ulbricht" writes: > Hello, > > > > first a big thank you to everone working on boost.python, this library > rocks! However, I have come across a problem I just can not solve. I > apologize for the length of the post, but in order to demonstrate the > problem I had to include this code. This is the class I try to wrap: > > > > class FXObject > > { > > public: > > virtual long handle(FXObject* sender, FXSelector sel, void* ptr) > > { > > } > > }; -- 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 fxdirk at insanesoftware.de Mon Mar 10 20:00:32 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Mon, 10 Mar 2003 20:00:32 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e729$d5f19550$0e01a8c0@dirkspc> Message-ID: <000001c2e737$589543f0$0e01a8c0@dirkspc> Hi Dave, I tested with the latest cvs, still the same results. I could narrow down the problem a bit, though. Only methods that are defined in the class-to-wrap can be called in the message handler, methods that are defined in the Wrapper (but not in the base class, like python_handle) are visible (print(dir(sender)) shows them) but they do not work. Do you have any ideas on how to work around that? - Dirk Ulbricht -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of Dirk Ulbricht Sent: Monday, March 10, 2003 6:24 PM To: c++-sig at python.org Subject: RE: [C++-sig] call_method trouble? Hi Dave, ok I'll be posting plain text. I use the 1.29.00 (download from the website). As I started working with boost.python, I tried the cvs version but at that time it didn't compile so I just sticked with the website download. I'll try again. The problem with the "virtual functions with default implementations" approach is that the virtual wrapper and the forwarder need to have the same method signature. However I couldn't find a way to wrap a method that takes a void* parameter, that doesn't make much sense anyway. Since this parameter is not needed in python I just omitted it. Also, FXObject::handle is not meant to be overridden in python, it is just a bit different for objects available to python. The infinite recursion could only happen if there are cycles in the "message sending chain", which should never happen. I'll try again with the latest cvs and let you know if that works better. Thank you for your time. - Dirk Ulbricht -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Monday, March 10, 2003 5:47 PM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? Dirk, I think the fact that you are posting in HTML (I'm guessing) is causing your code to be formatted badly in the mail messages. Please try posting in Plaintext. It looks to me like FXObjectWrap::python_handle should be calling FXObject::handle rather than the unqualified handle, because it will cause an infinite recursion otherwise when invoked via the Python onMessage callback. Also, you should probably be using the "virtual function with default implementation" wrapping formula described at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p ython/doc/tutorial/doc/virtual_functions_with_default_implementations.html. One possible explanation for the problem is that type information is lost when converting your FXObject* to a Python object in this line: long res = call_method(o, method_name, boost::python::ptr(sender), sel); Are you using the latest CVS state or the 1.30.0 beta? These are way ahead of the 1.29.0 release in handling polymorphic classes. "Dirk Ulbricht" writes: > Hello, > > > > first a big thank you to everone working on boost.python, this library > rocks! However, I have come across a problem I just can not solve. I > apologize for the length of the post, but in order to demonstrate the > problem I had to include this code. This is the class I try to wrap: > > > > class FXObject > > { > > public: > > virtual long handle(FXObject* sender, FXSelector sel, void* ptr) > > { > > } > > }; -- 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 From dave at boost-consulting.com Mon Mar 10 20:11:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 14:11:34 -0500 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e737$589543f0$0e01a8c0@dirkspc> ("Dirk Ulbricht"'s message of "Mon, 10 Mar 2003 20:00:32 +0100") References: <000001c2e737$589543f0$0e01a8c0@dirkspc> Message-ID: "Dirk Ulbricht" writes: > Hi Dave, > > I tested with the latest cvs, still the same results. I could narrow down > the problem a bit, though. Only methods that are defined in the > class-to-wrap can be called in the message handler, methods that are defined > in the Wrapper (but not in the base class, like python_handle) are visible > (print(dir(sender)) shows them) but they do not work. That's weird because I just tried a small test here which worked just fine. Can you send a _really_ _minimal_ reproducible case that I can use to diagnose the problem? > Do you have any ideas on how to work around that? I would have said, "Pass an FxObjectWrap* instead of an FxObject* to pythonHandle", but my test seemed to prove that it wasn't neccessary... and that matches my expectations since pointer to-python conversions are supposed to undergo automatic downcasting for polymorphic types. -- Dave Abrahams Boost Consulting www.boost-consulting.com From fxdirk at insanesoftware.de Mon Mar 10 21:10:59 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Mon, 10 Mar 2003 21:10:59 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: Message-ID: <000001c2e741$2f3777d0$0e01a8c0@dirkspc> Dave, I have attached a small test case that reproduces the problem. Also, "Pass an FxObjectWrap* instead of an FxObject* to pythonHandle" doesn't work either - same result. Thanks again! - Dirk -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Monday, March 10, 2003 8:12 PM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? "Dirk Ulbricht" writes: > Hi Dave, > > I tested with the latest cvs, still the same results. I could narrow down > the problem a bit, though. Only methods that are defined in the > class-to-wrap can be called in the message handler, methods that are defined > in the Wrapper (but not in the base class, like python_handle) are visible > (print(dir(sender)) shows them) but they do not work. That's weird because I just tried a small test here which worked just fine. Can you send a _really_ _minimal_ reproducible case that I can use to diagnose the problem? > Do you have any ideas on how to work around that? I would have said, "Pass an FxObjectWrap* instead of an FxObject* to pythonHandle", but my test seemed to prove that it wasn't neccessary... and that matches my expectations since pointer to-python conversions are supposed to undergo automatic downcasting for polymorphic types. -- 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: bp_test.zip Type: application/x-zip-compressed Size: 2360 bytes Desc: not available URL: From dave at boost-consulting.com Mon Mar 10 22:06:15 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 16:06:15 -0500 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e741$2f3777d0$0e01a8c0@dirkspc> ("Dirk Ulbricht"'s message of "Mon, 10 Mar 2003 21:10:59 +0100") References: <000001c2e741$2f3777d0$0e01a8c0@dirkspc> Message-ID: "Dirk Ulbricht" writes: > Dave, > > I have attached a small test case that reproduces the problem. > > Also, "Pass an FxObjectWrap* instead of an FxObject* to > pythonHandle" doesn't work either - same result. > Your comment in FXObjectWrap::handle is not accurate; I added an assert in that empty block and it fired. -- Dave Abrahams Boost Consulting www.boost-consulting.com From fxdirk at insanesoftware.de Tue Mar 11 00:04:34 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Tue, 11 Mar 2003 00:04:34 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: Message-ID: <000001c2e759$6e6343e0$0e01a8c0@dirkspc> Hi Dave, If you remove the 2 lines in the test script that are marked as beeing "ok", that code part is not reached. It is only reached when no python message handler was found. It should then look for a c++ message handler, but how this is done is irrelevant to the problem. The real problem arises when a python message handler is found, and called from c++ via call_method. Somehow this does not convert the FXObject* parameter correctly - I think it was not supposed to handle this case. - Dirk -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Monday, March 10, 2003 10:06 PM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? "Dirk Ulbricht" writes: > Dave, > > I have attached a small test case that reproduces the problem. > > Also, "Pass an FxObjectWrap* instead of an FxObject* to pythonHandle" > doesn't work either - same result. > Your comment in FXObjectWrap::handle is not accurate; I added an assert in that empty block and it fired. -- 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 dave at boost-consulting.com Tue Mar 11 02:41:51 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 20:41:51 -0500 Subject: [C++-sig] call_method trouble? In-Reply-To: <000001c2e741$2f3777d0$0e01a8c0@dirkspc> ("Dirk Ulbricht"'s message of "Mon, 10 Mar 2003 21:10:59 +0100") References: <000001c2e741$2f3777d0$0e01a8c0@dirkspc> Message-ID: "Dirk Ulbricht" writes: > Dave, > > I have attached a small test case that reproduces the problem. Not very small; please try to stick it all in one file next time. Anyway, I've attached a small solution to your problem -------------- next part -------------- A non-text attachment was scrubbed... Name: user.zip Type: application/zip Size: 3093 bytes Desc: not available URL: -------------- next part -------------- HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Mar 11 05:03:59 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 10 Mar 2003 23:03:59 -0500 Subject: AW: AW: AW: [C++-sig] New implementation for opaque_pointer_conve rter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A855@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Mon, 10 Mar 2003 15:48:20 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A855@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: > Hi Dave, > >> A favor: if you could leave a blank line before your reply it would >> enhance readability. > > ... >> Agh, why don't you just send the patch then; I need to try this -p1 >> option. ;-) > > Nothing easier ... > Here you are: my latest, greatest patch :-) I'm sorry to say that this version causes an illegal memory free() call, according to VC++'s debug mode. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at HAUFE.DE Tue Mar 11 09:48:17 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Tue, 11 Mar 2003 09:48:17 +0100 Subject: AW: AW: AW: AW: [C++-sig] New implementation for opaque_pointer_c onve rter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A859@berexch.ber.haufemg.com> > I'm sorry to say that this version causes an illegal memory free() > call, according to VC++'s debug mode. How did you manage to provoke that failure? I'm running like this: boost-rc-1.30\libs\python\test>bjam -sBUILD=debug-python opaque ...found 2038 targets... ...updating 2 targets... python-test-target ..\..\..\libs\python\test\bin\opaque.test\msvc\debug-python\runtime-link-dyn amic\opaque.test Adding parser accelerators ... Done. running... [6285 refs] python-runtest-target opaque.run Adding parser accelerators ... Done. running... [6285 refs] ...updated 2 targets... boost-rc-1.30\libs\python\test> I obtained the sources this morning from the CVS and applied my opaque_pointer.patch.3 I sent to you yesterday. Unfortunately bjam -sBUILD=debug failed because it linked the python_d-libs but tried to run with python.exe. When I removed the python_d-libs it wouldn't link at all asking for the python_d-libs... My compiler ist MSVC 6 SP5 which I'm also using for my production projects clueless ... Gottfried From fxdirk at insanesoftware.de Tue Mar 11 11:40:41 2003 From: fxdirk at insanesoftware.de (Dirk Ulbricht) Date: Tue, 11 Mar 2003 11:40:41 +0100 Subject: [C++-sig] call_method trouble? In-Reply-To: Message-ID: <000001c2e7ba$ad8dcd40$0e01a8c0@dirkspc> Hi Dave, Thanks a lot for your help! Everything works like expected now. - Dirk -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Tuesday, March 11, 2003 2:42 AM To: c++-sig at python.org; dave at boost-consulting.com Subject: Re: [C++-sig] call_method trouble? "Dirk Ulbricht" writes: > Dave, > > I have attached a small test case that reproduces the problem. Not very small; please try to stick it all in one file next time. Anyway, I've attached a small solution to your problem From dave at boost-consulting.com Tue Mar 11 14:44:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 11 Mar 2003 08:44:12 -0500 Subject: AW: AW: AW: AW: [C++-sig] New implementation for opaque_pointer_c onve rter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A859@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Tue, 11 Mar 2003 09:48:17 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A859@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: >> I'm sorry to say that this version causes an illegal memory free() >> call, according to VC++'s debug mode. > > How did you manage to provoke that failure? > I'm running like this: > boost-rc-1.30\libs\python\test>bjam -sBUILD=debug-python opaque Basically, just like that. > I obtained the sources this morning from the CVS and applied my > opaque_pointer.patch.3 I sent to you yesterday. I can try to do it again. > Unfortunately bjam -sBUILD=debug failed because it linked the python_d-libs > but tried to run with python.exe. Oh, that's TERRIBLE! It shouldn't link with the python_d lib! > When I removed the python_d-libs it wouldn't link at all asking for > the python_d-libs... > > My compiler ist MSVC 6 SP5 which I'm also using for my production projects My tests were with vc7 and vc7.1 I could try again with vc6, but I assume it would be the same. I'll try re-applying the patch. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at HAUFE.DE Tue Mar 11 15:25:50 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Tue, 11 Mar 2003 15:25:50 +0100 Subject: [C++-sig] New implementation for opaque_pointer_converter Message-ID: <2040C0A1CA23D51181A30050BAAC990274A85D@berexch.ber.haufemg.com> > >> I'm sorry to say that this version causes an illegal memory free() > >> call, according to VC++'s debug mode. Apart from the technicalities: I presume you tried to run my previous patch and it didn't show that behaviour. So what could be responsible for that change in behaviour? I made only two changes to the converter itself, both in method convert() in opaque_pointer_converter.hpp. For the first change I switched from PyObject_New to PyObject_NEW, which according to it's documentation omits the check for type_object != 0 and consequently should run a little bit faster. The second change was for the NULL-pointer itself. When I detect a NULL-pointer I return detail:none(). In a strict sense the first change is not necessary so in order to determine the cause of the failure you should probably change it back to PyObject_New and test again. The second change *is* necessary and for the life of me I can't imagine that effect as a consequence to this change. If the failure remains it would be interesting when it happens: Does it happen during module initialization or after a call to get() or after a call to getnull(). Maybe I have to debug that with VC7 myself, perhaps it's a problem with that implementation? Cheers, Gottfried From harold at imb-jena.de Tue Mar 11 15:23:34 2003 From: harold at imb-jena.de (harold fellermann) Date: Tue, 11 Mar 2003 15:23:34 +0100 Subject: [C++-sig] iterate through boot::python::list In-Reply-To: Message-ID: <0AC90D76-53CD-11D7-9DE2-000393DA32FA@imb-jena.de> hello, >> Is there any possibility to iterate trough a boost::python::list (or >> dictionary) >> from within C++ ? I could not find anything in the documentation. > Well, for a list you can call x.attr("__len__")() to get its length > and index it. how can I convert the return type list.attr("__len__") from boost::python::api::proxy to size_t? will it then be possible to reach the elements of the list via 'list[index]' or how can this be done? thanks, - harold - -- Live in a world of your own. But always welcome visitors. -- From dirk at gerrits.homeip.net Tue Mar 11 15:46:32 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Tue, 11 Mar 2003 15:46:32 +0100 Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: <0AC90D76-53CD-11D7-9DE2-000393DA32FA@imb-jena.de> References: <0AC90D76-53CD-11D7-9DE2-000393DA32FA@imb-jena.de> Message-ID: harold fellermann wrote: > hello, > >>> Is there any possibility to iterate trough a boost::python::list (or >>> dictionary) >>> from within C++ ? I could not find anything in the documentation. >> >> Well, for a list you can call x.attr("__len__")() to get its length >> and index it. > > > how can I convert the return type list.attr("__len__") from > boost::python::api::proxy > to size_t? As Dave mentioned, you need to use x.attr("__len__")(). Notice the *additional* pair of braces. > will it then be possible to reach the elements of the list via > 'list[index]' Yes. Dirk Gerrits From dave at boost-consulting.com Tue Mar 11 16:39:02 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 11 Mar 2003 10:39:02 -0500 Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: (Dirk Gerrits's message of "Tue, 11 Mar 2003 15:46:32 +0100") References: <0AC90D76-53CD-11D7-9DE2-000393DA32FA@imb-jena.de> Message-ID: Dirk Gerrits writes: > As Dave mentioned, you need to use x.attr("__len__")(). Notice the > *additional* pair of braces. True, but that result is just an 'object'. He needs extract(x.attr("__len__")()) to get a size_t out of it. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Mar 11 17:23:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 11 Mar 2003 11:23:30 -0500 Subject: [C++-sig] New implementation for opaque_pointer_converter In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A85D@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Tue, 11 Mar 2003 15:25:50 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A85D@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: > Maybe I have to debug that with VC7 myself, perhaps it's a problem with that > implementation? Yep, it still fails with VC7 and doesn't fail with VC6. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Gottfried.Ganssauge at haufe.de Tue Mar 11 23:46:20 2003 From: Gottfried.Ganssauge at haufe.de (=?iso-8859-1?Q?Gottfried_Gan=DFauge?=) Date: Tue, 11 Mar 2003 23:46:20 +0100 Subject: [C++-sig] New implementation for opaque_pointer_converter References: <2040C0A1CA23D51181A30050BAAC990274A85D@berexch.ber.haufemg.com> Message-ID: <001701c2e820$0904c420$44a837c2@gieke> Hi Dave, it was the change from PyObject_New to PyObject_NEW. I could reproduce the failure with VC7 and could verify that it's now gone. Here is patch #4 against the RC_1_30_0-branch. Cheers, Gottfried -------------- next part -------------- A non-text attachment was scrubbed... Name: opaque_pointer.patch.4 Type: application/octet-stream Size: 24319 bytes Desc: not available URL: From nicodemus at globalite.com.br Wed Mar 12 15:26:43 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 12 Mar 2003 11:26:43 -0300 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator Message-ID: <3E6F43A3.5090009@globalite.com.br> Hello All! I'm pleased to announce that Pyste has been released! Pyste is a Boost.Python code generator. The user specifies the classes and functions to be exported using a simple interface file, which following the Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to parse all the headers and extract the necessary information to automatically generate C++ code. The project is in experimental phase, and can be found in the current Boos.Python CVS, and in the next 1.30.0 release, at libs/python/pyste. There's documentation and examples. Everyone is invited to try it out and provide feedback! The following features are supported in this release: * Functions * Classes * Class Templates * Virtual Methods * Overloading * Attributes * Enums (both "free" enums and class enums) * Nested Classes Regards, Nicodemus. From niki at vintech.bg Wed Mar 12 16:26:25 2003 From: niki at vintech.bg (Niki Spahiev) Date: Wed, 12 Mar 2003 17:26:25 +0200 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E6F43A3.5090009@globalite.com.br> References: <3E6F43A3.5090009@globalite.com.br> Message-ID: <3E6F51A1.20201@vintech.bg> Nicodemus wrote: > Hello All! > > I'm pleased to announce that Pyste has been released! > > Pyste is a Boost.Python code generator. The user specifies the classes and > functions to be exported using a simple interface file, which following the > Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to > parse all the headers and extract the necessary information to > automatically > generate C++ code. Great! Can you give some info about using its back-end AKA Exporter. I have DB of C++ classes and want to wrap them using boost. Niki Spahiev From harold at imb-jena.de Wed Mar 12 16:32:49 2003 From: harold at imb-jena.de (harold fellermann) Date: Wed, 12 Mar 2003 16:32:49 +0100 Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: Message-ID: On Dienstag, M?rz 11, 2003, at 04:39 Uhr, David Abrahams wrote: > Dirk Gerrits writes: >> As Dave mentioned, you need to use x.attr("__len__")(). Notice the >> *additional* pair of braces. > > True, but that result is just an 'object'. He needs > extract(x.attr("__len__")()) to get a size_t out of it. Thank you, this works fine. But I still cannot get along with my stuff... My plan is to insert references to C++ objects within a boost::python::list. The code looks like the following: class X { // ... }; class Y { public: void insert(X &); boost::python::list xlist; }; void Y::insert(X &x) { // do some other things xlist.insert(0,x) } int main() { X x; Y y; y.insert(x); } Unfortunately this little snippet crashes: Program received signal SIGABRT, Aborted. [Switching to Thread 1024 (LWP 26257)] 0x401a6df1 in kill () from /lib/libc.so.6 (gdb) bt #0 0x401a6df1 in kill () from /lib/libc.so.6 #1 0x4008f06d in pthread_kill () from /lib/libpthread.so.0 #2 0x4008f5eb in raise () from /lib/libpthread.so.0 #3 0x401a84d9 in abort () from /lib/libc.so.6 #4 0x4012a5d7 in __cxxabiv1::__terminate(void (*)()) () from /usr/lib/libstdc++.so.5 #5 0x4012a624 in std::terminate() () from /usr/lib/libstdc++.so.5 #6 0x4012a7a6 in __cxa_throw () from /usr/lib/libstdc++.so.5 #7 0x4004df59 in boost::python::throw_error_already_set() () from /usr/local/lib/libboost_python.so.1.29.0 #8 0x080e9fea in boost::python::converter::arg_to_python::arg_to_python(Node const&) () #9 0x080e8c41 in _object* boost::python::api::object_initializer::get(Node const*, int*) () #10 0x080e777c in boost::python::api::object::object(Node const&) () #11 0x080e748d in void boost::python::list::insert(int, Node const&) () #12 0x080e63cf in Network::add_node(Node&) () #13 0x080e2858 in DynamicNetwork::add_node(DynamicNode&) () #14 0x080e1e81 in main () #15 0x401954a2 in __libc_start_main () from /lib/libc.so.6 What am I doing wrong this time? My general ambition is to reimplement some classes originally written in python. So my intention is not to not intrude the underlying C++-classes, but rather to not intrude the overlying python-classes. This is why I need a boost::python::list as a public member of some C++ classes. The references inside the list must be accessible from either python and C++. Do you think this approach is passable with boost::python or is this a misuse of the library? thank you, - harold - -- Live in a world of your own. But always welcome visitors. -- From nicodemus at globalite.com.br Wed Mar 12 16:36:44 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 12 Mar 2003 12:36:44 -0300 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E6F51A1.20201@vintech.bg> References: <3E6F43A3.5090009@globalite.com.br> <3E6F51A1.20201@vintech.bg> Message-ID: <3E6F540C.8020802@globalite.com.br> Niki Spahiev wrote: > Nicodemus wrote: > >> Hello All! >> >> I'm pleased to announce that Pyste has been released! >> >> Pyste is a Boost.Python code generator. The user specifies the >> classes and >> functions to be exported using a simple interface file, which >> following the >> Boost.Python's philosophy, is simple Python code. Pyste then uses >> GCCXML to >> parse all the headers and extract the necessary information to >> automatically >> generate C++ code. > > > Great! Can you give some info about using its back-end AKA Exporter. > I have DB of C++ classes and want to wrap them using boost. What do you mean "DB of C++ classes"? Did you look at the documentation? All the information needed to use Pyste is present there. Regards, Nicodemus.\ From niki at vintech.bg Wed Mar 12 17:56:03 2003 From: niki at vintech.bg (Niki Spahiev) Date: Wed, 12 Mar 2003 18:56:03 +0200 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E6F540C.8020802@globalite.com.br> References: <3E6F43A3.5090009@globalite.com.br> <3E6F51A1.20201@vintech.bg> <3E6F540C.8020802@globalite.com.br> Message-ID: <3E6F66A3.2040607@vintech.bg> Nicodemus wrote: > What do you mean "DB of C++ classes"? Did you look at the documentation? > All the information needed to use Pyste is present there. OCAS - http://opencascade.org It has many header files autogenerated from metainfo in DB. I can read this metainfo with python and want to generate boost.python wrappers. I want to skip GCCXML parser and use ClassExporter or HeaderExporter. Niki Spahiev From rwgk at yahoo.com Wed Mar 12 18:01:54 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 12 Mar 2003 09:01:54 -0800 (PST) Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: Message-ID: <20030312170154.75466.qmail@web20207.mail.yahoo.com> --- harold fellermann wrote: > The code looks like the following: > > class X { > // ... > }; > > class Y { > public: > void insert(X &); > boost::python::list xlist; > }; > > void Y::insert(X &x) { > // do some other things > xlist.insert(0,x) > } > > int main() { > X x; Y y; > y.insert(x); > } > > Unfortunately this little snippet crashes: Of course. You are not initializing the Python interpreter. Are you aware of the difference between "extending" and "embedding"? There is an "embedding" example in the Boost 1.30.0 release candidate that you might want to look at (boost/libs/python/test/embedding.cpp). Most everything else in that directory are "extending" examples. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - establish your business online http://webhosting.yahoo.com From dave at boost-consulting.com Wed Mar 12 18:16:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 12 Mar 2003 12:16:34 -0500 Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: (harold fellermann's message of "Wed, 12 Mar 2003 16:32:49 +0100") References: Message-ID: harold fellermann writes: > Thank you, this works fine. But I still cannot get along with my > stuff... > My plan is to insert references to C++ objects within a > boost::python::list. > The code looks like the following: > > class X { > // ... > }; > > class Y { > public: > void insert(X &); > boost::python::list xlist; > }; > > void Y::insert(X &x) { > // do some other things > xlist.insert(0,x) > } > > int main() { > X x; Y y; > y.insert(x); > } > > Unfortunately this little snippet crashes: You're not being (completely) honest with us ;-) There's a class called "Node" somewhere which you haven't told us about. Aside from not initializing the interpreter, it looks like you have not exposed class Node to python. That's what's causing the exception throw you see in the stack backtrace. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Mar 12 18:05:10 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 12 Mar 2003 14:05:10 -0300 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator References: <3E6F43A3.5090009@globalite.com.br> <3E6F51A1.20201@vintech.bg> <3E6F540C.8020802@globalite.com.br> <3E6F66A3.2040607@vintech.bg> Message-ID: <003c01c2e8b9$eb06f250$0e00000a@esss.com.br> ----- Original Message ----- From: "Niki Spahiev" To: Sent: Wednesday, March 12, 2003 1:56 PM Subject: Re: [C++-sig] ANN: Pyste - Boost.Python Code Generator > Nicodemus wrote: > > What do you mean "DB of C++ classes"? Did you look at the documentation? > > All the information needed to use Pyste is present there. > > OCAS - http://opencascade.org > > It has many header files autogenerated from metainfo in DB. I can read > this metainfo with python and want to generate boost.python wrappers. > > I want to skip GCCXML parser and use ClassExporter or HeaderExporter. > > Niki Spahiev > Hmm, I see! I will give you instructions privately. Regards, Nicodemus. From harold at imb-jena.de Wed Mar 12 19:09:29 2003 From: harold at imb-jena.de (harold fellermann) Date: Wed, 12 Mar 2003 19:09:29 +0100 Subject: [C++-sig] Re: iterate through boot::python::list In-Reply-To: Message-ID: On Mittwoch, M?rz 12, 2003, at 06:16 Uhr, David Abrahams wrote: > harold fellermann writes: >> Thank you, this works fine. But I still cannot get along with my >> stuff... > You're not being (completely) honest with us ;-) There's a class > called "Node" somewhere which you haven't told us about. True, the X and Y-classes where to much of abstraction ... so here is the code that troubles me, and I hope I won't cut out anything essential this time. class Node { unsigned id; Network *net; // some stupid data that has nothing to do with python nor boost... }; class Network : public Node { public: virtual size_t add_node(Node &); python::list nodes; private: BGL_GRAPH graph; // BGL_GRAPH is a typedef defined somewhere other }; My implementation of Network::add_node is this: size_t Network::add_node(Node &node) { // get new BGL-node size_t id = add_vertex(graph); node.id = id; node.net = this; // insert the node in nodelist nodes.insert(0,node); return id; } and here is how I wrapped those lines: BOOST_PYTHON_MODULE(network) { class_("Node") .def_readonly("net_id", &Node::id) // [...] ; class_ >("Network") .def_readonly("nodes", &Network::nodes) .def("addNode", &Network::add_node, with_custodian_and_ward<1,2>()) // [...] ; } I don't know whether I still need 'with_custodian_and_ward' here (historical reasons). This seems to work if compiled as a python module. At least, my little test program from network import * net = Network() node = Node() net.addNode(node) print net.nodes doesn't complain about anything. Using the same classes from C++ causes trouble. Here is my main function (forgot to copy the Py_Initialize last time, so this is not the point). int main() { Py_Initialize(); Network net; Node node; net.add_node(node); cout << "node added." << endl; return 0; } The code fails in net.add_node(node). Here once again is my debugger's backtrace (In my last posting, things where slightly more complex, but I could reduce the erroneous behaviour to the lines above): (gdb) run Starting program: /home/tsb/harold/cpp_source/test [New Thread 1024 (LWP 27184)] Program received signal SIGABRT, Aborted. [Switching to Thread 1024 (LWP 27184)] 0x401a6df1 in kill () from /lib/libc.so.6 (gdb) bt #0 0x401a6df1 in kill () from /lib/libc.so.6 #1 0x4008f06d in pthread_kill () from /lib/libpthread.so.0 #2 0x4008f5eb in raise () from /lib/libpthread.so.0 #3 0x401a84d9 in abort () from /lib/libc.so.6 #4 0x4012a5d7 in __cxxabiv1::__terminate(void (*)()) () from /usr/lib/libstdc++.so.5 #5 0x4012a624 in std::terminate() () from /usr/lib/libstdc++.so.5 #6 0x4012a7a6 in __cxa_throw () from /usr/lib/libstdc++.so.5 #7 0x4004df59 in boost::python::throw_error_already_set() () from /usr/local/lib/libboost_python.so.1.29.0 #8 0x080e9cb4 in boost::python::converter::arg_to_python::arg_to_python(Node const&) () #9 0x080e8679 in _object* boost::python::api::object_initializer::get(Node const*, int*) () #10 0x080e7542 in boost::python::api::object::object(Node const&) () #11 0x080e6458 in Network::add_node(Node&) () #12 0x080e1e20 in main () #13 0x401954a2 in __libc_start_main () from /lib/libc.so.6 Why does the code run in python but not in C++? There must be a logical error I made, but I can't see it. Thank you very much for your help. By the way: as you can guess, I'm a newbie to boost::python (also with absolutely no knowledge about the Python-C-API). I think that there is a little gap between the short tutorial introduction and the rather technical reference. Is there any additional documentation that could narrow this gap? If not, I'd like to enhance the tutorial to boost::python, as soon as I look through the library, so that newbies like me have no need to steel your time with their questions. Is this a deal? - harold - -- Always remember that you are unique; just like everyone else. -- From harold at imb-jena.de Thu Mar 13 16:15:40 2003 From: harold at imb-jena.de (harold fellermann) Date: Thu, 13 Mar 2003 16:15:40 +0100 Subject: [C++-sig] wrapping reference to c++ object In-Reply-To: Message-ID: hi. As you might know in the meanwhile, I want to insert references (not instances) of C++ objects into a boost::python::list. I thought that calling CPPObject cpp_obj; list.insert(0,handle<>(borrowed(cpp_obj))) would do the thing. According to the documentation I need to inherit from PyObject: class CPPObject : public PyObject { // [...] }; and as soon as I do this, my code is compiled without error, but failed in the constructor of CPPObject. As stated in the Python/C-API, "you never declare an automatic or static variable of type PyObject, only pointer variables of type PyObject* can be declared." So how can the references be stored? - harold - -- "I know what I believe. I will continue to articulate what I believe and what I believe - I believe what I believe is right." -- George W. Bushman From rwgk at yahoo.com Thu Mar 13 18:43:28 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 13 Mar 2003 09:43:28 -0800 (PST) Subject: [C++-sig] wrapping reference to c++ object In-Reply-To: Message-ID: <20030313174328.32600.qmail@web20206.mail.yahoo.com> --- harold fellermann wrote: > class CPPObject : public PyObject > { > // [...] > }; > > and as soon as I do this, my code is compiled without error, but failed > in > the constructor of CPPObject. As stated in the Python/C-API, "you never > declare > an automatic or static variable of type PyObject, only pointer > variables of > type PyObject* can be declared." So how can the references be stored? PyObjects are C objects. They have no constructor and destructor etc. Instead you have to use a combination of Python C API functions to emulate what is normally done by C++ constructors and destructors. If you use Boost.Python's class_<> template all this will be done for you automatically. This is pretty much the essence of Boost.Python. Please study the fine tutorial to learn more about class_<>. You can create wrapped instances of your C++ objects in various ways. The simplest method is to copy an existing object into the newly created wrapped object. But you can also copy references/pointers to existing C++ objects. This is more involved because you have to think about and correctly deal with lifetime issues. This is nicely explained in the tutorial under "Call Policies." Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - establish your business online http://webhosting.yahoo.com From dave at boost-consulting.com Thu Mar 13 18:56:22 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 13 Mar 2003 12:56:22 -0500 Subject: [C++-sig] wrapping reference to c++ object In-Reply-To: (harold fellermann's message of "Thu, 13 Mar 2003 16:15:40 +0100") References: Message-ID: harold fellermann writes: > hi. > > As you might know in the meanwhile, I want to insert references (not > instances) > of C++ objects into a boost::python::list. I thought that calling > > CPPObject cpp_obj; > list.insert(0,handle<>(borrowed(cpp_obj))) > > would do the thing. According to the documentation I need to inherit > from > PyObject: > > class CPPObject : public PyObject > { > // [...] > }; > > and as soon as I do this, my code is compiled without error, but > failed in the constructor of CPPObject. As stated in the > Python/C-API, "you never declare an automatic or static variable of > type PyObject, only pointer variables of type PyObject* can be > declared." So how can the references be stored? First, please do what Ralf said and read the fine tutorial front-to-back before proceeding, or trying anything I've said below. You need to get a better sense of how the library works in order to understand any advice we can give here. One way, but not neccessarily a safe one, to get a Python object into your list which wraps a reference to a C++ object, is list.insert(0, boost::ref(cpp_obj)); I say "not neccessarily safe" because there is nothing here to help manage the lifetime of the C++ object properly; if it is destroyed before the last Python reference you could crash the program with Python code. Since you say: "My general ambition is to reimplement some classes originally written in python. So my intention is not to not intrude the underlying C++-classes, but rather to not intrude the overlying python-classes" I would recommend that you manage all your C++ objects with boost::shared_ptr<>. This is probably the most-foolproof way of getting lifetime issues sorted out, since boost::shared_ptr magically takes care of many issues; see http://article.gmane.org/gmane.comp.python.c++/2530/match=shared+ptr -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Fri Mar 14 01:08:14 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 13 Mar 2003 21:08:14 -0300 Subject: [C++-sig] Support for more than one smart_ptr? Message-ID: <3E711D6E.8030700@globalite.com.br> Hi All! Does Boost.Python support more than one type of smart-pointer for a class? Suppose this code: struct C { C(int x_) : x(x_) {} int x; }; boost::shared_ptr shared_foo( int x ) { return boost::shared_ptr(new C(x)); } std::auto_ptr auto_foo( int x ) { return std::auto_ptr(new C(x)); } How can I make both auto_foo and shared_foo work? Regards, Nicodemus. From dave at boost-consulting.com Fri Mar 14 02:10:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 13 Mar 2003 20:10:29 -0500 Subject: [C++-sig] Support for more than one smart_ptr? In-Reply-To: <3E711D6E.8030700@globalite.com.br> (Nicodemus's message of "Thu, 13 Mar 2003 21:08:14 -0300") References: <3E711D6E.8030700@globalite.com.br> Message-ID: Nicodemus writes: > Hi All! > > Does Boost.Python support more than one type of smart-pointer for a > class? Suppose this code: > > > struct C > { > C(int x_) : x(x_) {} > int x; > }; > > boost::shared_ptr shared_foo( int x ) > { > return boost::shared_ptr(new C(x)); > } > > std::auto_ptr auto_foo( int x ) > { > return std::auto_ptr(new C(x)); > } > > > How can I make both auto_foo and shared_foo work? OK, it's like this _at the moment_: shared_ptr conversion from Python is automatic; you don't need to do anything special (e.g. class_ > ...) shared_ptr conversion to Python is automatic if the shared_ptr was originally converted from python, because the original Python object is maintained by the shared_ptr. If not, the mechanism of class_ > takes care of registering the converter. auto_ptr gets no special treatment; you have to do something explicit (e.g. class_ > ) to register converters. What do you do if you want both? Ugh, we need a reasonable publicly-accessible way to do this. Until then: objects::select_pointer_holder >::register_() registers the conversion to python. What registers the conversion from python? I have no clue, after more than 15 minutes of investigation. Please let me know when you figure it out. :( What I think we really want: auto_ptr to/from Python should be automatic as long as class_ is registered. Likewise for shared_ptr Other smart pointer conversions can be explicitly registered with a single function call: register_smart_ptr >(); -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Sat Mar 15 03:27:03 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 14 Mar 2003 20:27:03 -0600 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E6F43A3.5090009@globalite.com.br> References: <3E6F43A3.5090009@globalite.com.br> Message-ID: <3E728F77.1080709@vrac.iastate.edu> I am very excited by the potential for this tool, especially with its support for templates. (I really didn't want to go through the drudgery of exposing a library of templates to Python!) I am having a problem running Pyste, though. For some reason, copying 'filename' to 'infilename' (line 62 of CppParser.py) creates a file in /tmp that is read-only. I'm sure this is being caused by something screwy with my local environment settings, but I don't know what. I am testing on RedHat 8.0, and my umask is 022. I can modify CppParser.py to set the mode bits to 0644 immediately after the copy, but I would prefer to fix my environment settings rather than have a modified copy of Pyste. Any ideas? -Patrick Nicodemus wrote: > Hello All! > > I'm pleased to announce that Pyste has been released! > > Pyste is a Boost.Python code generator. The user specifies the classes and > functions to be exported using a simple interface file, which following the > Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to > parse all the headers and extract the necessary information to > automatically > generate C++ code. > > The project is in experimental phase, and can be found in the current > Boos.Python CVS, and in the next 1.30.0 release, at libs/python/pyste. > There's documentation and examples. Everyone is invited to try it out > and provide feedback! > > The following features are supported in this release: > * Functions > * Classes > * Class Templates > * Virtual Methods > * Overloading > * Attributes > * Enums (both "free" enums and class enums) > * Nested Classes > > Regards, > Nicodemus. > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- 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 Sat Mar 15 04:08:27 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 15 Mar 2003 00:08:27 -0300 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E728F77.1080709@vrac.iastate.edu> References: <3E6F43A3.5090009@globalite.com.br> <3E728F77.1080709@vrac.iastate.edu> Message-ID: <3E72992B.4050202@globalite.com.br> Patrick Hartling wrote: > I am very excited by the potential for this tool, especially with its > support for templates. (I really didn't want to go through the > drudgery of exposing a library of templates to Python!) I am having a > problem running Pyste, though. For some reason, copying 'filename' to > 'infilename' (line 62 of CppParser.py) creates a file in /tmp that is > read-only. I'm sure this is being caused by something screwy with my > local environment settings, but I don't know what. I am testing on > RedHat 8.0, and my umask is 022. I can modify CppParser.py to set the > mode bits to 0644 immediately after the copy, but I would prefer to > fix my environment settings rather than have a modified copy of > Pyste. Any ideas? > > -Patrick Hi Patrick, It's apparently a bug in Pyste: the permission bits from the filename were being copied to the tmp file. So, I guess your file was read-only, and Pyste couldn't open it for append. I fixed the bug in CVS, could you please update and check if it's ok? I could test it only on Windows. Thanks for the report Patrick! Nicodemus. From patrick at vrac.iastate.edu Sat Mar 15 05:21:12 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 14 Mar 2003 22:21:12 -0600 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E72992B.4050202@globalite.com.br> References: <3E6F43A3.5090009@globalite.com.br> <3E728F77.1080709@vrac.iastate.edu> <3E72992B.4050202@globalite.com.br> Message-ID: <3E72AA38.2070807@vrac.iastate.edu> Your change fixes the problem. Thanks very much. I was playing with the examples in boost/libs/python/pyste/examples, and yes, for me, they are read-only files. I assume that's a result of the anonymous CVS checkout. -Patrick Nicodemus wrote: > > Patrick Hartling wrote: > >> I am very excited by the potential for this tool, especially with its >> support for templates. (I really didn't want to go through the >> drudgery of exposing a library of templates to Python!) I am having a >> problem running Pyste, though. For some reason, copying 'filename' to >> 'infilename' (line 62 of CppParser.py) creates a file in /tmp that is >> read-only. I'm sure this is being caused by something screwy with my >> local environment settings, but I don't know what. I am testing on >> RedHat 8.0, and my umask is 022. I can modify CppParser.py to set the >> mode bits to 0644 immediately after the copy, but I would prefer to >> fix my environment settings rather than have a modified copy of >> Pyste. Any ideas? >> >> -Patrick > > > > Hi Patrick, > > It's apparently a bug in Pyste: the permission bits from the filename > were being copied to the tmp file. So, I guess your file was read-only, > and Pyste couldn't open it for append. I fixed the bug in CVS, could you > please update and check if it's ok? I could test it only on Windows. > > Thanks for the report Patrick! > Nicodemus. > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- 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 Sat Mar 15 08:12:32 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 15 Mar 2003 04:12:32 -0300 Subject: [C++-sig] ANN: Pyste - Boost.Python Code Generator In-Reply-To: <3E72AA38.2070807@vrac.iastate.edu> References: <3E6F43A3.5090009@globalite.com.br> <3E728F77.1080709@vrac.iastate.edu> <3E72992B.4050202@globalite.com.br> <3E72AA38.2070807@vrac.iastate.edu> Message-ID: <3E72D260.7000700@globalite.com.br> Patrick Hartling wrote: > Your change fixes the problem. Thanks very much. > > I was playing with the examples in boost/libs/python/pyste/examples, > and yes, for me, they are read-only files. I assume that's a result > of the anonymous CVS checkout. > > -Patrick Great! If you have any ideas/problems, feel free to share/ask them. Pyste is a very young tool, and feedback is very important. Thanks again for the bug report, Nicodemus. From harold at imb-jena.de Mon Mar 17 18:13:54 2003 From: harold at imb-jena.de (harold fellermann) Date: Mon, 17 Mar 2003 18:13:54 +0100 Subject: [C++-sig] wrapping reference to c++ object In-Reply-To: Message-ID: hi. >> As you might know in the meanwhile, I want to insert references (not >> instances) >> of C++ objects into a boost::python::list. I thought that calling >> >> CPPObject cpp_obj; >> list.insert(0,handle<>(borrowed(cpp_obj))) > First, please do what Ralf said and read the fine tutorial > front-to-back beforte proceeding, or trying anything I've said below. > You need to get a better sense of how the library works in order to > understand any advice we can give here. I did that, you were right. I also did some reading about extending and embedding python. It's getting clearer now, but there is still one questian unsolved (see below). > One way, but not neccessarily a safe one, to get a Python object into > your list which wraps a reference to a C++ object, is > > list.insert(0, boost::ref(cpp_obj)); > > I say "not neccessarily safe" because there is nothing here to help > manage the lifetime of the C++ object properly; if it is destroyed > before the last Python reference you could crash the program with > Python code. This works. I use with_custodian_and_ward to bind the lifetime of cpp_obj to the object that inserts it into its list of references. There encountert no lifetime problem when using the classes as python extensions. However, trying to use my classes with embedded python still troubles me. The thing I don't understand is the following: when I insert a cpp_obj in python, I deal with a python::object because of the wrapper classes, which works fine. But when I use the same (unwrapped) classes for embedded python, any attempt to insert ref(cpp_obj) into my python::list still dumps. What is the reason therefore? Is there a concept I haven't understood yet? Thank you for the patience! - harold - -- "2x2 = gr?n" -- Heinz von Foerster From dave at boost-consulting.com Mon Mar 17 22:30:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 17 Mar 2003 16:30:57 -0500 Subject: [C++-sig] wrapping reference to c++ object In-Reply-To: (harold fellermann's message of "Mon, 17 Mar 2003 18:13:54 +0100") References: Message-ID: harold fellermann writes: >> One way, but not neccessarily a safe one, to get a Python object into >> your list which wraps a reference to a C++ object, is >> >> list.insert(0, boost::ref(cpp_obj)); >> >> I say "not neccessarily safe" because there is nothing here to help >> manage the lifetime of the C++ object properly; if it is destroyed >> before the last Python reference you could crash the program with >> Python code. > > This works. I use with_custodian_and_ward to bind the lifetime of > cpp_obj to the object that inserts it into its list of references. That doesn't work. with_custodian_and_ward only binds the lifetime of Python objects. If the C++ object is held by a corresponding Python object via raw pointer or reference (as with boost::ref(cpp_obj)), it will not do anything to handle the problem I mentioned above. > There encountert no lifetime problem when using the classes as > python extensions. I think you were lucky. > However, trying to use my classes with embedded python still > troubles me. The thing I don't understand is the following: when I > insert a cpp_obj in python, I deal with a python::object because of > the wrapper classes, which works fine. But when I use the same > (unwrapped) classes for embedded python, any attempt to insert > ref(cpp_obj) into my python::list still dumps. What is the reason > therefore? Is there a concept I haven't understood yet? You haven't explained the problem well enough to know. Code (preferably minimal) helps. Minimizing the code may also teach you where you went wrong. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Mar 18 00:23:15 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 17 Mar 2003 18:23:15 -0500 Subject: [C++-sig] Problem compiling with Intel/VC7 In-Reply-To: <000001c2dc48$e9403350$0d00000a@esss.com.br> ("Marcelo A. Camelo"'s message of "Mon, 24 Feb 2003 18:08:40 -0300") References: <000001c2dc48$e9403350$0d00000a@esss.com.br> Message-ID: "Marcelo A. Camelo" writes: > I've have just checked-out boost from the CVS repository > and I'm trying to build it with bjam for the first time. > > I'm using the Intel 6.0 compiler, along with the VC7 > toolset. > > This is the command line I am using: > > bjam -sTOOLS=intel-win32 "-sINTEL_BASE_MSVC_TOOLSET=vc7" > "-sVC7_ROOT=C:\Program Files\Microsoft Visual Studio .NET\VC7" > "-sINTELC=C:\Program Files\Intel\Compiler60\IA32" > "-sPYTHON_ROOT=c:\Bin\Python22" > > Despite of this, bjam is still trying to use the VC6 > include path (that doesn't exist in my machine): > > -I"C:\Program Files\Microsoft Visual Studio\VC98\include" Did you get past this problem, Marcelo? -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Tue Mar 18 04:45:31 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Mon, 17 Mar 2003 21:45:31 -0600 Subject: [C++-sig] Pyste and STL types Message-ID: <3E76965B.2080206@vrac.iastate.edu> I am having some trouble in my initial experimentation with Pyste. It does not seem to like STL types very much. For example, I have attached a class declaration and .pyste file that generate the following stack trace: > python /home/patrick/boost/libs/python/pyste/src/pyste.py --module=test test.pyste Traceback (most recent call last): File "/home/patrick/boost/libs/python/pyste/src/pyste.py", line 153, in ? status = Main() File "/home/patrick/boost/libs/python/pyste/src/pyste.py", line 116, in Main export.Parse(parser) File "/home/patrick/boost/libs/python/pyste/src/Exporter.py", line 20, in Parse declarations, parser_header = parser.parse(header, tail=tail) File "/home/patrick/boost/libs/python/pyste/src/CppParser.py", line 82, in parse declarations = ParseDeclarations(xmlfile) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 394, in ParseDeclarations parser.Parse(filename) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 28, in Parse self.ParseElement(id, element) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 46, in ParseElement func(id, element) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 295, in ParseField type_ = self.GetType(element.get('type')) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 98, in GetType decl = self.GetDecl(id) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 82, in GetDecl self.ParseElement(id, elem) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 46, in ParseElement func(id, element) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 241, in ParseStruct self.ParseClass(id, element) File "/home/patrick/boost/libs/python/pyste/src/GCCXMLParser.py", line 229, in ParseClass assert isinstance(context, str) AssertionError The same trace results if my class body is empty and I simply include . I did try including instead just to verify that there wasn't a problem with the header specifically. I also tried the header_test.{pyste,h} files in the Pyste examples directory, and with those, I get this stack trace: > python ../src/pyste.py --module=header_test header_test.pyste Traceback (most recent call last): File "../src/pyste.py", line 153, in ? status = Main() File "../src/pyste.py", line 116, in Main export.Parse(parser) File "../src/Exporter.py", line 20, in Parse declarations, parser_header = parser.parse(header, tail=tail) File "../src/CppParser.py", line 82, in parse declarations = ParseDeclarations(xmlfile) File "../src/GCCXMLParser.py", line 394, in ParseDeclarations parser.Parse(filename) File "../src/GCCXMLParser.py", line 28, in Parse self.ParseElement(id, element) File "../src/GCCXMLParser.py", line 46, in ParseElement func(id, element) File "../src/GCCXMLParser.py", line 294, in ParseField classname = self.GetDecl(element.get('context')).FullName() File "../src/GCCXMLParser.py", line 82, in GetDecl self.ParseElement(id, elem) File "../src/GCCXMLParser.py", line 46, in ParseElement func(id, element) File "../src/GCCXMLParser.py", line 241, in ParseStruct self.ParseClass(id, element) File "../src/GCCXMLParser.py", line 237, in ParseClass class_.members = self.GetMembers(element.get('members')) File "../src/GCCXMLParser.py", line 214, in GetMembers memberobjs.append(self.GetDecl(member)) File "../src/GCCXMLParser.py", line 82, in GetDecl self.ParseElement(id, elem) File "../src/GCCXMLParser.py", line 46, in ParseElement func(id, element) File "../src/GCCXMLParser.py", line 352, in ParseTypedef type = self.GetDecl(element.get('type')) File "../src/GCCXMLParser.py", line 78, in GetDecl raise ParserError, msg GCCXMLParser.ParserError: ID not found in elements: _9c Am I doing something wrong in my use of Pyste? I am using Python 2.2.1, GCCXML 0.4.2 with GCC 3.2, elementtree 1.0 (20020728), and the latest Boost code from the RC_1_30_0 branch. -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.pyste URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.h URL: From nicodemus at globalite.com.br Tue Mar 18 06:23:28 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 02:23:28 -0300 Subject: [C++-sig] Pyste and STL types In-Reply-To: <3E76965B.2080206@vrac.iastate.edu> References: <3E76965B.2080206@vrac.iastate.edu> Message-ID: <3E76AD50.5090908@globalite.com.br> Patrick Hartling wrote: > I am having some trouble in my initial experimentation with Pyste. It > does not seem to like STL types very much. For example, I have > attached a class declaration and .pyste file that generate the > following stack trace: > > > python /home/patrick/boost/libs/python/pyste/src/pyste.py > --module=test test.pyste > > The same trace results if my class body is empty and I simply include > . I did try including instead just to verify that > there wasn't a problem with the header specifically. I also > tried the header_test.{pyste,h} files in the Pyste examples directory, > and with those, I get this stack trace: > > > python ../src/pyste.py --module=header_test header_test.pyste > > > Am I doing something wrong in my use of Pyste? I am using Python > 2.2.1, GCCXML 0.4.2 with GCC 3.2, elementtree 1.0 (20020728), and the > latest Boost code from the RC_1_30_0 branch. Hi Patrick, No, you're use is correct. ;) I couldn't reproduce those errors on Windows, but in Linux they occur. Shame on me that didn't test all the examples in Linux! I made some fixes and now all the examples work in Linux, including your test file. Please update your copy. Thanks for the bug report! Nicodemus. From ejoy at peoplemail.com.cn Tue Mar 18 14:21:15 2003 From: ejoy at peoplemail.com.cn (Zhang Le) Date: Tue, 18 Mar 2003 21:21:15 +0800 Subject: [C++-sig] How to wrap function pointer in python? Message-ID: <20030318132115.GA1174@localhost.localdomain> Hi all, I just want to wrap a C++ function which takes a C++ function pointer as paramater. Then I think I can write callback function in python. In C++(part of source code): typedef boost::function FUNC_TYPE; void foo(FUNC_TYPE fp) { fp("hello,world!"); } BOOST_PYTHON_MODULE(test) { def("foo",foo) ; } In python I would like to write def hello(s): print s foo(hello) But I fail to link(compile is successful) the C++ code: || g++ -c test.cpp -I. -I/usr/include/python2.2 -Wall -g -O2 -march=i686 -pipe -ftemplate-depth-30 -g3 -O0 -o test.o || g++ test.o -o a.out || test.o: In function `inittest': test.cpp|49| undefined reference to `boost::python::detail::init_module(char const*, void (*)())' || test.o: In function `__static_initialization_and_destruction_0': /usr/local/include/boost/python/converter/registered.hpp|50| undefined reference to `boost::python::converter::registry::lookup(boost::python::type_info)' || test.o: In function `_ZN5boost6python3defIPFvNS_8functionIFvSsENS_6detail8function8unusableES6_S6_S6_S6_S6_S6_S6_S6_S6_EEEEEvPKcT_': test.cpp|36| undefined reference to `boost::python::detail::scope_setattr_doc(char const*, boost::python::api::object const&, char const*)' || test.o: In function `_ZN5boost6python13make_functionIPFvNS_8functionIFvSsENS_6detail8function8unusableES6_S6_S6_S6_S6_S6_S6_S6_S6_EEEEENS0_3api6objectET_': test.cpp|36| undefined reference to `boost::python::objects::function_object(boost::function2<_object*, _object*, _object*, boost::empty_function_policy, boost::empty_function_mixin, std::allocator > const&, unsigned)' || test.o: In function `_ZN5boost6python9converter22arg_rvalue_from_pythonINS_8functionIFvSsENS_6detail8function8unusableES7_S7_S7_S7_S7_S7_S7_S7_S7_EEEC2EP7_object': test.cpp|36| undefined reference to `boost::python::converter::rvalue_from_python_stage1(_object*, boost::python::converter::registration const&)' || test.o: In function `boost::python::detail::none()': test.cpp|35| undefined reference to `_Py_NoneStruct' test.cpp|36| undefined reference to `_Py_NoneStruct' || collect2: ld returned 1 exit status || make: *** [a.out] Error 1 Can you figure out the reason? Thanks in advance. -- Sincerely yours, Zhang Le From dave at boost-consulting.com Tue Mar 18 15:11:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 09:11:50 -0500 Subject: [C++-sig] How to wrap function pointer in python? In-Reply-To: <20030318132115.GA1174@localhost.localdomain> (Zhang Le's message of "Tue, 18 Mar 2003 21:21:15 +0800") References: <20030318132115.GA1174@localhost.localdomain> Message-ID: Zhang Le writes: > Hi all, > I just want to wrap a C++ function which takes a C++ function > pointer as paramater. Then I think I can write callback function in python. > > In C++(part of source code): > typedef boost::function FUNC_TYPE; > > void foo(FUNC_TYPE fp) > { > fp("hello,world!"); > } > > BOOST_PYTHON_MODULE(test) > { > def("foo",foo) ; > } > > In python I would like to write > def hello(s): > print s > foo(hello) What you're trying to do isn't possible, for Boost.Python or any other wrapping system other than *possibly* something like weave which recompiles C++ code on the fly during execution. See http://aspn.activestate.com/ASPN/Mail/Message/1554837 for more details. -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Tue Mar 18 15:23:20 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Tue, 18 Mar 2003 08:23:20 -0600 Subject: [C++-sig] Pyste and STL types In-Reply-To: <3E76AD50.5090908@globalite.com.br> References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> Message-ID: <3E772BD8.1010006@vrac.iastate.edu> Nicodemus wrote: > Patrick Hartling wrote: > >> I am having some trouble in my initial experimentation with Pyste. It >> does not seem to like STL types very much. For example, I have >> attached a class declaration and .pyste file that generate the >> following stack trace: >> >> > python /home/patrick/boost/libs/python/pyste/src/pyste.py >> --module=test test.pyste >> >> The same trace results if my class body is empty and I simply include >> . I did try including instead just to verify that >> there wasn't a problem with the header specifically. I also >> tried the header_test.{pyste,h} files in the Pyste examples directory, >> and with those, I get this stack trace: >> >> > python ../src/pyste.py --module=header_test header_test.pyste >> >> >> Am I doing something wrong in my use of Pyste? I am using Python >> 2.2.1, GCCXML 0.4.2 with GCC 3.2, elementtree 1.0 (20020728), and the >> latest Boost code from the RC_1_30_0 branch. > > > > Hi Patrick, > > No, you're use is correct. ;) > I couldn't reproduce those errors on Windows, but in Linux they occur. > Shame on me that didn't test all the examples in Linux! I made some > fixes and now all the examples work in Linux, including your test file. > Please update your copy. Thanks very much, Nicodemus, things are much improved now. Based on further usage, I have a question: are unions supported? I am not a Python guru, but I don't think that there is a union concept in Python. In that case, it would make sense if Pyste ran into a problem with a class containing a public data member that is a union type. I would grant that the C++ class I have in mind should probably encapsulate its data better, but in the meantime, should exclude() work to keep the union data member out of the mix? With the attached .h and .pyste files, I get this stack trace: Traceback (most recent call last): File "/home/patrick/boost/libs/python/pyste/src/pyste.py", line 153, in ? status = Main() File "/home/patrick/boost/libs/python/pyste/src/pyste.py", line 116, in Main export.Parse(parser) File "/home/patrick/boost/libs/python/pyste/src/Exporter.py", line 22, in Parse self.SetDeclarations(declarations) File "/home/patrick/boost/libs/python/pyste/src/ClassExporter.py", line 62, in SetDeclarations [x for x in self.class_.members if x.visibility == Scope.public] AttributeError: 'Declaration' object has no attribute 'visibility' My environment is the same as described above. -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: union.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: union.pyste URL: From dave at boost-consulting.com Tue Mar 18 15:43:26 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 09:43:26 -0500 Subject: [C++-sig] How to wrap function pointer in python? In-Reply-To: (David Abrahams's message of "Tue, 18 Mar 2003 09:11:50 -0500") References: <20030318132115.GA1174@localhost.localdomain> Message-ID: David Abrahams writes: > What you're trying to do isn't possible, for Boost.Python or any other > wrapping system other than *possibly* something like weave which > recompiles C++ code on the fly during execution. See > http://aspn.activestate.com/ASPN/Mail/Message/1554837 for more > details. I've just added a FAQ about this; it's in the CVS and will go out with 1.30.0. One thing I added which wasn't in my reply is: If you have the luxury of changing the C++ code you're wrapping, pass it a boost::python::object instead and call that; the overloaded function call operator will invoke the Python function you pass it behind the object. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Mar 18 16:03:15 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 12:03:15 -0300 Subject: [C++-sig] Pyste and STL types References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> Message-ID: <009601c2ed5f$80a10ef0$0e00000a@esss.com.br> ----- Original Message ----- From: "Patrick Hartling" To: Sent: Tuesday, March 18, 2003 11:23 AM Subject: Re: [C++-sig] Pyste and STL types > Thanks very much, Nicodemus, things are much improved now. > > Based on further usage, I have a question: are unions supported? I am > not a Python guru, but I don't think that there is a union concept in > Python. In that case, it would make sense if Pyste ran into a problem > with a class containing a public data member that is a union type. I > would grant that the C++ class I have in mind should probably > encapsulate its data better, but in the meantime, should exclude() work > to keep the union data member out of the mix? With the attached .h and > .pyste files, I get this stack trace: > > AttributeError: 'Declaration' object has no attribute 'visibility' > > My environment is the same as described above. > > -Patrick Hi Patrick, It seems that Boost.Python doesn't support unions. The following code fails to compile: union test { int t1; short s1; short s2; }; // Module ====================================================================== BOOST_PYTHON_MODULE(_3d) { class_("test") .def_readwrite("t1", &test::t1) .def_readwrite("s1", &test::s1) .def_readwrite("s2", &test::s2) ; } From dave at boost-consulting.com Tue Mar 18 16:06:32 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 10:06:32 -0500 Subject: [C++-sig] Pyste and STL types In-Reply-To: <3E772BD8.1010006@vrac.iastate.edu> (Patrick Hartling's message of "Tue, 18 Mar 2003 08:23:20 -0600") References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > Thanks very much, Nicodemus, things are much improved now. > > Based on further usage, I have a question: are unions supported? Almost certainly not. > I am not a Python guru, but I don't think that there is a union > concept in Python. Sure there is: x = 1 x = 'hello' x = 3.14 type(x) ;-) In other words, in Python everything is a union. > In that case, it would make sense if Pyste ran into a problem with a > class containing a public data member that is a union type. I would > grant that the C++ class I have in mind should probably encapsulate > its data better, but in the meantime, should exclude() work to keep > the union data member out of the mix? Probably a good idea. Eventually, this is the sort of problem that can be handled by something like Pyste but not easily by Boost.Python alone. In order to do the wrapping, you'd need to provide Pyste with a function that it could use to determine which member of the union was "active". Come to think of it, I guess you could use Boost.Python properties with appropriate C++ accessor functions to expose a union data member. -- Dave Abrahams Boost Consulting www.boost-consulting.com From seefeld at sympatico.ca Tue Mar 18 16:21:45 2003 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 18 Mar 2003 10:21:45 -0500 Subject: [C++-sig] Pyste and STL types References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> Message-ID: <5ecfba82e21c2a179c70d25002f3bc633e773619@Orthosoft.ca> Hi there David Abrahams wrote: > Patrick Hartling writes: > > >>Thanks very much, Nicodemus, things are much improved now. >> >>Based on further usage, I have a question: are unions supported? > > > Almost certainly not. > > >>I am not a Python guru, but I don't think that there is a union >>concept in Python. > > > Sure there is: > > x = 1 > x = 'hello' > x = 3.14 > type(x) > > ;-) > > In other words, in Python everything is a union. Good point. Along this line, I always thought of boost.python as a tool not only to map between languages but also to map between idioms (idiosyncrasies), to make the mapping smooth and as natural as possible. In this light, why would boost.python support unions ? As you point out, python uses the concept intrinsically. C++ doesn't need it, so it's really just a relict of C. Why not treat it as just that ? Regards, Stefan From dave at boost-consulting.com Tue Mar 18 17:08:26 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 11:08:26 -0500 Subject: [C++-sig] Pyste and STL types In-Reply-To: <5ecfba82e21c2a179c70d25002f3bc633e773619@Orthosoft.ca> (Stefan Seefeld's message of "Tue, 18 Mar 2003 10:21:45 -0500") References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> <5ecfba82e21c2a179c70d25002f3bc633e773619@Orthosoft.ca> Message-ID: Stefan Seefeld writes: > Hi there > > David Abrahams wrote: > >> In other words, in Python everything is a union. > > Good point. Along this line, I always thought of boost.python as > a tool not only to map between languages but also to map between > idioms (idiosyncrasies), to make the mapping smooth and as natural > as possible. Exactly. > In this light, why would boost.python support unions ? As you point > out, python uses the concept intrinsically. C++ doesn't need it, so > it's really just a relict of C. Why not treat it as just that ? Because we aim as much as possible to support wrapping existing C++ interfaces, relics and all. In fact, unions are not exactly a relic except that they aren't as capable as we might like. Boost just accepted a C++ variant library which provides a union-plus-ctor/dtor-and-introspectability, and it makes complete sense to think about converting those directly to/from Python based on which type they are holding. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Mar 18 18:41:30 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 14:41:30 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> Message-ID: <3E775A4A.7000309@globalite.com.br> David Abrahams writes: >Patrick Hartling writes: > > >>In that case, it would make sense if Pyste ran into a problem with a >>class containing a public data member that is a union type. I would >>grant that the C++ class I have in mind should probably encapsulate >>its data better, but in the meantime, should exclude() work to keep >>the union data member out of the mix? >> >> >Probably a good idea. > That's the way it should be, but there's a bug in the implementation. I will fix it as soon as possible. >Eventually, this is the sort of problem that >can be handled by something like Pyste but not easily by Boost.Python >alone. In order to do the wrapping, you'd need to provide Pyste with >a function that it could use to determine which member of the union >was "active". > >Come to think of it, I guess you could use Boost.Python properties >with appropriate C++ accessor functions to expose a union data member. > I don't know much about Unions, so please correct me if any statement below is wrong. From what I understand, unions act exactly like a struct, except that it's members all share the same adress space. The only point to this is to save memory. The union doesn't keep track of each variable is "active", the programmer must take care of that: union Test { float d; int i; }; void main() { Test t; t.d = 3.0; cout << t.i << endl; } Using t.i in the example above gives you garbage. The programmer should only access t.d, or set a new value for the union using t.i. Given that, I believe that Boost.Python could expose it exactly like an struct: class_("Test") .def_readwrite("d", &Test::d) .def_readwrite("i", &Test::i) ; This currently fails, apparently because of an internal mechanism of Boost.Python involving polimorphism. From what I gather from the error message, Boost.Python tries to derive from Test to check for polimorphic behaviour, and unions can't be subclassed. So, a possible solution would be to specialize a class_ to take in account the details of a union (lack of polimorphism, no derivation): union_("Test") .def_readwrite("d", &Test::d) .def_readwrite("i", &Test::i) ; What you think? From dave at boost-consulting.com Wed Mar 19 00:39:47 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 18:39:47 -0500 Subject: [C++-sig] Pyste and STL types References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> <009601c2ed5f$80a10ef0$0e00000a@esss.com.br> Message-ID: "Nicodemus" writes: >>From the error message, it seems that Boost.Python tries to derive from the > union, which is forbidden. Does anyone knows if I'm overlooking something? Is this happening somewhere in the type traits code? Can you post an instantiation backtrace? > If Boost.Python doesn't indeed support unions, then Pyste will not support > them too. But the stack trace is a bug: it should just ignore the union. I > will work on it later today, and when it's ready I will let you know. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Mar 19 00:58:14 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 20:58:14 -0300 Subject: [C++-sig] Pyste and STL types In-Reply-To: References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> <009601c2ed5f$80a10ef0$0e00000a@esss.com.br> Message-ID: <3E77B296.3010200@globalite.com.br> David Abrahams wrote: >Is this happening somewhere in the type traits code? Can you post an >instantiation backtrace? > > It seems to be. Here's the error message: D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(26) : error C2569: 'Test' : enum/union cannot be used as a base class D:\Temp\pyste-tests\boost.cpp(9) : see declaration of 'Test' D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(79) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp1' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(84) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/inheritance.hpp(67) : see reference to class template instantiation 'boost::is_polymorphic' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/inheritance.hpp(77) : see reference to class template instantiation 'boost::python::objects::dynamic_id_generator' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/class_converters.hpp(77) : see reference to function template instantiation 'void __cdecl boost::python::objects::register_dynamic_id(union Test *)' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(34) : error C2569: 'Test' : enum/union cannot be used as a base class D:\Temp\pyste-tests\boost.cpp(9) : see declaration of 'Test' D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(79) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp1' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/type_traits/is_polymorphic.hpp(84) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/inheritance.hpp(67) : see reference to class template instantiation 'boost::is_polymorphic' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/inheritance.hpp(77) : see reference to class template instantiation 'boost::python::objects::dynamic_id_generator' being compiled D:\Programming\Libraries\boost-cvs\boost\boost/python/object/class_converters.hpp(77) : see reference to function template instantiation 'void __cdecl boost::python::objects::register_dynamic_id(union Test *)' being compiled Error executing xicl6.exe. From dave at boost-consulting.com Wed Mar 19 01:06:32 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 19:06:32 -0500 Subject: [C++-sig] is_polymorphic and unions (was: Pyste and STL types) In-Reply-To: <3E77B296.3010200@globalite.com.br> (Nicodemus's message of "Tue, 18 Mar 2003 20:58:14 -0300") References: <3E76965B.2080206@vrac.iastate.edu> <3E76AD50.5090908@globalite.com.br> <3E772BD8.1010006@vrac.iastate.edu> <009601c2ed5f$80a10ef0$0e00000a@esss.com.br> <3E77B296.3010200@globalite.com.br> Message-ID: Nicodemus writes: >>Is this happening somewhere in the type traits code? Can you post an >>instantiation backtrace? >> > > It seems to be. Here's the error message: I guess the question here is: "should is_polymorphic::value compile?" If so, then we have a bug in is_polymorphic. If not, we should change all uses of is_polymorphic in boost/python/class.hpp boost/python/object/class_converters.hpp boost/python/object/inheritance.hpp to: mpl::and_, is_polymorphic > You can make this patch yourself in Boost.Python as an interim measure to see if it makes wrapping unions work. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 19 01:49:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 19:49:29 -0500 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E775A4A.7000309@globalite.com.br> (Nicodemus's message of "Tue, 18 Mar 2003 14:41:30 -0300") References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> Message-ID: Nicodemus writes: > This currently fails, apparently because of an internal mechanism of > Boost.Python involving polimorphism. From what I gather from the error > message, Boost.Python tries to derive from Test to check for > polimorphic behaviour, and unions can't be subclassed. So, a possible > solution would be to specialize a class_ to take in account the > details of a union (lack of polimorphism, no derivation): > > union_("Test") > .def_readwrite("d", &Test::d) > .def_readwrite("i", &Test::i) ; I just want to point out again that I don't think this is _usually_ the best way to map a union to Python. For any union that could be used effectively from Python there has to be information somewhere saying which field is active. When converting the union to Python, it should use the information to convert the appropriate field to Python instead. When converting from python, it should set the information up based on the type of the Python object. A scheme like this requires some user intervention, but it smooths over the difference between the language idioms. Having something which really acts like a C++ union is anti-idiomatic in Python. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Mar 19 02:13:19 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 22:13:19 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> Message-ID: <3E77C42F.5030106@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>This currently fails, apparently because of an internal mechanism of >>Boost.Python involving polimorphism. From what I gather from the error >>message, Boost.Python tries to derive from Test to check for >>polimorphic behaviour, and unions can't be subclassed. So, a possible >>solution would be to specialize a class_ to take in account the >>details of a union (lack of polimorphism, no derivation): >> >> union_("Test") >> .def_readwrite("d", &Test::d) >> .def_readwrite("i", &Test::i) ; >> >> > >I just want to point out again that I don't think this is _usually_ >the best way to map a union to Python. For any union that could be >used effectively from Python there has to be information somewhere >saying which field is active. When converting the union to Python, it >should use the information to convert the appropriate field to Python >instead. When converting from python, it should set the information >up based on the type of the Python object. > > What do you mean by "active field"? I ask because my knowledge of unions is limited. From dave at boost-consulting.com Wed Mar 19 02:44:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 20:44:34 -0500 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E77C42F.5030106@globalite.com.br> (Nicodemus's message of "Tue, 18 Mar 2003 22:13:19 -0300") References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> Message-ID: Nicodemus writes: > What do you mean by "active field"? I ask because my knowledge of > unions is limited. The one someone stored data in. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Mar 19 02:58:37 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 18 Mar 2003 22:58:37 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> Message-ID: <3E77CECD.8020002@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > >>What do you mean by "active field"? I ask because my knowledge of >>unions is limited. >> > >The one someone stored data in. > I know, but from your comment I understood that C/C++ took care of this for you, like this: union Test { float d; int i; }; void main() { Test t; t = 3.0; // use the d member float x = t; // get the d member t = 1; // set the i member int z = t; // get the i member } Which I don't think is the case. The programmer has to take care of what field is active: void main() { Test t; t.d = 3.0; // set the d member int z = t.i; // member i has garbage float x = t.d; // ok } What am I missing? From nicodemus at globalite.com.br Wed Mar 19 04:15:05 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 19 Mar 2003 00:15:05 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E775A4A.7000309@globalite.com.br> References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> Message-ID: <3E77E0B9.1020700@globalite.com.br> Nicodemus wrote: > > David Abrahams writes: > >> Patrick Hartling writes: >> >> >>> In that case, it would make sense if Pyste ran into a problem with a >>> class containing a public data member that is a union type. I would >>> grant that the C++ class I have in mind should probably encapsulate >>> its data better, but in the meantime, should exclude() work to keep >>> the union data member out of the mix? >> >> Probably a good idea. > > > That's the way it should be, but there's a bug in the implementation. > I will fix it as soon as possible. Fixed in the current CVS and in the branch for release 1.30.0. You can now exclude the union, until we figure how to export them. Regards, Nicodemus. From patrick at vrac.iastate.edu Wed Mar 19 04:44:09 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Tue, 18 Mar 2003 21:44:09 -0600 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E77E0B9.1020700@globalite.com.br> References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77E0B9.1020700@globalite.com.br> Message-ID: <3E77E789.4030307@vrac.iastate.edu> Nicodemus wrote: > Nicodemus wrote: > >> >> David Abrahams writes: >> >>> Patrick Hartling writes: >>> >>> >>>> In that case, it would make sense if Pyste ran into a problem with a >>>> class containing a public data member that is a union type. I would >>>> grant that the C++ class I have in mind should probably encapsulate >>>> its data better, but in the meantime, should exclude() work to keep >>>> the union data member out of the mix? >>> >>> >>> Probably a good idea. >> >> >> >> That's the way it should be, but there's a bug in the implementation. >> I will fix it as soon as possible. > > > > Fixed in the current CVS and in the branch for release 1.30.0. You can > now exclude the union, until we figure how to export them. Again, thank you very much. -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 dave at boost-consulting.com Wed Mar 19 05:05:28 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 18 Mar 2003 23:05:28 -0500 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E77CECD.8020002@globalite.com.br> (Nicodemus's message of "Tue, 18 Mar 2003 22:58:37 -0300") References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> <3E77CECD.8020002@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>Nicodemus writes: >> >> >>>What do you mean by "active field"? I ask because my knowledge of >>>unions is limited. >>> >> >>The one someone stored data in. >> > > I know, but from your comment I understood that C/C++ took care of > this for you, like this: > > union Test > { > float d; > int i; > }; > > void main() > { > Test t; > t = 3.0; // use the d member > float x = t; // get the d member > t = 1; // set the i member > int z = t; // get the i member > } > > Which I don't think is the case. I didn't meant that. > The programmer has to take care of > what field is active: Yes. > void main() > { > Test t; > t.d = 3.0; // set the d member > int z = t.i; // member i has garbage > float x = t.d; // ok > } > > What am I missing? Nothing; I am just suggesting that the Python interface ought to work like the first example when the union is a member of another class, as it commonly will be. In order to handle a union coherently there must be some additional data telling you which field is active, so the union is commonly packaged in a struct: struct Test { bool is_float; union val { float d; char* s; }; }; In Python, we ought to be able to say: Test.val = 3.14 or Test.val = 'hello' ...just IMO. -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Wed Mar 19 05:31:17 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Tue, 18 Mar 2003 22:31:17 -0600 Subject: [C++-sig] Missing address-of operator for overloaded member function Message-ID: <3E77F295.1060104@vrac.iastate.edu> Thanks to Nicodemus' quick bug fixes, I have made quite a bit more progress with Pyste tonight. I am now to the point where I am compiling the generated C++ code. Now, however, I've run into a problem with overloaded member functions wherein the address-of operator (&) is missing in the second argument to boost::python::class_::def(). I have attached an example that results in the following C++ code (using the latest Pyste sources): BOOST_PYTHON_MODULE(overload) { class_< Overload >("Overload", init< >()) .def(init< const Overload & >()) .def("data", (void (Overload::*)(int) )Overload::data) .def("data", (int (Overload::*)() )Overload::data) ; } The problem appears to be that Function.PointerDeclaration() (in declarations.py) doesn't add the '&' in the pointer-to-member case. I'm still working with GCC 3.2, though I assume other compilers would also fail to compile the above. -Patrick P.S. Pyste really is a great tool. It's precisely what I needed to jump-start a project I had let stagnate in the last couple of months. -- 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: overload.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: overload.pyste URL: From nicodemus at globalite.com.br Wed Mar 19 05:56:46 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 19 Mar 2003 01:56:46 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> <3E77CECD.8020002@globalite.com.br> Message-ID: <3E77F88E.4070603@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > >>What am I missing? >> >> > >Nothing; I am just suggesting that the Python interface ought to work >like the first example when the union is a member of another class, as >it commonly will be. In order to handle a union coherently there >must be some additional data telling you which field is active, so >the union is commonly packaged in a struct: > > struct Test > { > bool is_float; > union val > { > float d; > char* s; > }; > }; > >In Python, we ought to be able to say: > > Test.val = 3.14 > >or > > Test.val = 'hello' > >...just IMO. > > Now I see what you mean. Indeed, that would be a nice interface. One problem that I see is that there's no way to know when the "active" member changes in the C++ side, unless the user gives a mechanism that allows us to know, like you suggested. But then the user would have to change the wrapping code to update this mechanism. Consider this: struct Test { bool is_float; union { float d; char* s; } val; }; void use(Test& t) { t.val.d = 3.0; } There's no way to know that now the active member is "d". The user would have to change it to: void use(Test& t) { t.val.d = 3.0; t.is_float = true; } (unless this is a common practice: like I said before, I know little about unions). So I don't think this solution is optimal. Sure, the user could provide wrappers for functions like "use", but it's a lot of work compared to the gains, in my opinion. Given this, I think exporting it to python as it is seen in C++ is enough. Don't get me wrong: I would gladly implement in Pyste a system to export unions like you suggested (I'm not lazy), but I don't know if it is possible to do it in a reasonable way for the user. From nicodemus at globalite.com.br Wed Mar 19 06:13:00 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 19 Mar 2003 02:13:00 -0300 Subject: [C++-sig] Missing address-of operator for overloaded member function In-Reply-To: <3E77F295.1060104@vrac.iastate.edu> References: <3E77F295.1060104@vrac.iastate.edu> Message-ID: <3E77FC5C.7050307@globalite.com.br> Patrick Hartling wrote: > Thanks to Nicodemus' quick bug fixes, I have made quite a bit more > progress with Pyste tonight. I am now to the point where I am > compiling the generated C++ code. Now, however, I've run into a > problem with overloaded member functions wherein the address-of > operator (&) is missing in the second argument to > boost::python::class_::def(). > > I have attached an example that results in the following C++ code > (using the latest Pyste sources): > > BOOST_PYTHON_MODULE(overload) > { > class_< Overload >("Overload", init< >()) > .def(init< const Overload & >()) > .def("data", (void (Overload::*)(int) )Overload::data) > .def("data", (int (Overload::*)() )Overload::data) > ; > > } > > The problem appears to be that Function.PointerDeclaration() (in > declarations.py) doesn't add the '&' in the pointer-to-member case. > I'm still working with GCC 3.2, though I assume other compilers would > also fail to compile the above. > My main platform is windows using the intel compiler (both at home and at work), and it doesn't complain about the missing & operator, which is why this bug has lived for so long. 8/ Again, fixed both in the CVS trunk and the RC branch. > -Patrick > > > P.S. Pyste really is a great tool. It's precisely what I needed to > jump-start a project I had let stagnate in the last couple of months. Glad to know. And I want to thank you for your patience with the bugs and your clear reports. Regards, Nicodemus. From dave at boost-consulting.com Thu Mar 20 01:56:02 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 19 Mar 2003 19:56:02 -0500 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: <3E77F88E.4070603@globalite.com.br> (Nicodemus's message of "Wed, 19 Mar 2003 01:56:46 -0300") References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> <3E77CECD.8020002@globalite.com.br> <3E77F88E.4070603@globalite.com.br> Message-ID: Nicodemus writes: > Now I see what you mean. Indeed, that would be a nice interface. > One problem that I see is that there's no way to know when the > "active" member changes in the C++ side, unless the user gives a > mechanism that allows us to know, like you suggested. Right. > But then the user would have to change the wrapping code to update > this mechanism. Consider this: > > struct Test > { > bool is_float; > union > { > float d; > char* s; > } val; > }; > > void use(Test& t) > { > t.val.d = 3.0; > } > > There's no way to know that now the active member is "d". The user > would have to change it to: > > void use(Test& t) > { > t.val.d = 3.0; > t.is_float = true; > } My point is that if there's no way to know that the active member is "d", the union is useless anyway, so the user "always" has some member like is_float which she is keeping in synch to indicate the correct member to access. > (unless this is a common practice: like I said before, I know little > about unions). I'm saying it's a common practice. How would you use the union otherwise? > So I don't think this solution is optimal. Sure, the user could > provide wrappers for functions like "use", but it's a lot of work > compared to the gains, in my opinion. That's debatable. Part of the philosophy of Boost.Python is that you should be able to wrap C++ code in such a way that it can't be abused from Python to cause a crash. Some unions are like that naturally, e.g.: union { int x; char bytes[sizeof(int)]; }; but others like the union in Test above are not. > Given this, I think exporting it to python as it is seen in C++ is > enough. Don't get me wrong: I would gladly implement in Pyste a > system to export unions like you suggested (I'm not lazy), but I > don't know if it is possible to do it in a reasonable way for the > user. It requires the user to write some extra code. Worth it? I don't know; I hardly ever use unions myself ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Thu Mar 20 02:29:44 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 19 Mar 2003 22:29:44 -0300 Subject: Fw: [C++-sig] Pyste and STL types In-Reply-To: References: <00a201c2ed61$08c27ed0$0e00000a@esss.com.br> <3E775A4A.7000309@globalite.com.br> <3E77C42F.5030106@globalite.com.br> <3E77CECD.8020002@globalite.com.br> <3E77F88E.4070603@globalite.com.br> Message-ID: <3E791988.7060401@globalite.com.br> David Abrahams wrote: >My point is that if there's no way to know that the active member is >"d", the union is useless anyway, so the user "always" has some member >like is_float which she is keeping in synch to indicate the correct >member to access. > > > >>(unless this is a common practice: like I said before, I know little >>about unions). >> >> > >I'm saying it's a common practice. How would you use the union >otherwise? > > I never used unions before, that's why I claimed that tha I knew little about them. 8) >>So I don't think this solution is optimal. Sure, the user could >>provide wrappers for functions like "use", but it's a lot of work >>compared to the gains, in my opinion. >> >> > >That's debatable. Part of the philosophy of Boost.Python is that you >should be able to wrap C++ code in such a way that it can't be abused >from Python to cause a crash. Some unions are like that naturally, >e.g.: > > union { int x; char bytes[sizeof(int)]; }; > >but others like the union in Test above are not. > > I see... like the operator[] for vectors, where the missuse can cause a crash. >>Given this, I think exporting it to python as it is seen in C++ is >>enough. Don't get me wrong: I would gladly implement in Pyste a >>system to export unions like you suggested (I'm not lazy), but I >>don't know if it is possible to do it in a reasonable way for the >>user. >> >> > >It requires the user to write some extra code. Worth it? I don't >know; I hardly ever use unions myself ;-) > I never used them too. 8) I propose we wait for user feedback. If people start to ask for unions, we could then discuss a way to export them nicely. Boost.Python doesn't support them, and I never seen anyone asking for it. Regards, Nicodemus. From patrick at vrac.iastate.edu Thu Mar 20 05:14:24 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Wed, 19 Mar 2003 22:14:24 -0600 Subject: [C++-sig] Small Pyste patch Message-ID: <3E794020.8020605@vrac.iastate.edu> I have attached a small patch to the Pyste infos.py file. This change allows template parameters to include the C++ scope operator. -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: pyste.patch URL: From nicodemus at globalite.com.br Thu Mar 20 05:56:49 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 20 Mar 2003 01:56:49 -0300 Subject: [C++-sig] Small Pyste patch In-Reply-To: <3E794020.8020605@vrac.iastate.edu> References: <3E794020.8020605@vrac.iastate.edu> Message-ID: <3E794A11.8030602@globalite.com.br> Patrick Hartling wrote: > I have attached a small patch to the Pyste infos.py file. This change > allows template parameters to include the C++ scope operator. > > -Patrick Thanks Patrick! But unfortunately your patch doesn't adress template parameters that are templates themselves, for instance, std::vector would produce the name std_vector. This is of course an oversight from my implementation, and you pointed it out. I fixed it in the CVS. Thanks again, Nicodemus. From jochen.heckl at novatrix.de Fri Mar 21 12:13:24 2003 From: jochen.heckl at novatrix.de (Jochen Heckl) Date: Fri, 21 Mar 2003 12:13:24 +0100 Subject: [C++-sig] std::string& parameter Message-ID: I wan't to retrieve strings via out parameter. Isn't there some predefined solution, so I do not have to export class_< std::string > on my own ? The problem is: class A { bool DoSomethingWithString< std::string& o_String > } class_( "A" ) .def( "DoSomethingWithString", &A::DoSomethingWithString ) ; to be able to call A::DoSomethingWithString() I must also export class_< std::string >( "STLString" ) ; but I don't want to kind of "reinvent the wheel". Isn't there a standard solution for that ? Jochen Heckl NovaTrix GmbH Ettishofer Str. 10C 88250 Weingarten EMail: jochen.heckl at novatrix.de Phone: 0049 (0) 751 50921- 57 Fax: 0049 (0) 751 50921- 31 From dave at boost-consulting.com Fri Mar 21 13:34:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 21 Mar 2003 07:34:40 -0500 Subject: [C++-sig] std::string& parameter In-Reply-To: ("Jochen Heckl"'s message of "Fri, 21 Mar 2003 12:13:24 +0100") References: Message-ID: "Jochen Heckl" writes: > I wan't to retrieve strings via out parameter. Isn't there some > predefined solution, so I do not have to export class_< std::string > > on my own ? What is your problem with that? > The problem is: > > class A { bool DoSomethingWithString< std::string& o_String > } ^ ^ You must mean something else, right?--^-----------------------^ These were supposed to be parens? > class_( "A" ) .def( "DoSomethingWithString", > &A::DoSomethingWithString ) ; > > > to be able to call A::DoSomethingWithString() I must also export > > class_< std::string >( "STLString" ) ; > > but I don't want to kind of "reinvent the wheel". Isn't there a > standard solution for that ? Considering that Python strings are immutable, no there is not. If you want to avoid wrapping std::string, you could add a thin wrapper over your member function and wrap that: tuple DoSomethingWithString(A& self, std::string s) { bool x = self.DoSomethingWithString(s); return make_tuple(x, s); } class_( "A" ) .def( "DoSomethingWithString", DoSomethingWithString ) ; -- Dave Abrahams Boost Consulting www.boost-consulting.com From patrick at vrac.iastate.edu Fri Mar 21 20:28:34 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 21 Mar 2003 13:28:34 -0600 Subject: [C++-sig] Missing definitions for virtual methods in Pyste-generated code Message-ID: <3E7B67E2.8040201@vrac.iastate.edu> In my continued experimentation with Pyste, I have run into a problem relating to virtual methods. I have attached example code that demonstrates the problem specifically, but I will try to explain it in general terms here. First, the class structure is similar to this: class A { public: virtual void f1(); }; class B : public A { public: virtual void f2(); }; My goal, then, is to derive from B a class C written in Python: class C(MyModule.B): def __init__(self): MyModule.B.__init__(self) def f1(self): # Do something ... def f2(self): # Do something else ... Ultimately, an instance of C will be handed off to some C++ code where it needs to be treated polymorphically as an instance of either A or B, depending on the context. In Pyste, I declare that I want to expose both A and B to Python. However, the Boost.Python code that gets generated for class B is missing the definition for the f1() method that is inherited from class A: class_< B, bases< A > , boost::noncopyable, B_Wrapper >("B", init< >()) .def("f2", &B::f2, &B_Wrapper::default_f2) ; Without the definition for the f1() member function, C.f1() is never invoked by the C++ code. C.f2() works fine, however. I can easily modify the generated Boost.Python code to add the definition of f1(), but this seems like a bug in how Pyste deals with inherited member functions. More specifcally, I get the following output with the attached code by compiling the unmodified Pyste-generated C++: > ./virtualTest.py Base::func() BaseExt::otherFunc() MyClass.pureVirtual() If I modify the generated C++ code to include the definition of f1() for the class B, I get this output (which is what I want): > ./virtualTest.py MyClass.func() BaseExt::otherFunc() MyClass.pureVirtual() Right now, I am using Pytse and Boost.Python from the Boost CVS HEAD branch so that I have the latest Pyste fixes. -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: virtualTest.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: virtualTest.pyste URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: virtualTest.py URL: From dave at boost-consulting.com Fri Mar 21 21:18:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 21 Mar 2003 15:18:30 -0500 Subject: [C++-sig] Missing definitions for virtual methods in Pyste-generated code In-Reply-To: <3E7B67E2.8040201@vrac.iastate.edu> (Patrick Hartling's message of "Fri, 21 Mar 2003 13:28:34 -0600") References: <3E7B67E2.8040201@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > In my continued experimentation with Pyste, I have run into a problem > relating to virtual methods. I have attached example code that > demonstrates the problem specifically, but I will try to explain it in > general terms here. > > First, the class structure is similar to this: > > class A > { > public: > virtual void f1(); > }; > > class B : public A > { > public: > virtual void f2(); > }; > > My goal, then, is to derive from B a class C written in Python: > > class C(MyModule.B): > def __init__(self): > MyModule.B.__init__(self) > > def f1(self): > # Do something ... > > def f2(self): > # Do something else ... > > Ultimately, an instance of C will be handed off to some C++ code where > it needs to be treated polymorphically as an instance of either A or > B, depending on the context. > > In Pyste, I declare that I want to expose both A and B to > Python. However, the Boost.Python code that gets generated for class B > is missing the definition for the f1() method that is inherited from > class A: > > class_< B, bases< A > , boost::noncopyable, B_Wrapper >("B", init< >()) > .def("f2", &B::f2, &B_Wrapper::default_f2) > ; > > Without the definition for the f1() member function, C.f1() is never > invoked by the C++ code. C.f2() works fine, however. I can easily > modify the generated Boost.Python code to add the definition of f1(), > but this seems like a bug in how Pyste deals with inherited member > functions. Something is slightly wrong with your analysis: 1. The generated code for wrapping A should contain a definition of f1 2. That's not what causes C.f1 to be called when invoked from C++ anyway: it's the override in the wrapper class for A which I presume from reading the code above should be called A_Wrapper that makes sure C.f1 gets called. ...and now I see the problem. For scenarios like this, the Wrapper classes really need to use virtual inheritance. It should look something like this: struct A_Wrapper : virtual A { A_Wrapper(PyObject* self) : self(self) {} void f1() { call_method(self, "f1"); } void A_f1() { this->A::f1(); } }; // note inheritance from A_Wrapper struct B_Wrapper : A_Wrapper, virtual B { B_Wrapper(PyObject* self) : self(self) {} void f2() { call_method(self, "f2"); } void B_f2() { this->B::f2(); } }; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Fri Mar 21 21:54:28 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 21 Mar 2003 17:54:28 -0300 Subject: [C++-sig] Missing definitions for virtual methods in Pyste-generated code In-Reply-To: References: <3E7B67E2.8040201@vrac.iastate.edu> Message-ID: <3E7B7C04.9070904@globalite.com.br> David Abrahams wrote: >Patrick Hartling writes: > > > >>In my continued experimentation with Pyste, I have run into a problem >>relating to virtual methods. I have attached example code that >>demonstrates the problem specifically, but I will try to explain it in >>general terms here. >> >>First, the class structure is similar to this: >> >>class A >>{ >>public: >> virtual void f1(); >>}; >> >>class B : public A >>{ >>public: >> virtual void f2(); >>}; >> >>My goal, then, is to derive from B a class C written in Python: >> >>class C(MyModule.B): >> def __init__(self): >> MyModule.B.__init__(self) >> >> def f1(self): >> # Do something ... >> >> def f2(self): >> # Do something else ... >> >>Ultimately, an instance of C will be handed off to some C++ code where >>it needs to be treated polymorphically as an instance of either A or >>B, depending on the context. >> >>In Pyste, I declare that I want to expose both A and B to >>Python. However, the Boost.Python code that gets generated for class B >>is missing the definition for the f1() method that is inherited from >>class A: >> >>class_< B, bases< A > , boost::noncopyable, B_Wrapper >("B", init< >()) >> .def("f2", &B::f2, &B_Wrapper::default_f2) >>; >> >>Without the definition for the f1() member function, C.f1() is never >>invoked by the C++ code. C.f2() works fine, however. I can easily >>modify the generated Boost.Python code to add the definition of f1(), >>but this seems like a bug in how Pyste deals with inherited member >>functions. >> >> > >Something is slightly wrong with your analysis: > >1. The generated code for wrapping A should contain a definition of f1 > >2. That's not what causes C.f1 to be called when invoked from C++ > anyway: it's the override in the wrapper class for A which I > presume from reading the code above should be called A_Wrapper > that makes sure C.f1 gets called. > >...and now I see the problem. For scenarios like this, the Wrapper >classes really need to use virtual inheritance. It should look >something like this: > >struct A_Wrapper : virtual A >{ > A_Wrapper(PyObject* self) : self(self) {} > void f1() { call_method(self, "f1"); } > void A_f1() { this->A::f1(); } >}; > >// note inheritance from A_Wrapper >struct B_Wrapper : A_Wrapper, virtual B >{ > B_Wrapper(PyObject* self) : self(self) {} > void f2() { call_method(self, "f2"); } > void B_f2() { this->B::f2(); } >}; > >HTH, > Unfortunetely I get the same output, even after this changes. From what I understand, they should work too. Do you have any other idea Dave? I cleaned the examples from Patrick a bit, and here are they for reference: ------------ test.h #include using namespace std; struct A { virtual void f1() { cout << "A::f1" << endl; } }; struct B: public A { virtual void f2() { cout << "B::f2" << endl; } }; void call(A* a) { a->f1(); B* b = dynamic_cast(a); b->f2(); } ------------ test.cpp (generated, and then manual-changed) #include #include using namespace boost::python; struct A_Wrapper: virtual A { A_Wrapper(PyObject* self_, const A & p0): A(p0), self(self_) {} A_Wrapper(PyObject* self_): A(), self(self_) {} void f1() { call_method< void >(self, "f1"); } void default_f1() { A::f1(); } PyObject* self; }; struct B_Wrapper: virtual B, A_Wrapper { B_Wrapper(PyObject* self_, const B & p0): B(p0), A_Wrapper(self_), self(self_) {} B_Wrapper(PyObject* self_): B(), A_Wrapper(self_), self(self_) {} void f2() { call_method< void >(self, "f2"); } void default_f2() { B::f2(); } PyObject* self; }; BOOST_PYTHON_MODULE(test) { def("call", &call); class_< A, A_Wrapper >("A", init< >()) .def(init< const A & >()) .def("f1", &A::f1, &A_Wrapper::default_f1) ; class_< B, bases< A > , B_Wrapper >("B", init< >()) .def(init< const B & >()) .def("f2", &B::f2, &B_Wrapper::default_f2) ; } ----------------- test.py from test import * class C(B): def __init__(self): B.__init__(self) def f1(self): print 'C.f1' def f2(self): print 'C.f2' call(C()) ------------------- output A::f1 C.f2 From dave at boost-consulting.com Fri Mar 21 22:31:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 21 Mar 2003 16:31:00 -0500 Subject: [C++-sig] Missing definitions for virtual methods in Pyste-generated code In-Reply-To: <3E7B7C04.9070904@globalite.com.br> (Nicodemus's message of "Fri, 21 Mar 2003 17:54:28 -0300") References: <3E7B67E2.8040201@vrac.iastate.edu> <3E7B7C04.9070904@globalite.com.br> Message-ID: Nicodemus writes: > Unfortunetely I get the same output, even after this changes. From > what I understand, they should work too. Do you have any other idea > Dave? I cleaned the examples from Patrick a bit, and here are they for > reference: I think I misunderstood how virtual inheritance works. Unfortunately, the scheme I proposed will only work if B inherits from A virtually (try it and see for yourself). This code demonstrates that there are two A objects in a B_wrap: #include struct A { A() { std::cout << "A\n"; } }; struct A_wrap : virtual A { A_wrap() { std::cout << "A_wrap\n"; } }; struct B : A { B() { std::cout << "B\n"; } }; struct B_wrap : A_wrap, virtual B // note inheritance order { B_wrap() { std::cout << "B_wrap\n"; } }; int main() { B_wrap bw; } ====== BEGIN OUTPUT ====== A A B A_wrap B_wrap ====== END OUTPUT ====== Probably by doing the inheritance in the order shown above you could get it to "work", but that would be masking a real problem. I guess I have to reluctantly conclude that you need to repeat the virtual function overrides in derived wrapper classes. It would be great to factor out the invocations of call_method at least, but I guess you have to do whatever works at this point. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sat Mar 22 19:23:39 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 22 Mar 2003 15:23:39 -0300 Subject: [C++-sig] Missing definitions for virtual methods in Pyste-generated code In-Reply-To: References: <3E7B67E2.8040201@vrac.iastate.edu> <3E7B7C04.9070904@globalite.com.br> Message-ID: <3E7CAA2B.3030004@globalite.com.br> David Abrahams wrote: >I guess I have to reluctantly conclude that you need to repeat the >virtual function overrides in derived wrapper classes. > >It would be great to factor out the invocations of call_method at >least, but I guess you have to do whatever works at this point. > Thanks for the clarification Dave! I fixed it, it's in the CVS. Thanks once again for the bug report, Patrick. ;) Regards, Nicodemus. From dave at boost-consulting.com Sun Mar 23 03:00:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 22 Mar 2003 21:00:41 -0500 Subject: [C++-sig] Re: BOOST help again ... In-Reply-To: (Jim's message of "Fri, 21 Mar 2003 18:23:27 GMT") References: Message-ID: The following message is a courtesy copy of an article that has been posted to comp.lang.python as well. Jim writes: > Hi ... > I have a new boost question ... how do convert a tuple to a c struct > ... my half brained attempt is below ... but it has some obvious > compile problems ... Please post Boost.Python questions to the c++-sig: http://mail.python.org/mailman/listinfo/c++-sig > void BOOSTED_cosim_define_board(boost::python::tuple t) > { > double x60_clk, pwm_clk, utx_clk, urx_clk, local_ref_clk, > pcr_ref_clk, mod_ref_clk, demod_ref_clk; > long mod_utopia, demod_utopia, dac_type, adc_type; > > if (!PyArg_ParseTuple(t, "(ddddddddllll)", > &x60_clk, > &pwm_clk, > &utx_clk, > &urx_clk, > > &local_ref_clk, > &pcr_ref_clk, > &mod_ref_clk, > &demod_ref_clk, > > &mod_utopia, > &demod_utopia, > > &dac_type, > &adc_type)) > { > PyErr_SetString( PyCosim_Error, "invalid args" ); > return; > } use extract(t[0]) extract(t[8]) etc., to get the values out. Your approach won't interact properly with exception-handling. > theboard.x60_clk=x60_clk*1e6; > theboard.pwm_clk=pwm_clk*1e6; > theboard.utx_clk=utx_clk*1e6; > theboard.urx_clk=urx_clk*1e6; > > theboard.local_ref_clk=local_ref_clk*1e6; > theboard.pcr_ref_clk=pcr_ref_clk*1e6; > theboard.mod_ref_clk=mod_ref_clk*1e6; > theboard.demod_ref_clk=demod_ref_clk*1e6; > > theboard.mod_utopia=static_cast(mod_utopia); > theboard.demod_utopia=static_cast(demod_utopia); > > theboard.dac_type=static_cast(dac_type); > theboard.adc_type=static_cast(adc_type); > > return; > } Your compile problems are not "obvious" from what you posted. If you need help with compilation errors, it helps to show us a few. Reproducible test cases are also good. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sun Mar 23 03:04:14 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 22 Mar 2003 21:04:14 -0500 Subject: [C++-sig] Re: Boost help please In-Reply-To: <_fjea.3599$j5.16816@news> (Jim's message of "Thu, 20 Mar 2003 13:22:02 GMT") References: <_fjea.3599$j5.16816@news> Message-ID: The following message is a courtesy copy of an article that has been posted to comp.lang.python as well. Jim writes: > Hi, > > I am switching some C++ code over to use boost ... but i am having > some problems just getting things to compile ... the compile error is > not very helpful so i'll leave it out for now ... the problem i think > is more related to the fact i need return a structure from a boost > function .... can anyone help ;-) Please post Boost.Python questions to the c++-sig: http://mail.python.org/mailman/listinfo/c++-sig > > The my attempt at a boosted function is here: > --------------------------------------------- > > struct boardInfoStruct { > double d1; > double d2; > double d3; > double d4; > double d5; > double d6; > double d7; > double d8; > long l1; > long l2; > long l3; > long l4; > }; > > boardInfoStruct BOOSTED_cosim_get_board() > { > boardInfoStruct * ret = new boardInfoStruct(); > > ret.d1 = theboard.x60_clk/1e6; > ret.d2 = theboard.pwm_clk/1e6; > ret.d3 = theboard.utx_clk/1e6; > ret.d4 = theboard.urx_clk/1e6; > ret.d5 = theboard.local_ref_clk/1e6; > ret.d6 = theboard.pcr_ref_clk/1e6; > ret.d7 = theboard.mod_ref_clk/1e6; > ret.d8 = theboard.demod_ref_clk/1e6; > > ret.l1 = theboard.mod_utopia; > ret.l2 = theboard.demod_utopia; > ret.l3 = theboard.dac_type; > ret.l4 = theboard.adc_type; > > return ret; > > } Why not just expose boardInfoStruct? class_("board_info") .def_readwrite("d1", &boardInfoStruct::d1) .def_readwrite("d2", &boardInfoStruct::d2) .def_readwrite("d3", &boardInfoStruct::d3) ... ; -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 24 21:35:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 24 Mar 2003 15:35:50 -0500 Subject: [C++-sig] Upcoming Boost.Python talks Message-ID: Hi All, I'll be giving talks on Boost.Python at the PyConDC conference this week and at the ACCU conference next week, for anyone who's going to be around. Hope to see you there! -Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From Giulio.Eulisse at cern.ch Wed Mar 26 10:00:32 2003 From: Giulio.Eulisse at cern.ch (Giulio Eulisse) Date: Wed, 26 Mar 2003 10:00:32 +0100 (CET) Subject: [C++-sig] How to exclude a function from being exported using pyste. Message-ID: Hi, I've a class like this: class A { public: A(int x); A(float x); int b(int x); int b(float x); }; And I want to export to python only A::b(int x), not A::b(float x). How do I do it using pyste? A = Class("A","A.h") exclude(A.b) excludes BOTH. Same problem with constructors: how do I get rid of only one of the two constructors? Ciao, Giulio From dave at boost-consulting.com Wed Mar 26 19:14:08 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 26 Mar 2003 13:14:08 -0500 Subject: [C++-sig] Re: Boost.Python problems In-Reply-To: ("Ben Hutchings"'s message of "Wed, 26 Mar 2003 17:43:41 -0000") References: Message-ID: "Ben Hutchings" writes: > David, > > I have recently tried to use Boost.Python as released in Boost > 1.29.0. Hi Ben, 1. The current release is 1.30.0. 2. Please post Boost.Python related stuff to the python C++-sig: http://www.python.org/sigs/c++-sig/ > It's obviously very useful, but it still has a few bugs and limitations. > It turns out that I won't need to use Boost.Python now, but I thought I > should let you know about these problems. > > 1. doesn't include the class definition > for policies. The proxies it defines can't be used without these > definitions. This limitation is mentioned in the header but not > documented elsewhere. You're not supposed to include object_core yourself; it's an implementation detail. The documentation doesn't mention object_core.hpp, only object.hpp. > 2. doesn't include > Why is that a problem? It doesn't seem to need it. Any headers in boost/python/detail are also implementation details, and not for user consumption. > 3. The test programs are run without quotes around the path to the > python interpreter. On Windows it is not uncommon to have spaces in > a path name, in which case the tests fail to run at all. Are you saying that bjam fails to quote the path, or something else? > 4. There are no converters for std::wstring or wchar_t. Good point. Care to contribute some? > 5. boost::python::converter::registry doesn't seem to be documented. Right. > As far as I can see, this is essential for installing new > conversions for rvalues that aren't implicit in C++. I may just > have missed something though. (The specific things I used this for > were conversions from unicode to std::string and from str to > std::wstring.) No, you're right. I was never satisfied enough with the interface to consider it worth publishing. We're going to rework some of that stuff for the next release and it will be documented then. > I have attached a patch that deals with item 4, Wonderful! > though it isn't good enough as it is. The STATIC_ASSERTs need to be > taken out and all the new code should be conditional on Python's > HAVE_USABLE_WCHAR_T macro. I don't know what to do about > environments where wchar_t is typedef'd. Thanks; we'll look into it. > I hope this is useful to you. If not, sorry for wasting your time. Thanks very much for your input. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Mar 26 19:21:35 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 26 Mar 2003 15:21:35 -0300 Subject: [C++-sig] How to exclude a function from being exported using pyste. In-Reply-To: References: Message-ID: <3E81EFAF.7090808@globalite.com.br> Giulio Eulisse wrote: >Hi, > Hi Giulio, >I've a class like this: > >class A >{ > public: > A(int x); > A(float x); > int b(int x); > int b(float x); >}; > >And I want to export to python only A::b(int x), not A::b(float x). >How do I do it using pyste? > >A = Class("A","A.h") >exclude(A.b) > >excludes BOTH. Same problem with constructors: how do I get rid of only >one of the two constructors? > > Alas, you can't do that. 8/ I didn't include this capability because I couldn't think of a way to nicely allow the user to specify which of the overloads to address. A first thought would be something like this: exclude(A.b('int b(int x)')) But this can get ugly pretty quickly: exclude(C.foo('const std::vector > & foo(const std::list >&, int, int, double) const')) A friend of mine suggested that the user could specify only part of the full signature: struct C { std::string& Name(); const std::string& Name() const; }; ... exclude(Match(C.Name, 'const')) # to get the "const" version of the function But I have no idea if this system is reliable, or how it would work exactly. Does any one have a good suggestion on this? Regards, Nicodemus. From Giulio.Eulisse at cern.ch Thu Mar 27 09:31:21 2003 From: Giulio.Eulisse at cern.ch (Giulio Eulisse) Date: Thu, 27 Mar 2003 09:31:21 +0100 (CET) Subject: [C++-sig] How to exclude a function from being exported using pyste. In-Reply-To: <3E81EFAF.7090808@globalite.com.br> Message-ID: > exclude(Match(C.Name, 'const')) # to get the "const" version of the function > But I have no idea if this system is reliable, or how it would work exactly. > Does any one have a good suggestion on this? For what I'm concerned that would be a nice start, as I'm interested in masking functions accessing classes I have not "pystified" yet. For example exclude(Match(QString,'QDataStream')) would be very useful to me as it would permit to have pythonized qstrings without having to deal with all QDataStream related classes...;-) Anyway what I'm also trying to do is to have a XSL stylesheet which does the same done by pyste, I'll tell you if it gets any good... Ciao, Giulio From harold at imb-jena.de Thu Mar 27 11:52:16 2003 From: harold at imb-jena.de (Harold Fellermann) Date: Thu, 27 Mar 2003 11:52:16 +0100 Subject: [C++-sig] translate exceptions In-Reply-To: Message-ID: <2C95A903-6042-11D7-8765-000393DA32FA@imb-jena.de> hi, While trying to translate some exceptions with register_exception_translator<> I compiled the example source code of the reference manual http://www.boost.org/libs/python/doc/v2/ exception_translator.html#examples. Unfortunately the code doesn't seem to work by me: calling 'something_that_throws()' leads to a segmentation fault of the python interpreter. Same thing happened to all exceptions I tried to register myself. Has anyone a clue what is going wrong here? Thanks, - harold fellermann - -- Abandon the search for Truth -- settle for a good fantasy. -- From giulio.eulisse at cern.ch Thu Mar 27 14:59:55 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 27 Mar 2003 14:59:55 +0100 Subject: [C++-sig] relocation error? Message-ID: <1048773595.23080.22.camel@lxcms25> Using boost 1.30.0 I get the following error when trying to import a boost module in python with "import boostQT" or similar: ImportError: ./boostQT.so: undefined symbol: init_module__Q35boost6python6detailPCcPFv_v Any idea? Works fine with 1.29.0 Ciao, Giulio From dave at boost-consulting.com Thu Mar 27 15:14:44 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 27 Mar 2003 09:14:44 -0500 Subject: [C++-sig] translate exceptions In-Reply-To: <2C95A903-6042-11D7-8765-000393DA32FA@imb-jena.de> (Harold Fellermann's message of "Thu, 27 Mar 2003 11:52:16 +0100") References: <2C95A903-6042-11D7-8765-000393DA32FA@imb-jena.de> Message-ID: Harold Fellermann writes: > hi, > > While trying to translate some exceptions with > register_exception_translator<> I compiled the example source code of > the reference manual http://www.boost.org/libs/python/doc/v2/ > exception_translator.html#examples. Unfortunately the code doesn't > seem to work by me: calling 'something_that_throws()' leads to a > segmentation fault of the python interpreter. Same thing happened to > all exceptions I tried to register myself. Has anyone a clue what is > going wrong here? 1. What is your compiler and platform? 2. If you go to $BOOST_ROOT/libs/python/test/ and do "bjam ... exception_translator.run" what happens? If that works, there's probably something wrong with the example. If that fails, it's almost certainly a bug in your compiler, since that test passes on nearly all compilers. See http://cci.lbl.gov/boost/ -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Mar 27 16:34:14 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 27 Mar 2003 10:34:14 -0500 Subject: [C++-sig] How to exclude a function from being exported using pyste. In-Reply-To: <3E81EFAF.7090808@globalite.com.br> (Nicodemus's message of "Wed, 26 Mar 2003 15:21:35 -0300") References: <3E81EFAF.7090808@globalite.com.br> Message-ID: Nicodemus writes: > exclude(Match(C.Name, 'const')) # to get the "const" version of the function > > But I have no idea if this system is reliable, or how it would work exactly. > > Does any one have a good suggestion on this? "Good?" no. I can suggest the following possibilities: 1. Intrusive: the C++ code is annotated with comments that say "this overload is excluded". I hate this one. 2. exclude(A.b.overload[1]) -- Dave Abrahams Boost Consulting www.boost-consulting.com From giulio.eulisse at cern.ch Thu Mar 27 17:24:00 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 27 Mar 2003 17:24:00 +0100 Subject: [C++-sig] unnamed enum Message-ID: <1048782240.23099.35.camel@lxcms25> Hi, when pystifing qcolor.h from QT 3.0.5, there is an unnamed enum: class QColor{ [...] enum { Dirt = 0x44495254, Invalid = 0x49000000 }; [...] }; This gets translated by pyste as enum_< QColor::._0 >("._0") .value("Invalid", QColor::Invalid) .value("Dirt", QColor::Dirt) ; Which is obviously not valid because of ._0...Is this a known bug? Any idea on how to mask/exclude it? Ciao, Giulio -- Giulio Eulisse Northeastern University, Boston, MA (USA) CERN, Geneve, GE (CH) Office: 40-3-A15 Office phone:76 71692 Cellphone:(+39) 3356972726 From rwgk at yahoo.com Thu Mar 27 17:53:29 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 27 Mar 2003 08:53:29 -0800 (PST) Subject: [C++-sig] relocation error? In-Reply-To: <1048773595.23080.22.camel@lxcms25> Message-ID: <20030327165329.69597.qmail@web20204.mail.yahoo.com> --- Giulio Eulisse wrote: > Using boost 1.30.0 I get the following error when trying to import a > boost module in python with "import boostQT" or similar: > > ImportError: ./boostQT.so: undefined symbol: > init_module__Q35boost6python6detailPCcPFv_v > > Any idea? Works fine with 1.29.0 Could it be that you are mixing .o files compiled with different gcc's? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From giulio.eulisse at cern.ch Thu Mar 27 17:57:44 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 27 Mar 2003 17:57:44 +0100 Subject: [C++-sig] relocation error? In-Reply-To: <20030327165329.69597.qmail@web20204.mail.yahoo.com> References: <20030327165329.69597.qmail@web20204.mail.yahoo.com> Message-ID: <1048784264.23080.39.camel@lxcms25> On Thu, 2003-03-27 at 17:53, Ralf W. Grosse-Kunstleve wrote: > --- Giulio Eulisse wrote: > > Using boost 1.30.0 I get the following error when trying to import a > > boost module in python with "import boostQT" or similar: > > > > ImportError: ./boostQT.so: undefined symbol: > > init_module__Q35boost6python6detailPCcPFv_v > > > > Any idea? Works fine with 1.29.0 > > Could it be that you are mixing .o files compiled with different gcc's? mmm...I would say no, as I'm not producing any .o file but directly .so (I've a single .cc file)... Ciao, Giulio From nicodemus at globalite.com.br Fri Mar 28 00:36:49 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 27 Mar 2003 20:36:49 -0300 Subject: [C++-sig] unnamed enum In-Reply-To: <1048782240.23099.35.camel@lxcms25> References: <1048782240.23099.35.camel@lxcms25> Message-ID: <3E838B11.2040101@globalite.com.br> Giulio Eulisse wrote: >Hi, >when pystifing > >qcolor.h > >from QT 3.0.5, there is an unnamed enum: > >class QColor{ >[...] >enum { Dirt = 0x44495254, Invalid = 0x49000000 }; >[...] >}; > >This gets translated by pyste as > >enum_< QColor::._0 >("._0") > .value("Invalid", QColor::Invalid) > .value("Dirt", QColor::Dirt) > ; > >Which is obviously not valid because of ._0...Is this a known bug? >Any idea on how to mask/exclude it? > > It's a bug in pyste, certainly. 8) But does anybody know how to export an unnamed enum? From cleung at eos.ubc.ca Fri Mar 28 00:46:24 2003 From: cleung at eos.ubc.ca (Charles Leung) Date: Thu, 27 Mar 2003 15:46:24 -0800 (PST) Subject: [C++-sig] relocation error? In-Reply-To: <1048784264.23080.39.camel@lxcms25> References: <20030327165329.69597.qmail@web20204.mail.yahoo.com> <1048784264.23080.39.camel@lxcms25> Message-ID: <32989.137.82.23.131.1048808784.squirrel@webmail.eos.ubc.ca> > On Thu, 2003-03-27 at 17:53, Ralf W. Grosse-Kunstleve wrote: >> --- Giulio Eulisse wrote: >> > Using boost 1.30.0 I get the following error when trying to import a >> boost module in python with "import boostQT" or similar: >> > >> > ImportError: ./boostQT.so: undefined symbol: >> > init_module__Q35boost6python6detailPCcPFv_v >> > >> > Any idea? Works fine with 1.29.0 >> >> Could it be that you are mixing .o files compiled with different >> gcc's? > > mmm...I would say no, as I'm not producing any .o file but directly .so > (I've a single .cc file)... Hi, I had a similar error when I tried building boost_python using the jam I built from 1_29_0. [cleung at gull hdf]$ python Python 2.2.2 (#1, Oct 22 2002, 12:23:26) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import HDF_ext Traceback (most recent call last): File "", line 1, in ? ImportError: ./HDF_ext.so: undefined symbol: _ZN5boost6python9converter18shared_ptr_deleterclEPKv then I rebuilt boost from the ground up (starting with jam) and it worked fine. I hope that helps... Aside from that, the Makefile and common.mk seem to be missing from $BOOST_ROOT/tools/build/jam_src in the boost_1_30_0.tar.gz I downloaded yesterday from SourceForge. Is there a way to build jam without them on Linux? Thanks, Charles From patrick at vrac.iastate.edu Fri Mar 28 04:41:00 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Thu, 27 Mar 2003 21:41:00 -0600 Subject: [C++-sig] Arrays and Boost.Python Message-ID: <3E83C44C.9080602@vrac.iastate.edu> Does Boost.Python (from Boost 1.30.0 or the Boost CVS trunk) provide handling of arrays as public data members in a C++ class? Using Boost.Python from Boost 1.30.0, I get an error from GCC 3.2 about line 68 of boost/python/data_members.hpp stating that "ISO C++ forbids assignment of arrays." If I change the array definition in my Boost.Python code so that the data member is read-only instead of read/write, that gets rid of the error. I don't mind doing that in this case--really I am just curious about how Boost.Python handles C++ arrays. -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 giulio.eulisse at cern.ch Fri Mar 28 10:45:50 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 28 Mar 2003 10:45:50 +0100 Subject: [C++-sig] Another pyste bug...;-) In-Reply-To: <3E838B11.2040101@globalite.com.br> References: <1048782240.23099.35.camel@lxcms25> <3E838B11.2040101@globalite.com.br> Message-ID: <1048844750.25444.6.camel@lxcms25> Looks like I'm stress-testing pyste...;-) In QCString.h from QT you have class QCString { [...] operator const char * () const; [...] }; which gets boostified in: .def("to_char", &QCString::operator char) which is not found (missing *, I guess) when compiling... Ciao, Giulio From dave at boost-consulting.com Fri Mar 28 18:07:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 28 Mar 2003 12:07:33 -0500 Subject: [C++-sig] relocation error? In-Reply-To: <32989.137.82.23.131.1048808784.squirrel@webmail.eos.ubc.ca> ("Charles Leung"'s message of "Thu, 27 Mar 2003 15:46:24 -0800 (PST)") References: <20030327165329.69597.qmail@web20204.mail.yahoo.com> <1048784264.23080.39.camel@lxcms25> <32989.137.82.23.131.1048808784.squirrel@webmail.eos.ubc.ca> Message-ID: "Charles Leung" writes: > then I rebuilt boost from the ground up (starting with jam) and it worked > fine. I hope that helps... Aside from that, the Makefile and common.mk > seem to be missing from $BOOST_ROOT/tools/build/jam_src in the > boost_1_30_0.tar.gz I downloaded yesterday from SourceForge. Is there a > way to build jam without them on Linux? ./build.sh See the docs at http://www.boost.org/tools/build/jam_src/index.html#installing -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Mar 28 18:11:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 28 Mar 2003 12:11:41 -0500 Subject: [C++-sig] Arrays and Boost.Python In-Reply-To: <3E83C44C.9080602@vrac.iastate.edu> (Patrick Hartling's message of "Thu, 27 Mar 2003 21:41:00 -0600") References: <3E83C44C.9080602@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > Does Boost.Python (from Boost 1.30.0 or the Boost CVS trunk) provide > handling of arrays as public data members in a C++ class? Using > Boost.Python from Boost 1.30.0, I get an error from GCC 3.2 about line > 68 of boost/python/data_members.hpp stating that "ISO C++ forbids > assignment of arrays." If I change the array definition in my > Boost.Python code so that the data member is read-only instead of > read/write, that gets rid of the error. But I doubt it will do anything other than raise an exception when you try to use it from Python. > I don't mind doing that in this case--really I am just curious about > how Boost.Python handles C++ arrays. So far, it doesn't. If you can write down precisely what semantics you'd like to see, considering what would constitute an argument match for overloaded functions, we might be able to do something about it. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Fri Mar 28 22:04:11 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 28 Mar 2003 18:04:11 -0300 Subject: [C++-sig] Another pyste bug...;-) In-Reply-To: <1048844750.25444.6.camel@lxcms25> References: <1048782240.23099.35.camel@lxcms25> <3E838B11.2040101@globalite.com.br> <1048844750.25444.6.camel@lxcms25> Message-ID: <3E84B8CB.7010906@globalite.com.br> Giulio Eulisse wrote: >Looks like I'm stress-testing pyste...;-) > Great! Just don't hesitate in posting bugs, please! 8) >In QCString.h from QT you have > >class QCString >{ >[...] >operator const char * () const; >[...] >}; > >which gets boostified in: > >.def("to_char", &QCString::operator char) > >which is not found (missing *, I guess) when compiling... > Fixed in CVS. Plus, converter operators which return char * or std::string are automatically named "__str__" in python. 8) Thanks again for the bug report! Nicodemus. PS: You probably already know about this, but there's already a binding for Qt: PyQt. ;) From spahievi at vega.bg Sat Mar 29 21:34:38 2003 From: spahievi at vega.bg (Niki Spahiev) Date: Sat, 29 Mar 2003 22:34:38 +0200 Subject: [C++-sig] bug with const double and msvc Message-ID: <3E86035E.9000109@vega.bg> Commented lines in attached code procude errors with msvc toolset. There is workaround which i can use thanks to pyste. I patched it to always cast member pointers and then removed all consts from const double. Niki Spahiev P.S. pyste is great even without gcc-xml. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: bbug.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: errorlog URL: From spahievi at vega.bg Sat Mar 29 21:51:52 2003 From: spahievi at vega.bg (Niki Spahiev) Date: Sat, 29 Mar 2003 22:51:52 +0200 Subject: [C++-sig] pyste and big files Message-ID: <3E860768.7080506@vega.bg> I got msvc internal overflow with pyste generated files. Can pyste write separate finctions for each class? Niki Spahiev From dave at boost-consulting.com Sat Mar 29 23:00:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 29 Mar 2003 17:00:38 -0500 Subject: [C++-sig] bug with const double and msvc In-Reply-To: <3E86035E.9000109@vega.bg> (Niki Spahiev's message of "Sat, 29 Mar 2003 22:34:38 +0200") References: <3E86035E.9000109@vega.bg> Message-ID: Niki Spahiev writes: > Commented lines in attached code procude errors with msvc > toolset. There is workaround which i can use thanks to pyste. I > patched it to always cast member pointers and then removed all consts > from const double. The answer to this is to write the declarations without const. The definitions can still be written with const. The bug in MSVC is that it considers cv-qualifiers oni function arguments to be part of the function type. -- Dave Abrahams Boost Consulting www.boost-consulting.com From spahievi at vega.bg Sat Mar 29 23:35:30 2003 From: spahievi at vega.bg (Niki Spahiev) Date: Sun, 30 Mar 2003 00:35:30 +0200 Subject: [C++-sig] bug with const double and msvc In-Reply-To: References: <3E86035E.9000109@vega.bg> Message-ID: <3E861FB2.4010901@vega.bg> David Abrahams wrote: > The answer to this is to write the declarations without const. The > definitions can still be written with const. The bug in MSVC is that > it considers cv-qualifiers oni function arguments to be part of the > function type. Unfortunately this is opencascade library, not my own. Workaround seems fine so far. Niki Spahiev From nicodemus at globalite.com.br Sun Mar 30 03:23:59 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 29 Mar 2003 22:23:59 -0300 Subject: [C++-sig] pyste and big files In-Reply-To: <3E860768.7080506@vega.bg> References: <3E860768.7080506@vega.bg> Message-ID: <3E86472F.4090407@globalite.com.br> Niki Spahiev wrote: > I got msvc internal overflow with pyste generated files. Can pyste > write separate finctions for each class? I don't understand what you mean by "functions for each class", but you can always generate various little modules, one for each pyste file if you want. If you're using a single pyste file for the entire library, break it into smaller ones, one for each submodule your library has (or any other criteria you find appropriate). Note that you can still access the library in Python as a single module: pyste --module=sub_module1 sub_module1.pyste pyste --module=sub_module2 sub_module2.pyste pyste --module=sub_module3 sub_module3.pyste (Each sub_module is a subset of your library called here "library" ;)) Then you create a "library.py", which imports the sub modules: # file library.py from sub_module1 import * from sub_module2 import * from sub_module3 import * And then as a user: >>> import library >>> # use library normally Which is the same as: pyste --module=library library.pyste >>> import library >>> # use library normally too Which I believe it's what you're doing right now. I recommend this approach anyway for large libraries, even if you're not having the problems you're describing. HTH, Nicodemus. From patrick at vrac.iastate.edu Sun Mar 30 07:54:10 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Sat, 29 Mar 2003 23:54:10 -0600 Subject: [C++-sig] Arrays and Boost.Python In-Reply-To: References: <3E83C44C.9080602@vrac.iastate.edu> Message-ID: <3E868682.3080806@vrac.iastate.edu> David Abrahams wrote: > Patrick Hartling writes: > > >>Does Boost.Python (from Boost 1.30.0 or the Boost CVS trunk) provide >>handling of arrays as public data members in a C++ class? Using >>Boost.Python from Boost 1.30.0, I get an error from GCC 3.2 about line >>68 of boost/python/data_members.hpp stating that "ISO C++ forbids >>assignment of arrays." If I change the array definition in my >>Boost.Python code so that the data member is read-only instead of >>read/write, that gets rid of the error. > > > But I doubt it will do anything other than raise an exception when > you try to use it from Python. That is true. I hadn't actually tested it prior to reading your response. Oh well. >>I don't mind doing that in this case--really I am just curious about >>how Boost.Python handles C++ arrays. > > > So far, it doesn't. If you can write down precisely what semantics > you'd like to see, considering what would constitute an argument match > for overloaded functions, we might be able to do something about it. I hadn't really thought about it much so far. It was one of those things I was hoping would "just work." The fact that it is not handled right now is not a big problem for me personally. What I see as a problem is that arrays in C/C++ are just syntactic sugar for accessing a block of memory. In languages such as Java and C# (and even Managed C++ from what I have seen so far), their handling is more formalized. In other words, there is no question that a function with a signature such as 'void f(int[] intList)' takes an array of integers. In the land of C/C++, we have to deal with the uncertainty of 'void f(int* intList)'. Is it a pointer to a single integer, an array, or a pointer into the middle of an array? All that is certain is that it points to four bytes of memory (for ILP32, anyway). Honestly, I don't feel too strongly about seeing support for arrays in Boost.Python. Considering that neither lists nor tuples in Python provide quite the right semantics for a C-style array, the concept may just not map into the world of Python very well. Of course, I could be wrong about all of this--I'm just a user, not an expert. :) -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 patrick at vrac.iastate.edu Sun Mar 30 07:56:53 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Sat, 29 Mar 2003 23:56:53 -0600 Subject: [C++-sig] How to exclude a function from being exported using pyste. In-Reply-To: References: <3E81EFAF.7090808@globalite.com.br> Message-ID: <3E868725.9060803@vrac.iastate.edu> I'd like to chime in and vote for #2 unless there are better ideas. The syntax is simple, and as long as the ordering of the overloads can be guaranteed, it's easy enough to figure out which overload is which. -Patrick P.S. In case it isn't obvious, I too have run into a case where I would like to exclude at least one overloaded method from an exposed class. David Abrahams wrote: > Nicodemus writes: > > >>exclude(Match(C.Name, 'const')) # to get the "const" version of the function >> >>But I have no idea if this system is reliable, or how it would work exactly. >> >>Does any one have a good suggestion on this? > > > "Good?" no. > > I can suggest the following possibilities: > > 1. Intrusive: the C++ code is annotated with comments that say "this > overload is excluded". I hate this one. > > 2. exclude(A.b.overload[1]) > > -- 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 dave at boost-consulting.com Sun Mar 30 15:40:57 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 30 Mar 2003 08:40:57 -0500 Subject: [C++-sig] Arrays and Boost.Python In-Reply-To: <3E868682.3080806@vrac.iastate.edu> (Patrick Hartling's message of "Sat, 29 Mar 2003 23:54:10 -0600") References: <3E83C44C.9080602@vrac.iastate.edu> <3E868682.3080806@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > David Abrahams wrote: >> Patrick Hartling writes: >> >>>Does Boost.Python (from Boost 1.30.0 or the Boost CVS trunk) provide >>>handling of arrays as public data members in a C++ class? Using >>>Boost.Python from Boost 1.30.0, I get an error from GCC 3.2 about line >>>68 of boost/python/data_members.hpp stating that "ISO C++ forbids >>>assignment of arrays." If I change the array definition in my >>>Boost.Python code so that the data member is read-only instead of >>> read/write, that gets rid of the error. >> But I doubt it will do anything other than raise an exception when >> you try to use it from Python. > > That is true. I hadn't actually tested it prior to reading your > response. Oh well. > >>>I don't mind doing that in this case--really I am just curious about >>>how Boost.Python handles C++ arrays. >> So far, it doesn't. If you can write down precisely what semantics >> you'd like to see, considering what would constitute an argument match >> for overloaded functions, we might be able to do something about it. > > I hadn't really thought about it much so far. It was one of those > things I was hoping would "just work." The fact that it is not > handled right now is not a big problem for me personally. > > What I see as a problem is that arrays in C/C++ are just syntactic > sugar for accessing a block of memory. That's not quite true. C++ recognizes types like int[4] and int(&)[4] so the dimensions are part of the type and it doesn't devolve into a pointer immediately. > In languages such as Java and C# (and even Managed C++ from what I > have seen so far), their handling is more formalized. In other > words, there is no question that a function with a signature such as > 'void f(int[] intList)' takes an array of integers. In the land of > C/C++, we have to deal with the uncertainty of 'void f(int* > intList)'. Is it a pointer to a single integer, an array, or a > pointer into the middle of an array? All that is certain is that it > points to four bytes of memory (for ILP32, anyway). Use boost::array if you can, or you can accept a reference to an array of a given dimension. Of course, if fixed size isn't what you want anyway, arrays are the wrong data abstraction. > Honestly, I don't feel too strongly about seeing support for arrays > in Boost.Python. Considering that neither lists nor tuples in > Python provide quite the right semantics for a C-style array, the > concept may just not map into the world of Python very well. Of > course, I could be wrong about all of this--I'm just a user, not an > expert. :) Ralf Grosse-Kunstleve has done some work which supports mapping between Python sequences and C++ arrays, vectors, etc. Check the FAQ. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Giulio.Eulisse at cern.ch Mon Mar 31 10:17:30 2003 From: Giulio.Eulisse at cern.ch (Giulio Eulisse) Date: Mon, 31 Mar 2003 10:17:30 +0200 (CEST) Subject: [C++-sig] Another pyste bug...;-) In-Reply-To: <3E84B8CB.7010906@globalite.com.br> Message-ID: > >Looks like I'm stress-testing pyste...;-) > Great! Just don't hesitate in posting bugs, please! 8) Don't worry, I will...;-) > Fixed in CVS. Plus, converter operators which return char * or > std::string are automatically named "__str__" in python. 8) How (un)stable is the CVS version?do you tag bug-fixes? > PS: You probably already know about this, but there's already a binding > for Qt: PyQt. ;) I know, I know...;-) The problem is that they use SIP while I cannot... Ciao, Giulio From giulio.eulisse at cern.ch Mon Mar 31 11:11:13 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 11:11:13 +0200 Subject: [C++-sig] operator !=? Message-ID: <1049101874.9875.11.camel@lxcms25> When trying to pystify any of the operator!= of any of the QT classes I get the following error: boostQT.cc: In function `void init_module_boostQT ()': boostQT.cc:1458: no matching function for call to `boost::python::class_::def (bool)' boostQT.cc:1914: parse error before `.' boostQT.cc:2914: no matching function for call to `boost::python::class_::def (const char[15], {unknown type}, void ({unnamed}::QWidget_Wrapper::*) (int, int))' /usr/include/g++-3/stl_relops.h: In function `bool operator!= (const _Tp &, const _Tp &) [with _Tp = boost::python::self_ns::self_t]': boostQT.cc:1458: instantiated from here /usr/include/g++-3/stl_relops.h:38: no match for `!boost::python::detail::operator_' /usr/include/g++-3/stl_relops.h:38: candidates are: operator!(bool) It happens, for example, with QVariant: class QVariant { [...] bool operator==( const QVariant& ) const; [...] }; which gets converted to: .def( self != self ) which looks correct to me...Any idea? -- Giulio Eulisse Northeastern University, Boston, MA (USA) CERN, Geneve, GE (CH) Office: 40-3-A15 Office phone:76 71692 Cellphone:(+39) 3356972726 Homepage: http://home.cern.ch/eulisse/ From giulio.eulisse at cern.ch Mon Mar 31 14:24:18 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 14:24:18 +0200 Subject: [C++-sig] pyste and virtual classes. Message-ID: <1049113458.10102.53.camel@lxcms25> It's my understanding that if I exclude() some virtual function out of a pystified class, pyste generates a code which is not compilable because the compiler complains about abstract functions being present in the wrapper class as wrapper methods for excluded one are not generate by pyste. I think it would be nice to have some wrapper code being generated anyway(maybe just throwing some exception) so that one can exclude safely virtual methods out of a class interface. Ciao, Giulio From dave at boost-consulting.com Mon Mar 31 15:02:09 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 31 Mar 2003 08:02:09 -0500 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049113458.10102.53.camel@lxcms25> (Giulio Eulisse's message of "31 Mar 2003 14:24:18 +0200") References: <1049113458.10102.53.camel@lxcms25> Message-ID: Giulio Eulisse writes: > It's my understanding that if I exclude() some virtual function out of a > pystified class, pyste generates a code which is not compilable because > the compiler complains about abstract functions being present in the > wrapper class as wrapper methods for excluded one are not generate by > pyste. That will only happen if the function is pure virtual in the class being wrapped. > I think it would be nice to have some wrapper code being generated > anyway(maybe just throwing some exception) so that one can exclude > safely virtual methods out of a class interface. That sounds really questionable to me. Why not just derive a class from the abstract class, override the virtual function yourself, and wrap that? -- Dave Abrahams Boost Consulting www.boost-consulting.com From giulio.eulisse at cern.ch Mon Mar 31 15:20:33 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 15:20:33 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: References: <1049113458.10102.53.camel@lxcms25> Message-ID: <1049116833.10102.76.camel@lxcms25> > That sounds really questionable to me. Why not just derive a class > from the abstract class, override the virtual function yourself, and > wrap that? Because it's annoying have to do that for tens of classes, especially if you have a lot of constructors which needs to be implemented again to have the wrapper class behave just like the other. I think that it would be nice if pyste had an option to do that for you. Ciao, Giulio -- Giulio Eulisse Northeastern University, Boston, MA (USA) CERN, Geneve, GE (CH) Office: 40-3-A15 Office phone:76 71692 Cellphone:(+39) 3356972726 From giulio.eulisse at cern.ch Mon Mar 31 16:35:20 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 16:35:20 +0200 Subject: [C++-sig] Pyste typedef problems... Message-ID: <1049121321.9875.92.camel@lxcms25> Tring to pystify ---CUT-HERE--- typedef unsigned int B; class A { B b; public: B &f(void){return b;}; }; ---CUT-HERE--- with pyste file: ---CUT-HERE--- A=Class("A","A.h") ---CUT-HERE--- gets to the following error, when compiling the output c++ code... /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/object/make_instance.hpp: In static member function `static PyObject* boost::python::objects::make_instance_impl::execute(Arg&) [with Arg = unsigned int*, T = unsigned int, Holder = boost::python::objects::pointer_holder, Derived = boost::python::objects::make_ptr_instance >]': /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/to_python_indirect.hpp:62: instantiated from `static PyObject* boost::python::detail::make_reference_holder::execute(T*) [with T = unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:19: instantiated from `Generator::result_type boost::python::detail::unwind_type_cv(U*, boost::python::detail::cv_tag, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:48: instantiated from `Generator::result_type boost::python::detail::unwind_ptr_type(U*, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:58: instantiated from `static Generator::result_type boost::python::detail::unwind_helper::execute(U, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int*, bool is_ptr = true]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:77: instantiated from `Generator::result_type boost::python::detail::unwind_type(const U&, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int*]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:26: instantiated from `Generator::result_type boost::python::detail::unwind_type_cv(const U*, boost::python::detail::cv_tag, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:48: instantiated from `Generator::result_type boost::python::detail::unwind_ptr_type(U*, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = const unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:69: instantiated from `static Generator::result_type boost::python::detail::unwind_helper::execute(U&, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = const unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/unwind_type.hpp:77: instantiated from `Generator::result_type boost::python::detail::unwind_type(const U&, Generator*) [with Generator = boost::python::detail::make_reference_holder, U = unsigned int]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/to_python_indirect.hpp:103: instantiated from `PyObject* boost::python::to_python_indirect::operator()(T) const [with T = B&, MakeHolder = boost::python::detail::make_reference_holder]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/invoke.hpp:93: instantiated from `PyObject* boost::python::detail::invoke(boost::python::detail::mem_fn_tag, RC*, F&, TC&) [with RC = boost::python::to_python_indirect, F = B&(A::*)(), TC = boost::python::detail::nullary >]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/detail/caller.hpp:162: instantiated from `PyObject* boost::python::detail::caller_arity<1>::impl::operator()(PyObject*, PyObject*) [with F = B&(A::*)(), ConverterGenerators = boost::python::detail::args_from_python, Policies = boost::python::return_internal_reference<1, boost::python::default_call_policies>, Sig = boost::mpl::list2]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/function/function_template.hpp:117: instantiated from `static R boost::detail::function::function_obj_invoker2::invoke(boost::detail::function::any_pointer, T0, T1) [with FunctionObj = boost::python::detail::caller, boost::mpl::list2 >, R = PyObject*, T0 = PyObject*, T1 = PyObject*]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/function/function_template.hpp:481: instantiated from `void boost::function2::assign_to(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = boost::python::detail::caller, boost::mpl::list2 >, R = PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator = std::allocator]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/function/function_template.hpp:432: instantiated from `void boost::function2::assign_to(Functor) [with Functor = boost::python::detail::caller, boost::mpl::list2 >, R = PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator = std::allocator]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/function/function_template.hpp:293: instantiated from `boost::function2::function2(Functor, boost::detail::function::enable_if::value>::value, int>::type) [with Functor = boost::python::detail::caller, boost::mpl::list2 >, R = PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator = std::allocator]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/make_function.hpp:61: instantiated from `boost::python::api::object boost::python::detail::make_function_aux(F, const CallPolicies&, const ConverterGenerators&, const Sig&, const boost::python::detail::keyword_range&, NumKeywords) [with F = B&(A::*)(), CallPolicies = boost::python::return_internal_reference<1, boost::python::default_call_policies>, ConverterGenerators = boost::python::detail::args_from_python, Sig = boost::mpl::list2, NumKeywords = boost::mpl::int_<0>]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/make_function.hpp:90: instantiated from `boost::python::api::object boost::python::make_function(F, const CallPolicies&, const Keywords&) [with F = B&(A::*)(), CallPolicies = boost::python::return_internal_reference<1, boost::python::default_call_policies>, Keywords = boost::python::detail::keywords<0>]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/class.hpp:395: instantiated from `void boost::python::class_::def_impl(const char*, Fn, const Helper&, ...) [with Fn = B&(A::*)(), Helper = boost::python::detail::def_helper, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>, T = A, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/class.hpp:459: instantiated from `void boost::python::class_::def_maybe_overloads(const char*, Fn, const A1&, ...) [with Fn = B&(A::*)(), A1 = boost::python::return_internal_reference<1, boost::python::default_call_policies>, T = A, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/class.hpp:253: instantiated from `boost::python::class_& boost::python::class_::def(const char*, A1, const A2&) [with A1 = B&(A::*)(), A2 = boost::python::return_internal_reference<1, boost::python::default_call_policies>, T = A, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' typedef_confusion.cpp:14: instantiated from here /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/object/make_instance.hpp:23: `sizeof' applied to incomplete type `boost::STATIC_ASSERTION_FAILURE' Any idea? Ciao, Giulio From dave at boost-consulting.com Mon Mar 31 17:50:17 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 31 Mar 2003 10:50:17 -0500 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049116833.10102.76.camel@lxcms25> (Giulio Eulisse's message of "31 Mar 2003 15:20:33 +0200") References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> Message-ID: Giulio Eulisse writes: >> That sounds really questionable to me. Why not just derive a class >> from the abstract class, override the virtual function yourself, and >> wrap that? > > Because it's annoying have to do that for tens of classes, especially if > you have a lot of constructors which needs to be implemented again to > have the wrapper class behave just like the other. > I think that it would be nice if pyste had an option to do that for you. I can understand that, but I am having a hard time understanding what the use-case for such an arrangement is. The C++ class designer explicitly said "you can't instantiate a class unless you implement this function". Now you want to subvert that, in some sense. Is the result really useful? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 31 18:22:54 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 31 Mar 2003 11:22:54 -0500 Subject: [C++-sig] Pyste typedef problems... In-Reply-To: <1049121321.9875.92.camel@lxcms25> (Giulio Eulisse's message of "31 Mar 2003 16:35:20 +0200") References: <1049121321.9875.92.camel@lxcms25> Message-ID: Giulio Eulisse writes: > Tring to pystify > > ---CUT-HERE--- > typedef unsigned int B; > > class A > { > B b; > public: > B &f(void){return b;}; > }; > ---CUT-HERE--- > > with pyste file: > > ---CUT-HERE--- > A=Class("A","A.h") > ---CUT-HERE--- > > gets to the following error, when compiling the output c++ code... Have you ever tried to wrap a function returning a reference to an unsigned int without using pyste? What would you expect the result to be? -- Dave Abrahams Boost Consulting www.boost-consulting.com From giulio.eulisse at cern.ch Mon Mar 31 18:34:37 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 18:34:37 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> Message-ID: <1049128478.10102.148.camel@lxcms25> > I can understand that, but I am having a hard time understanding what > the use-case for such an arrangement is. The C++ class designer > explicitly said "you can't instantiate a class unless you implement > this function". Now you want to subvert that, in some sense. Is the > result really useful? I understand what you mean and I would generally agree with what you say. The point is that in my case I cannot modify the library in question (QT) and at the same time I would like to have a working (although very limited) python module to see if what I want to do works or not. Because of the complexity of QT I have to remove some pure virtual methods because otherwise I would end up implementing bindings for the whole library. So I'm not saying that it would be really useful or a good coding practice but, at least for me, it would be nice to have, for prototyping and experimenting, just like the "exclude all that contains xyz" feature. Another possible solution would be get rid of the whole boost/QT idea, and make PyQT and boost play nicely together(and play nicely with an existing QApplication object). The problem is that I have to do the following: I have a virtual class "Base", which derives from a QT one, this class gets derived into "Derived" and extended in python. An instance of the class "Derived" is created in an embedded python environment and is passed to C++ using something like extract. The virtual method MyBase.method() is then called in C++ and its python implementation in Derived gets called. Both the C++ and the Python environment need to access the QT part of the class, and I don't want (better: I have not to) to write wrappers around all the QT functions I need. I haven't figured out how to do the extract part when using PyQt. Maybe you can help me? Ciao, Giulio From giulio.eulisse at cern.ch Mon Mar 31 19:06:24 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 31 Mar 2003 19:06:24 +0200 Subject: [C++-sig] Pyste typedef problems... In-Reply-To: References: <1049121321.9875.92.camel@lxcms25> Message-ID: <1049130384.9875.167.camel@lxcms25> > Have you ever tried to wrap a function returning a reference to an > unsigned int without using pyste? What would you expect the result > to be? mmm...Ok,you are right...It's not the typedef, it's the unsigned int... And it's not pyste related. Sorry about that. Now, is there a solution for that or I cannot deal with unsigned int at all? Again, I'm not really interested in writing a wrapper for it, if there is no way out I will just exclude the function. Ciao, Giulio From dave at boost-consulting.com Mon Mar 31 20:16:59 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 31 Mar 2003 13:16:59 -0500 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049128478.10102.148.camel@lxcms25> (Giulio Eulisse's message of "31 Mar 2003 18:34:37 +0200") References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> Message-ID: Giulio Eulisse writes: >> I can understand that, but I am having a hard time understanding what >> the use-case for such an arrangement is. The C++ class designer >> explicitly said "you can't instantiate a class unless you implement >> this function". Now you want to subvert that, in some sense. Is the >> result really useful? > > I understand what you mean and I would generally agree with what you > say. > The point is that in my case I cannot modify the library in question > (QT) and at the same time I would like to have a working (although very > limited) python module to see if what I want to do works or not. > Because of the complexity of QT I have to remove some pure virtual > methods because otherwise I would end up implementing bindings for the > whole library. OK. > So I'm not saying that it would be really useful or a good coding > practice but, at least for me, it would be nice to have, for prototyping > and experimenting, just like the "exclude all that contains xyz" > feature. I understand what you're asking for, but I can't for the life of me understand why you need it. See ** below. > Another possible solution would be get rid of the whole boost/QT idea, > and make PyQT and boost play nicely together It's not clear that PyQT (SIP) will automatically generate empty virtual functions for you either. > (and play nicely with an existing QApplication object). The problem > is that I have to do the following: > > I have a virtual class "Base", You must mean an abstract class. There's no such thing as a virtual class. > which derives from a QT one, this class gets derived into "Derived" > and extended in python. An instance of the class "Derived" is > created in an embedded python environment and is passed to C++ using > something like extract. It's not clear what you mean by "passed to C++ using extract". You can only write extract in C++, so the object must already be available in C++ code somehow. > The virtual method MyBase.method() is then called in C++ and its > python implementation in Derived gets called. **OK so far; I don't see any need to provide a C++ implementation of the virtual member function other than the one provided automatically by pyste's generated wrapper class. That alone should be enough to ensure that there is no problem with instantiating an abstract base class. > Both the C++ and the Python environment need to access the > QT part of the class, and I don't want (better: I have not to) to > write wrappers around all the QT functions I need. I haven't figured > out how to do the extract part when using PyQt. Maybe you can > help me? I don't know the first thing about PyQt, but the real issue is that I can't understand the problem you're having. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Mar 31 22:17:20 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 31 Mar 2003 17:17:20 -0300 Subject: [C++-sig] Another pyste bug...;-) In-Reply-To: References: Message-ID: <3E88A250.7010509@globalite.com.br> Giulio Eulisse wrote: >Nicodemus wrote: > > >>Fixed in CVS. Plus, converter operators which return char * or >>std::string are automatically named "__str__" in python. 8) >> >> > >How (un)stable is the CVS version?do you tag bug-fixes? > > It's not very stable yet, is a work in progress yet. 8) I don't tag bug fixes, I only update the version number. Current version is 0.6.4. You think I should tag each bug fix? Regards, Nicodemus From nicodemus at globalite.com.br Mon Mar 31 22:18:36 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 31 Mar 2003 17:18:36 -0300 Subject: [C++-sig] operator !=? In-Reply-To: <1049101874.9875.11.camel@lxcms25> References: <1049101874.9875.11.camel@lxcms25> Message-ID: <3E88A29C.1080804@globalite.com.br> Giulio Eulisse wrote: >When trying to pystify any of the operator!= of any of the QT classes I >get the following error: > >boostQT.cc: In function `void init_module_boostQT ()': >boostQT.cc:1458: no matching function for call to >`boost::python::class_boost::python::detail::not_specified, >boost::python::detail::not_specified>::def (bool)' >boostQT.cc:1914: parse error before `.' >boostQT.cc:2914: no matching function for call to >`boost::python::class_{unnamed}::QWidget_Wrapper, boost::python::detail::not_specified>::def >(const char[15], {unknown type}, void ({unnamed}::QWidget_Wrapper::*) >(int, int))' >/usr/include/g++-3/stl_relops.h: In function `bool operator!= (const >_Tp &, const _Tp &) [with _Tp = boost::python::self_ns::self_t]': >boostQT.cc:1458: instantiated from here >/usr/include/g++-3/stl_relops.h:38: no match for >`!boost::python::detail::operator_boost::python::self_ns::self_t, boost::python::self_ns::self_t>' >/usr/include/g++-3/stl_relops.h:38: candidates are: operator!(bool) > > >It happens, for example, with QVariant: > >class QVariant >{ >[...] >bool operator==( const QVariant& ) const; >[...] >}; > >which gets converted to: > > > .def( self != self ) > >which looks correct to me...Any idea? > > I don't know, seems correct to me too. Dave? From nicodemus at globalite.com.br Mon Mar 31 22:23:51 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 31 Mar 2003 17:23:51 -0300 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> Message-ID: <3E88A3D7.7020503@globalite.com.br> David Abrahams wrote: >Giulio Eulisse writes: > > >>>I can understand that, but I am having a hard time understanding what >>>the use-case for such an arrangement is. The C++ class designer >>>explicitly said "you can't instantiate a class unless you implement >>>this function". Now you want to subvert that, in some sense. Is the >>>result really useful? >>> >>I understand what you mean and I would generally agree with what you >>say. >>The point is that in my case I cannot modify the library in question >>(QT) and at the same time I would like to have a working (although very >>limited) python module to see if what I want to do works or not. >>Because of the complexity of QT I have to remove some pure virtual >>methods because otherwise I would end up implementing bindings for the >>whole library. >> > >OK. > > >>So I'm not saying that it would be really useful or a good coding >>practice but, at least for me, it would be nice to have, for prototyping >>and experimenting, just like the "exclude all that contains xyz" >>feature. >> > >I understand what you're asking for, but I can't for the life of me >understand why you need it. See ** below. > > >>Another possible solution would be get rid of the whole boost/QT idea, >>and make PyQT and boost play nicely together >> > >It's not clear that PyQT (SIP) will automatically generate empty >virtual functions for you either. > > >>(and play nicely with an existing QApplication object). The problem >>is that I have to do the following: >> >>I have a virtual class "Base", >> > >You must mean an abstract class. There's no such thing as a virtual >class. > > >>which derives from a QT one, this class gets derived into "Derived" >>and extended in python. An instance of the class "Derived" is >>created in an embedded python environment and is passed to C++ using >>something like extract. >> > >It's not clear what you mean by "passed to C++ using >extract". You can only write extract in C++, so the >object must already be available in C++ code somehow. > > >> The virtual method MyBase.method() is then called in C++ and its >>python implementation in Derived gets called. >> > >**OK so far; I don't see any need to provide a C++ implementation of >the virtual member function other than the one provided automatically >by pyste's generated wrapper class. That alone should be enough to >ensure that there is no problem with instantiating an abstract base >class. > > >>Both the C++ and the Python environment need to access the >>QT part of the class, and I don't want (better: I have not to) to >>write wrappers around all the QT functions I need. I haven't figured >>out how to do the extract part when using PyQt. Maybe you can >>help me? >> > >I don't know the first thing about PyQt, but the real issue is that I >can't understand the problem you're having. > But Giulio, what's the problem in exporting all virtual functions? I assume you have something like: struct A { virtual C getC(); }; and you don't want to export the class C, right? But remember that exporting class A without class C will compile just fine. If you try to call getC in Python, you will just get an exception. Was that the problem, or I misunderstood? Regards, Nicodemus. From nicodemus at globalite.com.br Mon Mar 31 22:29:15 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 31 Mar 2003 17:29:15 -0300 Subject: [C++-sig] Pyste typedef problems... In-Reply-To: <1049130384.9875.167.camel@lxcms25> References: <1049121321.9875.92.camel@lxcms25> <1049130384.9875.167.camel@lxcms25> Message-ID: <3E88A51B.6030602@globalite.com.br> Giulio Eulisse wrote: >>Have you ever tried to wrap a function returning a reference to an >>unsigned int without using pyste? What would you expect the result >>to be? >> >> > >mmm...Ok,you are right...It's not the typedef, it's the unsigned int... >And it's not pyste related. Sorry about that. >Now, is there a solution for that or I cannot deal with unsigned int at >all? Again, I'm not really interested in writing a wrapper for it, if >there is no way out I will just exclude the function. > >Ciao, >Giulio > When I test your example, Pyste generates a warning for you: ]pyste --module=A A.pyste ---> Error: A::f returns a pointer or a reference, but no policy was specified. So you have to specify a police for that function. Please look at the documentation for that. For this particular function, you have to write: A = Class("A", "A.h") set_policy(A.f, return_value_policy(copy_non_const_reference)) since you can't change the value of b, because integers are immutable in Python. From dave at boost-consulting.com Mon Mar 31 22:45:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 31 Mar 2003 15:45:00 -0500 Subject: [C++-sig] operator !=? In-Reply-To: <3E88A29C.1080804@globalite.com.br> (Nicodemus's message of "Mon, 31 Mar 2003 17:18:36 -0300") References: <1049101874.9875.11.camel@lxcms25> <3E88A29C.1080804@globalite.com.br> Message-ID: Nicodemus writes: > Giulio Eulisse wrote: > >>When trying to pystify any of the operator!= of any of the QT classes I >>get the following error: >> >>boostQT.cc: In function `void init_module_boostQT ()': >> boostQT.cc:1458: no matching function for call to >> boost::python::class_> boost::python::detail::not_specified, >> boost::python::detail::not_specified, >> boost::python::detail::not_specified>::def (bool)' >>boostQT.cc:1914: parse error before `.' >> boostQT.cc:2914: no matching function for call to >> boost::python::class_> {unnamed}::QWidget_Wrapper, >> boost::python::detail::not_specified>::def (const char[15], {unknown >> type}, void ({unnamed}::QWidget_Wrapper::*) (int, int))' >> /usr/include/g++-3/stl_relops.h: In function `bool operator!= (const >> _Tp &, const _Tp &) [with _Tp = boost::python::self_ns::self_t]': >>boostQT.cc:1458: instantiated from here >> /usr/include/g++-3/stl_relops.h:38: no match for >> !boost::python::detail::operator_> boost::python::self_ns::self_t, boost::python::self_ns::self_t>' >> /usr/include/g++-3/stl_relops.h:38: candidates are: operator!(bool) >> >> >>It happens, for example, with QVariant: >> >>class QVariant >>{ >>[...] >>bool operator==( const QVariant& ) const; >>[...] >> }; which gets converted to: >> >> >> .def( self != self ) >> >>which looks correct to me...Any idea? >> > I don't know, seems correct to me too. Dave? Me too. However I note that it's doing something in stl_relops, which is mighty suspicious. G++ is known to have overly liberal argument-dependent lookup; maybe that's causing a problem here. -- Dave Abrahams Boost Consulting www.boost-consulting.com