From lists at nabble.com Wed Jan 4 01:02:19 2006 From: lists at nabble.com (EXTEIDE (sent by Nabble.com)) Date: Tue, 3 Jan 2006 16:02:19 -0800 (PST) Subject: [C++-sig] The New Extension IDE - EXTEIDE Message-ID: <2193915.post@talk.nabble.com> EXTEIDE is freeware. Anyone can download now. Please visit http://www.exteide.com Thanks. -- Sent from the Python - c++-sig forum at Nabble.com: http://www.nabble.com/The-New-Extension-IDE---EXTEIDE-t846323.html#a2193915 -------------- next part -------------- An HTML attachment was scrubbed... URL: From reddy at pixar.com Wed Jan 4 00:14:27 2006 From: reddy at pixar.com (Martin Reddy) Date: Tue, 3 Jan 2006 15:14:27 -0800 (PST) Subject: [C++-sig] Using python doc tools on boost-generated functions Message-ID: Hey there, We are using boost.python to create Python bindings to C++ code. We'd like to produce automatic Python API docs using a tool like epydoc or pydoc. However, we've been running into a number of problems, such as epydoc not picking up any free functions that are generated by boost.python. Checking the C++-sig archives, I found a message from Sep 2004 saying that boost.python functions are not generated with the same set of attributes on them as built-in python functions, and the doc tools like epydoc rely on those attributes. http://mail.python.org/pipermail/c++-sig/2004-September/008137.html It looks like this is still an issue today. I'm just wondering if anyone has come up with any workarounds for using tools like epydoc or pydoc with boost.python functions, or what would be involved to fix this in boost.python? Cheers, Martin. --------------------------------------------------------------------------- Martin Reddy Pixar Animation Studios 1200 Park Avenue reddy at pixar.com Emeryville, CA 94608 http://MartinReddy.net/ Tel. (510) 752 4093 From ndbecker2 at gmail.com Wed Jan 4 02:37:19 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 03 Jan 2006 20:37:19 -0500 Subject: [C++-sig] Using python doc tools on boost-generated functions References: Message-ID: Martin Reddy wrote: > > Hey there, > > We are using boost.python to create Python bindings to C++ code. We'd like > to produce automatic Python API docs using a tool like epydoc or pydoc. > However, we've been running into a number of problems, such as epydoc not > picking up any free functions that are generated by boost.python. > > Checking the C++-sig archives, I found a message from Sep 2004 saying that > boost.python functions are not generated with the same set of attributes > on them as built-in python functions, and the doc tools like epydoc rely > on those attributes. > > http://mail.python.org/pipermail/c++-sig/2004-September/008137.html > > It looks like this is still an issue today. I'm just wondering if anyone > has come up with any workarounds for using tools like epydoc or pydoc with > boost.python functions, or what would be involved to fix this in > boost.python? > > Cheers, > I did explore a few approaches. Probably the simplest is something like this: This is an excerpt from some of my code: scope().attr("__doc__") = "Module for Block Interleavers\n"; class_ > ("block_interleaver", "Block Interleaver", init((arg ("size"), arg ("rows"), arg ("cols")), "__init__(size,rows,cols)\n" "Construct a Block Interleaver.\n" "Only full arrays are supported.\n" "@param size: array size\n" "@type size: int\n" "@param rows: rows\n" "@type rows: int\n" "@param cols: cols\n" "@type cols: int\n" ) ) .def ("v", &BlockInterleaver::GetV) .def ("vinv", &BlockInterleaver::GetVinv) // .def_readonly ("v", &BlockInterleaver::v) // .def_readonly ("vinv", &BlockInterleaver::vinv) ; def ("interleave", &interleave_block, ublas::vector >, "interleave(inter,x)\n" "Interleave input I{x} using interleaver I{inter}" "@param inter: stuff\n" ); Then running PYTHONPATH=./ epydoc seems to work OK. From Mathieu.Lacage at sophia.inria.fr Wed Jan 4 09:34:14 2006 From: Mathieu.Lacage at sophia.inria.fr (Mathieu Lacage) Date: Wed, 04 Jan 2006 09:34:14 +0100 Subject: [C++-sig] binding a userspace thread library Message-ID: <1136363654.6155.64.camel@chronos> hi, I am trying to bind a c/c++ userspace thread library. My test python code: class MyThread(yans.Thread): def run(self): print "before sleep"; sleep_s (1.0); print "after sleep"; MyThread ("test"); simulator.run () simulator.destroy (); The class Thread, and the simulator package are implemented as c++ code. Thread is a wrapper around the yans::Thread C++ class: class Thread { public: Thread (char const *name); virtual ~Thread (); void yield (void); void sleep_s (double delta); void sleep_us (uint64_t delta); double time_s (void); private: virtual void run (void) = 0; Fiber *m_fiber; Semaphore *m_sleep_sem; }; The wrapping code looks like this: struct ThreadWrap : Thread { ThreadWrap (PyObject *self, char const *name) : Thread (name), m_self (self) { Py_INCREF(m_self); } ThreadWrap::~ThreadWrap() { Py_DECREF(m_self); } private: virtual void run (void) { call_method(m_self, "run"); } PyObject *m_self; }; /* specialize has_back_reference for ThreadWrap to make sure a PyObject* is passed to its constructor */ namespace boost { namespace python { template <> struct has_back_reference : mpl::true_ {}; }} void export_thread (void) { class_ thread ("Thread", init ()); thread.def ("yield", &Thread::yield); thread.def ("sleep_s", &Thread::sleep_s); thread.def ("sleep_us", &Thread::sleep_us); thread.def ("time_s", &Thread::time_s); } I get this backtrace when running the sample python code shown above: #0 0xb7fda402 in __kernel_vsyscall () #1 0x008627d5 in raise () from /lib/tls/libc.so.6 #2 0x00864149 in abort () from /lib/tls/libc.so.6 #3 0x00cf31db in __gnu_cxx::__verbose_terminate_handler () from /usr/lib/libstdc++.so.6 #4 0x00cf0ef1 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.6 #5 0x00cf0f26 in std::terminate () from /usr/lib/libstdc++.so.6 #6 0x00cf106f in __cxa_throw () from /usr/lib/libstdc++.so.6 #7 0xb7d0e35a in boost::python::throw_error_already_set () from /usr/lib/libboost_python.so.1 #8 0xb7cfdd82 in boost::python::converter::void_result_from_python () from /usr/lib/libboost_python.so.1 #9 0xb7d3523d in boost::python::converter::return_from_python::operator() (this=0x9361297, x=0x0) at return_from_python.hpp:101 #10 0xb7d35226 in boost::python::call_method (self=0xb7f4c70c, name=0xb7d36ef6 "run") at call_method.hpp:73 #11 0xb7d351f3 in ThreadWrap::run (this=0x935f2f8) at python/export-thread.cc:41 I have to say I did not really expect this to work because I can imagine thousands of reasons why the python interpreter or the boost python bindings would yell at me when having their stack being switched from under them. However, I would be happy to understand why I get this exception being thrown at me by the boost wrapper. As far as I can tell, the backtrace seems to happen from within the python method MyThread.run when Thread.sleep_s is called (which should call yans::Thread::sleep_s). Putting a breakpoint in yans::Thread::sleep_s shows that it is never called. Suggestions about a way to debug this ? Mathieu -- From Mathieu.Lacage at sophia.inria.fr Wed Jan 4 11:30:16 2006 From: Mathieu.Lacage at sophia.inria.fr (Mathieu Lacage) Date: Wed, 04 Jan 2006 11:30:16 +0100 Subject: [C++-sig] binding a userspace thread library In-Reply-To: <1136363654.6155.64.camel@chronos> References: <1136363654.6155.64.camel@chronos> Message-ID: <1136370616.6155.73.camel@chronos> On Wed, 2006-01-04 at 09:34 +0100, Mathieu Lacage wrote: > class MyThread(yans.Thread): > def run(self): > print "before sleep"; > sleep_s (1.0); > print "after sleep"; > MyThread ("test"); > simulator.run () > simulator.destroy (); [snip] > Suggestions about a way to debug this ? After quite a bit of debugging (I learned quite a few things about Boost.Python and the python c interface), it appears that the error here is that the python script does not qualify the calls to sleep_s with self. That is, the following script works flawlessly: class MyThread(yans.Thread): def run(self): print "before sleep"; self.sleep_s (1.0); print "after sleep %f" % self.time_s (); thread = MyThread ("test"); simulator.run () simulator.destroy (); I have to say that the python interpreter gives a better error message only when run under the debugger. i.e.: [mathieu at mathieu yans-current]$ python -m pdb ./bin/python/test-thread.py > /home/mathieu/code/yans-current/bin/python/test-thread.py(3)?() -> import yans; (Pdb) n > /home/mathieu/code/yans-current/bin/python/test-thread.py(4)?() -> from yans import *; (Pdb) > /home/mathieu/code/yans-current/bin/python/test-thread.py(6)?() -> class MyThread(yans.Thread): (Pdb) > /home/mathieu/code/yans-current/bin/python/test-thread.py(16)?() -> thread = MyThread ("test"); (Pdb) b MyThread.run Breakpoint 1 at /home/mathieu/code/yans-current/bin/python/test-thread.py:8 (Pdb) c SCHED leave main enter "test" active > /home/mathieu/code/yans-current/bin/python/test-thread.py(9)run() -> print "before sleep"; (Pdb) n before sleep > /home/mathieu/code/yans-current/bin/python/test-thread.py(12)run() -> print "after sleep %f" % time_s (); (Pdb) NameError: "global name 'time_s' is not defined" > /home/mathieu/code/yans-current/bin/python/test-thread.py(12)run() -> print "after sleep %f" % time_s (); (Pdb) The lack of a better error message by default for such a mistake is... annoying... Is there a way to improve this ? Mathieu -- From W.d.Jonge at cebra.tue.nl Wed Jan 4 12:34:11 2006 From: W.d.Jonge at cebra.tue.nl (Jonge, W. de (Cebra)) Date: Wed, 4 Jan 2006 12:34:11 +0100 Subject: [C++-sig] return reference to same python object Message-ID: Hi, I have interfaced a C++ class to Python, and have a function to get to existing C++ objects. However every time a retrieval for a C++ object is done a new Python wrapper object is constructed and I need this to be a reference to the same python object so I can add attributes in Python that will still exist when a new retrieval for the object is done. I have something like this in C++: typedef boost::shared_ptr ClientPtr; class VT_Client : public boost::enable_shared_from_this { ... } ClientPtr getClient(const std::string& username); def("getClient", getClient); When I now retrieve an object in Python, and assign an extra attribute: a = getClient("joe"); a.some_attribute = 1 I will lose the python object and attribute when a goes out of scope. What I need is that the underlying python object stays alive and that that is returned next time instead of a new one. So later on in my script I want to be able to do: b = getClient("joe") print b.some_attribute # should work here, but doesn't as explained above How can I make this work? Any help is greatly appreciated. Thanks, Willem From beyer at fli-leibniz.de Wed Jan 4 14:30:21 2006 From: beyer at fli-leibniz.de (Andreas Beyer) Date: Wed, 04 Jan 2006 14:30:21 +0100 Subject: [C++-sig] return reference to same python object In-Reply-To: References: Message-ID: <43BBCDED.80109@fli-leibniz.de> You may want to take a look at these threads: http://mail.python.org/pipermail/c++-sig/2003-August/005173.html http://mail.python.org/pipermail/c++-sig/2005-April/008805.html Note that they deal with two different problems, but I think it is a good idea to know both of them. Which of the solutions works depends on who (C++ code or Python code?) is constructing the VT_Client instances. Andreas Jonge, W. de (Cebra) wrote: >Hi, > >I have interfaced a C++ class to Python, and have a function to get to >existing C++ objects. However every time a retrieval for a C++ object is >done a new Python wrapper object is constructed and I need this to be a >reference to the same python object so I can add attributes in Python >that will still exist when a new retrieval for the object is done. > >I have something like this in C++: > >typedef boost::shared_ptr ClientPtr; > >class VT_Client : public boost::enable_shared_from_this >{ >... >} > >ClientPtr getClient(const std::string& username); > >def("getClient", getClient); > > >When I now retrieve an object in Python, and assign an extra attribute: > >a = getClient("joe"); >a.some_attribute = 1 > >I will lose the python object and attribute when a goes out of scope. >What I need is that the underlying python object stays alive and that >that is returned next time instead of a new one. So later on in my >script I want to be able to do: > >b = getClient("joe") >print b.some_attribute # should work here, but doesn't as explained >above > >How can I make this work? > >Any help is greatly appreciated. > > From seefeld at sympatico.ca Wed Jan 4 15:06:41 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 04 Jan 2006 09:06:41 -0500 Subject: [C++-sig] binding a userspace thread library In-Reply-To: <1136370616.6155.73.camel@chronos> References: <1136363654.6155.64.camel@chronos> <1136370616.6155.73.camel@chronos> Message-ID: <43BBD671.6000604@sympatico.ca> Mathieu Lacage wrote: > On Wed, 2006-01-04 at 09:34 +0100, Mathieu Lacage wrote: > >>class MyThread(yans.Thread): >> def run(self): >> print "before sleep"; >> sleep_s (1.0); >> print "after sleep"; >>MyThread ("test"); >>simulator.run () >>simulator.destroy (); [ no need for all those ';' here, by the way ] > After quite a bit of debugging (I learned quite a few things about > Boost.Python and the python c interface), it appears that the error here > is that the python script does not qualify the calls to sleep_s with > self. Indeed, though that is neither related to Boost.Python nor the C interface, it's simply the way Python works. > I have to say that the python interpreter gives a better error message > only when run under the debugger. i.e.: You didn't actually print the error message you get in the original (i.e. non-pdb) session, only the stack trace. > The lack of a better error message by default for such a mistake is... > annoying... Is there a way to improve this ? The error itself is generated by the python runtime. Boost.Python then only throws an 'error_already_set' exception to properly unwind the stack inside the C++ layer in between the two python layers, but that should be fully transparent (well, beside the stack trace, of course). The problem, IIUC, is that you don't catch 'error_already_set' exceptions inside the worker thread, and so the C++ runtime aborts with the unexpected handler. When running inside bdp that won't happen because the debugger will catch the python exception before it leaves the inner python layer. So: if you prepare your thread's private 'run' method to catch errors (by terminating the thread properly, probably), you will get much nicer error messages. HTH, Stefan From W.d.Jonge at cebra.tue.nl Wed Jan 4 15:10:33 2006 From: W.d.Jonge at cebra.tue.nl (Jonge, W. de (Cebra)) Date: Wed, 4 Jan 2006 15:10:33 +0100 Subject: [C++-sig] return reference to same python object Message-ID: Hi Andreas, Thanks for the reply, as my objects are created in C++ space I think the latter thread applies (http://mail.python.org/pipermail/c++-sig/2005-April/008805.html). Did you ever got something working, and if so how? With or without using the to_python_converter, this sounds as a good solution to me and I would also think to use a global map mapping C++ pointers to already existing python wrappers. Thanks, Willem > -----Original Message----- > From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On > Behalf Of Andreas Beyer > Sent: Wednesday, January 04, 2006 2:30 PM > To: Development of Python/C++ integration > Subject: Re: [C++-sig] return reference to same python object > > You may want to take a look at these threads: > http://mail.python.org/pipermail/c++-sig/2003-August/005173.html > http://mail.python.org/pipermail/c++-sig/2005-April/008805.html > > Note that they deal with two different problems, but I think it is a > good idea to know both of them. Which of the solutions works depends on > who (C++ code or Python code?) is constructing the VT_Client instances. > > Andreas > > Jonge, W. de (Cebra) wrote: > > >Hi, > > > >I have interfaced a C++ class to Python, and have a function to get to > >existing C++ objects. However every time a retrieval for a C++ object is > >done a new Python wrapper object is constructed and I need this to be a > >reference to the same python object so I can add attributes in Python > >that will still exist when a new retrieval for the object is done. > > > >I have something like this in C++: > > > >typedef boost::shared_ptr ClientPtr; > > > >class VT_Client : public boost::enable_shared_from_this > >{ > >... > >} > > > >ClientPtr getClient(const std::string& username); > > > >def("getClient", getClient); > > > > > >When I now retrieve an object in Python, and assign an extra attribute: > > > >a = getClient("joe"); > >a.some_attribute = 1 > > > >I will lose the python object and attribute when a goes out of scope. > >What I need is that the underlying python object stays alive and that > >that is returned next time instead of a new one. So later on in my > >script I want to be able to do: > > > >b = getClient("joe") > >print b.some_attribute # should work here, but doesn't as explained > >above > > > >How can I make this work? > > > >Any help is greatly appreciated. > > > > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From rwgk at yahoo.com Wed Jan 4 15:43:38 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 4 Jan 2006 06:43:38 -0800 (PST) Subject: [C++-sig] Using python doc tools on boost-generated functions In-Reply-To: Message-ID: <20060104144338.65057.qmail@web31507.mail.mud.yahoo.com> --- Martin Reddy wrote: > We are using boost.python to create Python bindings to C++ code. We'd like to > > produce automatic Python API docs using a tool like epydoc or pydoc. However, > we've been running into a number of problems, such as epydoc not picking up > any free functions that are generated by boost.python. > > Checking the C++-sig archives, I found a message from Sep 2004 saying that > boost.python functions are not generated with the same set of attributes on > them as built-in python functions, and the doc tools like epydoc rely on > those attributes. > > http://mail.python.org/pipermail/c++-sig/2004-September/008137.html > > It looks like this is still an issue today. I'm just wondering if anyone has > come up with any workarounds for using tools like epydoc or pydoc with > boost.python functions, or what would be involved to fix this in > boost.python? This must have been addressed since it works for me. Ever since last summer I am dragging a local patch around with me which automatically adds the C++ signatures to the doc strings. E.g. for a function (to prove it works): Help on built-in function min in scitbx.array_family.flex: scitbx.array_family.flex.min = min(...) C++ signatures: min(scitbx::af::versa > >) -> d min(scitbx::af::versa > >) -> f min(scitbx::af::versa > >) -> l min(scitbx::af::versa > >) -> i min(scitbx::af::versa > >) -> m Or for a class: Help on class histogram in scitbx.array_family.flex: scitbx.array_family.flex.histogram = class histogram(Boost.Python.instance) | Method resolution order: | histogram | Boost.Python.instance | __builtin__.object | | Methods defined here: | | __init__(...) | C++ signatures: | __init__(_object*, scitbx::histogram other, scitbx::af::co nst_ref data) -> v | __init__(_object*, scitbx::histogram other, scitbx::af::co nst_ref data, d relative_tolerance=0.0001) -> v | __init__(_object*, scitbx::af::const_ref data) -> v | __init__(_object*, scitbx::af::const_ref data, m n_slots=1000) -> v | This is output from gcc 3.4 compiled code which has some bug in the name demangler. With other compilers the output contains full type names (e.g. "bool" instead of just "b"). You have to update just two files in the boost tree to get the doc signatures feature: wget http://cci.lbl.gov/~rwgk/boost_python/doc_signatures/function.hpp_2006_01_04_0620 wget http://cci.lbl.gov/~rwgk/boost_python/doc_signatures/function.cpp_2006_01_04_0620 Copy these files to boost/boost/python/object/function.hpp boost/libs/python/src/object/function.cpp The modified files are based on the current CVS. There are older files from last summer in the same web directory (omit the file names from the URL). They probably work with the latest boost release. In the worst case, take the diffs from the same web directory and use the patch command to backport to your boost version. Sorry I never found the time to check the changes in. Unfortunately my changes break some unit tests and it takes more time than I can affort right now to adjust them. Cheers, Ralf __________________________________________ Yahoo! DSL ? Something to write home about. Just $16.99/mo. or less. dsl.yahoo.com From beyer at fli-leibniz.de Wed Jan 4 16:28:54 2006 From: beyer at fli-leibniz.de (Andreas Beyer) Date: Wed, 04 Jan 2006 16:28:54 +0100 Subject: [C++-sig] return reference to same python object In-Reply-To: References: Message-ID: <43BBE9B6.60105@fli-leibniz.de> Jonge, W. de (Cebra) wrote: >Hi Andreas, > >Thanks for the reply, as my objects are created in C++ space I think the >latter thread applies >(http://mail.python.org/pipermail/c++-sig/2005-April/008805.html). >Did you ever got something working, and if so how? > If you exactly follow David's suggestions it works. The example that I gave works with David's solution. >With or without using >the to_python_converter, this sounds as a good solution to me and I >would also think to use a global map mapping C++ pointers to already >existing python wrappers. > > I recommend *not* to create a map for C++ pointers. You are doubbling information that BP already has. You also don't gain a lot. In order to use the map, you will have to check if a certain smart pointer is already registered in the map before you return it to python. (You will do this in some kind of thin-wrapper function.) At the same point in your code you could also just call hold_python() - it does the job for you. The problem here: you have to create a wrapper for all functions returning the smart pointers. I never created a to_python_converter (don't know how to do that). However, you may not need it anyway. My workaround is: call hold_python() immediately after creating an object. Afterwards BP 'knows' the respective smart pointer. There is no need to call hold_python() at any other location in your code. The drawback: I couldn't find a way (in my code) that is not intrusive into the originial C++ code. What I am doing now is something like this: A_ptr my_factory_method() { // this is my original factory method, which I had to modify A_ptr * a = create_new_A(); #ifdef BP_WRAPPING hold_python(a); // register new smart pointer at boost.python #endif return a; } Of course you have to define BP_WRAPPING and hold_python() somewhere. I am sure there are better solutions. Yet, I don't know them. Andreas From Mathieu.Lacage at sophia.inria.fr Wed Jan 4 17:03:29 2006 From: Mathieu.Lacage at sophia.inria.fr (Mathieu Lacage) Date: Wed, 04 Jan 2006 17:03:29 +0100 Subject: [C++-sig] binding a userspace thread library In-Reply-To: <43BBD671.6000604@sympatico.ca> References: <1136363654.6155.64.camel@chronos> <1136370616.6155.73.camel@chronos> <43BBD671.6000604@sympatico.ca> Message-ID: <1136390609.6155.93.camel@chronos> On Wed, 2006-01-04 at 09:06 -0500, Stefan Seefeld wrote: > Mathieu Lacage wrote: > > On Wed, 2006-01-04 at 09:34 +0100, Mathieu Lacage wrote: > > > >>class MyThread(yans.Thread): > >> def run(self): > >> print "before sleep"; > >> sleep_s (1.0); > >> print "after sleep"; > >>MyThread ("test"); > >>simulator.run () > >>simulator.destroy (); > > [ no need for all those ';' here, by the way ] Yes, I am quite new to python so it is hard to resist the perl/sh compulsion to add ; everywhere. [snip] > You didn't actually print the error message you get in the original > (i.e. non-pdb) session, only the stack trace. Yes. There is no error message printed at all: it seems the error is printed by the interpreter's outer loop and the c++ runtime aborted before giving the interpreter a chance to run. [snip] > So: if you prepare your thread's private 'run' method to catch > errors (by terminating the thread properly, probably), you will > get much nicer error messages. I see. I now terminate the c++ thread properly (that is, I catch and ignore the exception) and I now get this: [mlacage at chronos yans-current]$ ./bin/python/test-thread.py before sleep Exception exceptions.NameError: "global name 'time_s' is not defined" in 'garbage collection' ignored Fatal Python error: unexpected exception during garbage collection Aborted [mlacage at chronos yans-current]$ This error message does not look quite right: it looks like a collision of two error messages. Am I wrong ? I suspect this might be related to the fact that I am not forwarding properly the c++ exception from my thread to the interpreter's thread. I tried calling a python method with the same problem from a c++ function called from the c++ interpreter and I got the following message instead: Traceback (most recent call last): File "./bin/python/test-simulator.py", line 34, in ? simulator.run () File "./bin/python/test-simulator.py", line 7, in notify print "my event class now=%f" % now_s (); NameError: global name 'now_s' is not defined I suspect that the c++ exception I ignore is interpreted correctly by the boost bindings which re-generate the correct python error. Or maybe not. I don't know. I guess I will have to see whether or not I can try to forward exceptions from one thread to another. Or maybe try to deal with the c++ exception by generating the correct python error myself... thanks for your suggestions, Mathieu -- From seefeld at sympatico.ca Wed Jan 4 17:20:18 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 04 Jan 2006 11:20:18 -0500 Subject: [C++-sig] binding a userspace thread library In-Reply-To: <1136390609.6155.93.camel@chronos> References: <1136363654.6155.64.camel@chronos> <1136370616.6155.73.camel@chronos> <43BBD671.6000604@sympatico.ca> <1136390609.6155.93.camel@chronos> Message-ID: <43BBF5C2.7090109@sympatico.ca> Mathieu Lacage wrote: >>So: if you prepare your thread's private 'run' method to catch >>errors (by terminating the thread properly, probably), you will >>get much nicer error messages. > > > I see. I now terminate the c++ thread properly (that is, I catch and > ignore the exception) and I now get this: > > [mlacage at chronos yans-current]$ ./bin/python/test-thread.py > before sleep > Exception exceptions.NameError: "global name 'time_s' is not defined" in 'garbage collection' ignored > Fatal Python error: unexpected exception during garbage collection > Aborted > [mlacage at chronos yans-current]$ > > This error message does not look quite right: it looks like a collision > of two error messages. Am I wrong ? To me it looks plausible: The worker thread writes 'before sleep' and then stops. The error you are seeing then seems to be coming from the cleanup at the end of your script, i.e. it appears to be an entirely different issue. > I suspect this might be related to > the fact that I am not forwarding properly the c++ exception from my > thread to the interpreter's thread. I tried calling a python method with > the same problem from a c++ function called from the c++ interpreter and > I got the following message instead: > > Traceback (most recent call last): > File "./bin/python/test-simulator.py", line 34, in ? > simulator.run () > File "./bin/python/test-simulator.py", line 7, in notify > print "my event class now=%f" % now_s (); > NameError: global name 'now_s' is not defined > > I suspect that the c++ exception I ignore is interpreted correctly by > the boost bindings which re-generate the correct python error. Or maybe > not. I'm not sure. Are you saying that the 'now_s()' call should actually succeed ? May be you are right, and you need to clear the error flag first before terminating the worker thread. Try calling 'PyErr_Clear()' in your exception handler in the worker thread. (see http://docs.python.org/api/exceptions.html) Regards, Stefan From michael.drumheller at boeing.com Wed Jan 4 19:55:53 2006 From: michael.drumheller at boeing.com (Drumheller, Michael) Date: Wed, 4 Jan 2006 10:55:53 -0800 Subject: [C++-sig] Pyste with MPL (well, Boost.Serialize, actually...) Message-ID: <716621DCB4468F46BBCC1BCFBED45C120129DA86@XCH-NW-2V2.nw.nos.boeing.com> I am having trouble running Pyste version 0.9.30 (gccxml version 0.6.0) with Boost MPL 1.32 on Windows XP. A complete (and trivial) example that demonstrates the problem is included below The problem has to do with the #ifdef's based on _MSC_VER that appear in files such as or.hpp, and.hpp, etc. It seems that _MSC_VER *is* defined, but does anyone know why that should be? After all, it is GCCXML that is being run, not the VC7 compiler. I found this page which is probably address similar problems, but has no fixes that I can discern. <> Note: This actually came up because I was trying to run Pyste on a file that contained classes that use Boost.Serialization to serialize themselvs, and Boost.Serialization uses MPL a lot. I noticed that the first signs of problems stem from the MPL headers, as in my example below, and I am _hoping_ that once I fix this Boost.Serialization will just work. Has anyone else had success running Pyste on Boost.Serialize'd classes? Thank you. Michael Drumheller Example: -------------------------MplTest.pyste------------------------- Class("MplTest", "MplTest.h") -------------------------MplTest.h------------------------------- #include class MplTest {}; -------------------------pyste command and output----------------------- mpltest.deleteme=> c:/Python24/python.exe c:/Python24/Lib/site-packages/Pyste/pyste.py -Ic:/Boost/include/boost-1_32 MplTest.pyste In file included from MplTest.h:1: c:/Boost/include/boost-1_32/boost/mpl/or.hpp:33:13: operator "defined" requires an identifier c:/Boost/include/boost-1_32/boost/mpl/or.hpp:33:13: ("or" is an alternative token for "||" in C++) c:/Boost/include/boost-1_32/boost/mpl/or.hpp:33:15: missing '(' in expression c:/Boost/include/boost-1_32/boost/mpl/or.hpp:44:13: operator "defined" requires an identifier c:/Boost/include/boost-1_32/boost/mpl/or.hpp:44:13: ("or" is an alternative token for "||" in C++) c:/Boost/include/boost-1_32/boost/mpl/or.hpp:44:15: missing '(' in expression Traceback (most recent call last): File "c:/Python24/Lib/site-packages/Pyste/pyste.py", line 424, in ? main() File "c:/Python24/Lib/site-packages/Pyste/pyste.py", line 418, in main status = Begin() File "c:/Python24/Lib/site-packages/Pyste/pyste.py", line 257, in Begin return GenerateCode(parser, module, out, interfaces, multiple) File "c:/Python24/Lib/site-packages/Pyste/pyste.py", line 376, in GenerateCode declarations, parsed_header = parser.Parse(header, interface, tail) File "c:\Python24\Lib\site-packages\Pyste\CppParser.py", line 165, in Parse declarations = self.ParseWithGCCXML(header, tail) File "c:\Python24\Lib\site-packages\Pyste\CppParser.py", line 126, in ParseWithGCCXML raise CppParserError, 'Error executing gccxml' CppParser.CppParserError: Error executing gccxml mpltest.deleteme=> From dave at boost-consulting.com Thu Jan 5 02:37:44 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Jan 2006 15:37:44 -1000 Subject: [C++-sig] Pyste with MPL (well, Boost.Serialize, actually...) References: <716621DCB4468F46BBCC1BCFBED45C120129DA86@XCH-NW-2V2.nw.nos.boeing.com> Message-ID: "Drumheller, Michael" writes: > The problem has to do with the #ifdef's based on _MSC_VER that appear in > files such as or.hpp, and.hpp, etc. It seems that _MSC_VER *is* > defined, but does anyone know why that should be? After all, it is > GCCXML that is being run, not the VC7 compiler. I found this page > which is probably address similar problems, but has no fixes that I can > discern. > <> I don't think that's related. GCC_XML seems to be running in a VC compatibility mode. This seems to be a GCC_XML problem; I suggest you ask on its mailing list. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Jan 5 02:49:25 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 04 Jan 2006 15:49:25 -1000 Subject: [C++-sig] Cycles won't be deleted References: <1464.192.168.0.2.1135029664.squirrel@www.glumol.com> Message-ID: bob at glumol.com writes: > Hello, > > I'm sorry if this question has already been asked but I didn't find an > answer on the archives. > With the Python code : > > class C: pass > > c1 = C() > c2 = C() > c1.child = c2 > c2.parent = c1 > del c1 > del c2 > import gc > gc.collect() > > gc.collect() will return 2. > Now if C is not a pure Python class but a BPL one, gc.collect() will > return 0 and the 2 objects seem to never be deleted. > I can define 'child' and 'parent' as members of the C++ class (using a > shared_ptr and a weak_ptr, that works) but if an other cycle is defined in > Python, the objects won't be deleted. > > Could someone explain me why such a behavior ? Because there is no way, in general, to traverse all the references to Python objects that may be embedded in (or otherwise owned by) a given C++ object, Boost.Python marks all wrapped C++ objects as "not GC-able." If we didn't do that, you would see objects disappearing too early, which is much worse than a leak. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Mathieu.Lacage at sophia.inria.fr Thu Jan 5 10:05:21 2006 From: Mathieu.Lacage at sophia.inria.fr (Mathieu Lacage) Date: Thu, 05 Jan 2006 10:05:21 +0100 Subject: [C++-sig] binding a userspace thread library In-Reply-To: <43BBF5C2.7090109@sympatico.ca> References: <1136363654.6155.64.camel@chronos> <1136370616.6155.73.camel@chronos> <43BBD671.6000604@sympatico.ca> <1136390609.6155.93.camel@chronos> <43BBF5C2.7090109@sympatico.ca> Message-ID: <1136451921.6155.120.camel@chronos> On Wed, 2006-01-04 at 11:20 -0500, Stefan Seefeld wrote: > > [mlacage at chronos yans-current]$ ./bin/python/test-thread.py > > before sleep > > Exception exceptions.NameError: "global name 'time_s' is not defined" in 'garbage collection' ignored > > Fatal Python error: unexpected exception during garbage collection > > Aborted > > [mlacage at chronos yans-current]$ > > > > This error message does not look quite right: it looks like a collision > > of two error messages. Am I wrong ? > > To me it looks plausible: The worker thread writes 'before sleep' and > then stops. The error you are seeing then seems to be coming from > the cleanup at the end of your script, i.e. it appears to be an entirely > different issue. I fail to see how the call to Simulator.destroy could generate such a warning but you are likely to be right. [snip] > > Traceback (most recent call last): > > File "./bin/python/test-simulator.py", line 34, in ? > > simulator.run () > > File "./bin/python/test-simulator.py", line 7, in notify > > print "my event class now=%f" % now_s (); > > NameError: global name 'now_s' is not defined > > > > I suspect that the c++ exception I ignore is interpreted correctly by > > the boost bindings which re-generate the correct python error. Or maybe > > not. > > I'm not sure. Are you saying that the 'now_s()' call should actually succeed ? no. I am merely concerned by the fact that I do not get the same warning when using a Thread and when not using a Thread. I suspect that, in the case shown here, we have: - python interpreter calls Simulator.run which calls c++ Simulator::Run - c++ Simulator::run calls c++ EventWrap::notify which calls python MyEvent.notify - MyEvent.notify generates python error because now_s is not defined and returns. - c++ EventWrap sees python error, generates c++ exception. - c++ exception propagates to the outer of Simulator::run, that is the boost binding for Simulator::run. - c++ boost binding eats the c++ exception, generates a python error. In the other case I was looking at, I have: - python interpreter calls Simulator.run which calls c++ Simulator::Run - Simulator::Run calls some Event::notify which switches to another c+ + Thread's stack (c++ Thread::run) - c++ ThreadWrap::run calls python Thread.run - python Thread.run generates python error because now_s is not defined and returns. - c++ boost binding code generates c++ exception from python error. - c++ ThreadWrap::run sees exception, eats c++ exception, switches back to main thread - c++ main thread (that is, Simulator::run) keeps on executing until the end of the simulation. - at the end of the simulation, c++ Simulator::run returns to python interpreter which keeps on executing - python interpreter runs Simulator.destroy (), triggers, another errors, and displays the new error's message together with the old error message. So, I decided to work around this by forwarding the boost c++ exception from my c++ thread to the c++ main thread such that the python interpreter can generate the right error message as soon as possible. I ended up doing this: class ThreadWrap { void rethrow_exception (error_already_set &set) { throw set; } virtual void run (void) { try { call_method(m_self, "run"); } catch (error_already_set &set) { Simulator::insert_later (make_event (&ThreadWrap::rethrow_exception, this, set)); } } }; Which as the nice side-effect of now generating the correct error message with a buggy script: [mlacage at chronos yans-current]$ bin/python/test-thread.py before sleep Traceback (most recent call last): File "bin/python/test-thread.py", line 14, in ? simulator.run () File "bin/python/test-thread.py", line 10, in run print "after sleep %f" % time_s (); NameError: global name 'time_s' is not defined [mlacage at chronos yans-current]$ Which is really uber-cool. > May be you are right, and you need to clear the error flag first before > terminating the worker thread. Try calling 'PyErr_Clear()' in your exception > handler in the worker thread. (see http://docs.python.org/api/exceptions.html) Nice. But I don't think I want to do this. thanks for your comments, Mathieu -- From koen_van_herck at yahoo.com Thu Jan 5 13:59:13 2006 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Thu, 5 Jan 2006 13:59:13 +0100 Subject: [C++-sig] Docstring for operators Message-ID: Hello, Is it possible to provide a docstring for operators (in general), or in particalar for the 'str' operator? I currently have: namespace bp = boost::python; bp::class_