From cmbruns at stanford.edu Thu Apr 1 17:11:26 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Thu, 1 Apr 2010 08:11:26 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: On Tue, Mar 30, 2010 at 12:02 AM, Michele De Stefano wrote: > there is a much easier way to treat a FILE* as a C++ stream. The easy > way is to use my open source library (mds-utils, > http://code.google.com/p/mds-utils/). If I have a C++ api like: void foo(ostream& os); using mds-utils, would I be able to wrap in python: foo(sys.stdout) # 1 or would the python side need to be something more like: foo(oFileObj(sys.stdout)) # 2 From micdestefano at gmail.com Thu Apr 1 18:12:13 2010 From: micdestefano at gmail.com (Michele De Stefano) Date: Thu, 1 Apr 2010 18:12:13 +0200 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: I think the second one, but I suggest to follow the example provided with the doxygen documentation. May be you will have to make a wrapper that takes a Python object as argument, create an oFileObj object within it, and then, call your function. I don't have the time now to investigate the problem ... I'll return on it tomorrow. Bye, Michele 2010/4/1 Christopher Bruns : > On Tue, Mar 30, 2010 at 12:02 AM, Michele De Stefano > wrote: >> there is a much easier way to treat a FILE* as a C++ stream. The easy >> way is to use my open source library (mds-utils, >> http://code.google.com/p/mds-utils/). > > If I have a C++ api like: > ?void foo(ostream& os); > > using mds-utils, would I be able to wrap in python: > > ?foo(sys.stdout) # 1 > > or would the python side need to be something more like: > > ?foo(oFileObj(sys.stdout)) # 2 > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Michele De Stefano http://www.linkedin.com/in/micdestefano http://code.google.com/p/mds-utils http://xoomer.virgilio.it/michele_de_stefano From cmbruns at stanford.edu Thu Apr 1 21:49:08 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Thu, 1 Apr 2010 12:49:08 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <284121.72841.qm@web111412.mail.gq1.yahoo.com> References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> Message-ID: On Tue, Mar 30, 2010 at 11:33 AM, Ralf W. Grosse-Kunstleve wrote: > http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/boost_adaptbx/python_streambuf.h?view=markup I have not seen this cctbx product before. It especially interesting to me, since I am performing molecular computations, and also because I was a protein crystallographer for ten years. I like that the streambuf class appears to work with gzip files and other file objects that presumably do not have a FILE* internally. Is it necessary to explicitly invoke the streambuf object from python? In other words, given C++ api: void foo(ostream&); // C++ API Is it possible for the python api to be used like: foo(sys.stdout) # python invocation 1 or must it be foo(streambuf(sys.stdout)) From micdestefano at gmail.com Thu Apr 1 22:32:21 2010 From: micdestefano at gmail.com (Michele De Stefano) Date: Thu, 1 Apr 2010 22:32:21 +0200 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: Christopher, I've figured out how you can use mds-utils. The example is present into the documentation page of the mds_utils::python::FileObj class. So you have foo(ostream& os) and you would like to call it passing a Python file object. You cannot call foo(oFileObj(...)) directly, simply because there is no converter for converting from a Python object into an oFileObj object. So, as shown into the doxygen example, you have to program a wrapper like this one: foo_wrap(boost::python::object pyfile) { mds_utils::python::oFileObj fobj(py_file); foo(fobj); } That's all, and it is quite simple. I hope it helps. Best regards. Michele 2010/4/1 Christopher Bruns : > On Tue, Mar 30, 2010 at 12:02 AM, Michele De Stefano > wrote: >> there is a much easier way to treat a FILE* as a C++ stream. The easy >> way is to use my open source library (mds-utils, >> http://code.google.com/p/mds-utils/). > > If I have a C++ api like: > ?void foo(ostream& os); > > using mds-utils, would I be able to wrap in python: > > ?foo(sys.stdout) # 1 > > or would the python side need to be something more like: > > ?foo(oFileObj(sys.stdout)) # 2 > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Michele De Stefano http://www.linkedin.com/in/micdestefano http://code.google.com/p/mds-utils http://xoomer.virgilio.it/michele_de_stefano From rwgk at yahoo.com Fri Apr 2 04:11:44 2010 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 1 Apr 2010 19:11:44 -0700 (PDT) Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> Message-ID: <858331.49982.qm@web111411.mail.gq1.yahoo.com> > I like that the streambuf class appears to work with gzip files and > other file objects that presumably do not have a FILE* internally. Yes, because it simply uses the Python methods .read(), .write() etc. > Is it necessary to explicitly invoke the streambuf object from python? Yes. I could be different and in fact was different in the initial implementation (if you look back in the svn history). But there were a few subtle problems (buffer size, exception handling) and in the end I decided the most obvious and robust approach is to require streambuf(sys.stdout) or ostream(sys.stdout). I think it is safe to re-use the same streambuf, e.g. def foo(): out = ostream(sys.stdout) func1(out) func2(out) which is almost what you want. But I'd avoid "out" as a global because output may get stuck in the buffer and only appear surprisingly in unrelated contexts. Note that buffer_size=1 introduces a noticeable performance penalty. See time_it() in boost_adaptbx/tests/tst_python_streambuf.py . Ralf From swarfrat at gmail.com Fri Apr 2 06:51:39 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Fri, 2 Apr 2010 00:51:39 -0400 Subject: [C++-sig] custom r-value converters In-Reply-To: <7465b6171003291331pbffcecvffe720170e84cecb@mail.gmail.com> References: <9857ba051003281808k1d4bc3b0x4d4006c04af34d05@mail.gmail.com> <9857ba051003290008i75706ffdjf712cab02b011d8d@mail.gmail.com> <7465b6171003291331pbffcecvffe720170e84cecb@mail.gmail.com> Message-ID: On Mon, Mar 29, 2010 at 4:31 PM, Roman Yakovenko wrote: > May be I am missing something, but (py++) variable_t class doesn't > have return_by_value property. > > Indeed it doesn't. I was having trouble figuring out how to create a return_by_value property to pass to the make functions. >I am not sure. What py++ version do you use > Can you post small and complete example, of what you are trying to do? I didn't post an example because it's essentially 'How to Wrap a Custom String' from the boost.python FAQ in py++. Here's an example - I'm using py++ 1.0 and trying to wrap the following: class CustomString { operator=(...) string& val; }; struct TypeOne { CustomString name; }; struct TypeTwo { CustomString label; } In my py++ script, I create the CustomString_to_pystring and CustomString_from_pystring structs as in the boost.python docs, and register the converter. Where I'm getting a bit confused, is do I need to let py++ wrap the CustomString class, or does the rvalue converter replace that? I got around the original property question by having my py++ script iterate through my TypeN structs and if the type matches CustomString then I do a property.exlude() and add the code using struct.add_registration_code() for that property. At least that generates registration code like this: bp::class_("TypeOne") .add_property("name", make_getter(&TypeOne::name, bp::return_by_value_policy()), make_setter(&TypeOne::name, bp::return_by_value_policy())) Back to the question of wrapping CustomString though, if I exclude it (thinking that exposing it was somehow messing with the rvalue conversion stuff), it just segfaults. If I assign to my CustomString, it behaves as a python string after that point. But until it has been assigned, it shows up as . My converters look like this: struct CustomString_to_python_str { static PyObject* convert(CustomString const& s) { return boost::python::incref(boost::python::object(const_cast(s)).ptr()); } }; struct CustomString_from_python_str { CustomString_from_python_str() { boost::python::converter::registry::push_back( &convertible, &construct, boost::python::type_id()); } static void* convertible(PyObject* obj_ptr) { if (!PyString_Check(obj_ptr)) return 0; return obj_ptr; } static void construct(PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data) { const char* value = PyString_AsString(obj_ptr); if (value == 0) boost::python::throw_error_already_set(); void* storage = ((boost::python::converter::rvalue_from_python_storage*) data)->storage.bytes; new (storage) CustomStringvalue); data->convertible = storage; } }; // struct CustomString_from_python_str And of course in the module init code, they're installed like so: boost::python::to_python_converter(); CustomString_from_python_str(); The property getters & setters don't seem to be helpful or necessary - I think now this might just be a default ctor initialization issue, but providing initialization of the C++ class doesn't seem to work - it looks like my converter is suspect. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cmbruns at stanford.edu Sat Apr 3 18:56:56 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Sat, 3 Apr 2010 09:56:56 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <858331.49982.qm@web111411.mail.gq1.yahoo.com> References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> <858331.49982.qm@web111411.mail.gq1.yahoo.com> Message-ID: On Thu, Apr 1, 2010 at 7:11 PM, Ralf W. Grosse-Kunstleve wrote: >> Is it necessary to explicitly invoke the streambuf object from python? > > Yes. I could be different and in fact was different in the initial > implementation (if you look back in the svn history). But there were > a few subtle problems (buffer size, exception handling) and in the end > I decided the most obvious and robust approach is to require > streambuf(sys.stdout) or ostream(sys.stdout). I finally got streambuf to work with my wrapped classes. This feels much better than the approach I was using before. I added "[with_custodian_and_ward< 1, 2 >()]" to the streambuf wrapper init declaration, because I imagined it might be possible for the python file to be destroyed before the streambuf otherwise. Now I am faced with wrapping a constructor that takes a "std::ostream&" as an argument. I don't know how to write a wrapper for a constructor in boost.python. I'm open to suggestions on this. For example: // C++ API struct Foo { Foo(ostream& os); }; # desired python usage foo = Foo(streambuf(sys.stdout)) How would I wrap this Foo example? From cmbruns at stanford.edu Sat Apr 3 19:26:23 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Sat, 3 Apr 2010 10:26:23 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: On Thu, Apr 1, 2010 at 1:32 PM, Michele De Stefano wrote: > So, as shown into the doxygen example, you have to program a wrapper > like this one: > > foo_wrap(boost::python::object pyfile) { > > ? ? mds_utils::python::oFileObj ? ? ?fobj(py_file); > > ? ? foo(fobj); > } That's clever. I wonder how boost.python would deal with overloaded methods that use this technique. void foo_wrap1(boost::python::object pyfile) {} void foo_wrap2(bar_t bar) {} def("foo", &foo_wrap1); def("foo", &foo_wrap2); Would boost.python know to send "bar" objects to foo_wrap2? From nicolas.colombe at gmail.com Sat Apr 3 20:29:43 2010 From: nicolas.colombe at gmail.com (Nicolas Colombe) Date: Sat, 3 Apr 2010 20:29:43 +0200 Subject: [C++-sig] Boost.Python to_python_indirect and intrusive_ptr. Message-ID: Hi everyone. I'm trying to use Boost.Python to expose some of my C++ classes and I encountered an odd behaviour of the to_python_indirect result converter for intrusive_ptr with specific classes. Here is the deal: I'm using a component-based design for my classes, meaning an aggregation of objects with different features. These objects are ref-counted, and if they are in the same aggregation, they share the same lifetime. That is to say, as long as one of the components in the "ring" has a strictly positive reference counter, every component in the ring survive even if their ref-count drops to zero. I use boost::intrusive_ptr to manipulate them easily. There is the basic interface: class Component { void AddRef(); void Release(); unsigned int GetRefCount(); bool AddComponent(Component*); bool RemoveComponent(Component*); Component* ComponentIterator(Component*); //-->Used to parse the ring. virtual some_virtual_fn(); }; To avoid lifetime problems when manipulating an object both from C++ and python side, i want python to manipulate components only through boost::intrusive_ptr. There is the exposition code: //-->Object wrapper struct Component_wrapper : SandBoxProj::Component, bp::wrapper< SandBoxProj::Component > { Component_wrapper( ) :Component( ), bp::wrapper< SandBoxProj::Component >(){} virtual some_virtual_fn() { //overriding code... } default_some_virtual_fn() { Component::some_virtual_fn(); } }; //-->Some declarations that boost.python needs to manipulate boost::intrusive_ptr namespace boost { namespace python { template struct pointee< intrusive_ptr > //-->pointee struct for intrusive_ptr holder { typedef T type; }; struct make_owning_intrusive_ptr_holder //-->ResultConverter to make an intrusive_ptr from a raw one, inspired from to_python_indirect.hpp:79 { template static PyObject* execute(T* p) { typedef objects::pointer_holder, T> holder_t; boost::intrusive_ptr ptr(p); return boost::python::objects::make_ptr_instance::execute(ptr); } }; struct return_by_intrusive_ptr //-->corresponding ResultConverterGenerator { template struct apply { typedef to_python_indirect type; //--> here is the usage of to_python_indirect }; }; }} bp::class_< Component_wrapper,boost::intrusive_ptr,boost::noncopyable >( "Component", bp::init< >() ) .def( "AddComponent", &Component::AddComponent, ( bp::arg("arg0") ) ) .def( "ComponentIterator",&Component::ComponentIterator, ( bp::arg("arg0") ), bp::return_value_policy< bp::return_by_intrusive_ptr >() ) //-->this class uses the converter. .def( "some_virtual_fn",&Component::some_virtual_fn,&Component_wrapper::default_some_virtual_fn) .def( "GetRefCount",&Component::GetRefCount) .def( "RemoveComponent",&Component::RemoveComponent, ( bp::arg("arg0") ) ) ; And finally there is a scripts that uses this class and its output: >>>from pythonbinder import * >>>import gc >>>Comp1=Component() >>>Comp2=Component() >>>print Comp2.GetRefCount() 1 //-->Ok, I manipulate an intrusive_ptr >>>Comp2.AddComponent(Comp1) >>>iter=None >>>iter=Comp1.ComponentIterator(iter) >>>print iter //-->Ok, There is my C++ object >>>iter=Comp1.ComponentIterator(iter) >>>print iter >>>print iter.GetRefCount() 1 //-->What the ? iter is supposed to be an intrusive ptr. After a look at to_python_indirect, it seems that iter==Comp2, the python object wrapping the intrusive_ptr was just addref'ed. Ok, fair enough. >>>iter=Comp1.ComponentIterator(iter) >>>print iter None //-->Now the troubles begin. >>>del Comp2 >>>gc.collect() //-->ensure deletion, Comp2 is still alive from the C++ side, because Comp1 is alive. >>>iter=Comp1.ComponentIterator(iter) //May crash >>>print iter //-->if we made it through, a weak_ptr to some random structure. After that, i figured out that i never went through the ResultConverters i declared. Let's look at the execute function from to_python_indirect, template inline PyObject* execute(U const& x, mpl::false_) const { U* const p = &const_cast(x); if (is_polymorphic::value) //-->My type is polymorphic { if (PyObject* o = detail::wrapper_base_::owner(p)) //-->Ok, that's why I have a refcount of 1, no matter how many python intrusive_ptr wrappers I seem to have return incref(o); } return MakeHolder::execute(p); //-->There is the call to my result converter. } What happen is that after deletion of the last python wrapping of the intrusive_ptr, which is o in the code above, the Component_wrapper, which is partly a python object, is not deleted (the component ring still holds it), but it still reference its last owner which is the last instance_holder that just got deleted, so the object returned is a random memory garbage. Changing the holder type fromintrusive_ptr to intrusive_ptr solves the above problems but then it's not possible to use the class Component_wrapper as a base in python anymore. I tried to create a class derived from Component in python and the constructor of Component_wrapper was not called. (purpose is overriding virtual functions in python) I wondered if I'm going the wrong way, or if I discovered a bug. It may be a limitation of the library, which cannot understand that an object survived the deletion of its last holder. Maybe if i made my own version of to_python_indirect but removing the is_polymorphic case, it would work? Is there a fundamental reason to this test, other than saving memory? -------------- next part -------------- An HTML attachment was scrubbed... URL: From troy at resophonic.com Sat Apr 3 20:53:00 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 03 Apr 2010 14:53:00 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: <4BB78E8C.6040203@resophonic.com> Michele De Stefano wrote: > > there is a much easier way to treat a FILE* as a C++ stream. The easy > way is to use my open source library (mds-utils, > http://code.google.com/p/mds-utils/). > Elegant use of boost::iostreams if I may say so. I've been looking for some usecases for some boost.python modifications I've been playing with so I tried incorporating your FileObj. Seems to work well. One can wrap a function that takes a std::ostream& like this: using mds_utils::python::FileObj; // c++ function we're wrapping void sayhello(std::ostream& os) { os << "*** hello ***\n"; } // // function object that converts object& and implements // result_of protocol // struct conv { typedef FileObj result_type; result_type operator()(object& obj) { return FileObj(obj); } }; BOOST_PYTHON_MODULE(mod) { def("sayhello", as( &sayhello )); // arg converter ^^^^^^^^^^^^^ }; In this case python sees "sayhello" as taking a bp::object. The as<> might need some clarification.... It takes a function type argument. Above, the argument is the type of a function that returns void, which takes one argument, which is a function that returns conv and takes one argument of type object&. In general, for a unary function 'fn' returning type R it is: as(&fn) where T(U) means "convert the python object to C++ type U, then create a temporary object T and use it to create result_of::type, then convert that type to R and return to python". This is a little boost::proto-ish. Maybe also a little like a C++1x concept map. You could also provide a generic 'conv' struct, I skipped this so as not to confuse things. -t From troy at resophonic.com Sat Apr 3 21:01:45 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 03 Apr 2010 15:01:45 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: <4BB79099.90305@resophonic.com> Christopher Bruns wrote: > On Thu, Apr 1, 2010 at 1:32 PM, Michele De Stefano > wrote: >> So, as shown into the doxygen example, you have to program a wrapper >> like this one: >> >> foo_wrap(boost::python::object pyfile) { >> >> mds_utils::python::oFileObj fobj(py_file); >> >> foo(fobj); >> } > > That's clever. I wonder how boost.python would deal with overloaded > methods that use this technique. > > void foo_wrap1(boost::python::object pyfile) {} > void foo_wrap2(bar_t bar) {} > > def("foo", &foo_wrap1); > def("foo", &foo_wrap2); > > Would boost.python know to send "bar" objects to foo_wrap2? Boost python's "first match" overloading would kick in here... there was a long discussion about this on the list, check the archives. Short story: order of registration matters. I have a possible alternate implementation that went dormant and hasn't been thoroughly vetted, but I'm coming back around to it now. -t From troy at resophonic.com Sat Apr 3 21:03:42 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 03 Apr 2010 15:03:42 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB78E8C.6040203@resophonic.com> References: <4BB78E8C.6040203@resophonic.com> Message-ID: <4BB7910E.6090803@resophonic.com> troy d. straszheim wrote: > > as(&fn) > > where T(U) means "convert the python object to C++ type U, then create a > temporary object T and use it to create result_of::type, correction, add here "then pass that thing to fn" > then > convert that type to R and return to python". -t From rwgk at yahoo.com Sun Apr 4 05:54:41 2010 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 3 Apr 2010 20:54:41 -0700 (PDT) Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> <858331.49982.qm@web111411.mail.gq1.yahoo.com> Message-ID: <970574.30673.qm@web111405.mail.gq1.yahoo.com> > Now I am faced with wrapping a constructor that takes a > "std::ostream&" as an argument. I don't know how to write a wrapper > for a constructor in boost.python. I'm open to suggestions on this. > For example: > > // C++ API > struct Foo { > Foo(ostream& os); > }; > > # desired python usage > foo = Foo(streambuf(sys.stdout)) Did you already try the usual def(init((arg("os")))) ? I think it should just work (but I haven't actually tried it). Ralf From cmbruns at stanford.edu Sun Apr 4 21:10:22 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Sun, 4 Apr 2010 12:10:22 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB78E8C.6040203@resophonic.com> References: <4BB78E8C.6040203@resophonic.com> Message-ID: On Sat, Apr 3, 2010 at 11:53 AM, troy d. straszheim wrote: > BOOST_PYTHON_MODULE(mod) > { > ?def("sayhello", as( &sayhello )); > ?// ?arg converter ? ? ? ^^^^^^^^^^^^^ > }; > > The as<> might need some clarification.... Thanks Troy for the helpful tip. I'm still confused by the "as<>" symbol. Is there a particular boost header I need to include to get this to work? I get a compile error ('as' : undeclared identifier) when I try this with 'as<..." or 'boost::python::as<..." or 'boost::as<...". Plus, my google-fu is too clumsy to be able to google up the documentation for such a thing. From cmbruns at stanford.edu Sun Apr 4 22:07:11 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Sun, 4 Apr 2010 13:07:11 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <970574.30673.qm@web111405.mail.gq1.yahoo.com> References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> <858331.49982.qm@web111411.mail.gq1.yahoo.com> <970574.30673.qm@web111405.mail.gq1.yahoo.com> Message-ID: On Sat, Apr 3, 2010 at 8:54 PM, Ralf W. Grosse-Kunstleve wrote: >> // C++ API >> struct Foo { >> ? ? Foo(ostream& os); >> }; >> >> # desired python usage >> foo = Foo(streambuf(sys.stdout)) > > Did you already try the usual > > ?def(init((arg("os")))) Yes. Well pretty close. Py++ code generator gives me this: Foo_exposer.def( bp::init< std::ostream & >(( bp::arg("os") )) ); which I believe is completely equivalent. Given the following test API: ///// C++ API to wrap //// #include class Foo { public: Foo() {std::cout << "constructor1" << std::endl;} // The following constructor that takes an ostream& is the tricky part explicit Foo(std::ostream& os) {os << "constructor2" << std::endl;} // These say_hello member functions can be wrapped using current technology void say_hello_fileobj(std::ostream& os) {os << "hello fileobj" << std::endl;} void say_hello_streambuf(std::ostream& os) {os << "hello streambuf" << std::endl;} }; //////////////////////// I can wrap the say_hello_streambuf() member function with wrapper functions like these: namespace bp = boost::python; using boost_adaptbx::python::streambuf; void foo_say_hello_streambuf_wrapper1(Foo& foo, streambuf& output) { streambuf::ostream os(output); foo.say_hello_streambuf(os); } void foo_say_hello_streambuf_wrapper2(Foo& foo, bp::object& pyfile) { streambuf output(pyfile); foo_say_hello_streambuf_wrapper1(foo, output); } [...] BOOST_PYTHON_MODULE('_test') { [...] bp::class_< Foo >("Foo", bp::init< >()) .def( bp::init< std::ostream & >(( bp::arg("os") )) .def("say_hello_streambuf", &foo_say_hello_streambuf_wrapper2) .def("say_hello_streambuf", &Foo::say_hello_streambuf) .def("say_hello_streambuf", &foo_say_hello_streambuf_wrapper1) [...] } I know how to create wrapper methods to delegate the member_functions, but I don't know how to create a wrapper method for the constructor. ###### python test program ###### import _test as test import sys foo = test.Foo() # Test ostream wrapping based on Ralf W. Grosse-Kunstleve's # boost_adaptbx::python::streambuf class foo.say_hello_streambuf(test.cout) # OK foo.say_hello_streambuf(test.streambuf(sys.stdout)) # OK foo.say_hello_streambuf(sys.stdout) # OK # Test wrapping based on Michele De Stefano's # mds_utils::python::oFileObj class foo.say_hello_fileobj(test.cout) # OK foo.say_hello_fileobj(test.oFileObj(sys.stdout)) # OK foo.say_hello_fileobj(sys.stdout) # OK # But I don't know how to create a wrapper to delegate this constructor for ctor_arg in ( test.cout, # OK test.streambuf(sys.stdout), # Boost.Python.ArgumentError test.oFileObj(sys.stdout), # Boost.Python.ArgumentError sys.stdout # Boost.Python.ArgumentError ): try: foo = test.Foo(ctor_arg) except ArgumentError: print "Argument error with argument %s" % ctor_arg ##################### desired output of test program: ===================== constructor1 hello streambuf hello streambuf hello streambuf hello fileobj hello fileobj hello fileobj constructor2 constructor2 constructor2 constructor2 actual output of test program: ===================== constructor1 hello streambuf hello streambuf hello streambuf hello fileobj hello fileobj hello fileobj constructor2 Argument error with argument <_test.streambuf object at 0x00B75DB0> Argument error with argument <_test.oFileObj object at 0x00B75E40> Argument error with argument ', mode 'w' at 0x00373070> From troy at resophonic.com Sun Apr 4 22:16:46 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sun, 04 Apr 2010 16:16:46 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: <4BB78E8C.6040203@resophonic.com> Message-ID: <4BB8F3AE.1000301@resophonic.com> Christopher Bruns wrote: > On Sat, Apr 3, 2010 at 11:53 AM, troy d. straszheim wrote: >> BOOST_PYTHON_MODULE(mod) >> { >> def("sayhello", as( &sayhello )); >> // arg converter ^^^^^^^^^^^^^ >> }; >> >> The as<> might need some clarification.... > > Thanks Troy for the helpful tip. > > I'm still confused by the "as<>" symbol. Is there a particular boost > header I need to include to get this to work? I get a compile error > ('as' : undeclared identifier) when I try this with 'as<..." or > 'boost::python::as<..." or 'boost::as<...". Plus, my google-fu is too > clumsy to be able to google up the documentation for such a thing. Sorry to confuse you. My fault. The boost.python code behind this is in a separate repository, here: git://gitorious.org/~straszheim/boost/straszheims-python.git The code has diverged quite a bit from trunk boost.python by now. I was only playing with your use case, tossing my results out there. Ravi and I discussed the as<...> interface at length on this list some time ago, and I've recently resumed playing with it. -t From lists_ravi at lavabit.com Sun Apr 4 23:12:17 2010 From: lists_ravi at lavabit.com (Ravi) Date: Sun, 4 Apr 2010 17:12:17 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB8F3AE.1000301@resophonic.com> References: <4BB8F3AE.1000301@resophonic.com> Message-ID: <201004041712.17814.lists_ravi@lavabit.com> Hi Troy, On Sunday 04 April 2010 16:16:46 troy d. straszheim wrote: > The boost.python code behind this is > in a separate repository, here: > > git://gitorious.org/~straszheim/boost/straszheims-python.git > > The code has diverged quite a bit from trunk boost.python by now. > I was only playing with your use case, tossing my results out there. > Ravi and I discussed the as<...> interface at length on this list some > time ago, and I've recently resumed playing with it. I am quite concerned about the divergence. How could I help integrate your changes back to trunk? As far as I am aware, neither Dave A nor RWGK have expressed any interest in these changes, and I am worried that all this work will be for nought. You are doing quite a bit of work with boost.python but I am worried that everything will stay as patches (sort of like Niall Douglas' thread-safety patches). Regards, Ravi From troy at resophonic.com Mon Apr 5 01:29:03 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sun, 04 Apr 2010 19:29:03 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <201004041712.17814.lists_ravi@lavabit.com> References: <4BB8F3AE.1000301@resophonic.com> <201004041712.17814.lists_ravi@lavabit.com> Message-ID: <4BB920BF.3010505@resophonic.com> Ravi wrote: > Hi Troy, > > On Sunday 04 April 2010 16:16:46 troy d. straszheim wrote: >> The boost.python code behind this is >> in a separate repository, here: >> >> git://gitorious.org/~straszheim/boost/straszheims-python.git >> >> The code has diverged quite a bit from trunk boost.python by now. >> I was only playing with your use case, tossing my results out there. >> Ravi and I discussed the as<...> interface at length on this list some >> time ago, and I've recently resumed playing with it. > > I am quite concerned about the divergence. How could I help integrate your > changes back to trunk? As far as I am aware, neither Dave A nor RWGK have > expressed any interest in these changes, and I am worried that all this work > will be for nought. You are doing quite a bit of work with boost.python but I > am worried that everything will stay as patches (sort of like Niall Douglas' > thread-safety patches). Your concern is quite justified, IMV. At this point it is way beyond patches, we're in to the thousands of lines of code, throughout the library and testsuites. The first main change was to gut a bunch of the old preprocessor gunk and replace with boost.fusion. This would make my branch incompatible with Niall's threadsafety changes; on the other hand, it would probably be much easier to implement them. as<...> and scored overload resolution are built on top of the fusionization stuff. I've removed a great many old workaround #ifdefs. Off the top of my head, there are several significant problems: * MSVC can't compile the fusionization: I tried briefly to get it through but am not familiar enough with this compiler to figure out how to trick it in to doing the right thing. * None of it is integrated with boost.build: the branch builds against any boost >= 1.38 or so. It uses CMake. * The testsuite has been completely overhauled to work on python 2 and 3 without that nasty 2to3 business that came with the original py3k patches. valgrind is integrated. I found a few odd py3k bugs in the process IIRC. None of this has been boost.buildized... it uses CTest. * This new overload resolution and as<...> business isn't documented, and hasn't been really stress-tested. The current docs are of uncertain origin and difficult to deal with, the whole business needs overhauling. There is probably more less major stuff. There are various bugfixes on svn.boost.org that are marked '[fix in git]', with links to my git commits, those probably could be simply applied to boost svn. The stl_iterator was one of them I think. I caused some confusion with these markings, I plan to remove them and track this information separately. One possible plan would be: - Call this branch boost.python v2.1 or v3 or something - Figure out what else should go in there, e.g. --- Niall's threadsafety patches --- the recent std::ostream& stuff --- better indexing suites (I have an improved map_indexing_suite sitting around that should go in) --- maybe some of your numpy stuff? --- things laying around on various wiki pages --- docs, docs, docs --- examples, examples, examples - Get all that implemented separate from boost trunk, beat on it at length, including having "power users" actually try it with their production apps: py++, TnFOX, my physics stuff, etc. Then boost.buildize and commit wholesale back to trunk. That's my two cents, anyway. In any case I'd love to have you play with the code. Hopefully you're familiar with git and cmake... -t From roman.yakovenko at gmail.com Mon Apr 5 08:43:25 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 5 Apr 2010 09:43:25 +0300 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB920BF.3010505@resophonic.com> References: <4BB8F3AE.1000301@resophonic.com> <201004041712.17814.lists_ravi@lavabit.com> <4BB920BF.3010505@resophonic.com> Message-ID: On Mon, Apr 5, 2010 at 2:29 AM, troy d. straszheim > - Get all that implemented separate from boost trunk, beat on it at length, > including having "power users" actually try it with their production apps: > ?py++, TnFOX, my physics stuff, etc. I don't have a lot of free time these days, nevertheless I will be glad to test your changes, when they will be ready. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From s_sourceforge at nedprod.com Mon Apr 5 14:03:17 2010 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 05 Apr 2010 13:03:17 +0100 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB920BF.3010505@resophonic.com> References: , <201004041712.17814.lists_ravi@lavabit.com>, <4BB920BF.3010505@resophonic.com> Message-ID: <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com> On 4 Apr 2010 at 19:29, troy d. straszheim wrote: > The first main change was to gut a bunch of the old preprocessor gunk > and replace with boost.fusion. This would make my branch incompatible > with Niall's threadsafety changes; on the other hand, it would probably > be much easier to implement them. as<...> and scored overload > resolution are built on top of the fusionization stuff. I've removed a > great many old workaround #ifdefs. If I have to rewrite the patch because you have eliminated preprocessor complexity then I am extremely happy! Back in the day when I was first developing the patch there was a discussion about how best to modularise the threading support such that *any* threading system could be added. The upshot that I remember (and I might add that my memory is definitely increasingly rewriting itself with age) was that Boost was going to be getting its own threading support module and then thereafter C++ itself. I have a vague recollection of strongly criticising the POSIX thread API which in my opinion is very poorly thought through, and then a discussion erupted about how a proper threading API should look. Needless to say, it all culminated in nothing. I think, with hindsight, that we all were going at it wrong at that time. What we *ought* to have been doing is an upcall mechanism such that routine X is always called just before entering C++ space and routine Y is always called just before entering Python space. That way you get the best of all worlds. > * None of it is integrated with boost.build: the branch builds against > any boost >= 1.38 or so. It uses CMake. I've said it before and I'll say it again: Boost.Python ought to have SCons build files in there as standard. Moreover, SCons just keeps on getting better with age too, the most recent version allowed me to greatly simplify my previous SCons setup. It's getting a real good balance of power and simplicity, though the learning curve is still extremely steep. > - Figure out what else should go in there, e.g. > > --- Niall's threadsafety patches > --- the recent std::ostream& stuff > --- better indexing suites (I have an improved map_indexing_suite > sitting around that should go in) > --- maybe some of your numpy stuff? > --- things laying around on various wiki pages > --- docs, docs, docs > --- examples, examples, examples > > - Get all that implemented separate from boost trunk, beat on it at > length, including having "power users" actually try it with their > production apps: py++, TnFOX, my physics stuff, etc. > > Then boost.buildize and commit wholesale back to trunk. That's my two > cents, anyway. The older I get the more I like encapsulating-but-abstracting template parameter classes. I think that the threading support is best implemented as a simple upcall hook for C++ <=> Python traversal, then you get lots of other potential applications of the upcall too. This time last year I had thought that I'd have GSoc mentoring time during the summer. I'm sure had I been allocated a slot I'd have created the time, but as it happened most of the summer got sucked up in all sorts of unforeseen events created by the starting of my consulting company. This summer shouldn't be so unpredictable - I might even get a TnFOX release out, hopefully with OpenCL and AVX support - but sadly paying work must take precedence above all else. I like consulting more than any other job I've ever had, but I do find that paying work tends to skirt major refactoring in favour of patching up cracks even if it costs them a lot more in the long run. Understandable I suppose given the money hole refactoring can become. Anyway, if you'd like me to contribute the generic upcall support complete with docs and unit tests to your new code branch then let me know. I'll create the time necessary :) Cheers, Niall From micdestefano at gmail.com Tue Apr 6 09:22:41 2010 From: micdestefano at gmail.com (Michele De Stefano) Date: Tue, 6 Apr 2010 09:22:41 +0200 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB78E8C.6040203@resophonic.com> References: <4BB78E8C.6040203@resophonic.com> Message-ID: Thank you, I'm happy you liked my library. And I thank you also for the suggestion on conversion. I did not thought to that solution ... I'll implement it as soon as I will have the time. Thank you very much. Michele 2010/4/3 troy d. straszheim : > Michele De Stefano wrote: >> >> there is a much easier way to treat a FILE* as a C++ stream. The easy >> way is to use my open source library (mds-utils, >> http://code.google.com/p/mds-utils/). >> > > Elegant use of boost::iostreams if I may say so. ?I've been looking for > some usecases for some boost.python modifications I've been playing with > so I tried incorporating your FileObj. ?Seems to work well. ?One can > wrap a function that takes a std::ostream& like this: > > using mds_utils::python::FileObj; > > // c++ function we're wrapping > void sayhello(std::ostream& os) > { > ?os << "*** hello ***\n"; > } > > // > // function object that converts object& and implements > // result_of protocol > // > struct conv { > ?typedef FileObj result_type; > > ?result_type operator()(object& obj) > ?{ > ? ? return FileObj(obj); > ?} > }; > > BOOST_PYTHON_MODULE(mod) > { > ?def("sayhello", as( &sayhello )); > ?// ?arg converter ? ? ? ^^^^^^^^^^^^^ > }; > > In this case python sees "sayhello" as taking a bp::object. > > The as<> might need some clarification.... It takes a function type > argument. ?Above, the argument is the type of a function that returns void, > which takes one argument, which is a function that returns conv and takes > one argument of type object&. ? In general, for a unary function 'fn' > returning type R it is: > > ?as(&fn) > > where T(U) means "convert the python object to C++ type U, then create a > temporary object T and use it to create result_of::type, then convert > that type to R and return to python". ?This is a little boost::proto-ish. > Maybe also a little like a C++1x concept map. ?You could also provide a > generic 'conv' struct, I skipped this so as not to confuse things. > > -t > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Michele De Stefano http://www.linkedin.com/in/micdestefano http://code.google.com/p/mds-utils http://xoomer.virgilio.it/michele_de_stefano From cmbruns at stanford.edu Tue Apr 6 17:52:40 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Tue, 6 Apr 2010 08:52:40 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: <284121.72841.qm@web111412.mail.gq1.yahoo.com> <858331.49982.qm@web111411.mail.gq1.yahoo.com> <970574.30673.qm@web111405.mail.gq1.yahoo.com> Message-ID: On Sun, Apr 4, 2010 at 1:07 PM, Christopher Bruns wrote: [...] >>> // C++ API >>> struct Foo { >>> ? ? Foo(ostream& os); >>> }; >>> >>> # desired python usage >>> foo = Foo(streambuf(sys.stdout)) Solved. Thanks everyone was politely waiting for me to find the answer in the FAQ at http://wiki.python.org/moin/boost.python/HowTo#namedconstructors.2BAC8factories.28asPythoninitializers.29 The way to wrap constructors such as this is like so: //////////// namespace bp = boost::python; // I am still debating whether to use streambuf or FileObj, so both approaches shown... using boost_adaptbx::python::streambuf; using mds_utils::python::oFileObj; // Create wrapper methods for the desired constructors static boost::shared_ptr makeFoo1(streambuf& output) { streambuf::ostream os(output); return boost::shared_ptr(new Foo(os)); } static boost::shared_ptr makeFoo2(oFileObj& output) { std::ostream& os = static_cast(output); return boost::shared_ptr(new Foo(os)); } // This one must be treated carefully, since it can take any boost::python object as an argument static boost::shared_ptr makeFoo3(bp::object& pyfile) { // oFileObj output(pyfile); // return makeFoo2(output); // or streambuf output(pyfile); return makeFoo1(output); } [...] BOOST_PYTHON_MODULE(_test) { bp::class_< Foo >("Foo", bp::init<>()) // First method declared here is last method to be consulted during overload resolution .def("__init__", bp::make_constructor(makeFoo3)) // This one MUST be defined first! .def(bp::init< std::ostream& >()) .def("__init__", bp::make_constructor(makeFoo1)) .def("__init__", bp::make_constructor(makeFoo2)) ; } //////////// Now in python I can use any of the following: foo = Foo(test_.cout) # actual C++ ostream foo = Foo(streambuf(sys.stdout)) # boost_adaptbx wrapper foo = Foo(oFileObje(sys.stdout)) # mds_utils wrapper foo = Foo(sys.stdout) # seamless file object conversion, what I wanted all along. From troy at resophonic.com Tue Apr 6 18:14:46 2010 From: troy at resophonic.com (troy d. straszheim) Date: Tue, 06 Apr 2010 12:14:46 -0400 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com> References: , <201004041712.17814.lists_ravi@lavabit.com>, <4BB920BF.3010505@resophonic.com> <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com> Message-ID: <4BBB5DF6.40306@resophonic.com> Niall Douglas wrote: > On 4 Apr 2010 at 19:29, troy d. straszheim wrote: > >> The first main change was to gut a bunch of the old preprocessor gunk >> and replace with boost.fusion. This would make my branch incompatible >> with Niall's threadsafety changes; on the other hand, it would probably >> be much easier to implement them. as<...> and scored overload >> resolution are built on top of the fusionization stuff. I've removed a >> great many old workaround #ifdefs. > > If I have to rewrite the patch because you have eliminated > preprocessor complexity then I am extremely happy! > > Back in the day when I was first developing the patch there was a > discussion about how best to modularise the threading support such > that *any* threading system could be added. The upshot that I > remember (and I might add that my memory is definitely increasingly > rewriting itself with age) was that Boost was going to be getting its > own threading support module and then thereafter C++ itself. I have a > vague recollection of strongly criticising the POSIX thread API which > in my opinion is very poorly thought through, and then a discussion > erupted about how a proper threading API should look. Needless to > say, it all culminated in nothing. > > I think, with hindsight, that we all were going at it wrong at that > time. What we *ought* to have been doing is an upcall mechanism such > that routine X is always called just before entering C++ space and > routine Y is always called just before entering Python space. That > way you get the best of all worlds. Makes perfect sense to me, but I'm very new to the problem. Help me out a bit... What code of yours should I be looking at? I found this: http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1865844 In that patch, why do you (un)lock in invoke.hpp instead of in static PyObject* function_call(...) in function.cpp and the various other static C linkage functions that are registered directly with the Python C/API via PyTypeObjects? At a glance, these seem the closest points to the language boundary. What is supposed to happen when python calls cpp, which calls python again? How about with multiple interpreters? Would you also need to lock in e.g. object_protocol.cpp: void setattr(object const& target, object const& key, object const& value) { if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) throw_error_already_set(); } If you could indeed use those C linkage functions, how about having boost.python send boost::signals that cppland has been entered/left. (sanity check?) This would support multiple receivers, connect/disconnect, all that stuff that comes with boost::signals. This could compile out for singlethreaded versions. You could even send, say, an enum value with the signal to indicate what was happening (instance_get, instance_new, function_call) and get some kind of tracing ability out of it. Thoughts? Thanks in advance for your indulgence, again I'm new to the problem. -t From mpiepenbrink at gmail.com Wed Apr 7 15:30:44 2010 From: mpiepenbrink at gmail.com (Max Piepenbrink) Date: Wed, 7 Apr 2010 06:30:44 -0700 Subject: [C++-sig] CEGUI, Python, C++ and signature errors, oh my! Message-ID: Hey everyone, I'm working on a pretty straight forward obstacle right now. I'm doing a game project with CEGUI (http://www.cegui.org.uk/wiki/index.php/Main_Page), and Boost.Python (compiled as a shared lib against Stackless, actually), I've successfully learned enough to expose some really useful stuff, I've written converters and exposures for a few basic types of CEGUI's bread and butter classes (UVector2, UDim, String) and exposed a whole bunch of primary functions/properties, but I ran into an issue when setting up a specific method. I had this issue earlier today, I was getting a signature error, it ended up fixing itself somehow and I was never able to reproduce it in that context (version control? what's that?), but I've run into it again and this time it's not magically fixing itself. I've done a few hours of googling and come across some resources that were mildly useful in exposing the issue which I'll leave linked at the bottom. Signature errors at runtime are common enough, but apparently very "scattered" when it comes to why people run into it, which is why I'm having such a hard time. I'm not a seasoned/battle hardened programmer so I hope it doesn't end up being something really stupid! (hint: it probably will) So let's jump into it. I'm going to go through my logic for each of my steps to hopefully expose a possible "misunderstanding" as far as my approach is concerned. Here's my C++ which exposes the base Window class (no pure virtuals or anything, it's fully usable): class_< CEGUI::Window, boost::noncopyable >("UIWindow",no_init) .def("__init__", make_constructor(GetWindow)) .def("addChildWindow", &CEGUI::Window::addChildWindow) .def("addChildWindow", &CEGUI::Window::addChildWindow) This works beautifully, here you can witness two overloads which both work exactly how they should. CEGUI::Window::addChildWindow(const CEGUI::String&) CEGUI::Window::addChildWindow(CEGUI::Window*) This works so well that I can use them exactly as I hoped in Python noodle = UIWindow("Theme/Window","Noodle") foo = UIWindow("Theme/Window","Foo") zebra = UIWindow("Theme/Window","Zebra") noodle.addChildWindow("foo") # adding a child by resolving reference by String (the 2nd param of the ctor) foo.addChildWindow(zebra) # adding a child from immediate reference The fundamental reason this can work is because I have written a converter for Python's str to CEGUI::String. Which leads me to my next step (and the problem) Let's add onto my class exposure, I want to expose two functions, // CEGUI::Event::Group is a typedef for unsigned int virtual CEGUI::Event::Connection subscribeScriptedEvent(const CEGUI::String& name, Event::Group group, const CEGUI::String& subscriber_name); virtual CEGUI::Event::Connection subscribeScriptedEvent(const CEGUI::String& name, const CEGUI::String& subscriber_name); So I write them out (I'm not doing any using; here, since explicit is best in this case) .def("subscribeScriptedEvent",&CEGUI::Window::subscribeScriptedEvent) .def("subscribeScriptedEvent",&CEGUI::Window::subscribeScriptedEvent) To be sure that Connection wont cause any big trouble I wrote a dummy converter (I don't care about it right now, I just want the base functionality of the subscribeScriptedEvent to work, could this be the issue? I havent sorted out how I'm going to convert Event::Connection to a PyObject yet...) struct CEGUI_Connection_To { static PyObject* convert(CEGUI::Event::Connection const& s) { return NULL; } }; I registered the above convert-to, compiled, then I gave it a twirl! ref_test.subscribeScriptedEvent("OnClicked","call_me") Traceback (most recent call last): File "", line 59, in Boost.Python.ArgumentError: Python argument types in UIWindow.subscribeScriptedEvent(UIWindow, str, str) did not match C++ signature: subscribeScriptedEvent(class CEGUI::Window {lvalue}, class CEGUI::String, cl ass CEGUI::String) subscribeScriptedEvent(class CEGUI::Window {lvalue}, class CEGUI::String, un signed int, class CEGUI::String) This is strange to me, since I have converters (implicitly and explicitly) for CEGUI::Window, AND for CEGUI::String, both of which were shown to work up above in my earlier example. It really seems like (UIWindow, str, str) should line up with (class CEGUI::Window {lvalue}, class CEGUI::String, class CEGUI::String) given that I am basically doing this above just with one less CEGUI::String My shot-in-the-dark-error-message-googling lead me to some vague explanations of common reasons for this problem, one of which might apply to me but I am simply too dim to comprehend: * http://regina.sourceforge.net/docs/python-caveats.html#python-ownership goes over some ownership concerns and how this error can sometimes be a result of ownership issues (I'm not sure that's the problem? I played with some Callpolicies but assumed the defaults should be fine for this relatively simple dummy function) * http://mail.python.org/pipermail/cplusplus-sig/2004-June/007204.html an older posting from this very mailing list (haha!) but I simply don't understand his solution. I basically went through the first ~20 results from http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=did+not+match+C%2B%2B+signature:+python and went back through the docs trying to see what I'm messing up, but I'm getting kind flustered and figured I'd eloquently ask it here. It's highly likely I'm butchering Python by not using the right call policy (I tried a few and just got hideous compile errors unrelated to syntax, put some thought into it, got scared, ran back to defaults/return_internal_reference<>() ), or that I'm simply forgetting a single, important template parameter somewhere. But at this point I feel like it SHOULD work. I'm pretty sure I gave enough information to outline the problem/what basic steps I took to troubleshoot, any help on the matter and illumination on my poor understanding as to why this is happening is greatly appreciated! Thanks, Max Piepenbrink -------------- next part -------------- An HTML attachment was scrubbed... URL: From eudoxos at arcig.cz Thu Apr 8 11:36:00 2010 From: eudoxos at arcig.cz (=?UTF-8?Q?V=C3=A1clav_=C5=A0milauer?=) Date: Thu, 08 Apr 2010 11:36:00 +0200 Subject: [C++-sig] disallow instance attributes created by assignement to nonexistent class attribute Message-ID: <1270719360.2304.42.camel@flux> Hi all, I have classes wrapped with boost::python defining certain attributes. If user assigns value to an attribute that doesn't exist as class attribute, python automatically creates instance attribute of that name. I would like to avoid this (although I know that is the way Python is supposed to work), as python classes, in my case, model c++ classes closely: AttributeError should be raised. It happened to me (and other people) that I assigned nonexistent attribute (by typo or by confusing the name in my head), then debugging the c++ code to see why it did not have the effect it should obviously have. I wasn't able to find answer via google, besides overriding __setattr__, which would have most likely have performance implications. I appreciate any pointers or suggestions. Thanks, V?clav From vishal.bayskar at nechclst.in Fri Apr 9 13:29:24 2010 From: vishal.bayskar at nechclst.in (vishal bayskar) Date: Fri, 9 Apr 2010 04:29:24 -0700 (PDT) Subject: [C++-sig] "operator++" is not supported Message-ID: <28187684.post@talk.nabble.com> Hi, Actually I am generating a python binding for my source code, in which there were a extensive use of operator like operator++(), "operator*", "operator->". As python does not support for these operators. and pyplusplus is failing to generate wrapper code for these operator. Are there any work around or some functionality available in py++ to handle these. Thanks in Advance. Regards, Vishal -- View this message in context: http://old.nabble.com/%22operator%2B%2B%22-is-not-supported-tp28187684p28187684.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Fri Apr 9 22:15:02 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 9 Apr 2010 23:15:02 +0300 Subject: [C++-sig] "operator++" is not supported In-Reply-To: <28187684.post@talk.nabble.com> References: <28187684.post@talk.nabble.com> Message-ID: On Fri, Apr 9, 2010 at 2:29 PM, vishal bayskar wrote: > > Hi, > > Actually I am generating a python binding for my source code, in which there > were a extensive use of operator like operator++(), "operator*", > "operator->". > > As python does not support for these operators. and pyplusplus is failing to > generate wrapper code for these operator. Are there any work around or some > functionality available in py++ to handle these. If you will create small and complete example of what your are trying to do, then may be I would be able to help. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From s_sourceforge at nedprod.com Sat Apr 10 16:14:41 2010 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sat, 10 Apr 2010 15:14:41 +0100 Subject: [C++-sig] Make threading support official (was: Re: Conversion of python files to C++ ostreams) In-Reply-To: <4BBB5DF6.40306@resophonic.com> References: , <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com>, <4BBB5DF6.40306@resophonic.com> Message-ID: <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com> On 6 Apr 2010 at 12:14, troy d. straszheim wrote: My apologies for the delay in replying. > > I think, with hindsight, that we all were going at it wrong at that > > time. What we *ought* to have been doing is an upcall mechanism such > > that routine X is always called just before entering C++ space and > > routine Y is always called just before entering Python space. That > > way you get the best of all worlds. > > Makes perfect sense to me, but I'm very new to the problem. Help me out > a bit... What code of yours should I be looking at? I found this: > > http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1865844 Yeah, that's old. Try http://github.com/ned14/tnfox/blob/master/Python/BoostPatches.zip which is about two years fresher. > In that patch, why do you (un)lock in invoke.hpp instead of in > > static PyObject* function_call(...) > > in function.cpp and the various other static C linkage functions that > are registered directly with the Python C/API via PyTypeObjects? At a > glance, these seem the closest points to the language boundary. I am afraid that I do not remember why. It could have been out of ignorance, or simply because the patch I used as a base did so there as well. It could also have been that I had a very good reason such as forcing an ABI incompatibility to prevent accidental mixing of incompatible binaries or something, or perhaps it was a maintenance issue or some question of exception safety. It's old code I am happy to see replaced with something much better anyway. > What > is supposed to happen when python calls cpp, which calls python again? In my patch at least the GIL gets repeatedly locked and unlocked as necessary however deep you go, including if an exception gets thrown or something is being iterated. This isn't fast nor was I ever happy about it, but it meant behaviour consistent with people's expectations. > How about with multiple interpreters? Last time I checked this worked fine, though this was some time ago. Running multiple interpreters is one of the TnFOX test suite tests anyway. > Would you also need to lock in e.g. object_protocol.cpp: > > void setattr(object const& target, object const& key, object const& value) > { > if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) > throw_error_already_set(); > } Maybe I am missing your point, but surely all accesses to Python must hold the GIL first, not least because the GIL also specifies the current interpreter to use? (I know that you can get away with some calls, but relying on this seems hardly prudent). > If you could indeed use those C linkage functions, how about having > boost.python send boost::signals that cppland has been entered/left. > (sanity check?) This would support multiple receivers, > connect/disconnect, all that stuff that comes with boost::signals. This > could compile out for singlethreaded versions. You could even send, > say, an enum value with the signal to indicate what was happening > (instance_get, instance_new, function_call) and get some kind of > tracing ability out of it. Thoughts? I would have issue with boost::signals2 solely because it uses mutexes when a lock free implementation is not only entirely possible, but highly desirable given the typical use cases of a signals and slots implementation. It may however be possible to use boost:signals and the Python GIL to serialise around it - in this situation then yes, using boost::signals would be useful assuming that its overhead is minimal. Obviously enough if you're firing a signal in something as minor as your setattr() function then in the ideal case you want no code being executed if there are no slots registered for that particular signal. In TnFOX I have a metaprogramming construct which assembles inline a jump table of specialisations of classes between which at run time can be dynamically chosen. Fairly amazingly, all major compilers correctly elide table entries which cannot be chosen such that they will remove the choice logic entirely if there is just one possible choice, or the whole construct if there are none. This particular construct is really useful in BPL actually because it lets you fake stuff like setting at runtime arbitrary python code as a C (not C++) API based sort function. Hence it may well be that a static signals and slots implementation could be more appropriate in this situation. I guess I wouldn't know until I run benchmarks. Your thoughts? Cheers, Niall From troy at resophonic.com Sun Apr 11 03:11:59 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 10 Apr 2010 21:11:59 -0400 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com> References: , <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com>, <4BBB5DF6.40306@resophonic.com> <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com> Message-ID: <4BC121DF.30407@resophonic.com> Niall Douglas wrote: > On 6 Apr 2010 at 12:14, troy d. straszheim wrote: > Try > http://github.com/ned14/tnfox/blob/master/Python/BoostPatches.zip > which is about two years fresher. Thanks. > >> In that patch, why do you (un)lock in invoke.hpp instead of in >> >> static PyObject* function_call(...) >> >> in function.cpp and the various other static C linkage functions that >> are registered directly with the Python C/API via PyTypeObjects? At a >> glance, these seem the closest points to the language boundary. > > I am afraid that I do not remember why. It could have been out of > ignorance, or simply because the patch I used as a base did so there > as well. It could also have been that I had a very good reason such > as forcing an ABI incompatibility to prevent accidental mixing of > incompatible binaries or something, or perhaps it was a maintenance > issue or some question of exception safety. It's old code I am happy > to see replaced with something much better anyway. I see some special handling in invoke.hpp for boost::python::objects::detail::py_iter_, maybe that has something to do with it. If one did lock/unlock where I suggest above, one wouldn't have the necessary c++ type information to do such handling. Google doesn't turn up much on this case... hints? [snip] >> Would you also need to lock in e.g. object_protocol.cpp: >> >> void setattr(object const& target, object const& key, object const& value) >> { >> if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) >> throw_error_already_set(); >> } > > Maybe I am missing your point, but surely all accesses to Python must > hold the GIL first, not least because the GIL also specifies the > current interpreter to use? (I know that you can get away with some > calls, but relying on this seems chardly xprudent). Take function new_class(...) in src/object.cpp: this is called during BOOST_PYTHON_MODULE(), and invoke.hpp doesn't know about it, therefore nothing would be locked. [snip] > In TnFOX I have a metaprogramming construct which assembles inline a > jump table of specialisations of classes between which at run time > can be dynamically chosen. Fairly amazingly, all major compilers > correctly elide table entries which cannot be chosen such that they > will remove the choice logic entirely if there is just one possible > choice, or the whole construct if there are none. This particular > construct is really useful in BPL actually because it lets you fake > stuff like setting at runtime arbitrary python code as a C (not C++) > API based sort function. Could you point me at the code? > Hence it may well be that a static signals and slots implementation > could be more appropriate in this situation. I guess I wouldn't know > until I run benchmarks. Your thoughts? Thanks for the discussion. I'm now thinking that the handling of these enter/exit "signals" emitted by boost.python shouldn't be coupled to boost::signals or anything else. Seems cleaner and easier to provide an interface behind which one could put a simple lock/unlocker or something more complicated involving boost::signals if desired. -t From troy at resophonic.com Sun Apr 11 03:14:12 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 10 Apr 2010 21:14:12 -0400 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC121DF.30407@resophonic.com> References: , <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com>, <4BBB5DF6.40306@resophonic.com> <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com> <4BC121DF.30407@resophonic.com> Message-ID: <4BC12264.2050704@resophonic.com> troy d. straszheim wrote: > Take function new_class(...) in src/object.cpp: this is called during > BOOST_PYTHON_MODULE(), and invoke.hpp doesn't know about it, therefore > nothing would be locked. During module import that is: BOOST_PYTHON_MODULE(m) { class_("T"); // <- here } -t From troy at resophonic.com Sun Apr 11 05:42:06 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sat, 10 Apr 2010 23:42:06 -0400 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC121DF.30407@resophonic.com> References: , <4BB9D185.31674.79983BF1@s_sourceforge.nedprod.com>, <4BBB5DF6.40306@resophonic.com> <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com> <4BC121DF.30407@resophonic.com> Message-ID: <4BC1450E.4070607@resophonic.com> troy d. straszheim wrote: > > Take function new_class(...) in src/object.cpp: this is called during > BOOST_PYTHON_MODULE(), and invoke.hpp doesn't know about it, therefore > nothing would be locked. > Maybe this is a more practical example: void set_foo_attr(object& obj, object& what) { api::setattr(obj, "foo", what); // leave cpp in here, no unlock } BOOST_PYTHON_MODULE(m) { def("set_foo_attr", &set_foo_attr); } >>> class X: pass >>> x = X() >>> set_foo_attr(x, ['something']) >>> print x.foo ['something'] Here, enter/exitCPP would be called by invoke.hpp when set_foo_attr fires, but not when api::setattr calls PyObject_SetAttrString. -t From s_sourceforge at nedprod.com Sun Apr 11 19:10:12 2010 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Sun, 11 Apr 2010 18:10:12 +0100 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC121DF.30407@resophonic.com> References: , <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com>, <4BC121DF.30407@resophonic.com> Message-ID: <4BC20274.27251.99977928@s_sourceforge.nedprod.com> On 10 Apr 2010 at 21:11, troy d. straszheim wrote: > I see some special handling in invoke.hpp for > boost::python::objects::detail::py_iter_, maybe that has something to do > with it. If one did lock/unlock where I suggest above, one wouldn't > have the necessary c++ type information to do such handling. Google > doesn't turn up much on this case... hints? Yes, I do remember that iterators caught me when I was developing that patch. I remember being stuck for three or four days tracking down the bug and getting very frustrated with the metaprogramming poverty in the MSVC debugger of the time. Not only that, but I also wanted the future ability to specialise a type to set rules for locking or unlocking. > >> Would you also need to lock in e.g. object_protocol.cpp: > >> > >> void setattr(object const& target, object const& key, object const& value) > >> { > >> if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) > >> throw_error_already_set(); > >> } > > > > Maybe I am missing your point, but surely all accesses to Python must > > hold the GIL first, not least because the GIL also specifies the > > current interpreter to use? (I know that you can get away with some > > calls, but relying on this seems chardly xprudent). > > Take function new_class(...) in src/object.cpp: this is called during > BOOST_PYTHON_MODULE(), and invoke.hpp doesn't know about it, therefore > nothing would be locked. > [paste] > During module import that is: > > BOOST_PYTHON_MODULE(m) > { > class_("T"); // <- here > } > [paste] > Maybe this is a more practical example: > > void set_foo_attr(object& obj, object& what) > { > api::setattr(obj, "foo", what); // leave cpp in here, no unlock > } > > BOOST_PYTHON_MODULE(m) > { > def("set_foo_attr", &set_foo_attr); > } > > >>> class X: pass > >>> x = X() > >>> set_foo_attr(x, ['something']) > >>> print x.foo > ['something'] > > > Here, enter/exitCPP would be called by invoke.hpp when set_foo_attr > fires, but not when api::setattr calls PyObject_SetAttrString. Ah I see your point now. TnFOX's BPL patch made the assumption that when python calls into C++ land that it was going to be executing C++ stuff rather than interfacing with C++ representations of python stuff. This was a very reasonable assumption to make when you are simply providing python bindings for a large C++ library, so on the point of entering C++ land it unlocks the GIL and sets the current python interpreter to null. For that thread, any attempt to do *anything* with python henceforth guarantees an exception. Now if that C++ thread happens to want to do some work in Python, it must hold a RAII instance of FXPython_CtxHold around the relevant code. FXPython_CtxHold simply takes a FXPythonInterp to set as current - this grabs the GIL and sets the current python interpreter. I have never been particularly happy with this solution because excess locking is real bad for system latency i.e. when python calls a virtual function the GIL gets unlocked, relocked, a check for a python override is made, unlocked, jump to base class implementation, on exit relock. I personally would use a technique I call "a hanging lock" whereby you wrap a parameter with a thin metaprogramming construct which lets you effectively bind a RAII held lock with a parameter such that a callee takes possession, but I don't know if this is a common technique in Boost and adding it made patching in updates too difficult. > > Hence it may well be that a static signals and slots implementation > > could be more appropriate in this situation. I guess I wouldn't know > > until I run benchmarks. Your thoughts? > > Thanks for the discussion. I'm now thinking that the handling of these > enter/exit "signals" emitted by boost.python shouldn't be coupled to > boost::signals or anything else. Seems cleaner and easier to provide an > interface behind which one could put a simple lock/unlocker or something > more complicated involving boost::signals if desired. I was maybe thinking of doing it properly with a boost::staticsignals library. > [snip] > > In TnFOX I have a metaprogramming construct which assembles inline a > > jump table of specialisations of classes between which at run time > > can be dynamically chosen. Fairly amazingly, all major compilers > > correctly elide table entries which cannot be chosen such that they > > will remove the choice logic entirely if there is just one possible > > choice, or the whole construct if there are none. This particular > > construct is really useful in BPL actually because it lets you fake > > stuff like setting at runtime arbitrary python code as a C (not C++) > > API based sort function. > > Could you point me at the code? Sure. The general TnFOX docs are at http://tnfox.sourceforge.net/TnFOX- svn/html/ where the header file FXGenericTools.h (http://tnfox.sourceforge.net/TnFOX- svn/html/_f_x_generic_tools_8h.html) contains most of the metaprogramming library. In this file there is a template called FX::Generic::TL::dynamicAt< typelist, instance > (http://tnfox.sourceforge.net/TnFOX- svn/html/struct_f_x_1_1_generic_1_1_t_l_1_1dynamic_at.html). You can see the source of FXGenericTools.h at http://tnfox.sourceforge.net/TnFOX-svn/html/_f_x_generic_tools_8h- source.html with dynamicAt<> being at around line 2226. As you'll note, dynamicAt<> statically assembles a sixteen entry array of runtime generated code points into read only space, then it jumps into it by array indexation. I have to hand full kudos to the compiler guys such that the compiler knows the right thing to do if the array index is fixed. The example I refered to of faking arbitrary python code is documented at http://tnfox.sourceforge.net/TnFOX- svn/html/class_f_x_1_1_f_x_code_to_python_code.html. It may help you when you are reading the code to know that FX::Generic::TL::instantiateH<> is a horizontal instantiator of a typelist i.e. TL::instantiateH::value, Holder> will make a class instantiateH<> : public Holder, public Holder, public Holder. If you have any questions then please do let me know - I appreciate that yet another metaprogramming library can hurt the head. With regard to implementing support for all this, could you clarify your planned timetable with respect to your branch of Boost? Cheers, Niall From troy at resophonic.com Tue Apr 13 05:20:56 2010 From: troy at resophonic.com (troy d. straszheim) Date: Mon, 12 Apr 2010 23:20:56 -0400 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC20274.27251.99977928@s_sourceforge.nedprod.com> References: , <4BC087D1.26606.93D06D6A@s_sourceforge.nedprod.com>, <4BC121DF.30407@resophonic.com> <4BC20274.27251.99977928@s_sourceforge.nedprod.com> Message-ID: <4BC3E318.7040308@resophonic.com> Niall Douglas wrote: > On 10 Apr 2010 at 21:11, troy d. straszheim wrote: > >> I see some special handling in invoke.hpp for >> boost::python::objects::detail::py_iter_, maybe that has something to do >> with it. If one did lock/unlock where I suggest above, one wouldn't >> have the necessary c++ type information to do such handling. Google >> doesn't turn up much on this case... hints? > > Yes, I do remember that iterators caught me when I was developing > that patch. I remember being stuck for three or four days tracking > down the bug and getting very frustrated with the metaprogramming > poverty in the MSVC debugger of the time. Not only that, but I also > wanted the future ability to specialise a type to set rules for > locking or unlocking. I don't grok it just yet. The code prevents locking around any call to a function that returns a py_iter_, and the specialization mechanism you've built would allow you to prevent locking around functions that return other types, but that's all it can do. Do you recall why you needed to avoid locking here? My guess would be that this py_iter_ calls back into python, the same situation as with overrides, below. Are there other cases where you'd want special handling? What if I wrap a function that takes a boost::python::object (ie a call back to python could happen at any time)? >>>> Would you also need to lock in e.g. object_protocol.cpp: >>>> >>>> void setattr(object const& target, object const& key, object const& value) >>>> { >>>> if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) >>>> throw_error_already_set(); >>>> } >>> Maybe I am missing your point, but surely all accesses to Python must >>> hold the GIL first, not least because the GIL also specifies the >>> current interpreter to use? (I know that you can get away with some >>> calls, but relying on this seems chardly xprudent). >> Take function new_class(...) in src/object.cpp: this is called during >> BOOST_PYTHON_MODULE(), and invoke.hpp doesn't know about it, therefore >> nothing would be locked. >> [paste] >> During module import that is: >> >> BOOST_PYTHON_MODULE(m) >> { >> class_("T"); // <- here >> } >> [paste] >> Maybe this is a more practical example: >> >> void set_foo_attr(object& obj, object& what) >> { >> api::setattr(obj, "foo", what); // leave cpp in here, no unlock >> } >> >> BOOST_PYTHON_MODULE(m) >> { >> def("set_foo_attr", &set_foo_attr); >> } >> >> >>> class X: pass >> >>> x = X() >> >>> set_foo_attr(x, ['something']) >> >>> print x.foo >> ['something'] >> >> >> Here, enter/exitCPP would be called by invoke.hpp when set_foo_attr >> fires, but not when api::setattr calls PyObject_SetAttrString. > > Ah I see your point now. > > TnFOX's BPL patch made the assumption that when python calls into C++ > land that it was going to be executing C++ stuff rather than > interfacing with C++ representations of python stuff. This was a very > reasonable assumption to make when you are simply providing python > bindings for a large C++ library, so on the point of entering C++ > land it unlocks the GIL and sets the current python interpreter to > null. For that thread, any attempt to do *anything* with python > henceforth guarantees an exception. Hrm. If I wrap a C++ base class, so that one can inherit from it in python, then you've got exactly this situation. This is a common pattern in our application, a C++ framework, configured and run by a python script, which can take C++ or python plugins. So the user runs a python script, which creates an application instance, and then tells it to load several modules, some of which are pure c++, some are python-inheriting-from-c++. The python plugins operate on objects which are, you guessed it, C++ objects wrapped in python. So you're constantly bouncing back and forth across the language barrier. Ah, now I see you come to this in your next paragraph: > Now if that C++ thread happens to want to do some work in Python, it > must hold a RAII instance of FXPython_CtxHold around the relevant > code. FXPython_CtxHold simply takes a FXPythonInterp to set as > current - this grabs the GIL and sets the current python interpreter. > > I have never been particularly happy with this solution because > excess locking is real bad for system latency i.e. when python calls > a virtual function the GIL gets unlocked, relocked, a check for a > python override is made, unlocked, jump to base class implementation, > on exit relock. I personally would use a technique I call "a hanging > lock" whereby you wrap a parameter with a thin metaprogramming > construct which lets you effectively bind a RAII held lock with a > parameter such that a callee takes possession, but I don't know if > this is a common technique in Boost and adding it made patching in > updates too difficult. Seems to me that if one wants to claim that boost.python "supports multithreading", it needs to support this case, even if there are performance hits. I'd be interested to learn more about these hanging locks... >>> Hence it may well be that a static signals and slots implementation >>> could be more appropriate in this situation. I guess I wouldn't know >>> until I run benchmarks. Your thoughts? >> Thanks for the discussion. I'm now thinking that the handling of these >> enter/exit "signals" emitted by boost.python shouldn't be coupled to >> boost::signals or anything else. Seems cleaner and easier to provide an >> interface behind which one could put a simple lock/unlocker or something >> more complicated involving boost::signals if desired. > > I was maybe thinking of doing it properly with a boost::staticsignals > library. > Ah, I think I interpreted "static signals" to mean boost::signals (not the threadsafe boost::signals2). Anyhow, I think the user should just supply something like struct mylocker { void enterCPP(); void exitCPP(); }; boost.python would call those at the appropriate times and the user could put whatever they wanted inside those functions. I mentioned a tracing facility: maybe this interface would be more elaborate, depending on where inside boost.python these calls originate... we'll see... >> [snip] >>> In TnFOX I have a metaprogramming construct which assembles > inline a >>> jump table of specialisations of classes between which at run > time >>> can be dynamically chosen. Fairly amazingly, all major compilers >>> correctly elide table entries which cannot be chosen such that > they >>> will remove the choice logic entirely if there is just one > possible >>> choice, or the whole construct if there are none. This particular > >>> construct is really useful in BPL actually because it lets you > fake >>> stuff like setting at runtime arbitrary python code as a C (not > C++) >>> API based sort function. >> Could you point me at the code? > > Sure. > > The general TnFOX docs are at http://tnfox.sourceforge.net/TnFOX- > svn/html/ where the header file FXGenericTools.h > (http://tnfox.sourceforge.net/TnFOX- > svn/html/_f_x_generic_tools_8h.html) contains most of the > metaprogramming library. In this file there is a template called > FX::Generic::TL::dynamicAt< typelist, instance > > (http://tnfox.sourceforge.net/TnFOX- > svn/html/struct_f_x_1_1_generic_1_1_t_l_1_1dynamic_at.html). You can > see the source of FXGenericTools.h at > http://tnfox.sourceforge.net/TnFOX-svn/html/_f_x_generic_tools_8h- > source.html with dynamicAt<> being at around line 2226. As you'll > note, dynamicAt<> statically assembles a sixteen entry array of > runtime generated code points into read only space, then it jumps > into it by array indexation. I have to hand full kudos to the > compiler guys such that the compiler knows the right thing to do if > the array index is fixed. > > The example I refered to of faking arbitrary python code is > documented at . > > It may help you when you are reading the code to know that > FX::Generic::TL::instantiateH<> is a horizontal instantiator of a > typelist i.e. TL::instantiateH::value, Holder> > will make a class instantiateH<> : public Holder, public > Holder, public Holder. > > If you have any questions then please do let me know - I appreciate > that yet another metaprogramming library can hurt the head. Yeah, ouch. :) I'll come back to this... > With > regard to implementing support for all this, could you clarify your > planned timetable with respect to your branch of Boost? Well adding enterCPP() | exitCPP() code to my branch is easy. It would go in this file: http://gitorious.org/~straszheim/boost/straszheims-python/blobs/master/include/boost/python/detail/caller.hpp which has replaced all of the preprocessor stuff in detail/invoke.hpp. Lines 258 and 265 are where boost::fusion actually calls the registered C++ functions; you could just (un)lock around the call to go() at line 277. Then we'd have to figure out what to do about this py_iter_ stuff. Then, AFAICT we'd have in my branch exactly what your patches do to the boost.python from svn. Note: again, that code doesn't compile with MSVC, and I don't know enough about the compiler to read its mind and restructure things such that it doesn't choke... Is MSVC support a prerequisite for you to be interested in all this? -t From vishal.bayskar at nechclst.in Wed Apr 14 09:25:20 2010 From: vishal.bayskar at nechclst.in (vishal bayskar) Date: Wed, 14 Apr 2010 00:25:20 -0700 (PDT) Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus Message-ID: <28239246.post@talk.nabble.com> Hi I have a requirement of using dereferencing pointer, like in the below code checkSmartPtr.h ============ #include #include"test.h" using namespace std; template class SmartPtr { public: SmartPtr(T *ptr):pointee(ptr) { } T *operator->() { return pointee; } private: T *pointee; }; SmartPtr make_test() { return SmartPtr(new Test(5)); } void do_something(SmartPtr f) { f->display(); } test.h ==== #include using namespace std; class Test { public: Test(int i); void display(); int getNum(); private: int x; }; test.cpp ===== #include #include"test.h" using namespace std; // a class for testing purpose only(Smart ptr can wrap the object of this class) Test::Test(int i): x(i) { } void Test::display() { cout << "value of x: " << this->x << endl; } int Test::getNum() { return this->x; } Like in cpp I can use the display() function using Test *test = new Test(10); SmartPtr obj1(test); obj1->display(); How would I use it in python from the binding generated by pyplusplus? When I generate the wrapper for checkSmartPtr.h using pyplusplus Below warnings displayed. Looking at warnings it seems like operator -> is not supported in pyplusplus. ------------- WARNING: Test * SmartPtr::operator->() [member operator] > compilation error W1014: "operator->" is not supported. See Boost.Python > documentation: > http://www.boost.org/libs/python/doc/v2/operators.html#introduction. WARNING: Test * SmartPtr::operator->() [member operator] > compilation error W1050: The function returns "Test *" type. You have to > specify a call policies.Be sure to take > a look on Py++ defined call policies: http://language- > binding.net/pyplusplus/documentation/functions/call_policies.html#py-defined-call-policies ---------- If operator -> is not supported then what is the mechanism for using it? -- View this message in context: http://old.nabble.com/How-to-make-use-of--%3E-%28dereferncing%29-operator-in-pyplusplus-tp28239246p28239246.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Wed Apr 14 09:41:28 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Apr 2010 10:41:28 +0300 Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus In-Reply-To: <28239246.post@talk.nabble.com> References: <28239246.post@talk.nabble.com> Message-ID: On Wed, Apr 14, 2010 at 10:25 AM, vishal bayskar wrote: > > Hi I have a requirement of using dereferencing pointer, like in the below > code > >... > > Below warnings displayed. Looking at warnings it seems like operator -> is > not supported in pyplusplus. > > If operator -> is not supported then what is the mechanism for using it? > ... You should not export export "SmartPtr" class as is. You can "teach" Boost.Python to understand that an object is the instance of SmartPtr class and it will handle for you and your users "operator*" and "operator->". The following example ( http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html ) should help you. Also, in the past there were a lot of discussions on this subject, so using Google will definitely help. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From vishal.bayskar at nechclst.in Wed Apr 14 12:52:56 2010 From: vishal.bayskar at nechclst.in (vishal bayskar) Date: Wed, 14 Apr 2010 03:52:56 -0700 (PDT) Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus In-Reply-To: References: <28239246.post@talk.nabble.com> Message-ID: <28241082.post@talk.nabble.com> >You should not export export "SmartPtr" class as is. You can "teach" >Boost.Python to understand that an object is the instance of SmartPtr >class and it will handle for you and your users "operator*" and >"operator->". >The following example ( >http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html >) should help you. Also, in the past there were a lot of discussions >on this subject, so using Google will definitely help. Hi Roman, Thanks for reply. If possible can you please guide me how to "teach" Boost.Python about the custom SmartPtr. I have seen the link as suggested by you but I am not getting much idea (may be because I am new in this area) what exactly I need to do. Do I need to write wrapper myself and insert it into the wrapper code generated by py++ / I should use some interface to register my custom smart pointer? -- View this message in context: http://old.nabble.com/How-to-make-use-of--%3E-%28dereferncing%29-operator-in-pyplusplus-tp28239246p28241082.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Wed Apr 14 12:56:19 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Apr 2010 13:56:19 +0300 Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus In-Reply-To: <28241082.post@talk.nabble.com> References: <28239246.post@talk.nabble.com> <28241082.post@talk.nabble.com> Message-ID: On Wed, Apr 14, 2010 at 1:52 PM, vishal bayskar wrote: > Hi Roman, > > Thanks for reply. If possible can you please guide me how to "teach" > Boost.Python about the custom SmartPtr. I have seen the link as suggested by > you but I am not getting much idea (may be because I am new in this area) > what exactly I need to do. > > Do I need to write wrapper myself and insert it into the wrapper code > generated by py++ / I should use some interface to register my custom smart > pointer? http://language-binding.net/_downloads/smart_ptrs.zip contains a working example. You can download it and study. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From vishal.bayskar at nechclst.in Wed Apr 14 16:15:02 2010 From: vishal.bayskar at nechclst.in (vishal bayskar) Date: Wed, 14 Apr 2010 07:15:02 -0700 (PDT) Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus In-Reply-To: References: <28239246.post@talk.nabble.com> <28241082.post@talk.nabble.com> Message-ID: <28243207.post@talk.nabble.com> >http://language-binding.net/_downloads/smart_ptrs.zip contains a >working example. You can download it and study. Thanks Roman for your guidance, I have studied the example and also succesfully used it in python script. My next doubt is how did you generate the binding.cpp, becouse I also tried to generate this binding from classes.hpp file by below py++ code. ---------- mb=module_builder.module_builder_t(["classes.hpp"]) mb.build_code_creator(module_name = 'custom_sptr') mb.write_module('binding.cpp') ------------ It has produced little different binding. -- View this message in context: http://old.nabble.com/How-to-make-use-of--%3E-%28dereferncing%29-operator-in-pyplusplus-tp28239246p28243207.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Wed Apr 14 22:12:50 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Apr 2010 23:12:50 +0300 Subject: [C++-sig] How to make use of -> (dereferncing) operator in pyplusplus In-Reply-To: <28243207.post@talk.nabble.com> References: <28239246.post@talk.nabble.com> <28241082.post@talk.nabble.com> <28243207.post@talk.nabble.com> Message-ID: On Wed, Apr 14, 2010 at 5:15 PM, vishal bayskar > Thanks Roman for your guidance, I have studied the example and also > succesfully used it in python script. > My next doubt is how did you generate the binding.cpp, becouse I also tried > to generate this binding from classes.hpp file by below py++ code. > ---------- > mb=module_builder.module_builder_t(["classes.hpp"]) > mb.build_code_creator(module_name = 'custom_sptr') > mb.write_module('binding.cpp') > ------------ > It has produced little different binding. Right, because you have to "configure" py++ to produce such code. You can take a look on PyOgre project, as it does this. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From tmmikolajczyk at gmail.com Thu Apr 15 00:08:02 2010 From: tmmikolajczyk at gmail.com (Tomasz Mikolajczyk) Date: Thu, 15 Apr 2010 00:08:02 +0200 Subject: [C++-sig] std::auto_ptr<> in constructor Message-ID: <4BC63CC2.7080603@gmail.com> Hi, I'm a new user of boost::python art. I started to play a bit with the code and the py++ generator and encountered difficulties with the std::auto_ptr in constructor. The following code: class A { public: A(int value) : m_value(value) {} private: int m_value; }; class B { public: B(int value, std::auto_ptr a) : m_value(value), m_a(a.release()) {} private: int m_value; std::auto_ptr m_a; }; has been bound to the following code: BOOST_PYTHON_MODULE(pyplusplus) { { //::A typedef bp::class_< A, boost::noncopyable > A_exposer_t; A_exposer_t A_exposer = A_exposer_t( "A", bp::init< int >(( bp::arg("value") )) ); bp::scope A_scope( A_exposer ); bp::implicitly_convertible< int, A >(); bp::register_ptr_to_python< std::auto_ptr< A > >(); } bp::class_< B, boost::noncopyable >( "B", bp::init< int, std::auto_ptr< A > >(( bp::arg("value"), bp::arg("a") )) ); } Unfortunately, the generated code compiles with the following error: /usr/local/boost_1_42_0/include/boost/python/object/value_holder.hpp:137: error: no matching function for call to ?std::auto_ptr::auto_ptr(const std::auto_ptr&)? I understand the error but I don't know what to do to avoid it. Regeards, Tomek From roman.yakovenko at gmail.com Thu Apr 15 06:17:52 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 15 Apr 2010 07:17:52 +0300 Subject: [C++-sig] std::auto_ptr<> in constructor In-Reply-To: <4BC63CC2.7080603@gmail.com> References: <4BC63CC2.7080603@gmail.com> Message-ID: On Thu, Apr 15, 2010 at 1:08 AM, Tomasz Mikolajczyk wrote: > Hi, > > I'm a new user of boost::python art. I started to play a bit with the > code and the py++ generator and encountered difficulties with the > std::auto_ptr in constructor. > ... > I understand the error but I don't know what to do to avoid it. I will take a look on this issue today. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu Apr 15 08:13:25 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 15 Apr 2010 09:13:25 +0300 Subject: [C++-sig] std::auto_ptr<> in constructor In-Reply-To: References: <4BC63CC2.7080603@gmail.com> Message-ID: On Thu, Apr 15, 2010 at 7:17 AM, Roman Yakovenko wrote: > On Thu, Apr 15, 2010 at 1:08 AM, Tomasz Mikolajczyk > wrote: >> Hi, >> >> I'm a new user of boost::python art. I started to play a bit with the >> code and the py++ generator and encountered difficulties with the >> std::auto_ptr in constructor. >> ... >> I understand the error but I don't know what to do to avoid it. I believe this error has nothing to do with py++ and it is a pure Boost.Python issue. I can propose a work around for you: introduce the following function: std::auto_ptr< B > createB(int value, std::auto_ptr a){ return std::auto_ptr< B >( new B( value, a ) ); } and instruct py++ to use it as "__init__" method: B = mb.class_( 'B' ) B.constructors().exclude() B.add_fake_constructors( mb.free_function( 'createB' ) ) one more step: A = mb.class_('A' ) A.held_type = 'std::auto_ptr< %s >' % A.decl_string This will allow you to create A class instance in Python, and internally it will be held using auto_ptr class. I actually tested it and it works ( http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1837&view=rev ). HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From murrayc at murrayc.com Thu Apr 15 10:53:02 2010 From: murrayc at murrayc.com (Murray Cumming) Date: Thu, 15 Apr 2010 10:53:02 +0200 Subject: [C++-sig] Generating API documentation when using boost::python Message-ID: <1271321582.2438.108.camel@murrayc-x61> I tried running pydoc on my python module, (implemented here http://git.gnome.org/browse/glom/tree/glom/python_embed/python_module/py_glom_module.cc#n35 ) but the output has lots of stuff that is uninteresting to Python coders, even after using docstring_options. For instance: http://www.murrayc.com/temp/glom_1_14_pydoc.html In particular, it a) Mentions a Boost.Python.instance base class. b) Mentions stuff like "__instance_size__ = 84" b) Mentions the __setitem__, __getitem__ and __len__ implementation details of the [] syntax. c) Shows the arg1 self argument for each method. d) Shows just "object" for some of my argument types.. How can I say what specific type they are. e) Likewise, just shows "object" for my return types. (If anyone can suggest a better alternative to nasty pydoc, I'd be glad.) -- murrayc at murrayc.com www.murrayc.com www.openismus.com From s_sourceforge at nedprod.com Thu Apr 15 15:09:46 2010 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 15 Apr 2010 14:09:46 +0100 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC3E318.7040308@resophonic.com> References: , <4BC20274.27251.99977928@s_sourceforge.nedprod.com>, <4BC3E318.7040308@resophonic.com> Message-ID: <4BC7101A.2317.90DB242@s_sourceforge.nedprod.com> On 12 Apr 2010 at 23:20, troy d. straszheim wrote: > I don't grok it just yet. The code prevents locking around any call to > a function that returns a py_iter_, and the specialization mechanism > you've built would allow you to prevent locking around functions that > return other types, but that's all it can do. Do you recall why you > needed to avoid locking here? My guess would be that this py_iter_ > calls back into python, the same situation as with overrides, below. > Are there other cases where you'd want special handling? What if I wrap > a function that takes a boost::python::object (ie a call back to python > could happen at any time)? I wouldn't worry about it - it is a patch designed to be reapplied to every new release of BPL after all, so it can never be pretty nor sensible. The key thing here I think is to implement formal support. > > I have never been particularly happy with this solution because > > excess locking is real bad for system latency i.e. when python calls > > a virtual function the GIL gets unlocked, relocked, a check for a > > python override is made, unlocked, jump to base class implementation, > > on exit relock. I personally would use a technique I call "a hanging > > lock" whereby you wrap a parameter with a thin metaprogramming > > construct which lets you effectively bind a RAII held lock with a > > parameter such that a callee takes possession, but I don't know if > > this is a common technique in Boost and adding it made patching in > > updates too difficult. > > Seems to me that if one wants to claim that boost.python "supports > multithreading", it needs to support this case, even if there are > performance hits. I'd be interested to learn more about these hanging > locks... Well hanging locks are one of the core things which made me go develop my own portability library rather than use an existing one. Boost makes a lot of use of smart pointers to implement exception safety. I strongly believe that Boost makes a major semantic error in doing this, because exception safety ought to be written in *explicitly* and never handled *implicitly*. Smart pointers silently handle exception unwinds, and while this is a good thing in the context of say reference counting, it is a bad thing in the case of std::auto_ptr<> and all its kind. auto_ptr<> is ideal for passing around ownership of a pointer. It is NOT the proper approach for cleaning up after exception throws because it doesn't force the programmer to explicitly code for the exception throw. Because TnFOX doesn't make this semantic error, I can use a policy driven templated smart pointer where one of the policies implements the hanging lock. In other words, in TnFOX smart pointers don't "point", they *encapsulate* *metadata* with an object reference, or put more clearly, if you are working in TnFOX and you see a smart pointer being used then you can be very sure it is doing something special. [FYI RAII-style exception safety in TnFOX is handled using a C++ concept called rollbacks where you write in the steps to undo the current transaction as it is being performed. If an exception happens anywhere during a given atomic operation, it gets undone. Because the programmer explicitly writes in how he implements exception safety as he writes his code, it makes peer code review and auditing very significantly easier. It is also much, much rarer that you find exception safety bugs, especially in algorithm implementations. If you want to know more, see http://tnfox.sourceforge.net/TnFOX- svn/html/group__rollbacks.html]. Anyway, one can't just go start using hanging locks without all Boost programmers being used to the idea, or you'd get all sorts of bugs introduced. I would love some ISO C++ leadership here, especially by endorsing rollbacks as the preferred exception safety technique with a tiny bit of extra language support, but ever since they savaged me over rvalue references I couldn't be arsed dealing with them ever again. > > I was maybe thinking of doing it properly with a boost::staticsignals > > library. > > Ah, I think I interpreted "static signals" to mean boost::signals (not > the threadsafe boost::signals2). Anyhow, I think the user should just > supply something like > > struct mylocker > { > void enterCPP(); > void exitCPP(); > }; > > boost.python would call those at the appropriate times and the user > could put whatever they wanted inside those functions. I mentioned a > tracing facility: maybe this interface would be more elaborate, > depending on where inside boost.python these calls originate... we'll > see... Looks good to me. > > With > > regard to implementing support for all this, could you clarify your > > planned timetable with respect to your branch of Boost? > > Well adding enterCPP() | exitCPP() code to my branch is easy. It would > go in this file: > > http://gitorious.org/~straszheim/boost/straszheims-python/blobs/master/include/boost/python/detail/caller.hpp > > which has replaced all of the preprocessor stuff in detail/invoke.hpp. > Lines 258 and 265 are where boost::fusion actually calls the registered > C++ functions; you could just (un)lock around the call to go() at line > 277. Then we'd have to figure out what to do about this py_iter_ > stuff. Then, AFAICT we'd have in my branch exactly what your patches do > to the boost.python from svn. > > Note: again, that code doesn't compile with MSVC, and I don't know > enough about the compiler to read its mind and restructure things such > that it doesn't choke... Is MSVC support a prerequisite for you to be > interested in all this? MSVC support is an absolute requirement for me. Unlike others though, I don't care about supporting anything older than the most recently released free Express edition. I don't mind fixing things up to make it work on MSVC. I'll tell you where I'm at timetable wise: today, after many months of work, I finally submit my applications for PhD funding which have been a pain in the hole to get done in time. Tomorrow I start work on a consulting contract for Applied Research Associates which I have had on the backburner for the past two weeks which is to implement an O(1) realloc() function. It will likely take me a week or two to get that going as it won't be easy programming. Once I have first beta out of that code, I would be strongly inclined to implement boost::staticsignals and get it working with BPL, so basically I'm saying I'd be able to start work on it in a couple of weeks time. Does that suit you okay? Cheers, Niall From charlessolar at gmail.com Thu Apr 15 16:02:14 2010 From: charlessolar at gmail.com (Charles Solar) Date: Thu, 15 Apr 2010 09:02:14 -0500 Subject: [C++-sig] Make threading support official In-Reply-To: <4BC7101A.2317.90DB242@s_sourceforge.nedprod.com> References: <4BC20274.27251.99977928@s_sourceforge.nedprod.com> <4BC3E318.7040308@resophonic.com> <4BC7101A.2317.90DB242@s_sourceforge.nedprod.com> Message-ID: I was not originally going to say anything but from what i have skimmed from all these emails seems like someone really needs multithread safety in boost python. Turns out I needed the same thing about 2 months ago, and I looked at TnFOX, changed a few things, patched a couple files, and I am fairly confident that what I have is at least a good short term solution until multithread safety is put into the real boost python. I was not going to post this because I did not want to spend the time making the project pretty for other people to use, but if whoever you are is so desperate as to spend a week talking about this then I guess I can at least post what I have. http://rapidshare.com/files/376177125/boost_python.rar I just ripped the two folders right out of my own project, whoever wants thread safety can pick out the files and put them how they want in their own project :p A couple of things I noted while doing this that I think have come up here and a bit about what this patch does. This code will lock the GIL at every entry into python, and it will unlock it at every entry into cpp land. Python exceptions and cpp exceptions work, which was kind of tricky to get right. It should be noted that my code here is just me pounding a round peg into a square hole and should not be trusted 100%. I have some unit tests but its not nearly as thourally tested as I would like. About TnFox, I noticed it was doing a lot of complicated stuff like creating an interpreter per thread, saving gil states and doing a bunch of weird stuff. I only wanted a library where I could safety call into python from a different thread so all this does is manage the GIL lock appropriately. It will NOT allow 2 threads to run python code at the same time. If thats what TnFox does then that's impressive, but that's nowhere near what I needed so I just grabbed the ideas from invoke.hpp and added some locking structures of my own to complete this. Also if you do use this and you are trying to call into python from override objects like I was, I am sure you have been trying to lock the GIL with PyGILState_Ensure. I made it so that locking is not necessary. All GIL management should be handled by boost python in that code, there should be no read to lock the GIL in your own project anywhere. Thats about all I have to say, if I completely misinterpreted this thread please disregard. oh, it compiles fine in visual studio 2008/2010 and gcc, those are the compilers I currently use. Charles -------------- next part -------------- An HTML attachment was scrubbed... URL: From amundson at fnal.gov Thu Apr 15 20:39:03 2010 From: amundson at fnal.gov (James Amundson) Date: Thu, 15 Apr 2010 13:39:03 -0500 Subject: [C++-sig] Generating API documentation when using boost::python In-Reply-To: <1271321582.2438.108.camel@murrayc-x61> References: <1271321582.2438.108.camel@murrayc-x61> Message-ID: <4BC75D47.9020400@fnal.gov> On 04/15/2010 03:53 AM, Murray Cumming wrote: > (If anyone can suggest a better alternative to nasty pydoc, I'd be > glad.) > Well, Sphinx, , is the new standard for Python documentation, but I don't think it has any way to extract documentation from your boost python module. For that purpose, I'm using Breathe, , which takes the output of Doxygen and adapts it to Sphinx. It isn't perfect, but it seems useful. I think it has the potential to get much better. --Jim Amundson From frallain at gmail.com Fri Apr 16 10:42:48 2010 From: frallain at gmail.com (=?ISO-8859-1?Q?Fran=E7ois_ALLAIN?=) Date: Fri, 16 Apr 2010 10:42:48 +0200 Subject: [C++-sig] Wrapping a pure virtual method with multiple arguments Message-ID: Hello, I followed the "official" tutorial and others but still don't manage to expose this pure virtual method (getPeptide) : ms_mascotresults.hpp class ms_mascotresults { public: ms_mascotresults(ms_mascotresfile &resfile, const unsigned int flags, double minProbability, int maxHitsToReport, const char * unigeneIndexFile, const char * singleHit = 0); ... virtual ms_peptide getPeptide(const int q, const int p) const = 0; } ms_mascotresults.cpp #include using namespace boost::python; #include "msparser.hpp" // which includes "ms_mascotresults.hpp" using namespace matrix_science; #include #include struct ms_mascotresults_wrapper : ms_mascotresults, wrapper { ms_peptide getPeptide(const int q, const int p) { this->get_override("getPeptide")(q); this->get_override("getPeptide")(p); } }; BOOST_PYTHON_MODULE(ms_mascotresults) { class_("ms_mascotresults") .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) ) ; } Here are the bjam's errors : /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: cannot declare field ?boost::python::objects::value_holder::m_held? to be of abstract type ?ms_mascotresults_wrapper? ms_mascotresults.cpp:12: note: because the following virtual functions are pure within ?ms_mascotresults_wrapper?: ... include/ms_mascotresults.hpp:334: note: virtual matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, int) const ms_mascotresults.cpp: In constructor ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()?: ms_mascotresults.cpp:12: error: no matching function for call to ?matrix_science::ms_mascotresults::ms_mascotresults()? include/ms_mascotresults.hpp:284: note: candidates are: matrix_science::ms_mascotresults::ms_mascotresults(matrix_science::ms_mascotresfile&, unsigned int, double, int, const char*, const char*) include/ms_mascotresults.hpp:109: note: matrix_science::ms_mascotresults::ms_mascotresults(const matrix_science::ms_mascotresults&) ... /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp: In constructor ?boost::python::objects::value_holder::value_holder(PyObject*) [with Value = ms_mascotresults_wrapper]?: /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: note: synthesized method ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()? first required here /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: cannot allocate an object of abstract type ?ms_mascotresults_wrapper? ms_mascotresults.cpp:12: note: since type ?ms_mascotresults_wrapper? has pure vi Hello, I followed the "official" tutorial and others but still don't manage to expose this pure virtual method (getPeptide) : ms_mascotresults.hpp class ms_mascotresults { public: ms_mascotresults(ms_mascotresfile &resfile, const unsigned int flags, double minProbability, int maxHitsToReport, const char * unigeneIndexFile, const char * singleHit = 0); ... virtual ms_peptide getPeptide(const int q, const int p) const = 0; } ms_mascotresults.cpp #include using namespace boost::python; #include "msparser.hpp" // which includes "ms_mascotresults.hpp" using namespace matrix_science; #include #include struct ms_mascotresults_wrapper : ms_mascotresults, wrapper { ms_peptide getPeptide(const int q, const int p) { this->get_override("getPeptide")(q); this->get_override("getPeptide")(p); } }; BOOST_PYTHON_MODULE(ms_mascotresults) { class_("ms_mascotresults") .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) ) ; } Here are the bjam's errors : /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: cannot declare field ?boost::python::objects::value_holder::m_held? to be of abstract type ?ms_mascotresults_wrapper? ms_mascotresults.cpp:12: note: because the following virtual functions are pure within ?ms_mascotresults_wrapper?: ... include/ms_mascotresults.hpp:334: note: virtual matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, int) const ms_mascotresults.cpp: In constructor ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()?: ms_mascotresults.cpp:12: error: no matching function for call to ?matrix_science::ms_mascotresults::ms_mascotresults()? include/ms_mascotresults.hpp:284: note: candidates are: matrix_science::ms_mascotresults::ms_mascotresults(matrix_science::ms_mascotresfile&, unsigned int, double, int, const char*, const char*) include/ms_mascotresults.hpp:109: note: matrix_science::ms_mascotresults::ms_mascotresults(const matrix_science::ms_mascotresults&) ... /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp: In constructor ?boost::python::objects::value_holder::value_holder(PyObject*) [with Value = ms_mascotresults_wrapper]?: /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: note: synthesized method ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()? first required here /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: cannot allocate an object of abstract type ?ms_mascotresults_wrapper? ms_mascotresults.cpp:12: note: since type ?ms_mascotresults_wrapper? has pure virtual functions So I tried to change the constructor's signature by : class_("ms_mascotresults", init()) Giving these errors : /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: cannot declare field ?boost::python::objects::value_holder::m_held? to be of abstract type ?ms_mascotresults_wrapper? ms_mascotresults.cpp:12: note: because the following virtual functions are pure within ?ms_mascotresults_wrapper?: include/ms_mascotresults.hpp:334: note: virtual matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, int) const ... ms_mascotresults.cpp:24: instantiated from here /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: no matching function for call to ?ms_mascotresults_wrapper::ms_mascotresults_wrapper(matrix_science::ms_mascotresfile&, const unsigned int&, const double&, const int&, const char* const&, const char* const&)? ms_mascotresults.cpp:12: note: candidates are: ms_mascotresults_wrapper::ms_mascotresults_wrapper(const ms_mascotresults_wrapper&) ms_mascotresults.cpp:12: note: ms_mascotresults_wrapper::ms_mascotresults_wrapper() If I comment the virtual function getPeptide in the .hpp, it builds perfectly with this constructor : class_("ms_mascotresults", init()) This is the first time I use Boost.Python so I don't really know what happens inside, I don't understand this errors of candidates given the fact that there is only one constructor in the .hpp ... Thanks in advance for your help. Fallino -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.reid at mail.cryst.bbk.ac.uk Fri Apr 16 10:59:00 2010 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Fri, 16 Apr 2010 09:59:00 +0100 Subject: [C++-sig] Generating API documentation when using boost::python In-Reply-To: <4BC75D47.9020400@fnal.gov> References: <1271321582.2438.108.camel@murrayc-x61> <4BC75D47.9020400@fnal.gov> Message-ID: James Amundson wrote: > On 04/15/2010 03:53 AM, Murray Cumming wrote: >> (If anyone can suggest a better alternative to nasty pydoc, I'd be >> glad.) >> I always thought it should be possible make boost.python configurable so the user can choose which docstring format is output (standard, epytext markup, rst, ...) and have some control of how much detail is provided in the docstring by default. I did have a quick look in the code but didn't manage to work out what was going on. From roman.yakovenko at gmail.com Fri Apr 16 19:01:34 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 16 Apr 2010 20:01:34 +0300 Subject: [C++-sig] Wrapping a pure virtual method with multiple arguments In-Reply-To: References: Message-ID: Hello. You have provided too much information. Small example with short problem description can definitely help ( you ) On Fri, Apr 16, 2010 at 11:42 AM, Fran?ois ALLAIN wrote: > Hello, I followed the "official" tutorial and others but still don't manage > to expose this pure virtual method (getPeptide) : > > ms_mascotresults.hpp > > class ms_mascotresults { > ? ? ? ? public: > > > > ? ? ? ? ms_mascotresults(ms_mascotresfile ?&resfile, > ? ? ? ? ? ? ? ? ? ? ? ? ?const unsigned int flags, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?double ? ? ? ? ? ? minProbability, > ? ? ? ? ? ? ? ? ? ? ? ? ?int ? ? ? ? ? ? ? ?maxHitsToReport, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?const char * ? ? ? unigeneIndexFile, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?const char * ? ? ? singleHit = 0); > > > ? ? ? ? ... > > ? ? ? ? virtual ms_peptide getPeptide(const int q, const int p) const = 0; > > > } > > > > ms_mascotresults.cpp > > #include > > > using namespace boost::python; > > > #include "msparser.hpp" // which includes "ms_mascotresults.hpp" > > > using namespace matrix_science; > #include > > > #include > > struct ms_mascotresults_wrapper : ms_mascotresults, > wrapper { > > > ? ? ms_peptide getPeptide(const int q, const int p) { > > > ? ? ? ? this->get_override("getPeptide")(q); > > > ? ? ? ? this->get_override("getPeptide")(p); > > > ? ? } > }; > > BOOST_PYTHON_MODULE(ms_mascotresults) > > > { > ? ? class_("ms_mascotresults") > > > ? ? ? ? .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) ) > > > ? ? ; > } > > > > Here are the bjam's errors : > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: > cannot declare field > ?boost::python::objects::value_holder::m_held? to > be of abstract type ?ms_mascotresults_wrapper? > > > ms_mascotresults.cpp:12: note: ? because the following virtual functions are > pure within ?ms_mascotresults_wrapper?: > > > ... > include/ms_mascotresults.hpp:334: note: ? ? virtual > matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, > int) const > > > ms_mascotresults.cpp: In constructor > ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()?: > > > ms_mascotresults.cpp:12: error: no matching function for call to > ?matrix_science::ms_mascotresults::ms_mascotresults()? > > > include/ms_mascotresults.hpp:284: note: candidates are: > matrix_science::ms_mascotresults::ms_mascotresults(matrix_science::ms_mascotresfile&, > unsigned int, double, int, const char*, const char*) > > > include/ms_mascotresults.hpp:109: note: > matrix_science::ms_mascotresults::ms_mascotresults(const > matrix_science::ms_mascotresults&) > > > ... > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp: In constructor > ?boost::python::objects::value_holder::value_holder(PyObject*) [with > Value = ms_mascotresults_wrapper]?: > > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: note: > synthesized method ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()? > first required here > > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: > cannot allocate an object of abstract type ?ms_mascotresults_wrapper? > > > ms_mascotresults.cpp:12: note: ? since type ?ms_mascotresults_wrapper? has > pure vi > > Hello, I followed the "official" tutorial and others but still don't manage > to expose this pure virtual method (getPeptide) : > > ms_mascotresults.hpp > > class ms_mascotresults { > ? ? ? ? public: > > > > ? ? ? ? ms_mascotresults(ms_mascotresfile ?&resfile, > ? ? ? ? ? ? ? ? ? ? ? ? ?const unsigned int flags, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?double ? ? ? ? ? ? minProbability, > ? ? ? ? ? ? ? ? ? ? ? ? ?int ? ? ? ? ? ? ? ?maxHitsToReport, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?const char * ? ? ? unigeneIndexFile, > > > ? ? ? ? ? ? ? ? ? ? ? ? ?const char * ? ? ? singleHit = 0); > > > ? ? ? ? ... > > ? ? ? ? virtual ms_peptide getPeptide(const int q, const int p) const = 0; > > > } > > ms_mascotresults.cpp > > #include > > > using namespace boost::python; > > > #include "msparser.hpp" // which includes "ms_mascotresults.hpp" > > > using namespace matrix_science; > #include > > > #include > > struct ms_mascotresults_wrapper : ms_mascotresults, > wrapper { > > > ? ? ms_peptide getPeptide(const int q, const int p) { > > > ? ? ? ? this->get_override("getPeptide")(q); > > > ? ? ? ? this->get_override("getPeptide")(p); > > > ? ? } > }; > > BOOST_PYTHON_MODULE(ms_mascotresults) > > > { > ? ? class_("ms_mascotresults") > > > ? ? ? ? .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) ) > > > ? ? ; > } > > Here are the bjam's errors : > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: > cannot declare field > ?boost::python::objects::value_holder::m_held? to > be of abstract type ?ms_mascotresults_wrapper? > > > ms_mascotresults.cpp:12: note: ? because the following virtual functions are > pure within ?ms_mascotresults_wrapper?: > > > ... > include/ms_mascotresults.hpp:334: note: ? ? virtual > matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, > int) const > > > ms_mascotresults.cpp: In constructor > ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()?: > > > ms_mascotresults.cpp:12: error: no matching function for call to > ?matrix_science::ms_mascotresults::ms_mascotresults()? > > > include/ms_mascotresults.hpp:284: note: candidates are: > matrix_science::ms_mascotresults::ms_mascotresults(matrix_science::ms_mascotresfile&, > unsigned int, double, int, const char*, const char*) > > > include/ms_mascotresults.hpp:109: note: > matrix_science::ms_mascotresults::ms_mascotresults(const > matrix_science::ms_mascotresults&) > > > ... > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp: In constructor > ?boost::python::objects::value_holder::value_holder(PyObject*) [with > Value = ms_mascotresults_wrapper]?: > > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: note: > synthesized method ?ms_mascotresults_wrapper::ms_mascotresults_wrapper()? > first required here > > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: > cannot allocate an object of abstract type ?ms_mascotresults_wrapper? > > > ms_mascotresults.cpp:12: note: ? since type ?ms_mascotresults_wrapper? has > pure virtual functions > > > > > > So I tried to change the constructor's signature by : > > class_("ms_mascotresults", > init *,const char *>()) > > > > > > > Giving these errors : > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: > cannot declare field > ?boost::python::objects::value_holder::m_held? to > be of abstract type ?ms_mascotresults_wrapper? > > > ms_mascotresults.cpp:12: note: ? because the following virtual functions are > pure within ?ms_mascotresults_wrapper?: > > > include/ms_mascotresults.hpp:334: note: ? ? virtual > matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, > int) const > > > ... > ms_mascotresults.cpp:24: ? instantiated from here > > > /usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: no > matching function for call to > ?ms_mascotresults_wrapper::ms_mascotresults_wrapper(matrix_science::ms_mascotresfile&, > const unsigned int&, const double&, const int&, const char* const&, const > char* const&)? > > > ms_mascotresults.cpp:12: note: candidates are: > ms_mascotresults_wrapper::ms_mascotresults_wrapper(const > ms_mascotresults_wrapper&) > > > ms_mascotresults.cpp:12: note: > ms_mascotresults_wrapper::ms_mascotresults_wrapper() > > > > > > If I comment the virtual function getPeptide in the .hpp, it builds > perfectly with this constructor : > > ? ? ? ? class_("ms_mascotresults", init ?&, const unsigned int, double, int, const char *,const char *>()) > > This is the first time I use Boost.Python so I don't really know what > happens inside, I don't understand this errors of candidates given the fact > that there is only one constructor in the .hpp ... > > > Thanks in advance for your help. > > Fallino > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From hans_meine at gmx.net Wed Apr 21 22:36:10 2010 From: hans_meine at gmx.net (Hans Meine) Date: Wed, 21 Apr 2010 22:36:10 +0200 Subject: [C++-sig] Status of Numpy support in boost python Message-ID: <201004212236.12306.hans_meine@gmx.net> Am Montag 08 M?rz 2010 13:32:22 schrieb Pim Schellart: > we are working on a project for which it would be extremely useful if > numpy arrays could be passed as arguments to wrapped C++ methods. > On the website I cannot find any evidence that this is currently > supported by Boost Python. > Is this (or will this be) implemented? After all the recent discussion, I want to point to yet another (hopefully) interesting bit of code which I am involved with: Our "vigra" (computer vision) library now comes with numpy- and BPL-based python bindings. In addition to type-safe conversions between C++ and Python(*), this offers a vigra::MultiArray on the C++ side, which is an n-dimensional array class template, complete with n-dimensional iterators (using raw pointers for the innermost dimension to offer the best possible performance for unstrided arrays) and a lot of algorithms, i.e. pointwise transformation / [possibly type-coercing] copying / inspection etc. One particular feature Ulli is proud of is the automatic conversion to *subclasses* of ndarray, such that we can register and use e.g. 'Volume' python classes for 3D arrays. I really want to stress that VIGRA is a very versatile template library which should be able to work in conjunction with any other libraries and data structures, i.e. true generic code (usually you don't even need to compile VIGRA, if you are not interested in an image import/export library). So don't hesitate to give it a shot even if you are /not/ interested in any of its array / linalg algorithms. (Actually, the PythonArray template class should be even useful without boost::python, i.e. I am using it with SIP, too.) I don't think there will ever be just /one/ single solution for boost::python+numpy, since everyone seems to have different requirements/expectations w.r.t. available algorithms, static vs. dynamic element types etc. However, I do think that our vigranumpy approach could be very useful for some of this list's readers. HTH, Hans -------------- next part -------------- An embedded message was scrubbed... From: Ullrich Koethe Subject: [VIGRA] VIGRA 1.7.0 Released Date: Thu, 15 Apr 2010 20:58:40 +0200 Size: 4914 URL: From diepen at astron.nl Thu Apr 22 09:31:14 2010 From: diepen at astron.nl (Ger van Diepen) Date: Thu, 22 Apr 2010 09:31:14 +0200 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <201004212236.12306.hans_meine@gmx.net> References: <201004212236.12306.hans_meine@gmx.net> Message-ID: <4BD01762020000A90000B1A9@smtp.nfra.nl> Another library that can pass C++ arrays to/from python is pyrap (pyrap.googlecode.com). It is the python binding to the casacore package, so it maps (possibly strided) Python arrays to casa::Array objects. Unlike the other C++ array classes I know (Blitz, boost::multi_array, vigra::MultiArray) the dimensionality of casa::Array is a runtime parameter, not a template parameter. It makes it easier to handle arrays (e.g. reading from a file, passing in from python) of which the dimensionality is unknown at compile time. Iteration through a strided casa::Array is as fast as boost::multi_array. casa::Array axes are Fortran ordered, while numpy is basically C ordered (numpy can handle Fortran order, but slower; furthermore it converts to C order as soon you do something like an addition). Therefore pyrap reverses the axes. Note that pyrap can also handle the conversion of a numpy array element to a basic C++ type (like float). pyrap is based on an old version of Boost_Python, so it does not use newer, handier features. Cheers, Ger van Diepen >>> Hans Meine 4/21/2010 10:36 PM >>> Am Montag 08 M?rz 2010 13:32:22 schrieb Pim Schellart: > we are working on a project for which it would be extremely useful if > numpy arrays could be passed as arguments to wrapped C++ methods. > On the website I cannot find any evidence that this is currently > supported by Boost Python. > Is this (or will this be) implemented? After all the recent discussion, I want to point to yet another (hopefully) interesting bit of code which I am involved with: Our "vigra" (computer vision) library now comes with numpy- and BPL-based python bindings. In addition to type-safe conversions between C++ and Python(*), this offers a vigra::MultiArray on the C++ side, which is an n-dimensional array class template, complete with n-dimensional iterators (using raw pointers for the innermost dimension to offer the best possible performance for unstrided arrays) and a lot of algorithms, i.e. pointwise transformation / [possibly type-coercing] copying / inspection etc. One particular feature Ulli is proud of is the automatic conversion to *subclasses* of ndarray, such that we can register and use e.g. 'Volume' python classes for 3D arrays. I really want to stress that VIGRA is a very versatile template library which should be able to work in conjunction with any other libraries and data structures, i.e. true generic code (usually you don't even need to compile VIGRA, if you are not interested in an image import/export library). So don't hesitate to give it a shot even if you are /not/ interested in any of its array / linalg algorithms. (Actually, the PythonArray template class should be even useful without boost::python, i.e. I am using it with SIP, too.) I don't think there will ever be just /one/ single solution for boost::python+numpy, since everyone seems to have different requirements/expectations w.r.t. available algorithms, static vs. dynamic element types etc. However, I do think that our vigranumpy approach could be very useful for some of this list's readers. HTH, Hans -------------- next part -------------- An HTML attachment was scrubbed... URL: From zachelko at gmail.com Fri Apr 23 01:00:00 2010 From: zachelko at gmail.com (Zach Elko) Date: Thu, 22 Apr 2010 19:00:00 -0400 Subject: [C++-sig] Boost.Python Constructor Issue Message-ID: Hello all, Forgive me if this isn't the proper forum for this, but I'm having the following issue: http://codepad.org/EFPnkIUm System info (Boost is a tad outdated at the moment): Boost.Jam Version 3.1.16. OS=LINUX. BOOST_VERSION 103700 Python 2.6.1 Any help is greatly appreciated, thanks! Zach J. Elko -------------- next part -------------- An HTML attachment was scrubbed... URL: From jmclaughlin at istor.com Sat Apr 24 05:00:59 2010 From: jmclaughlin at istor.com (John McLaughlin) Date: Fri, 23 Apr 2010 20:00:59 -0700 Subject: [C++-sig] boost::python::len( list_object) throws "Access violation" (MSDev v9/Boost 1.41) Message-ID: <9F3F0A752CAEBE4FA7E906CC2FBFF57C01584A09@MERCURY.inside.istor.com> I have a strange crash in my C++ method when called from Python. I have a method that has one of the arguments a Python List. The symptoms are the same with an empty list and a non-empty one. In one method, early in the code I call; boost::python::len( var ) and it returns properly. HOWEVER, in another method, I am passing the *same value* from Python, but the "boost::python::len( var )" aborts when "PyErr_Occurred()" is called. It causes an access violation (like a bad pointer dereference). What is strange is that the line before (calling PyObject_Length(obj.ptr() ) returns a proper size. Any ideas? ------------------------------------------------------ namespace boost { namespace python { inline ssize_t len(object const& obj) { ssize_t result = PyObject_Length(obj.ptr()); if (PyErr_Occurred()) throw_error_already_set(); return result; } }} // namespace boost::python ------------------------------------------------------ void PyService_Volume::Reconfigure( const PyStorageSize & sizeInBytes, const iStor::UserAgent::UAEnums::VolumeCompositionName & compositionName, const boost::python::list & disks, int stripeWidth, const iStor::UserAgent::UAEnums::StripeDepth & stripeDepth) { Py_BEGIN_ALLOW_THREADS . . . if (boost::python::len(disks) > 0) { ... ------------------------------------------------------ John McLaughlin iStor Networks, Inc. From austin.bingham at gmail.com Mon Apr 26 10:22:41 2010 From: austin.bingham at gmail.com (Austin Bingham) Date: Mon, 26 Apr 2010 10:22:41 +0200 Subject: [C++-sig] Catching Boost.Python.ArgumentError Message-ID: I feel like I'm missing something simple, but how do I catch Boost.Python.ArgumentException? As far as I can tell, the Boost.Python module is not something I can import explicitly, so I can't write "catch Boost.Python.ArgumentException:". I can do something like comparing type and module name strings, but that just feels inelegant and a trouble for maintenance. Any ideas would be very welcome. Austin From rwgk at yahoo.com Mon Apr 26 18:27:27 2010 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 26 Apr 2010 09:27:27 -0700 (PDT) Subject: [C++-sig] Catching Boost.Python.ArgumentError In-Reply-To: References: Message-ID: <652181.53435.qm@web111415.mail.gq1.yahoo.com> The best you can do is: try: foo("abc") except Exception, e: if (not str(e).startswith("Python argument types in")): raise print "continue" ----- Original Message ---- From: Austin Bingham To: Cplusplus-sig at python.org Sent: Mon, April 26, 2010 1:22:41 AM Subject: [C++-sig] Catching Boost.Python.ArgumentError I feel like I'm missing something simple, but how do I catch Boost.Python.ArgumentException? As far as I can tell, the Boost.Python module is not something I can import explicitly, so I can't write "catch Boost.Python.ArgumentException:". I can do something like comparing type and module name strings, but that just feels inelegant and a trouble for maintenance. Any ideas would be very welcome. Austin From amohr at pixar.com Mon Apr 26 18:33:32 2010 From: amohr at pixar.com (Alex Mohr) Date: Mon, 26 Apr 2010 09:33:32 -0700 Subject: [C++-sig] Catching Boost.Python.ArgumentError In-Reply-To: References: Message-ID: <4BD5C05C.8090605@pixar.com> On 4/26/2010 1:22 AM, Austin Bingham wrote: > I feel like I'm missing something simple, but how do I catch > Boost.Python.ArgumentException? As far as I can tell, the Boost.Python > module is not something I can import explicitly, so I can't write > "catch Boost.Python.ArgumentException:". I can do something like > comparing type and module name strings, but that just feels inelegant > and a trouble for maintenance. Any ideas would be very welcome. I haven't looked at the code in awhile but I think I do it by intentionally generating an ArgumentError, catching it, and in the handler where I have the exception object, I store its class away for later use. Alex From jmclaughlin at istor.com Mon Apr 26 23:31:44 2010 From: jmclaughlin at istor.com (John McLaughlin) Date: Mon, 26 Apr 2010 14:31:44 -0700 Subject: [C++-sig] boost::python::len( list_object) throws "Access violation" (MSDev v9/Boost 1.41) Message-ID: <9F3F0A752CAEBE4FA7E906CC2FBFF57C01584A7F@MERCURY.inside.istor.com> I believe I have found my problem. I was allowing the GIL to be released (essentially letting multiple threads run concurrently) but the " const boost::python::list & disks" argument was not protected at this point. I can either move the Py_BEGIN_ALLOW_THREADS call to after I am finished accessing the "disks" arg, or use Py_BLOCK_THREADS and Py_UNBLOCK_THREADS to protect access calls. John John McLaughlin iStor Networks, Inc. -----Original Message----- From: John McLaughlin Sent: Friday, April 23, 2010 8:01 PM To: 'cplusplus-sig at python.org.' Subject: boost::python::len( list_object) throws "Access violation" (MSDev v9/Boost 1.41) I have a strange crash in my C++ method when called from Python. I have a method that has one of the arguments a Python List. The symptoms are the same with an empty list and a non-empty one. In one method, early in the code I call; boost::python::len( var ) and it returns properly. HOWEVER, in another method, I am passing the *same value* from Python, but the "boost::python::len( var )" aborts when "PyErr_Occurred()" is called. It causes an access violation (like a bad pointer dereference). What is strange is that the line before (calling PyObject_Length(obj.ptr() ) returns a proper size. Any ideas? ------------------------------------------------------ namespace boost { namespace python { inline ssize_t len(object const& obj) { ssize_t result = PyObject_Length(obj.ptr()); if (PyErr_Occurred()) throw_error_already_set(); return result; } }} // namespace boost::python ------------------------------------------------------ void PyService_Volume::Reconfigure( const PyStorageSize & sizeInBytes, const iStor::UserAgent::UAEnums::VolumeCompositionName & compositionName, const boost::python::list & disks, int stripeWidth, const iStor::UserAgent::UAEnums::StripeDepth & stripeDepth) { Py_BEGIN_ALLOW_THREADS . . . if (boost::python::len(disks) > 0) { ... ------------------------------------------------------ John McLaughlin iStor Networks, Inc. From a.schweitzer.grps at gmail.com Wed Apr 28 17:38:14 2010 From: a.schweitzer.grps at gmail.com (Andrew Schweitzer) Date: Wed, 28 Apr 2010 11:38:14 -0400 Subject: [C++-sig] boost graph bgl-python on MAC OS X 10.6.3 Message-ID: Hi, I'm trying to use the bgl-python library which exposes boost's graph library ('bgl') to python. Has anyone built this recently for MAC OS X? I tried versions bgl-python.0.9 and svn-HEAD. I got different errors in both cases. I suspect I'm doing something obvious wrong. Here is what I got from svn-HEAD: ../boost_1_42_0/bjam installwarning: No toolsets are configured. warning: Configuring default toolset "gcc". warning: If the default is wrong, your build may not work correctly. warning: Use the "toolset=xxxxx" option to override our guess. warning: For more configuration options, please consult warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html notice: could not find main target install notice: assuming it is a name of file to create. /Users/schweitz/Documents/misc/boost/boost_1_42_0/tools/build/v2/build/project.jam:740: in attribute warning: rulename $($(project).attributes).get expands to empty string /Users/schweitz/Documents/misc/boost/boost_1_42_0/tools/build/v2/build/project.jam:752: in project.target ... /Users/schweitz/Documents/misc/boost/boost_1_42_0/boost-build.jam:17: in module scope don't know how to make install ...found 1 target... ...can't find 1 target... Any ideas? Thanks Andrew From macieksitarz at wp.pl Thu Apr 29 01:24:47 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Thu, 29 Apr 2010 01:24:47 +0200 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> Message-ID: <4BD8C3BF.70301@wp.pl> On 28.03.2010 11:53, Roman Yakovenko wrote: > On Sun, Mar 28, 2010 at 4:53 AM, Maciej Sitarz > > So that would be a big problem, because that's a C++ API for a library > which >> isn't developed by me. >> Maybe you know how the pyogre developers handled this situation? The >> tuple.hpp is from theirs repo, but I didn't manage to investigate how did >> they do it. > > I sent the question to PyOgre main developer. When the answer will be > available, I will publish it here. Quite some time has past, thats a pity that there's no response. So if there are such problems with automatic boost::tuples conversion, maybe it's possible to write some converters by hand? For example for this tuple: boost::tuple Let's say just to read the values from the tuple. I've got some functions inserting the values and I just need to read them. Best regards -- Maciek Sitarz From roman.yakovenko at gmail.com Thu Apr 29 07:05:16 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 29 Apr 2010 08:05:16 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BD8C3BF.70301@wp.pl> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> Message-ID: On Thu, Apr 29, 2010 at 2:24 AM, Maciej Sitarz wrote: > On 28.03.2010 11:53, Roman Yakovenko wrote: >> >> On Sun, Mar 28, 2010 at 4:53 AM, Maciej Sitarz ?> >> So that would be a big problem, because that's a C++ API for a library >> which >>> >>> isn't developed by me. >>> Maybe you know how the pyogre developers handled this situation? The >>> tuple.hpp is from theirs repo, but I didn't manage to investigate how did >>> they do it. >> >> I sent the question to PyOgre main developer. When the answer will be >> available, I will publish it here. > > Quite some time has past, thats a pity that there's no response. Agree > So if there are such problems with automatic boost::tuples conversion, maybe > it's possible to write some converters by hand? > > For example for this tuple: > boost::tuple > > Let's say just to read the values from the tuple. I've got some functions > inserting the values and I just need to read them. I did it some time ago: http://language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html . The source code is available under "Download" section. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Thu Apr 29 10:03:33 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Thu, 29 Apr 2010 10:03:33 +0200 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> Message-ID: <4BD93D55.4000800@wp.pl> As I described it before I tried it, but gccxml couldn't parse the tuples.hpp file. I build gccxml from CVS ver. 0.9( 1.134 ) and it parsed the source file successfully. That's a big progress since the last time. But now... there's some problem with pygccxml I think :| I get the following error: $ python generate.py INFO Parsing source file "problem.h" ... INFO gccxml cmd: /usr/bin/gccxml -I"." -I"/home/macieks/error_examples/boost_tuples_to_python2" -I"/usr/include" -I"/usr/include/python2.4" -I"/home/macieks/boost/boost_1_42_0" "problem.h" -fxml="/tmp/tmp80gNLk.xml" INFO GCCXML version - 0.9( 1.134 ) INFO Parsing source file "tuples.hpp" ... INFO gccxml cmd: /usr/bin/gccxml -I"." -I"/home/macieks/error_examples/boost_tuples_to_python2" -I"/usr/include" -I"/usr/include/python2.4" -I"/home/macieks/boost/boost_1_42_0" "tuples.hpp" -fxml="/tmp/tmpkNs2uu.xml" INFO GCCXML version - 0.9( 1.134 ) Traceback (most recent call last): File "generate.py", line 17, in ? indexing_suite_version=2 File "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", line 95, in __init__ File "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", line 138, in __parse_declarations File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", line 217, in read_files File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", line 272, in __parse_file_by_file File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", line 445, in _join_class_hierarchy KeyError: ((u'/home/macieks/boost/boost_1_42_0/boost/type_traits/is_function.hpp', 52), (u'::', u'boost', u'detail', u'is_function_chooser', u'result_')) generate.py and problem.h attached Best regards -- Maciek Sitarz -------------- next part -------------- A non-text attachment was scrubbed... Name: generate.py Type: text/x-python Size: 1197 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: problem.h Type: text/x-chdr Size: 1211 bytes Desc: not available URL: From roman.yakovenko at gmail.com Thu Apr 29 10:19:52 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 29 Apr 2010 11:19:52 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BD93D55.4000800@wp.pl> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> <4BD93D55.4000800@wp.pl> Message-ID: On Thu, Apr 29, 2010 at 11:03 AM, Maciej Sitarz wrote: > As I described it before I tried it, but gccxml couldn't parse the > tuples.hpp file. > > I build gccxml from CVS ver. 0.9( 1.134 ) and it parsed the source file > successfully. That's a big progress since the last time. > But now... there's some problem with pygccxml I think :| This is indeed a huge progress, I will take a look on this error today. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu Apr 29 21:06:36 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 29 Apr 2010 22:06:36 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BD93D55.4000800@wp.pl> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> <4BD93D55.4000800@wp.pl> Message-ID: On Thu, Apr 29, 2010 at 11:03 AM, Maciej Sitarz wrote: > As I described it before I tried it, but gccxml couldn't parse the > tuples.hpp file. > > I build gccxml from CVS ver. 0.9( 1.134 ) and it parsed the source file > successfully. That's a big progress since the last time. > But now... there's some problem with pygccxml I think :| > > I get the following error: > ... Okey, now I have the ( positive I hope ) answers for you. First of all the error you see. In your case, py++ compiles separately both files and then it tries to merge their declarations tree. Obviously it fails. I will try to find time and fix this bug. The work around is pretty simple: create a helper file, which will include both files and path it to py++. It should resolve this problem. Unfortunately, py++ doesn't support/generate code for boost::tuple, so some additional work from you is needed: 1. You will need 'tuples.hpp' file from http://www.language-binding.net/_downloads/automatic_conversion.zip archive. 2. You will have to place it with the generated files 3. Add "include' and "registration' code to the code generator: mb = module_builder_t( ... ) #do this step for every tuple type you have mb.add_registration_code( 'boost::python::register_tuple< boost::tuple >();' ); mb.build_code_creator( ) mb.code_creator.add_include( 'tuples.hpp' ) And you should be fine. I created a test and verified that the proposed solution actually works. I will try to add "boost::tuple" support to py++ next week. Let me know, if you need more help with this issue. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Thu Apr 29 22:57:09 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Thu, 29 Apr 2010 22:57:09 +0200 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> <4BD93D55.4000800@wp.pl> Message-ID: <4BD9F2A5.60400@wp.pl> On 29.04.2010 21:06, Roman Yakovenko wrote: ... > First of all the error you see. In your case, py++ compiles separately > both files and then it tries to merge their declarations tree. > Obviously it fails. I will try to find time and fix this bug. > > The work around is pretty simple: create a helper file, which will > include both files and path it to py++. It should resolve this > problem. Yes, that helped :) > Unfortunately, py++ doesn't support/generate code for boost::tuple, so > some additional work from you is needed: ... > And you should be fine. All that worked, I was able to create python module. > I created a test and verified that the proposed solution actually > works. I will try to add "boost::tuple" support to py++ next week. boost::tuple automatic support in py++ would be a really nice feature :) > Let me know, if you need more help with this issue. Problem... as always when there's not enough knowledge: I got the warning: WARNING: boost::tuples::null_type [struct] > execution error W1040: The declaration is unexposed, but there are other declarations, which refer to it. This could cause "no to_python converter found" run time error. Declarations: boost::tuples::tuple JobIdWrapper, std::string, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>::tuple(JobIdWrapper::RESULT > const & t0, JobIdWrapper const & t1, std::basic_string,std::allocator > const & t2, boost::tuples::null_type const & t3) [constructor] boost::tuples::tuple std::string, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>::tuple(JobIdWrapper::RESULT const & t0, Compilation went successfully, but I can't import the module. I'm getting an error: python: /home/macieks/boost/boost_1_42_0/libs/python/src/converter/registry.cpp:212: void boost::python::converter::registry::insert(PyObject* (*)(const void*), boost::python::type_info, const PyTypeObject* (*)()): Assertion `slot->m_to_python == 0' failed. Aborted To fix the warning I included boost::python::null_type: mb.class_( 'null_type' ).include() the warning disapeared but the module still couldn't be loaded. Best regards -- Maciek Sitarz -------------- next part -------------- A non-text attachment was scrubbed... Name: all.h Type: text/x-chdr Size: 101 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: generate.py Type: text/x-python Size: 1588 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: problem.h Type: text/x-chdr Size: 1237 bytes Desc: not available URL: From roman.yakovenko at gmail.com Fri Apr 30 07:48:18 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 30 Apr 2010 08:48:18 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BD9F2A5.60400@wp.pl> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> <4BD93D55.4000800@wp.pl> <4BD9F2A5.60400@wp.pl> Message-ID: On Thu, Apr 29, 2010 at 11:57 PM, Maciej Sitarz wrote: > Problem... as always when there's not enough knowledge: > > I got the warning: > > WARNING: boost::tuples::null_type [struct] You don't need to expose boost.tuple. This is why you define custom converter. > Compilation went successfully, but I can't import the module. I'm getting an > error: > > python: > /home/macieks/boost/boost_1_42_0/libs/python/src/converter/registry.cpp:212: > void boost::python::converter::registry::insert(PyObject* (*)(const void*), > boost::python::type_info, const PyTypeObject* (*)()): Assertion > `slot->m_to_python == 0' failed. > Aborted This is a first time I see such error. Try to comment out pieces of the generated code to find out what cause it. > To fix the warning I included boost::python::null_type: > mb.class_( 'null_type' ).include() > > the warning disapeared but the module still couldn't be loaded. I attach the generated code from my test, which is based on your files, so you can study it. It works fine for me ( Ubuntu 10.04, gcc 4.4.3 and I think Boost SVN ). HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- A non-text attachment was scrubbed... Name: map_with_tuple.cpp Type: text/x-c++src Size: 3751 bytes Desc: not available URL: From macieksitarz at wp.pl Fri Apr 30 10:46:09 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Fri, 30 Apr 2010 10:46:09 +0200 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> <4BD8C3BF.70301@wp.pl> <4BD93D55.4000800@wp.pl> <4BD9F2A5.60400@wp.pl> Message-ID: <4BDA98D1.6010405@wp.pl> On 30.04.2010 07:48, Roman Yakovenko wrote: > On Thu, Apr 29, 2010 at 11:57 PM, Maciej Sitarz wrote: >> Problem... as always when there's not enough knowledge: >> >> I got the warning: >> >> WARNING: boost::tuples::null_type [struct] > > You don't need to expose boost.tuple. This is why you define custom converter. > >> Compilation went successfully, but I can't import the module. I'm getting an >> error: >> >> python: >> /home/macieks/boost/boost_1_42_0/libs/python/src/converter/registry.cpp:212: >> void boost::python::converter::registry::insert(PyObject* (*)(const void*), >> boost::python::type_info, const PyTypeObject* (*)()): Assertion >> `slot->m_to_python == 0' failed. >> Aborted > > This is a first time I see such error. Try to comment out pieces of > the generated code to find out what cause it. that was because I included the boost::tuple to be exposed. Now it's ok. I'll now try to include this solution into my production code :) I'm looking for forward too test the automatic boost::tuple support in py++. Great thanks for quick and comprehensive help Roman. Best regards -- Maciek Sitarz