From Paul_Kunz at SLAC.Stanford.EDU Wed Jan 1 19:33:53 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Wed, 01 Jan 2003 10:33:53 -0800 Subject: [C++-sig] Problems with exception passing In-Reply-To: References: Message-ID: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> Following the example at http://www.boost.org/libs/python/doc/v2/exception_translator.html I wrote --- void translate ( const std::exception & e ) { PyErr_SetString ( PyExc_RuntimeError, e.what() ); } --- and in my BOOST_PYTHON_MODULE I have --- register_exception_translator < std::exception > ( & translate ); --- The only exceptions my C++ code can throw are derived classes from std::exception and caught by a member function in the BOOST_PYTHON_MODULE like this... --- catch ( const FactoryException & e ) { qApp->unlock (); throw e; } catch ( const DataRepException & e ) { qApp->unlock (); throw e; } --- Now all seems to work fine with GCC 2.95.3 under Red Hat Linux 7.2. In fact, But with GCC 3.2.1 on the same system I get... [pfkeb at Kunz-pbdsl1 testsuite]$ qtest histogram.py >>> h = Display ( 'foo', nt1, 'bar' ) qtest: line 18: 14343 Aborted (core dumped) python -i $1 The gdb traceback shows that the exception was not caught and terminate was called. If I take out translate() and corresponding register function from the MODULE, then compiling with GCC 3.2.1 works OK... [pfkeb at Kunz-pbdsl1 testsuite]$ qtest histogram.py >>> h = Display ( 'foo', nt1, 'bar' ) Traceback (most recent call last): File "", line 1, in ? RuntimeError: No such type: foo could be found in factory >>> h = Display ( 'Histogram', nt1, 'bar' ) Traceback (most recent call last): File "", line 1, in ? RuntimeError: No such label: bar for ntuple column >>> h = Display ( 'Histogram', nt1, 'Age' ) >>> canvas.addDisplay ( h ) >>> So both exceptions were properly caught and error passed to Python with correct error message. Just like with GCC 2.95.3 with translate() and register in the code. If I leave translate out of the code and compile with GCC 2.95.3, then I get the same "Aborted" message as when the translate function is in the code compiled with GCC 3.2.1. This is all confusing, let me summarize... -with GCC 2.95.3, I need the translate function else it core dumps -with GCC 3.2.1, it core dumps with the translate function, works fine without it. Any ideas? From dave at boost-consulting.com Thu Jan 2 14:44:54 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 02 Jan 2003 08:44:54 -0500 Subject: [C++-sig] Re: [boost] Embedded Python Source Code In-Reply-To: <20030102120139.28175.qmail@web40610.mail.yahoo.com> (David Sankel's message of "Thu, 2 Jan 2003 04:01:39 -0800 (PST)") References: <20030102120139.28175.qmail@web40610.mail.yahoo.com> Message-ID: The C++-sig is the best place to ask Boost.Python questions: http://mail.python.org/mailman/listinfo/c++-sig David Sankel writes: > Hello, > > In the CVS-boost there is a new test file called > embedding.cpp that overviews embedding a python > interpreter in c++. This is very nice, but the CVS > version of boost.python doesn't compile for me. What errors are you seeing? What compiler are you using? What platform? > Does the CVS version of boost.python has some added support for this > kind of use? It's supposed to work. > Should I stick to the official release? It depends how much you crave stability ;-) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From n_lelong at hotmail.com Thu Jan 2 15:12:00 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Thu, 2 Jan 2003 15:12:00 +0100 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: Hi, I found out that the BOOST_PYTHON_MODULE macro for win32 always use the __declspec(dllexport) qualifier to declare the module init function. As in my case, I extend an embedded python interpreter (in my EXE) these symbols have no use. I thought that the use of the BOOST_PYTHON_DECL instead of __declspec(dllexport) should do the trick in most cases ; but perhaps this export behaviour should be controled in a separate way for people that would like to use a static BPL to build modules for stand-alone python. What do you think of it ? Thanks, Nicolas. From dirk at gerrits.homeip.net Thu Jan 2 15:36:50 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 15:36:50 +0100 Subject: [C++-sig] [BPL] python::interpreter proposal Message-ID: For the python::interpreter class that has been discussed here earlier I propose the following interface: interpreter::interpreter(int argc, char* argv[]) Initialize the (sub-)interpreter and set it's argument strings. interpreter::interpreter() Initialize the (sub-)interpreter. interpreter::~interpreter() Release the (sub-)interpreter. object interpreter::run(object code_string); Run the Python code in the string extract(code_string) with this (sub-)interpreter and return the result. object interpreter::run_file(char const* filename); Run the Python code in the specified file with this (sub-)interpreter and return the result. This should probably throw an exception if the file can't be opened. And of course these two run_* functions should throw upon a Python exception. Issues: - A sub-interpreter has no sys.argv variable, so the first form of the constructor would fail. Perhaps it is possible to artificially give the sub-interpreter this field? In any case I don't really see the use of giving argv paramaters to any interpreter other than the main interpreter. - The destructor must either fail or leak unless the Py_Finalize 'bug' is solved. I looked at the problem for a bit but I haven't put enough time in it to make the fix yet. As Dave said, the problem is not too hard to solve. However it is kind of tedious. I'll try to take another shot at it soon, but don't let that stop anyone else from making the fix. ;) - Should there be an interface for Py_SetProgramName(char *name)? Other notes: - If Python has already been initialized prior to the construction of the python::interpreter, then the client is apparently using the C API in addition to BPL and Py_Finalize should not be called in the destructor. There has already been some discussion in another thread about this and other destructor/constructor implementation issues. Any comments/improvements/etc. are greatly appreciated. Regards, Dirk Gerrits PS I regret to say that I have not spent any time on improving and expanding the tutorial during the last two weeks. I still mean to add the template Jamfile for embedding and a section about exceptions. Also, I'd like to filter out the Python C API stuff into a short rationale for why one would use BPL in embedding. Then I won't have to worry about explaining the BPL-way *and* the C-API-way of doing everything. From BPettersen at NAREX.com Thu Jan 2 17:08:20 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Thu, 2 Jan 2003 09:08:20 -0700 Subject: [C++-sig] [BPL] python::interpreter proposal Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDFF@admin56.narex.com> > From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] > > For the python::interpreter class that has been discussed > here earlier I propose the following interface: [...] > object interpreter::run(object code_string); > > Run the Python code in the string > extract(code_string) with > this (sub-)interpreter and return the result. Question... how are you going to distinguish calling PyRun_String with Py_eval_input vs. Py_file_input? (the former only takes expressions, the latter doesn't return a result...) -- bjorn From dave at boost-consulting.com Thu Jan 2 17:11:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 02 Jan 2003 11:11:41 -0500 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols In-Reply-To: ("Nicolas Lelong"'s message of "Thu, 2 Jan 2003 15:12:00 +0100") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: "Nicolas Lelong" writes: > Hi, > > I found out that the BOOST_PYTHON_MODULE macro for win32 always use the > __declspec(dllexport) qualifier to declare the module init function. > > As in my case, I extend an embedded python interpreter (in my EXE) these > symbols have no use. > > I thought that the use of the BOOST_PYTHON_DECL instead of > __declspec(dllexport) should do the trick in most cases ; but perhaps this > export behaviour should be controled in a separate way for people that would > like to use a static BPL to build modules for stand-alone python. > > What do you think of it ? > Thanks, Add -DBOOST_PYTHON_STATIC_LIB to your compiler command-line or BOOST_PYTHON_STATIC_LIB to your bjam requirements; that will turn off exporting. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Thu Jan 2 17:49:13 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 17:49:13 +0100 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDFF@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDFF@admin56.narex.com> Message-ID: Bjorn Pettersen wrote: >>From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] >> >>For the python::interpreter class that has been discussed >>here earlier I propose the following interface: > > [...] > >>object interpreter::run(object code_string); >> >>Run the Python code in the string >>extract(code_string) with >>this (sub-)interpreter and return the result. > > > Question... how are you going to distinguish calling PyRun_String with > Py_eval_input vs. Py_file_input? (the former only takes expressions, the > latter doesn't return a result...) It doesn't? I wasn't aware of that. The PyRun_String docs say: "Returns the result of executing the code as a Python object, or NULL if an exception was raised." And the Py_file_input doesn't say anything about the return value of the PyRun_* functions. Dirk Gerrits From dirk at gerrits.homeip.net Thu Jan 2 17:57:50 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 17:57:50 +0100 Subject: [C++-sig] Re: Presenting a Python embedding tutorial for Boost.Python In-Reply-To: <3e10d332.278977528@192.168.1.200> References: <3e10d332.278977528@192.168.1.200> Message-ID: Joerg Sauer wrote: [snip] > As I have to implement this scripting into the app till april I would > like to help and if I can do some serious job on it. So if help is > needed just contact me to get things work. That's greatly appreciated Joerg! You can start by pitching in on the new "[BPL] python::interpreter proposal"-thread I started. :) Dirk Gerrits From dirk at gerrits.homeip.net Thu Jan 2 18:04:45 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 18:04:45 +0100 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: References: Message-ID: Dirk Gerrits wrote: > object interpreter::run(object code_string); > > Run the Python code in the string extract(code_string) with > this (sub-)interpreter and return the result. Perhaps there should be object interpreter::run(char const* code); object interpreter::run(std::string const& code); overloads too, for efficiency? And perhaps even: object interpreter::run(compiled_string const& code); for a class compiled_string which wraps Py_CompileString. Just some brainstorming... Dirk Gerrits From BPettersen at NAREX.com Thu Jan 2 18:16:20 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Thu, 2 Jan 2003 10:16:20 -0700 Subject: [C++-sig] Re: [BPL] python::interpreter proposal Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE05@admin56.narex.com> > From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] > > Bjorn Pettersen wrote: > >>From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] > >> > >>For the python::interpreter class that has been discussed > >>here earlier I propose the following interface: > > > > [...] > > > >>object interpreter::run(object code_string); > >> > >>Run the Python code in the string > >>extract(code_string) with > >>this (sub-)interpreter and return the result. > > > > > > Question... how are you going to distinguish calling PyRun_String with > > Py_eval_input vs. Py_file_input? (the former only takes expressions, > > the latter doesn't return a result...) > > It doesn't? I wasn't aware of that. No, it's undocumented. > The PyRun_String docs say: "Returns the result of executing > the code as a Python object, or NULL if an exception was raised." [...] Try e.g. PyObject* res = PyRun_String("5", Py_file_input, ns, ns); and you'll see that res is pointing to None afterwards... Quite annoying :-) -- bjorn From n_lelong at hotmail.com Thu Jan 2 18:19:54 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Thu, 2 Jan 2003 18:19:54 +0100 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: > > Add -DBOOST_PYTHON_STATIC_LIB to your compiler command-line or > BOOST_PYTHON_STATIC_LIB to your bjam requirements; that will > turn off exporting. > I may make a big mistake but I've defined this symbol and this does not change anything. In fact, when reading 'config.hpp', we can find the only entry of BOOST_PYTHON_STATIC_LIB: #ifdef BOOST_PYTHON_STATIC_LIB # define BOOST_PYTHON_STATIC_LINK # elif !defined(BOOST_PYTHON_DYNAMIC_LIB) # define BOOST_PYTHON_DYNAMIC_LIB #endif This conditions the declaration of the BOOST_PYTHON_DECL symbol to either __declspec(dllexport) or __declspec(dllimport) or _nothing_. I'm OK with that. The 'problem' I have is with BOOST_PYTHON_MODULE_INIT in 'module_init.hpp' that always define (for win32) the init##name function as [cut & paste] : # if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ extern "C" __declspec(dllexport) void init##name() \ [...] I can see no way for BOOST_PYTHON_STATIC_LIB to control the 'init##name' declaration. In fact, I think that this definition could be changed to : # if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ extern "C" BOOST_PYTHON_DECL void init##name() \ [...] But in this case, having BPL as a static lib (with BOOST_PYTHON_STATIC_LIB defined) will prevent from being able to create DLL modules. In my local modifications, I started having a symbol BOOST_PYTHON_EXTEND_EMBEDDED that allowed me to explicitly tune the BPL code for my specific purpose of extending an embedded python (such as disabling all dll exports, mainly) - but maybe i missed something. Any thoughts? Thanks, Nicolas. From dirk at gerrits.homeip.net Thu Jan 2 18:34:06 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 18:34:06 +0100 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE05@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE05@admin56.narex.com> Message-ID: Bjorn Pettersen wrote: >>From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] >> >>Bjorn Pettersen wrote: >> >>>>From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] >>>> >>>>For the python::interpreter class that has been discussed >>>>here earlier I propose the following interface: >>> >>>[...] >>> >>> >>>>object interpreter::run(object code_string); >>>> >>>>Run the Python code in the string >>>>extract(code_string) with >>>>this (sub-)interpreter and return the result. >>> >>> >>>Question... how are you going to distinguish calling PyRun_String > > with > >>>Py_eval_input vs. Py_file_input? (the former only takes expressions, > > >>>the latter doesn't return a result...) >> >>It doesn't? I wasn't aware of that. > > > No, it's undocumented. > > >>The PyRun_String docs say: "Returns the result of executing >>the code as a Python object, or NULL if an exception was raised." > > [...] > > Try e.g. > > PyObject* res = PyRun_String("5", Py_file_input, ns, ns); > > and you'll see that res is pointing to None afterwards... Quite annoying > :-) Hmm that's quite a showstopper. Perhaps a second enum parameter is needed? Something like: enum code_type { single_expression, single_statement, multiple_statements }; Not very nice IMHO so if anyone knows a way around it, please enlighten me. ;) Dirk Gerrits From nicodemus at globalite.com.br Thu Jan 2 20:02:38 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 02 Jan 2003 16:02:38 -0300 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE05@admin56.narex.com> Message-ID: <3E148CCE.50807@globalite.com.br> Dirk Gerrits wrote: > Hmm that's quite a showstopper. Perhaps a second enum parameter is > needed? Something like: > > enum code_type > { single_expression, single_statement, multiple_statements }; > > Not very nice IMHO so if anyone knows a way around it, please > enlighten me. ;) > > Dirk Gerrits > > I think two separate functions would be better. void interpreter::exec( const std::string& code, dict& globals, dict& locals ); - Executes the given code in the context of the two given dictionaries. object interpreter::eval( const std::string& expr, dict& globals, dict& locals ); - Evaluates the Python expression given, in the context of the two dictionaries, and returns the resulting object. They're equivalent to the "exec" statement and to the "eval" builtin function in python. Farewell, Nicodemus. From dirk at gerrits.homeip.net Thu Jan 2 19:27:34 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 02 Jan 2003 19:27:34 +0100 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <3E148CCE.50807@globalite.com.br> References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE05@admin56.narex.com> <3E148CCE.50807@globalite.com.br> Message-ID: Nicodemus wrote: > Dirk Gerrits wrote: > >> Hmm that's quite a showstopper. Perhaps a second enum parameter is >> needed? Something like: >> >> enum code_type >> { single_expression, single_statement, multiple_statements }; >> >> Not very nice IMHO so if anyone knows a way around it, please >> enlighten me. ;) >> >> Dirk Gerrits >> >> > I think two separate functions would be better. > > void interpreter::exec( const std::string& code, dict& globals, dict& > locals ); > - Executes the given code in the context of the two given dictionaries. > > object interpreter::eval( const std::string& expr, dict& globals, dict& > locals ); > - Evaluates the Python expression given, in the context of the two > dictionaries, and returns the resulting object. > > They're equivalent to the "exec" statement and to the "eval" builtin > function in python. I like that. Let's hear what others think about it. Dirk Gerrits From BPettersen at NAREX.com Thu Jan 2 19:56:57 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Thu, 2 Jan 2003 11:56:57 -0700 Subject: [C++-sig] Re: [BPL] python::interpreter proposal Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE0D@admin56.narex.com> > From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] > > Nicodemus wrote: [...] > > I think two separate functions would be better. > > > > void interpreter::exec( const std::string& code, dict& globals, dict& locals ); > > - Executes the given code in the context of the two given dictionaries. > > > > object interpreter::eval( const std::string& expr, dict& globals, dict& locals ); > > - Evaluates the Python expression given, in the context of the two > > dictionaries, and returns the resulting object. > > > > They're equivalent to the "exec" statement and to the "eval" builtin > > function in python. > > I like that. Let's hear what others think about it. That's essentially what I ended up with, although I have the global/local dict be persistent with the interpreter (i.e. you don't pass them in). Making them optional would probably be most convenient/flexible. I ended up making exec return an int so that we could do: int foo(int x) { static int ok = py::exec( "def foo(y):\n" " return y**y\n"); return py::extract(py::fn("foo")(x)); } (i.e. only calling exec once). In addition to exec/eval I also have an "execute block" function that takes a series of statements, executes them, and returns the value of the last statement. It's convenient because we normally want to execute a "script" to get a result and the script normally consists of multiple lines. I implemented that by extracting the last statement, passing everything prior to it to exec, and returning the result of passing the last statement to eval. Of course, extracting the last statement is non-trivial and my implementation is wrong, although it does work for most cases . -- bjorn From sauer at programmatic.de Thu Jan 2 23:16:22 2003 From: sauer at programmatic.de (Joerg Sauer) Date: Thu, 02 Jan 2003 22:16:22 GMT Subject: [C++-sig] Re: [BPL] python::interpreter proposal References: Message-ID: <3e14b687.533782658@192.168.1.200> Hi, up to know we have calling scripts, evaluations and files. What about calling python functions directly and pass it arguments. Maybe I'm wrong, cause I'm new to all this, but I thought I could build my extension modules, some in c++ using BPL and some as Python code. In the Python modules I have declared some functions (in my case script hooks to extend /change the default behaviour of my app). Then I would like to call one of the functions and pass it their params directly. As far as I see I would use one of PyObject_CallObject() PyObject_CallFunction() PyObject_CallMethod() As far as I can see using PyObject_CallObject() would have the advantage to pass the parameters firectly. And with the to_python conversions I could pass my apps c++ objects (wrapper classes). This would have the advantage that the script (function) can manipulate the data directly. Using the proposed PyRun* calls has the disadvantage that I don't get my objects to deal with only indirectly, or did I miss something? Another thing is sync and async execution. For me it would be nice to have the possibility to run a python script in both states. If it is running async I would like to have a) a state function to get execution state (busy, finished) b) registered callback to be triggered when execution is finished. This could be done directly in the interpreter class or detaching a new thread for async execution by myself. So what do you think, better leaf async execution alone or include it as option in the interpreter? Joerg From nicodemus at globalite.com.br Fri Jan 3 01:37:45 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Thu, 02 Jan 2003 21:37:45 -0300 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE0D@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE0D@admin56.narex.com> Message-ID: <3E14DB59.4080106@globalite.com.br> Bjorn Pettersen wrote: >>Nicodemus wrote: >>They're equivalent to the "exec" statement and to the "eval" builtin >>function in python. >> >That's essentially what I ended up with, although I have the >global/local dict be persistent with the interpreter (i.e. you don't >pass them in). Making them optional would probably be most >convenient/flexible. > Agreed. You have working code for this already? >I ended up making exec return an int so that we could do: > > int foo(int x) { > static int ok = py::exec( > "def foo(y):\n" > " return y**y\n"); > return py::extract(py::fn("foo")(x)); > } > >(i.e. only calling exec once). > > You mean exec returning an int to describe success or failure? I would prefer an exception in case of an error, and returning void. > >In addition to exec/eval I also have an "execute block" function that >takes a series of statements, executes them, and returns the value of >the last statement. It's convenient because we normally want to execute >a "script" to get a result and the script normally consists of multiple >lines. I implemented that by extracting the last statement, passing >everything prior to it to exec, and returning the result of passing the >last statement to eval. Of course, extracting the last statement is >non-trivial and my implementation is wrong, although it does work for >most cases . > Sorry, but I didn't quite understand, how the script returns this value? Could you post a simple example of such a script? Just curious. 8) Farewell, Nicodemus. From dave at boost-consulting.com Fri Jan 3 15:51:04 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 09:51:04 -0500 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols In-Reply-To: ("Nicolas Lelong"'s message of "Thu, 2 Jan 2003 18:19:54 +0100") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: "Nicolas Lelong" writes: > The 'problem' I have is with BOOST_PYTHON_MODULE_INIT in 'module_init.hpp' > that always define (for win32) the init##name function as [cut & paste] : > > # if defined(_WIN32) || defined(__CYGWIN__) > # define BOOST_PYTHON_MODULE_INIT(name) \ > void init_module_##name(); \ > extern "C" __declspec(dllexport) void init##name() \ > [...] Aha! Sorry for not understanding this earlier. > I can see no way for BOOST_PYTHON_STATIC_LIB to control the 'init##name' > declaration. > In fact, I think that this definition could be changed to : > > # if defined(_WIN32) || defined(__CYGWIN__) > # define BOOST_PYTHON_MODULE_INIT(name) \ > void init_module_##name(); \ > extern "C" BOOST_PYTHON_DECL void init##name() \ > [...] Yeah, I don't think that's the right fix, because it will make your init##name() function into an IMported function when you link against the Boost.Python DLL. > But in this case, having BPL as a static lib (with > BOOST_PYTHON_STATIC_LIB defined) will prevent from being able to > create DLL modules. In my local modifications, I started having a > symbol BOOST_PYTHON_EXTEND_EMBEDDED that allowed me to explicitly > tune the BPL code for my specific purpose of extending an embedded > python (such as disabling all dll exports, mainly) - but maybe i > missed something. Any thoughts? Wouldn't it be enough to have a symbol which determines whether module init functions are exported or not, in addition to having BOOST_PYTHON_STATIC_LIB? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From n_lelong at hotmail.com Fri Jan 3 18:12:29 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Fri, 3 Jan 2003 18:12:29 +0100 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: Hi, > Yeah, I don't think that's the right fix, because it will make your > init##name() function into an IMported function when you link against > the Boost.Python DLL. Yep, I thought it may have problems like this. > Wouldn't it be enough to have a symbol which determines whether module > init functions are exported or not, in addition to having > BOOST_PYTHON_STATIC_LIB? Sure, that should be enough, but I was wondering if there would exist any other specificities tied to extending an embedded Python. Ican't think of any other - but this could be 'smart' to tie all of them to a single symbol. Moreover, I can't see any other use of not exporting module init functions besides extending an embedded python. From dave at boost-consulting.com Fri Jan 3 18:37:36 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 12:37:36 -0500 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols In-Reply-To: ("Nicolas Lelong"'s message of "Fri, 3 Jan 2003 18:12:29 +0100") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: "Nicolas Lelong" writes: >> Wouldn't it be enough to have a symbol which determines whether module >> init functions are exported or not, in addition to having >> BOOST_PYTHON_STATIC_LIB? > > Sure, that should be enough, but I was wondering if there would > exist any other specificities tied to extending an embedded > Python. Ican't think of any other - but this could be 'smart' to tie > all of them to a single symbol. Moreover, I can't see any other use > of not exporting module init functions besides extending an embedded > python. My problems with BOOST_PYTHON_EXTEND_EMBEDDED are twofold. First, it feels like premature generalization to me. Second, it ties orthogonal concepts together (extending and embedding). Can't you extend an embedded Python by sticking a dynamically-linked extension module in the PYTHONPATH? I also don't want to make this symbol define BOOST_PYTHON_STATIC_LIB, since you could still use an embedded Python with a Boost.Python DLL. It seems to me that BOOST_PYTHON_STATIC_MODULE is the right symbol for controlling what you want. Am I missing something? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From n_lelong at hotmail.com Fri Jan 3 19:17:07 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Fri, 3 Jan 2003 19:17:07 +0100 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: > My problems with BOOST_PYTHON_EXTEND_EMBEDDED are twofold. First, it > feels like premature generalization to me. OK, I think I'll rely on your experience for this point :) > Second, it ties orthogonal concepts together (extending and embedding). Can't you extend an > embedded Python by sticking a dynamically-linked extension module in the PYTHONPATH? That's true, but these modules should not be built in the same 'project' as the one defining the symbol we're after. My point was to mark that the modules defined in the 'project' were designed exclusively to extend the embedded interpreter. > I also don't want to make this symbol define BOOST_PYTHON_STATIC_LIB, since you could still > use an embedded Python with a Boost.Python DLL. I agree, I did not mention it, but I agree that the symbol we need should be well separated from BOOST_PYTHON_STATIC_LIB. > It seems to me that BOOST_PYTHON_STATIC_MODULE is the right symbol for > controlling what you want. Well, I don't feel like having much arguments against it. BOOST_PYTHON_STATIC_MODULE will certainly do the job quite well :) From BPettersen at NAREX.com Fri Jan 3 20:35:05 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Fri, 3 Jan 2003 12:35:05 -0700 Subject: [C++-sig] Re: [BPL] python::interpreter proposal Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6A@admin56.narex.com> > From: Nicodemus [mailto:nicodemus at globalite.com.br] > > Bjorn Pettersen wrote: > > >>Nicodemus wrote: > >>They're equivalent to the "exec" statement and to the > "eval" builtin > >>function in python. > >> > >That's essentially what I ended up with, although I have the > >global/local dict be persistent with the interpreter (i.e. you don't > >pass them in). Making them optional would probably be most > >convenient/flexible. > > Agreed. You have working code for this already? For our needs, certainly . It's really not a lot of code... let me know if you want to have a look... > >I ended up making exec return an int so that we could do: > > > > int foo(int x) { > > static int ok = py::exec( > > "def foo(y):\n" > > " return y**y\n"); > > return py::extract(py::fn("foo")(x)); > > } > > > >(i.e. only calling exec once). > > You mean exec returning an int to describe success or > failure? I would > prefer an exception in case of an error, and returning void. No, the point was being able to declare the int static so py::exec() was only called on the first call to foo() -- and throwing an exception when something bad happens. No use wasting cycles re-executing the function definition every time... If someone has a more graceful suggestion I'm all ears :-) [evalBlock description...] > > Sorry, but I didn't quite understand, how the script returns > this value? > Could you post a simple example of such a script? Just curious. 8) The script would look something like: x = foo(y) x += bar(y) x i.e. the value in x should be returned. We call it as: py::set("y", cppYObject); // assign our c++ object to variable 'y' int result = py::extract(py::block(theCodeAbove)); On a not completely related note , it was mentioned on c.l.py recently that the multiple interpreter functionality isn't implemented enough to be useful, so it might be better to focus on a single interpreter for now... hth, -- bjorn From BPettersen at NAREX.com Fri Jan 3 20:43:29 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Fri, 3 Jan 2003 12:43:29 -0700 Subject: [C++-sig] boost::python::object referencing c++ object Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6B@admin56.narex.com> I've got the following code to assign a wrapped object to a Python variable: template void set(const std::string& name, const T& value) { PyObject* key = PyString_FromString(name.c_str()); object val(value); PyDict_SetItem(interpreter()->mainmodule(), key, val.ptr()); Py_DECREF(key); } and I'd like to be able to set() a variable to a c++ object, then later mutate the object and have the changes visible to Python. I haven't traced through the code completely, but it looks like the object ctor makes a copy(?) Is there any way to accomplish what I'd like to do? -- bjorn From dave at boost-consulting.com Fri Jan 3 21:24:45 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 15:24:45 -0500 Subject: [C++-sig] boost::python::object referencing c++ object In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6B@admin56.narex.com> ("Bjorn Pettersen"'s message of "Fri, 3 Jan 2003 12:43:29 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6B@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: > I've got the following code to assign a wrapped object to a Python > variable: > > template > void set(const std::string& name, const T& value) { > PyObject* key = PyString_FromString(name.c_str()); > object val(value); > PyDict_SetItem(interpreter()->mainmodule(), key, val.ptr()); > Py_DECREF(key); > } Why make life hard for yourself? template void set(const std::string& name, const T& value) { interpreter()->mainmodule()[name] = value; } Of course, this relies on interpeter()->mainmodule() returning an object (or dict, or...) > and I'd like to be able to set() a variable to a c++ object, then later > mutate the object and have the changes visible to Python. I haven't > traced through the code completely, but it looks like the object ctor > makes a copy(?) More precisely, it converts its argument into a Python object. If your C++ object is a wrapped class type, it will be copied. > Is there any way to accomplish what I'd like to do? I'm not sure exactly what you want. Perhaps you'd like the resulting Python object to contain a raw pointer to the argument? In that case, the caveat is that if the lifetime of the C++ object ends before that of the Python object, that pointer will dangle and using the Python object may cause a crash. There is a way to do that, but it's more convoluted than it should be: template T& identity(T& x) { return x; } template object get_object_reference(T& x) { // build a function object around identity object f = make_function( &identity, return_value_policy()); // and call return f(x); } HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Jan 3 21:29:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 15:29:30 -0500 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: (Dirk Gerrits's message of "Thu, 02 Jan 2003 18:04:45 +0100") References: Message-ID: Dirk Gerrits writes: > Dirk Gerrits wrote: > >> object interpreter::run(object code_string); >> Run the Python code in the string extract(code_string) >> with this (sub-)interpreter and return the result. > > Perhaps there should be > > object interpreter::run(char const* code); > object interpreter::run(std::string const& code); > > overloads too, for efficiency? And perhaps even: > > object interpreter::run(compiled_string const& code); > > for a class compiled_string which wraps Py_CompileString. > > Just some brainstorming... This is all premature optimization, IMO. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Jan 3 21:32:37 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 15:32:37 -0500 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <3e14b687.533782658@192.168.1.200> (sauer@programmatic.de's message of "Thu, 02 Jan 2003 22:16:22 GMT") References: <3e14b687.533782658@192.168.1.200> Message-ID: sauer at programmatic.de (Joerg Sauer) writes: > Hi, > up to know we have calling scripts, evaluations and files. > What about calling python functions directly and pass it arguments. That's already covered. Just do it: call_some_function(object f, int arg1, object arg2) { return f(arg1, arg2); } > Maybe I'm wrong, cause I'm new to all this, but I thought I could > build my extension modules, some in c++ using BPL and some as Python > code. Extension modules are by definition not written in Python. But there's nothing wrong with distributing the functionality of your module in this way. > In the Python modules I have declared some functions (in my case > script hooks to extend /change the default behaviour of my app). > Then I would like to call one of the functions and pass it their > params directly. As far as I see I would use one of > PyObject_CallObject() > PyObject_CallFunction() > PyObject_CallMethod() Why complicate things? That's what the object interface is for. > As far as I can see using PyObject_CallObject() would have the > advantage to pass the parameters firectly. And with the to_python > conversions I could pass my apps c++ objects (wrapper classes). > > This would have the advantage that the script (function) can > manipulate the data directly. > > Using the proposed PyRun* calls has the disadvantage that I don't get > my objects to deal with only indirectly, or did I miss something? I think you did. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Jan 3 21:34:56 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 15:34:56 -0500 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE0D@admin56.narex.com> ("Bjorn Pettersen"'s message of "Thu, 2 Jan 2003 11:56:57 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE0D@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: >> From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] >> >> Nicodemus wrote: > [...] >> > I think two separate functions would be better. >> > >> > void interpreter::exec( const std::string& code, dict& globals, > dict& locals ); >> > - Executes the given code in the context of the two given > dictionaries. >> > >> > object interpreter::eval( const std::string& expr, dict& globals, > dict& locals ); >> > - Evaluates the Python expression given, in the context of the two >> > dictionaries, and returns the resulting object. >> > >> > They're equivalent to the "exec" statement and to the "eval" builtin >> > function in python. >> >> I like that. Let's hear what others think about it. > > That's essentially what I ended up with, although I have the > global/local dict be persistent with the interpreter (i.e. you don't > pass them in). Making them optional would probably be most > convenient/flexible. > > I ended up making exec return an int so that we could do: > > int foo(int x) { > static int ok = py::exec( > "def foo(y):\n" > " return y**y\n"); > return py::extract(py::fn("foo")(x)); > } > > (i.e. only calling exec once). Looks to me like that int should be an exception instead. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nicodemus at globalite.com.br Sat Jan 4 00:05:17 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 03 Jan 2003 20:05:17 -0300 Subject: [C++-sig] Re: [BPL] python::interpreter proposal In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6A@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE6A@admin56.narex.com> Message-ID: <3E16172D.5070504@globalite.com.br> Bjorn Pettersen wrote: >>>I ended up making exec return an int so that we could do: >>> >>> int foo(int x) { >>> static int ok = py::exec( >>> "def foo(y):\n" >>> " return y**y\n"); >>> return py::extract(py::fn("foo")(x)); >>> } >>> >>>(i.e. only calling exec once). >>> >>> >>You mean exec returning an int to describe success or >>failure? I would >>prefer an exception in case of an error, and returning void. >> >> >No, the point was being able to declare the int static so py::exec() was >only called on the first call to foo() -- and throwing an exception when >something bad happens. No use wasting cycles re-executing the function >definition every time... If someone has a more graceful suggestion I'm >all ears :-) > > I believe that a better aproach would be to separate the foo definition in a separate function: void create_foo() { static bool created = false; if (!created) { py::exec( "def foo(y):\n" " return y**y\n" ); created = true; } } int foo(int x) { create_foo(); stringstream ss; ss << "foo(" << x << ")" << endl; return py::extract(py::eval(ss.str())); } And even if there was no other approach, designing the interface of the interpreter with this specific use in mind would be bad design, in my opinion. The ideal, in my opinion, would be something like: // create_foo is called during initializtion void create_foo() { py::exec( "def foo(y):\n" " return y**y\n" ); } int foo(int x) { stringstream ss; ss << "foo(" << x << ")" << endl; return py::extract(py::eval(ss.str())); } So, I think the only reason to make exec to return an int is to signal an error, a job that is better handled by exceptions. 8) >The script would look something like: > > x = foo(y) > x += bar(y) > x > >i.e. the value in x should be returned. We call it as: > > py::set("y", cppYObject); // assign our c++ object to variable 'y' > int result = py::extract(py::block(theCodeAbove)); > > I don't know about the real utility of such an approach... you can get the same effect just by simply executing the code and then later inspect the globals dictionary for the variable that you want: { string code = "x = foo(y)\n" "x += bar(y)"; py::exec(code); int result = py::extract(py::globals["x"]); // py::globals is an instance of dict } So the functions "set" and "block" seems like code bloat to me. I think we should concentrate in the very basic functionality, and to try to fit any special case in this basic funcionality. If later the "special case" proves to be common enough, then it can be incorporated. Just my 2 cents, Nicodemus. From BPettersen at NAREX.com Sat Jan 4 00:22:13 2003 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Fri, 3 Jan 2003 16:22:13 -0700 Subject: [C++-sig] boost::python::object referencing c++ object Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDE77@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Bjorn Pettersen" writes: > > > template > > void set(const std::string& name, const T& value) { > > PyObject* key = PyString_FromString(name.c_str()); > > object val(value); > > PyDict_SetItem(interpreter()->mainmodule(), key, val.ptr()); > > Py_DECREF(key); > > } > > Why make life hard for yourself? > > template > void set(const std::string& name, const T& value) { > interpreter()->mainmodule()[name] = value; > } > > Of course, this relies on interpeter()->mainmodule() > returning an object (or dict, or...) Thanks (this code was written before we moved to BPL :-) [...] > Perhaps you'd like the resulting Python object to contain a > raw pointer to the argument? In that case, the caveat is > that if the lifetime of the C++ object ends before that of > the Python object, that pointer will dangle and using the > Python object may cause a crash. [example..] Understood. Thanks for the code. -- bjorn From camio at yahoo.com Sat Jan 4 00:55:14 2003 From: camio at yahoo.com (David Sankel) Date: Fri, 3 Jan 2003 15:55:14 -0800 (PST) Subject: [C++-sig] Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) Message-ID: <20030103235514.26119.qmail@web40613.mail.yahoo.com> Hello, I have several questions and I think they are all most easily answered by example: class Abstract { public: shared_ptr clone()=0; }; class Filter { public: vector > Abstract data; void doFilter( vector > &result )=0; }; How would I use boost.python to allow python code to use Filter as a base class? I figure there is going to be: class PythonFilter : public Filter { public: void doFilter( vector > &result) { //What goes here? } } and: BOOST_PYTHON_MODULE(embedded_Filter) { class_< Abstract > ("Abstract", no_init ); class_< Filter, PythonFilter >("Filter") //What goes here? ; } The python code to look something like this: import ... class SpecificFilter( Filter ): def doFilter( self, result ) #make result some modification of self.data Thanks beforehand for helping, David J. Sankel Head Consultant Electron Consulting From dave at boost-consulting.com Sat Jan 4 03:49:01 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 03 Jan 2003 21:49:01 -0500 Subject: [C++-sig] Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: <20030103235514.26119.qmail@web40613.mail.yahoo.com> (David Sankel's message of "Fri, 3 Jan 2003 15:55:14 -0800 (PST)") References: <20030103235514.26119.qmail@web40613.mail.yahoo.com> Message-ID: David Sankel writes: > Hello, > I have several questions and I think they are all > most easily answered by example: > > class Abstract > { > public: > shared_ptr clone()=0; > }; > > class Filter > { > public: > vector > Abstract data; > void doFilter( vector > &result )=0; > }; > > How would I use boost.python to allow python code to > use Filter as a base class? > > I figure there is going to be: > > class PythonFilter : public Filter > { > public: > void doFilter( vector >& result) > { > //What goes here? Here you need to invoke call_method(...) with some argument(s). You could write: call_method( ref(result) ); But that will only work if you've exposed vector > to Python. My guess is that you haven't. What type would you like your Python derived class to see when you override doFilter in Python? > } > } > > and: > > BOOST_PYTHON_MODULE(embedded_Filter) > { > class_< Abstract > ("Abstract", no_init ); > class_< Filter, > PythonFilter >("Filter") > //What goes here? So far, nothing. You don't need to (and shouldn't) expose a pure virtual function to Python. > ; > > } > > The python code to look something like this: > > import ... > class SpecificFilter( Filter ): > def doFilter( self, result ) > #make result some modification of self.data I don't understand the comment above. HTH, though. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From camio at yahoo.com Sat Jan 4 15:23:35 2003 From: camio at yahoo.com (David Sankel) Date: Sat, 4 Jan 2003 06:23:35 -0800 (PST) Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: <3E16D7BE.8090204@nonconformity.net> Message-ID: <20030104142335.80337.qmail@web40603.mail.yahoo.com> > David Sankel writes: > > > Hello, > > I have several questions and I think they are > all > > most easily answered by example: > > > > class Abstract > > { > > public: > > shared_ptr clone()=0; > > }; > > > > class Filter > > { > > public: > > vector > data; > > void doFilter( vector > > &result )=0; > > }; > > > > How would I use boost.python to allow python code > to > > use Filter as a base class? > > > > I figure there is going to be: > > > > class PythonFilter : public Filter > > { > > public: > > void doFilter( vector >& > result) > > { > > //What goes here? > > Here you need to invoke call_method(...) with > some argument(s). > You could write: > > call_method( ref(result) ); > > But that will only work if you've exposed > > vector > > > to Python. My guess is that you haven't. > > What type would you like your Python derived class > to see when you > override doFilter in Python? I would like the Python derived class to see a list of Abstracts. I guess this is where I don't understand how to expose vector > with the iterators. > > > } > > } > > > > and: > > > > BOOST_PYTHON_MODULE(embedded_Filter) > > { > > class_< Abstract > ("Abstract", no_init ); > > class_< Filter, > > PythonFilter >("Filter") > > //What goes here? > > So far, nothing. You don't need to (and shouldn't) > expose a pure > virtual function to Python. Wouldn't I need something so a python derived class could access the Filter::data member? Also, how would I allow python to see the Abstract::clone() function? > > ; > > > > } > > > > The python code to look something like this: > > > > import ... > > class SpecificFilter( Filter ): > > def doFilter( self, result ) > > #make result some modification of self.data > > I don't understand the comment above. > For example: class specificFiler( Filter ): def doFilter( self, result ): result = [x.clone() for x in self.data] result.reverse() Does this make more sense? Thanks, David J. Sankel From dave at boost-consulting.com Sat Jan 4 18:27:26 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 04 Jan 2003 12:27:26 -0500 Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: <20030104142335.80337.qmail@web40603.mail.yahoo.com> (David Sankel's message of "Sat, 4 Jan 2003 06:23:35 -0800 (PST)") References: <20030104142335.80337.qmail@web40603.mail.yahoo.com> Message-ID: David, you might want to set up your mailer so it doesn't wrap source code snippets at 55 characters... David Sankel writes: >> > void doFilter( vector >& result) >> > { >> > //What goes here? >> >> Here you need to invoke call_method(...) with >> some argument(s). >> You could write: >> >> call_method( ref(result) ); >> >> But that will only work if you've exposed >> >> vector > >> >> to Python. My guess is that you haven't. >> >> What type would you like your Python derived class >> to see when you >> override doFilter in Python? > > I would like the Python derived class to see a list of > Abstracts. And what do you expect it to be able to do to the list? I'm not asking about the items it contains, yet. Do you need to be able to modify the length of the list, or move items within it, etc? > I guess this is where I don't understand > how to expose vector > with the > iterators. I don't see what iterators have to do with it. >> >> > } >> > } >> > >> > and: >> > >> > BOOST_PYTHON_MODULE(embedded_Filter) >> > { >> > class_< Abstract > ("Abstract", no_init ); >> > class_< Filter, >> > PythonFilter >("Filter") >> > //What goes here? >> >> So far, nothing. You don't need to (and shouldn't) expose a pure >> virtual function to Python. > > Wouldn't I need something so a python derived class > could access the Filter::data member? If that's what you want to do. I didn't know that's what you were after. Have you looked at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html ? In order to use this, you'll need to expose the type of the Filter::data member. Unless... ...I suppose you want Filter::data to show up as a Python list also? > Also, how would I allow python to see the > Abstract::clone() function? Nothing. It's pure virtual. >> > ; >> > >> > } >> > >> > The python code to look something like this: >> > >> > import ... >> > class SpecificFilter( Filter ): >> > def doFilter( self, result ) >> > #make result some modification of self.data >> >> I don't understand the comment above. >> > > For example: > class specificFiler( Filter ): > def doFilter( self, result ): > result = [x.clone() for x in self.data] > result.reverse() > > Does this make more sense? A bit. It sounds like you may want to explore http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2 HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sat Jan 4 21:46:48 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 04 Jan 2003 15:46:48 -0500 Subject: [C++-sig] Problems with exception passing In-Reply-To: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Wed, 01 Jan 2003 10:33:53 -0800") References: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: > Following the example at > > http://www.boost.org/libs/python/doc/v2/exception_translator.html > > I wrote > > --- > void translate ( const std::exception & e ) > { > PyErr_SetString ( PyExc_RuntimeError, e.what() ); > } > --- > > and in my BOOST_PYTHON_MODULE I have > > --- > register_exception_translator < std::exception > ( & translate ); > --- Well, it shouldn't be neccessary to register a translator for std::exception, since the built-in translators handle that case. But it shouldn't hurt. > The only exceptions my C++ code can throw are derived classes from > std::exception and caught by a member function in the > BOOST_PYTHON_MODULE like this... > > --- > catch ( const FactoryException & e ) { > qApp->unlock (); > throw e; > } > catch ( const DataRepException & e ) { > qApp->unlock (); > throw e; > } > --- Hmm, that's suspicious looking. What does this "unlock" thing do? If it's important, you probably should be using the destructor of a class instance to do that, and maybe you should even be doing the same thing in your exception translator, since it's very unlikely that an exception will pass through your module init function. > Now all seems to work fine with GCC 2.95.3 under Red Hat Linux 7.2. > In fact, But with GCC 3.2.1 on the same system I get... > > [pfkeb at Kunz-pbdsl1 testsuite]$ qtest histogram.py >>>> h = Display ( 'foo', nt1, 'bar' ) > qtest: line 18: 14343 Aborted (core dumped) python -i $1 > > The gdb traceback shows that the exception was not caught and > terminate was called. How can you tell the exception was not caught? > If I take out translate() and corresponding register function from > the MODULE, then compiling with GCC 3.2.1 works OK... > > [pfkeb at Kunz-pbdsl1 testsuite]$ qtest histogram.py >>>> h = Display ( 'foo', nt1, 'bar' ) > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: No such type: foo could be found in factory >>>> h = Display ( 'Histogram', nt1, 'bar' ) > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: No such label: bar for ntuple column >>>> h = Display ( 'Histogram', nt1, 'Age' ) >>>> canvas.addDisplay ( h ) >>>> > > So both exceptions were properly caught and error passed to Python > with correct error message. Just like with GCC 2.95.3 with > translate() and register in the code. If I leave translate out of > the code and compile with GCC 2.95.3, then I get the same "Aborted" > message as when the translate function is in the code compiled with > GCC 3.2.1. > > This is all confusing, let me summarize... > > -with GCC 2.95.3, I need the translate function else it core dumps > > -with GCC 3.2.1, it core dumps with the translate function, works fine > without it. All I can tell you is that the way that GCC identifies the type of exception objects across dynamic library boundaries has changed since 2.9x. If the exception is originating in one dynamic library/executable ("link unit") and you're trying to catch it in another, it generally won't work with gcc 3.x unless one of the link units is explicitly linked to the other. Generally, though, the effect is that the exception won't be caught. All the C++ you wrap with Boost.Python gets enclosed in a try { /**/ } /**/ catch(...) { /**/ } block, so there's no obvious reason for termination here. I am suspicious that there's a threading issue involved. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sat Jan 4 23:25:53 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 04 Jan 2003 14:25:53 -0800 Subject: [C++-sig] Problems with exception passing In-Reply-To: References: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> Message-ID: <200301042225.h04MPrq23591@libra3.slac.stanford.edu> >>>>> On Sat, 04 Jan 2003 15:46:48 -0500, David Abrahams said: > Hmm, that's suspicious looking. What does this "unlock" thing do? Probably should have shown more of the code... void QtDisplay::createDisplay ( const std::string & type, const NTuple & nt, const std::vector < std::string > & bindings ) { if ( qApp ) qApp->lock (); DisplayController * controller = DisplayController::instance (); try { m_plotter = controller->createDisplay ( type, nt, bindings ); if ( qApp ) qApp->unlock (); } catch ( const FactoryException & e ) { if ( qApp ) qApp->unlock (); throw e; } catch ( const DataRepException & e ) { if ( qApp ) qApp->unlock (); throw e; } } where `aApp' is a QApplication object running in a separate thread from Python. `QtDisplay::createDisplay' is called by Python and will add something to the GUI so I have to lock the application before doing so and then unlock it when done. >> The gdb traceback shows that the exception was not caught and >> terminate was called. > How can you tell the exception was not caught? Because the terminate() function was called. > All I can tell you is that the way that GCC identifies the type of > exception objects across dynamic library boundaries has changed > since 2.9x. If the exception is originating in one dynamic > library/executable ("link unit") and you're trying to catch it in > another, it generally won't work with gcc 3.x unless one of the link > units is explicitly linked to the other. Generally, though, the > effect is that the exception won't be caught. All the C++ you wrap > with Boost.Python gets enclosed in a > try { /**/ } /**/ catch(...) { /**/ } > block, so there's no obvious reason for termination here. Hmmm. Exception is thrown in one shared library but caught in function shown above which is in the same library. Then thrown again to be caught by boost_python shared library. From dave at boost-consulting.com Sat Jan 4 23:38:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 04 Jan 2003 17:38:38 -0500 Subject: [C++-sig] Problems with exception passing In-Reply-To: <200301042225.h04MPrq23591@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Sat, 04 Jan 2003 14:25:53 -0800") References: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> <200301042225.h04MPrq23591@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: >>>>>> On Sat, 04 Jan 2003 15:46:48 -0500, David Abrahams said: > >> Hmm, that's suspicious looking. What does this "unlock" thing do? > > Probably should have shown more of the code... > > void QtDisplay::createDisplay ( const std::string & type, > const NTuple & nt, > const std::vector < std::string > & bindings ) > { > if ( qApp ) qApp->lock (); > DisplayController * controller = DisplayController::instance (); > try { > m_plotter = controller->createDisplay ( type, nt, bindings ); > if ( qApp ) qApp->unlock (); > } > catch ( const FactoryException & e ) { > if ( qApp ) qApp->unlock (); > throw e; > } > catch ( const DataRepException & e ) { > if ( qApp ) qApp->unlock (); > throw e; > } > } > > where `aApp' is a QApplication object running in a separate thread > from Python. `QtDisplay::createDisplay' is called by Python and will > add something to the GUI so I have to lock the application before > doing so and then unlock it when done. You should definitely be using the RAII idiom here (unlock in a stack object's destructor) instead of try/catch blocks. >>> The gdb traceback shows that the exception was not caught and >>> terminate was called. > >> How can you tell the exception was not caught? > > Because the terminate() function was called. There are other reasons terminate() might be called. It might be called after the exception was caught and rethrown, for example, if a destructor threw during stack unwinding. >> All I can tell you is that the way that GCC identifies the type of >> exception objects across dynamic library boundaries has changed >> since 2.9x. If the exception is originating in one dynamic >> library/executable ("link unit") and you're trying to catch it in >> another, it generally won't work with gcc 3.x unless one of the link >> units is explicitly linked to the other. Generally, though, the >> effect is that the exception won't be caught. All the C++ you wrap >> with Boost.Python gets enclosed in a > >> try { /**/ } /**/ catch(...) { /**/ } > >> block, so there's no obvious reason for termination here. > > Hmmm. Exception is thrown in one shared library but caught in > function shown above which is in the same library. Then thrown again > to be caught by boost_python shared library. Well, your shared lib is linked explicitly to boost_python, so that shouldn't be an issue. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sat Jan 4 23:52:47 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 04 Jan 2003 14:52:47 -0800 Subject: [C++-sig] Problems with exception passing In-Reply-To: References: <200301011833.h01IXrk24172@libra3.slac.stanford.edu> <200301042225.h04MPrq23591@libra3.slac.stanford.edu> Message-ID: <200301042252.h04MqlL23628@libra3.slac.stanford.edu> >>>>> On Sat, 04 Jan 2003 17:38:38 -0500, David Abrahams said: > You should definitely be using the RAII idiom here (unlock in a > stack object's destructor) instead of try/catch blocks. Not familiar with that idiom, but Google gives some hits to look at. > There are other reasons terminate() might be called. It might be > called after the exception was caught and rethrown, for example, if > a destructor threw during stack unwinding. You're right. I should have done a full traceback. > Well, your shared lib is linked explicitly to boost_python, so that > shouldn't be an issue. Great. Thanks for the suggestions. From mike.thompson at day8.com.au Mon Jan 6 08:00:00 2003 From: mike.thompson at day8.com.au (Mike Thompson) Date: Mon, 6 Jan 2003 18:00:00 +1100 Subject: [C++-sig] Re: Why Python for C++ programmers Message-ID: <002c01c2b551$3aa3ffc0$4a0d31d2@Notebook> "David Abrahams" wrote in message news:u8yz4qk31.fsf at boost-consulting.com... > > Hi All, > > I'm starting work on some articles and talks about Boost.Python. Some > of these are primarily for a "C++ audience", and I'll have to at least > briefly make the case for why a C++ programmer should care about > Python. Some of the answers are obvious to me, but I thought I should > get additional feedback from a group who must have their own > well-thought-out reasons. > > Here are some things I've thought of. > > In broad strokes, they're complimentary because: > > * C++ is hard. Python is easy > > * C++ is fast. Python is small > > * C++ is "dangerous" (easy to crash). Python is "safe" > > * C++ is rigorous. Python is loose. > > * C++ is compiled. Python is interactive. > > * C++ has a deep and focused standard library. Python has broad > libraries > > * C++ has limited introspection capability. Everything in Python is > introspectable > > * C++ is supported to varying degrees on different platforms. The > latest Python really does run ``everywhere''. > I'm a bit late to this, but my 2c worth is: C++ is deep. Python is broad. C++ is complex. Python is simple. C++ is wonderfully fast. Python is mostly fast enough. C++ is hard. Python is easy. C++ will be portable one day. Python genuinely is already. C++ is impressive. Python makes me smile. C++'s draws great power from rigidity. Python from flexibility. C++ is for large. Python is for small, medium and large. C++ is sometimes where I finish. Python is always where I start. Python and C++ are to my software development as Taxis and Aircraft are to my business travel. Most times I only need a Taxi. Sometimes I need more than that. Even then its the combination of the two that gets me there. I wouldn't be without either. -Mike. From jacek.generowicz at cern.ch Mon Jan 6 17:04:55 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 06 Jan 2003 17:04:55 +0100 Subject: [C++-sig] v2 def_raw ? Message-ID: What is the v2 equivalent of v1's class_builder::def_raw(...) ? (How should I have found this in the docs myself?) From camio at yahoo.com Mon Jan 6 17:39:14 2003 From: camio at yahoo.com (David Sankel) Date: Mon, 6 Jan 2003 08:39:14 -0800 (PST) Subject: [C++-sig] Re: [Fwd: Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :)] In-Reply-To: <3E19AFD8.8050705@nonconformity.net> Message-ID: <20030106163914.34430.qmail@web40601.mail.yahoo.com> --- "David Abrahams" wrote:> > I would like the Python derived class to see a> list of> > Abstracts. > > And what do you expect it to be able to do to the> list? I'm not> asking about the items it contains, yet. Do you> need to be able to> modify the length of the list, or move items within> it, etc?I would like to have the ability to do everything that you can do with a normal Python list. Such as modify the length, move items within it, etc.> I don't see what iterators have to do with it.That was my misunderstanding.> Have you looked at> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html> ?> > In order to use this, you'll need to expose the type> of the> Filter::data member. Unless...> > ...I suppose you want Filter::data to show up as a> Python list also?Yes, if possible.> It sounds like you may want to explore> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2Explored. Thanks a lot for your help with this thus far. I really appreciate it. Here is where I am now (I'm using the container conversions pointed to by the faq):class Abstract{public: virtual shared_ptr clone()=0; virtual ~Abstract(){}};class Filter{public: vector > data; virtual void doFilter( vector > &result)=0; virtual std::string name() const=0; virtual ~Filter(){}};class PythonFilter : public Filter{public: PythonFilter( PyObject * self ) : m_self( self ), m_initialized(true) { }; void doFilter( vector > &result) { if( m_initialized ) { cout > > ( m_self, "doFilter", ref( result ) ); } } virtual std::string name() const { return call_method ( m_self, "name" ); } virtual ~PythonFilter(){}private: PyObject * m_self; bool m_initialized;};BOOST_PYTHON_MODULE(embedded_Filter){ class_, boost::noncopyable > ("Abstract", no_init ); class_ ("Filter"); to_python_converter >, scitbx::boost_python::container_conversions::to_tuple > > > (); scitbx::boost_python::container_conversions::from_python_sequence >, scitbx::boost_python::container_conversions::variable_capacity_policy>();}But I am still missing something because I cannot get the following python code without the comments to work:from embedded_Filter import *class SpecificFilter( Filter ): def name( self ): return 'SpecificFilterA' def doFilter( self, result ): print("In SpecificFilter.doFilter\n") print( len( self.data ) ) ; #self.data is a normal python list print( len( result ) ); #So is result p = [x.clone() for x in self.data] #The members of self.data can #have their methods called result = p #result can be modified as a python list result.reverse() #another modification to result.Thanks again for the help,David J. SankelHead ConsultantElectron Consulting -------------- next part -------------- An HTML attachment was scrubbed... URL: From ron_clarke at hp.com Mon Jan 6 20:01:43 2003 From: ron_clarke at hp.com (CLARKE,RON (HP-Vancouver,ex1)) Date: Mon, 6 Jan 2003 11:01:43 -0800 Subject: [C++-sig] Boost.Python - Simple Pointer Question Message-ID: <6D805D4C4567D411AF32009027B683510E66E3C2@xvan02.vcd.hp.com> I know I've missed something that should be obvious and simple, but ... We have a medium-sized Python/C++ project and I am investigating replacing SWIG with Boost.Python (V2). I've read all the documentation more than once, reviewed the examples, etc. but I still don't see the syntax/macros/commands needed to allow Python to understand a pointer to an existing C++ class contained within another class. Here is a simplified scenario: class car { public: car(void); virtual ~car(void); private: ... }; class garage{ public: garage(void); ~garage(void); car* pCar; }; Class garage contains a public pointer to a car object (I don't have the option of changing the C++ code; it would negatively affect too many users). I can create garage and car objects OK and Python understands each one: c=car() g=garage() However, if I try something like this: g.pCar = car() the resulting object is null and trying to simply print the object yields a "TypeError: bad argument for built-in operation". What have I missed? Can someone please provide an example (other than what is in the documentation)? Similarly, if I want to pass a pointer to a C++ object as a parameter to a C++ function or method, how do I expose the function properly such that a user can type the function call in Python and have the object properly passed into the C++ module? For example: garage.parkTheCar(c) ## what is the proper Boost.Python syntax for exposing the parkTheCar method and pointer parameter? Thanks in advance for the help. _________________________________________ Ron Clarke Digital Printing Technologies Hewlett-Packard Company ron_clarke at hp.com 360-212-0193 -------------- next part -------------- An HTML attachment was scrubbed... URL: From camio at yahoo.com Mon Jan 6 21:05:07 2003 From: camio at yahoo.com (David Sankel) Date: Mon, 6 Jan 2003 12:05:07 -0800 (PST) Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: <3E19AFD8.8050705@nonconformity.net> Message-ID: <20030106200507.29389.qmail@web40611.mail.yahoo.com> Sorry about my garbled previous post. --- "David Abrahams" wrote: > > I would like the Python derived class to see a > list of > > Abstracts. > > And what do you expect it to be able to do to the > list? I'm not > asking about the items it contains, yet. Do you > need to be able to > modify the length of the list, or move items within > it, etc? I would like to have the ability to do everything that you can do with a normal Python list. Such as modify the length, move items within it, etc. > I don't see what iterators have to do with it. That was my misunderstanding. > Have you looked at > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html > ? > > In order to use this, you'll need to expose the type > of the > Filter::data member. Unless... > > ...I suppose you want Filter::data to show up as a > Python list also? Yes, if possible. > It sounds like you may want to explore > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2 Explored. Thanks a lot for your help with this thus far. I really appreciate it. Here is where I am now (I'm using the container conversions pointed to by the faq): class Abstract { public: virtual shared_ptr clone()=0; virtual ~Abstract(){} }; class Filter { public: vector > data; virtual void doFilter( vector > &result)=0; virtual std::string name() const=0; virtual ~Filter(){} }; class PythonFilter : public Filter { public: PythonFilter( PyObject * self ) : m_self( self ), m_initialized(true) { }; void doFilter( vector > &result) { if( m_initialized ) { cout << "Got into doFilter with " << name() << endl; call_method< void, vector< shared_ptr< Abstract > > > ( m_self, "doFilter", ref( result ) ); } } virtual std::string name() const { return call_method< std::string > ( m_self, "name" ); } virtual ~PythonFilter(){} private: PyObject * m_self; bool m_initialized; }; BOOST_PYTHON_MODULE(embedded_Filter) { class_< Abstract, shared_ptr< Abstract >, boost::noncopyable > ("Abstract", no_init ); class_< Filter, PythonFilter, boost::noncopyable > ("Filter"); to_python_converter< vector< shared_ptr< Abstract > >, scitbx::boost_python::container_conversions::to_tuple< vector< shared_ptr< Abstract > > > > (); scitbx::boost_python::container_conversions::from_python_sequence< vector< shared_ptr< Abstract > >, scitbx::boost_python::container_conversions::variable_capacity_policy>(); } But I am still missing something because I cannot get the following python code without the comments to work: from embedded_Filter import * class SpecificFilter( Filter ): def name( self ): return 'SpecificFilterA' def doFilter( self, result ): print("In SpecificFilter.doFilter\n") print( len( self.data ) ) ; #self.data is a normal python list print( len( result ) ); #So is result p = [x.clone() for x in self.data] #The members of self.data can #have their methods called result = p #result can be modified as a python list result.reverse() #another modification to result. Thanks again for the help, David J. Sankel Head Consultant Electron Consulting From python at mc2research.org Mon Jan 6 22:54:13 2003 From: python at mc2research.org (Daryl P McDaniel) Date: Mon, 6 Jan 2003 13:54:13 -0800 Subject: [C++-sig] Re: Why Python for C++ programmers In-Reply-To: <20030106170012.21387.52748.Mailman@mail.python.org> References: <20030106170012.21387.52748.Mailman@mail.python.org> Message-ID: <200301062154.NAA00582@sr71.mnet.com> Greetings, The Python / C++ relationship is not adversarial; it is complementary. I think that this is a very important point to get across to a C++ audience. One can easily prototype in Python then convert to C++. (There are significant benefits to prototyping in something other than your production language.) By coupling Python with application specific extension libraries, in C++, one can produce an application with very good performance while retaining the benefits (as expressed in the original messages) of Python. For us, the greatest benefit comes when Python is embedded in our product (Low-level management firmware for Mainframes). Through the facilities provided by Boost.Python, all "important" C++ objects are available in the Python environment. This allows one to easily interract with the system, and the system objects, for experimentation, development, and debugging. Where appropriate, portions of the final application that are not time critical can be written in Python. The breadth of Python library support usually results in small, easily maintained, modules. As one who has been programming in C++ daily for about 20 years, my initial reaction (in a seminar environment) to the phrase "C++ is hard, Python is easy" would be fairly negative. C++ is harder than Python to use correctly and fully. That which you know is always easier than that which you don't. Best of luck on the articles and talks. Sincerely, Daryl V. McDaniel python at mc2research.org Python Evangelist MC2 Research Portland, Oregon On Monday 06 January 2003 09:00 am, Mike Thompson wrote: > Message: 1 > From: "Mike Thompson" > To: > Date: Mon, 6 Jan 2003 18:00:00 +1100 > Subject: [C++-sig] Re: Why Python for C++ programmers > Reply-To: c++-sig at python.org > > > "David Abrahams" wrote in message > news:u8yz4qk31.fsf at boost-consulting.com... > > > Hi All, > > > > I'm starting work on some articles and talks about Boost.Python. Some > > of these are primarily for a "C++ audience", and I'll have to at least > > briefly make the case for why a C++ programmer should care about > > Python. Some of the answers are obvious to me, but I thought I should > > get additional feedback from a group who must have their own > > well-thought-out reasons. > > > > Here are some things I've thought of. > > > > In broad strokes, they're complimentary because: > > > > * C++ is hard. Python is easy > > > > * C++ is fast. Python is small > > > > * C++ is "dangerous" (easy to crash). Python is "safe" > > > > * C++ is rigorous. Python is loose. > > > > * C++ is compiled. Python is interactive. > > > > * C++ has a deep and focused standard library. Python has broad > > libraries > > > > * C++ has limited introspection capability. Everything in Python is > > introspectable > > > > * C++ is supported to varying degrees on different platforms. The > > latest Python really does run ``everywhere''. > > I'm a bit late to this, but my 2c worth is: > > C++ is deep. Python is broad. > C++ is complex. Python is simple. > C++ is wonderfully fast. Python is mostly fast enough. > C++ is hard. Python is easy. > C++ will be portable one day. Python genuinely is already. > C++ is impressive. Python makes me smile. > C++'s draws great power from rigidity. Python from flexibility. > C++ is for large. Python is for small, medium and large. > C++ is sometimes where I finish. Python is always where I start. > > Python and C++ are to my software development as Taxis and Aircraft are to > my > business travel. Most times I only need a Taxi. Sometimes I need more than > that. Even then its the combination of the two that gets me there. > > I wouldn't be without either. > > -Mike. > From dave at boost-consulting.com Tue Jan 7 00:45:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 06 Jan 2003 18:45:00 -0500 Subject: [C++-sig] Boost.Python - Simple Pointer Question In-Reply-To: <6D805D4C4567D411AF32009027B683510E66E3C2@xvan02.vcd.hp.com> ("CLARKE,RON's message of "Mon, 6 Jan 2003 11:01:43 -0800") References: <6D805D4C4567D411AF32009027B683510E66E3C2@xvan02.vcd.hp.com> Message-ID: "CLARKE,RON (HP-Vancouver,ex1)" writes: > I know I've missed something that should be obvious and simple, but ... > We have a medium-sized Python/C++ project and I am investigating replacing > SWIG with Boost.Python (V2). I've read all the documentation more than once, > reviewed the examples, etc. but I still don't see the syntax/macros/commands > needed to allow Python to understand a pointer to an existing C++ class > contained within another class. Here is a simplified scenario: > > class car > { > public: > car(void); > virtual ~car(void); > private: > ... > }; > > class garage{ > public: > garage(void); > ~garage(void); > car* pCar; > }; > > Class garage contains a public pointer to a car object (I don't have the > option of changing the C++ code; it would negatively affect too many users). > I can create garage and car objects OK and Python understands each one: > c=car() > g=garage() > > However, if I try something like this: > g.pCar = car() > the resulting object is null and trying to simply print the object yields a > "TypeError: bad argument for built-in operation". > > What have I missed? Can someone please provide an example (other than what > is in the documentation)? I think this might work for you: class_("garage") .add_property( make_getter(&garage::pCar, with_custodian_and_ward<1,2>()) , make_setter(&garage::pCar, return_internal_reference<>())) However, if garage::~garage() does "delete pCar" you're going to have big problems. Let me know if that's the case and we can try something else. > Similarly, if I want to pass a pointer to a C++ object as a parameter to a > C++ function or method, how do I expose the function properly such that a > user can type the function call in Python and have the object properly > passed into the C++ module? > For example: > garage.parkTheCar(c) ## what is the proper Boost.Python syntax for > exposing the parkTheCar method and pointer parameter? You don't need to do anything special as long as there are no ownership/lifetime issues in parkTheCar. If it just uses the pointer you pass and forgets it, you're fine. Otherwise you might need some CallPolicies. .def("parkTheCar", &garage::parkTheCar) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Jan 7 23:05:14 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Jan 2003 17:05:14 -0500 Subject: [C++-sig] Re: Why Python for C++ programmers In-Reply-To: <200301062154.NAA00582@sr71.mnet.com> (Daryl P McDaniel's message of "Mon, 6 Jan 2003 13:54:13 -0800") References: <20030106170012.21387.52748.Mailman@mail.python.org> <200301062154.NAA00582@sr71.mnet.com> Message-ID: Daryl P McDaniel writes: > Greetings, > > > The Python / C++ relationship is not adversarial; it is > complementary. I think that this is a very important point to get > across to a C++ audience. Yes, it was something I wanted to convey, but I thought I was failing. That's why I posted the question. I've long since solved those problems in my paper, but I had to rewrite it three times to get there ;-) > One can easily prototype in Python then convert to C++. (There are > significant benefits to prototyping in something other than your production > language.) By coupling Python with application specific extension libraries, > in C++, one can produce an application with very good performance while > retaining the benefits (as expressed in the original messages) of Python. > > For us, the greatest benefit comes when Python is embedded in our product > (Low-level management firmware for Mainframes). Through the facilities > provided by Boost.Python, all "important" C++ objects are available in the > Python environment. This allows one to easily interract with the system, and > the system objects, for experimentation, development, and debugging. Where > appropriate, portions of the final application that are not time critical can > be written in Python. The breadth of Python library support usually results > in small, easily maintained, modules. All good points. > As one who has been programming in C++ daily for about 20 years, my > initial reaction (in a seminar environment) to the phrase "C++ is > hard, Python is easy" would be fairly negative. C++ is harder than > Python to use correctly and fully. That which you know is always > easier than that which you don't. I daresay I know C++ better than I know Python. I still think C++ is harder. Maybe I'm just being too optimistic about Python? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From n_lelong at hotmail.com Tue Jan 7 10:29:28 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Tue, 7 Jan 2003 10:29:28 +0100 Subject: [C++-sig] weird bug of addressof in MSVC 7 Message-ID: Hi, I stumbled upon a weird compilation error due to function 'addressof' in MSVC7. Here is my test case : ************ class Test { public: struct Parameters { }; }; BOOST_PYTHON_MODULE( test ) { python::class_ Parameters_class("Parameters"); /* this line causes the compile bug */ }; ************ Here is what the compiler tells me : ************ d:\Sources\mgd\include\boost\utility\addressof.hpp(28) : error C2440: 'return' : cannot convert from 'const Test::Parameters *' to 'Test::Parameters *' Conversion loses qualifiers d:\Sources\mgd\include\boost\ref.hpp(40) : see reference to function template instantiation 'Test::Parameters *boost::addressof(const T &)' being compiled with [ T=Test::Parameters ] d:\Sources\mgd\include\boost\ref.hpp(40) : while compiling class-template member function 'boost::reference_wrapper::reference_wrapper(const Test::Parameters &)' with [ T=const Test::Parameters ] d:\Sources\mgd\include\boost\python\object\make_instance.hpp(64) : see reference to class template instantiation 'boost::reference_wrapper' being compiled with [ T=const Test::Parameters ] d:\Sources\mgd\include\boost\python\object\class_wrapper.hpp(27) : see reference to class template instantiation 'boost::python::objects::make_instance' being compiled with [ T=Test::Parameters, Holder=holder ] d:\Sources\mgd\include\boost\python\object\class_wrapper.hpp(26) : while compiling class-template member function 'PyObject *boost::python::objects::class_cref_wrapper::convert(const Src &)' with [ Src=Test::Parameters, MakeInstance=boost::python::objects::make_instance ] d:\Sources\mgd\include\boost\python\class.hpp(88) : see reference to class template instantiation 'boost::python::objects::class_cref_wrapper' being compiled with [ Src=Test::Parameters, MakeInstance=boost::python::objects::make_instance ] d:\Sources\mgd\include\boost\python\class.hpp(479) : see reference to function template instantiation 'void boost::python::detail::register_copy_constructor(const boost::mpl::bool_c &,const boost::python::objects::detail::select_value_holder &,Test::Parameters *)' being compiled with [ C=true, T=Test::Parameters, Held=Test::Parameters ] c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xlocnum(80) : while compiling class-template member function 'void boost::python::class_::register_(void) const' with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xmemory(136) : while compiling class-template member function 'boost::python::class_::class_(const char *,const char *)' with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] d:\Sources\mgd\Tests\Python\Python.cpp(232) : see reference to class template instantiation 'boost::python::class_' being compiled with [ T=Test::Parameters, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] ************ What is quite weird is that I added a '#pragma message (__FUNCSIG__)' in 'addressof' code ; and the faulty compiled function has the follwing signature: struct Test::Parameters *__cdecl boost::addressof(const struct Test::Parameters &) It seems to me that this signature should be : const struct Test::Parameters *__cdecl boost::addressof(const struct Test::Parameters &) It looks like a compiler bug to me. This only seems to happen for classes of structs contained in another class (or struct). I'm no expert in compiler bug workaround so I could not find anything interesting - but maybe am I just missing something ?! Any thoughts ? Thanks, Nicolas. From brettc.lists at paradise.net.nz Tue Jan 7 10:45:19 2003 From: brettc.lists at paradise.net.nz (Brett Calcott) Date: Tue, 7 Jan 2003 22:45:19 +1300 Subject: [C++-sig] MSVC project file [UPDATED] In-Reply-To: References: <003901c287bc$c078f870$2e6e4fcb@hare> <007101c28a25$291ec2a0$2e6e4fcb@hare> <20021125061210.GA1232@HARE> <20021127100702.GD796@HARE> <20021217084557.GB1364@HARE> Message-ID: <20030107094519.GA1240@HARE> On Dec 29 12:31, David Abrahams wrote: > > > Hi all, > > > > Here is a project and workspace file for the boost-python build and a > > patch to the building.html file. The two files should go into a dir > > under the build directory - I'll let you come up with a name... > > > > I have removed the python_debug configuration as I think it'll just > > cause confusion. > > It's a double-edged sword, Brett. I think you should put it back. If > people build a debug version of Python, and the debug version of > Boost.Python doesn't work with it, they get confused. You can't win. > Okay, back from hols now. I'll get onto this over the next week. Cheers, Brett From dave at boost-consulting.com Tue Jan 7 18:10:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Jan 2003 12:10:50 -0500 Subject: [C++-sig] v2 def_raw ? In-Reply-To: (Jacek Generowicz's message of "06 Jan 2003 17:04:55 +0100") References: Message-ID: Jacek Generowicz writes: > What is the v2 equivalent of v1's class_builder::def_raw(...) ? > > (How should I have found this in the docs myself?) We don't have a direct equivalent, though we probably should. What we /do/ have is the ability to specify optional arguments http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/overloads.html and keyword expressions http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/args.html#args-spec Does that cover your needs? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From camio at yahoo.com Tue Jan 7 18:38:33 2003 From: camio at yahoo.com (David Sankel) Date: Tue, 7 Jan 2003 09:38:33 -0800 (PST) Subject: [C++-sig] (no subject) Message-ID: <20030107173833.23470.qmail@web40612.mail.yahoo.com> --- "David Abrahams" wrote: > > I would like the Python derived class to see a > list of > > Abstracts. > > And what do you expect it to be able to do to the > list? I'm not > asking about the items it contains, yet. Do you > need to be able to > modify the length of the list, or move items within > it, etc? I would like to have the ability to do everything that you can do with a normal Python list. Such as modify the length, move items within it, etc. > I don't see what iterators have to do with it. That was my misunderstanding. > Have you looked at > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html > ? > > In order to use this, you'll need to expose the type > of the > Filter::data member. Unless... > > ...I suppose you want Filter::data to show up as a > Python list also? Yes, if possible. > It sounds like you may want to explore > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2 Explored. Thanks a lot for your help with this thus far. I really appreciate it. Here is where I am now (I'm using the container conversions pointed to by the faq): class Abstract { public: virtual shared_ptr clone()=0; virtual ~Abstract(){} }; class Filter { public: vector > data; virtual void doFilter( vector > &result)=0; virtual std::string name() const=0; virtual ~Filter(){} }; class PythonFilter : public Filter { public: PythonFilter( PyObject * self ) : m_self( self ), m_initialized(true) { }; void doFilter( vector > &result) { if( m_initialized ) { cout << "Got into doFilter with " << name() << endl; call_method< void, vector< shared_ptr< Abstract > > > ( m_self, "doFilter", ref( result ) ); } } virtual std::string name() const { return call_method< std::string > ( m_self, "name" ); } virtual ~PythonFilter(){} private: PyObject * m_self; bool m_initialized; }; BOOST_PYTHON_MODULE(embedded_Filter) { class_< Abstract, shared_ptr< Abstract >, boost::noncopyable > ("Abstract", no_init ); class_< Filter, PythonFilter, boost::noncopyable > ("Filter"); to_python_converter< vector< shared_ptr< Abstract > >, scitbx::boost_python::container_conversions::to_tuple< vector< shared_ptr< Abstract > > > > (); scitbx::boost_python::container_conversions::from_python_sequence< vector< shared_ptr< Abstract > >, scitbx::boost_python::container_conversions::variable_capacity_policy>(); } But I am still missing something because I cannot get the following python code without the comments to work: from embedded_Filter import * class SpecificFilter( Filter ): def name( self ): return 'SpecificFilterA' def doFilter( self, result ): print("In SpecificFilter.doFilter\n") print( len( self.data ) ) ; #self.data is a normal python list print( len( result ) ); #So is result p = [x.clone() for x in self.data] #The members of self.data can #have their methods called result = p #result can be modified as a python list result.reverse() #another modification to result. Thanks again for the help, David J. Sankel Head Consultant Electron Consulting From dave at boost-consulting.com Tue Jan 7 19:03:26 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Jan 2003 13:03:26 -0500 Subject: [C++-sig] win32: BOOST_PYTHON_MODULE always exports DLL symbols In-Reply-To: ("Nicolas Lelong"'s message of "Fri, 3 Jan 2003 19:17:07 +0100") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFDDCF@admin56.narex.com> Message-ID: "Nicolas Lelong" writes: >> It seems to me that BOOST_PYTHON_STATIC_MODULE is the right symbol for >> controlling what you want. > > Well, I don't feel like having much arguments against it. > BOOST_PYTHON_STATIC_MODULE will certainly do the job quite well :) OK, done and checked in, including docs. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Jan 7 19:45:49 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Jan 2003 13:45:49 -0500 Subject: [C++-sig] Presenting a Python embedding tutorial for Boost.Python In-Reply-To: (Dirk Gerrits's message of "Sun, 08 Dec 2002 22:47:08 +0100") References: Message-ID: Dirk Gerrits writes: > I've finally finished the first draft of the embedding tutorial I was > writing for Boost.Python. I guess I underestimated the task, because > it took several days longer than I anticipated, but here it is: > > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/libs/python/doc/tutorial/doc/embedding.html > > Note that I am neither an experienced writer, nor an experienced > Pythoneer. Any and all proof reading will be greatly appreciated. Dirk, you did a wonderful job! I am so embarrassed that I didn't look at this before. Joel, what do you think? Can you integrate it into the tutorial? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Jan 7 20:22:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Jan 2003 14:22:23 -0500 Subject: [C++-sig] Boost.Python - Simple Pointer Question In-Reply-To: <6D805D4C4567D411AF32009027B683510E66E3C2@xvan02.vcd.hp.com> ("CLARKE,RON's message of "Mon, 6 Jan 2003 11:01:43 -0800") References: <6D805D4C4567D411AF32009027B683510E66E3C2@xvan02.vcd.hp.com> Message-ID: I was sure I posted this a few days ago, but it seems it never reached the list: "CLARKE,RON (HP-Vancouver,ex1)" writes: > I know I've missed something that should be obvious and simple, but ... > We have a medium-sized Python/C++ project and I am investigating replacing > SWIG with Boost.Python (V2). I've read all the documentation more than once, > reviewed the examples, etc. but I still don't see the syntax/macros/commands > needed to allow Python to understand a pointer to an existing C++ class > contained within another class. Here is a simplified scenario: > > class car > { > public: > car(void); > virtual ~car(void); > private: > ... > }; > > class garage{ > public: > garage(void); > ~garage(void); > car* pCar; > }; > > Class garage contains a public pointer to a car object (I don't have the > option of changing the C++ code; it would negatively affect too many users). > I can create garage and car objects OK and Python understands each one: > c=car() > g=garage() > > However, if I try something like this: > g.pCar = car() > the resulting object is null and trying to simply print the object yields a > "TypeError: bad argument for built-in operation". > > What have I missed? Can someone please provide an example (other than what > is in the documentation)? I think this might work for you: class_("garage") .add_property( make_getter(&garage::pCar, with_custodian_and_ward<1,2>()) , make_setter(&garage::pCar, return_internal_reference<>())) However, if garage::~garage() does "delete pCar" you're going to have big problems. Let me know if that's the case and we can try something else. > Similarly, if I want to pass a pointer to a C++ object as a parameter to a > C++ function or method, how do I expose the function properly such that a > user can type the function call in Python and have the object properly > passed into the C++ module? > For example: > garage.parkTheCar(c) ## what is the proper Boost.Python syntax for > exposing the parkTheCar method and pointer parameter? You don't need to do anything special as long as there are no ownership/lifetime issues in parkTheCar. If it just uses the pointer you pass and forgets it, you're fine. Otherwise you might need some CallPolicies. .def("parkTheCar", &garage::parkTheCar) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Tue Jan 7 20:37:47 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Tue, 07 Jan 2003 20:37:47 +0100 Subject: [C++-sig] Presenting a Python embedding tutorial for Boost.Python In-Reply-To: References: Message-ID: <3E1B2C8B.6010408@gerrits.homeip.net> David Abrahams wrote: > Dirk Gerrits writes: > > >>I've finally finished the first draft of the embedding tutorial I was >>writing for Boost.Python. I guess I underestimated the task, because >>it took several days longer than I anticipated, but here it is: >> >>http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/libs/python/doc/tutorial/doc/embedding.html >> >>Note that I am neither an experienced writer, nor an experienced >>Pythoneer. Any and all proof reading will be greatly appreciated. > > > Dirk, you did a wonderful job! Thanks! Great praise from an expert in the field. This evening couldn't possibly become any better. ;) > I am so embarrassed that I didn't look at this before. But I thought that you did look at it before, judging from the 'high-level remarks' you made back then. In any case, I think the recent C++ sig discussions might require me to change my tutorial-contribution a bit. I propose the following changes: - Try to come up with different examples for "Manual Reference Counting" because the current examples are a strong case for using python::tuple, not python::handle. - Move the "Manual Reference Counting" and "Boost.Python to the rescue" around and edit them slightly to form a chapter on python::handle. - Add a chapter on exception handling issues (python::handle_exception() and such). - Remove the Py_Finalize warning from "Running Python code from C++". (Once the bug is fixed.) - Change the text of "Running Python code from C++" to use python::interpreter instead of the Python C API. (Once it is added to BPL.) - Add a template Jamfile for embedded programs, analogous to the template Jamfile in "Building Hello World" for extension modules. (You posted one to the C++ sig twice so this shouldn't take long. ;)) As you might remember though, we had a little discussion about whether the manual reference counting should be explained so rigorously. I feel that it makes for a good beginning to the python::handle explanation. You, on the other hand, suggested that it might not be needed in the explanation and could be used as a rationale instead. So what should I do? I'll trust your judgement as a more experienced writer and Pythoneer. :) I'm not exactly sure *when* I'll find the time to make these tutorial changes, and I still need to fix the Py_Finalize-bug as well. (Unless someone else feels the incontrollable urge to fix it of course. ;)) > Joel, what do you think? Can you integrate it into the tutorial? I would like that very much. Let me know if I can do anything to make that easier. The QuickDoc file to generate the HTML can be found here: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/libs/python/doc/tutorial/doc/embedding.txt. To generate the HTML I used the QuickDoc program that comes with Spirit, only slightely altered to change the copyright notice. (That's why the HTML file references the Spirit logo and not the Boost one.) Regards, Dirk Gerrits PS From rwgk at yahoo.com Wed Jan 8 04:16:38 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 7 Jan 2003 19:16:38 -0800 (PST) Subject: [C++-sig] (no subject) In-Reply-To: <20030107173833.23470.qmail@web40612.mail.yahoo.com> Message-ID: <20030108031638.9316.qmail@web20203.mail.yahoo.com> --- David Sankel wrote: > from embedded_Filter import * > class SpecificFilter( Filter ): > def name( self ): > return 'SpecificFilterA' > def doFilter( self, result ): > print("In SpecificFilter.doFilter\n") > print( len( self.data ) ) ; #self.data is a normal > python list > print( len( result ) ); #So is result > p = [x.clone() for x in self.data] #The members of > self.data can > #have their > methods called > result = p #result can be modified as a > python list > result.reverse() #another modification to result. Can you explain in more detail what you expect the doFilter() method to do? Do you want to modify result? Note that result = p Only replaces a reference inside the function. I.e. the caller will not see any changes to the object passed in as "result". Unless I am missing something. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From jacek.generowicz at cern.ch Wed Jan 8 13:03:17 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 08 Jan 2003 13:03:17 +0100 Subject: [C++-sig] Re: v2 def_raw ? References: Message-ID: David Abrahams writes: > What we /do/ have is the ability to specify optional arguments > and keyword expressions > Does that cover your needs? I don't think so. But it's possible that I have missed the point. I have a C++ function (which came in a v1 interface to a C++ library, which I am migrating to v2 - I hope to lose this function by the time I've finished, but I'm stuck with it for now): return_type function(PyObject* tuple, PyObject* dict) { // Igrone dict. // Mess around with the elements of tuple. } IOW, what I really want would be written in python as def function( *args ): # Mess arount with elements of args. I was wondering whether it might be done with a precall CallPolicy, but I'm finding the documentation of that area a little too cryptic and abstract. From Gottfried.Ganssauge at HAUFE.DE Wed Jan 8 14:39:25 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Wed, 8 Jan 2003 14:39:25 +0100 Subject: [C++-sig] Wrapping opaque pointers returned from API functions Message-ID: <2040C0A1CA23D51181A30050BAAC990274A64D@BEREXCH> I am trying to wrap an API like the following: typedef struct workspace_ *workspace; workspace osr_init (const char *) { return 0; } void osr_exit (workspace ws) { std::cerr << ws << std::endl; } My first attempt at wrapping that API was BOOST_PYTHON_MODULE(_pyOSR) { def ("osr_init", &::osr_init, return_value_policy()); def ("osr_exit", &::osr_exit); } That compiled fine, but (of course) failed miserably when run with the following test script: import _pyOSR ws = _pyOSR.osr_init(".") print ws _pyOSR.osr_exit(ws) Here is the traceback: Traceback (most recent call last): File "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Release\test.py", line 3, in ? ws = _pyOSR.osr_init(".") TypeError: No to_python (by-value) converter found for C++ type: struct workspace_ * Now I thought: ok, let's register a converter extern "C" void dealloc(PyObject* self) { PyObject_Del(self); } struct workspace_wrapper : PyObject { workspace x; }; PyTypeObject workspaceType = { PyObject_HEAD_INIT(NULL) 0, "workspace", sizeof(workspace_wrapper), 0, dealloc }; struct p_from_workspace { static workspace &execute (workspace_wrapper &p_) { return p_.x; } }; struct pworkspace_to_python : to_python_converter { static PyObject* convert(workspace x) { workspace_wrapper *o = PyObject_New (workspace_wrapper, &workspaceType); o->x = x; return ((PyObject*) o); } }; BOOST_PYTHON_MODULE(_pyOSR) { pworkspace_to_python(); lvalue_from_pytype(); def ("osr_init", &::osr_init, return_value_policy()); def ("osr_exit", &::osr_exit); } This time the output changed: Traceback (most recent call last): File "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Release\test.py", line 5, in ? _pyOSR.osr_exit(ws) TypeError: bad argument type for built-in operation The call to osr_init() succeeded and produced the expected result: a workspace object. Unfortunately the library is unable to find the proper converter for converting that object back to my workspace pointer. I'm sure, there is something obvious I'm doing wrong, but what? Cheers, Gottfried Gan?auge -------------- next part -------------- An HTML attachment was scrubbed... URL: From horace_hdsl at seed.net.tw Wed Jan 8 15:19:31 2003 From: horace_hdsl at seed.net.tw (horace(seednet)) Date: Wed, 8 Jan 2003 22:19:31 +0800 Subject: [C++-sig] how do i wrap enums defined in a struct/class Message-ID: <001601c2b720$f6607bf0$c7d33b3d@hdsl001p4> Could anybody be so kind to tell me how to wrap this code snippet (or where can I find the example) by Boost.Python : // struct NeedToBeWrapped { enum color { eRed = 0, eGreen = 1, eBlue = 2 }; enum ErrorStatus { eES1 = 0, eES2 = 1, eES3 = 2 }; ... }; Regards T.L.Ho -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Wed Jan 8 18:21:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Jan 2003 12:21:29 -0500 Subject: [C++-sig] weird bug of addressof in MSVC 7 In-Reply-To: ("Nicolas Lelong"'s message of "Tue, 7 Jan 2003 10:29:28 +0100") References: Message-ID: "Nicolas Lelong" writes: > Hi, > > I stumbled upon a weird compilation error due to function 'addressof' in > MSVC7. Here is my test case : > > Any thoughts ? Definitely a compiler bug. I've checked in a workaround to boost/utility/addressof.hpp. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From camio at yahoo.com Wed Jan 8 18:35:16 2003 From: camio at yahoo.com (David Sankel) Date: Wed, 8 Jan 2003 09:35:16 -0800 (PST) Subject: [C++-sig] PyObject * self member in class wrappers. Message-ID: <20030108173516.30991.qmail@web40605.mail.yahoo.com> When a python class is being inherited from a c++ class, one must write a c++ wrapper around the c++ class. This wrapper must have a pointer to a PyObject called self. I was wondering, what exactly is this PyObject? Say I have the following scenario: class Cloneable { public: virtual Cloneable * Clone()=0; }; class PythonCloneable { public: PyObject * self; PythonCloneable( PyObject * self_ ) : self(self_) {} Cloneable * Clone() { PythonCloneable * theCopy; //... What goes here? return theCopy; } }; I would like Clone to return a copy (not instance) of the original. This way, both the clone and the original could be modified independently. How would I manipulate the self member to do this? Thanks, David J. Sankel From camio at yahoo.com Wed Jan 8 18:40:17 2003 From: camio at yahoo.com (David Sankel) Date: Wed, 8 Jan 2003 09:40:17 -0800 (PST) Subject: [C++-sig] Re: how do i wrap enums defined in a struct/class In-Reply-To: <3E1C65A3.8080400@nonconformity.net> Message-ID: <20030108174017.33578.qmail@web40614.mail.yahoo.com> > Could anybody be so kind to tell me how to wrap > this code snippet (or where can I find the example) > by Boost.Python : > // > struct NeedToBeWrapped > { > enum color { eRed = 0, > eGreen = 1, > eBlue = 2 > }; > enum ErrorStatus { eES1 = 0, > eES2 > = 1, > eES3 > = 2 > }; > ... > }; Here: http://www.boost.org/libs/python/doc/v2/enum.html#enum_-spec Good Luck, David J. Sankel From sauer at programmatic.de Wed Jan 8 20:39:21 2003 From: sauer at programmatic.de (Joerg Sauer) Date: Wed, 08 Jan 2003 19:39:21 GMT Subject: [C++-sig] Can't build boost::python release lib on msvc-stlport Message-ID: <3e1c7d1e.1043373371@192.168.1.200> Hi, I posted this message a few days ago in the build group, but haven't got any replies yet. In the meentime I tried several things including the project file for msvc from the cvs (Also checked out the latest cvs version), but with no success :-( Here is my problem: I can't get boost::python's release build to compile. I'm used bjam and the project file and get internal compiler errors when trying to build the python release lib/dll. My system is: win2000 sp2 msvc 6.0 sp5 activestate python 2.2.2 stlport 4.5.3 I tried to build all using bjam with the following batch file: -----begin batch file ----------- call "C:\Programme\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" c: cd C:\Developer\boost_1_29_0\tools\build\jam_src set VISUALC="C:\Programme\Microsoft Visual Studio\VC98" set JAM_TOOLSET=VISUALC nmake -f builds\win32-visualc.mk cd c:\developer\boost_1_29_0 set stlport-iostream="on" set STLPORT_VERSION="4.5.3" set STLPORT_PATH="c:/developer" set PYTHON_ROOT="c:/developer/python22" set PYTHON_VERSION="2.2" C:\Developer\boost_1_29_0\tools\build\jam_src\bin.ntx86\bjam.exe "-sTOOLS=msvc-stlport" ------end of batch file------------- The internal compiler errors occur in _complex.h from stlport. This is the output: -----begin error messages--------------- vc-C++ libs\python\build\bin\boost_python.dll\msvc-stlport\release\runtime-link-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5.3\numeric.obj ****** {BD Software Proxy CL v2.26} STL Message Decryption is ON! ****** numeric.cpp c:/developer\STLport-4.5.3\stlport\stl/_complex.h(889): fatal error C1001: INTERNER COMPILER- FEHLER (Internal Compiler Error) (Compiler-Datei "msc1.cpp", Zeile 1794) "cl" /Zm800 -nologo -GX -c -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -D_STLP_DO_IMPORT_CSTD_FUNCTIONS=1 /O2 /GX /GR /MD -I"libs\python\build" -I"c:/developer\STLport-4.5.3\stlport" -I"C:\Developer\boost_1_29_0" -I"c:\developer\python22\include" -I"C:\PROGRA~1\MIAF9D~1\VC98\include" -Fo"libs\python\build\bin\boost_python.dll\msvc-stlport\release\runtime-link-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5.3\numeric.obj" -Tp"libs\python\build\../src\numeric.cpp" ...failed vc-C++ libs\python\build\bin\boost_python.dll\msvc-stlport\release\runtime-link-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5.3\numeric.obj... vc-C++ libs\python\build\bin\boost_python.dll\msvc-stlport\release\runtime-link-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5.3\list.obj ****** {BD Software Proxy CL v2.26} STL Message Decryption is ON! ****** list.cpp c:/developer\STLport-4.5.3\stlport\stl/_complex.h(889): fatal error C1001: INTERNER COMPILER- FEHLER (Compiler-Datei "msc1.cpp", Zeile 1794) "cl" /Zm800 -nologo -GX -c -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE -D_STLP_DO_IMPORT_CSTD_FUNCTIONS=1 /O2 /GX /GR /MD -I"libs\python\build" -I"c:/developer\STLport-4.5.3\stlport" -I"C:\Developer\boost_1_29_0" -I"c:\developer\python22\include" -I"C:\PROGRA~1\MIAF9D~1\VC98\include" -Fo"libs\python\build\bin\boost_python.dll\msvc-stlport\release\runtime-link-dynamic\stlport-cstd-namespace-std\stlport-iostream-on\stlport-version-4.5.3\list.obj" -Tp"libs\python\build\../src\list.cpp" ---------- end of error messages-------------------- Both debug builds compile without a problem. All other boost libs build in debug and release build. Any suggestions? Regards Joerg From dave at boost-consulting.com Wed Jan 8 21:17:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Jan 2003 15:17:40 -0500 Subject: [C++-sig] Can't build boost::python release lib on msvc-stlport In-Reply-To: <3e1c7d1e.1043373371@192.168.1.200> (sauer@programmatic.de's message of "Wed, 08 Jan 2003 19:39:21 GMT") References: <3e1c7d1e.1043373371@192.168.1.200> Message-ID: sauer at programmatic.de (Joerg Sauer) writes: > Hi, > I posted this message a few days ago in the build group, but haven't > got any replies yet. > > In the meentime I tried several things including the project file for > msvc from the cvs (Also checked out the latest cvs version), but with > no success :-( > > Here is my problem: > > I can't get boost::python's release build to compile. What can I say? It's an internal compiler error, and it doesn't even happen in my code. My suggestion is to use the debug build. One thing you might do is to gradually change the compilation options so they become like the debug build, so you can isolate which one(s) are causing the problem. Then I can modify the build to avoid it for that toolset. HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Jan 9 00:12:32 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Jan 2003 18:12:32 -0500 Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: <20030106200507.29389.qmail@web40611.mail.yahoo.com> (David Sankel's message of "Mon, 6 Jan 2003 12:05:07 -0800 (PST)") References: <20030106200507.29389.qmail@web40611.mail.yahoo.com> Message-ID: David Sankel writes: >> > I would like the Python derived class to see a list of Abstracts. >> >> And what do you expect it to be able to do to the >> list? I'm not asking about the items it contains, >> yet. Do you need to be able to modify the length of >> the list, or move items within it, etc? > > I would like to have the ability to do everything > that you can do with a normal Python list. Such as > modify the length, move items within it, etc. If you expect these changes to affect the std::vector<> that was used to produce the list, then you're out of luck. There's no way to get Python to notify us when you change the list so that we can update the vector. The approach you are using below will never allow you to manipulate the original vector as a list from Python. Are you sure it wouldn't work to just expose std::vector > using class_ and write all the neccessary methods so that it looks like a Python List? The only way your Python code could tell the difference would be if you inspected its __class__ or did isinstance(x, list) or the like. > That was my misunderstanding. > >> Have you looked at >> > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html >> ? >> >> In order to use this, you'll need to expose the type >> of the Filter::data member. Unless... >> >> ...I suppose you want Filter::data to show up as a >> Python list also? > > Yes, if possible. > >> It sounds like you may want to explore >> > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2 > > Explored. Thanks a lot for your help with this thus > far. I really appreciate it. Here is where I am now > (I'm using the container conversions pointed to by the > faq): > class PythonFilter : public Filter > { > public: > PythonFilter( PyObject * self ) > : m_self( self ), m_initialized(true) { }; > void doFilter( vector > &result) > { > if( m_initialized ) > { > cout << "Got into doFilter with " << name() << endl; > call_method< > void, > vector< shared_ptr< Abstract > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You should not be specifying this parameter; it defeats the use of ref(). > ( m_self, "doFilter", ref( result ) ); > } > } > virtual std::string name() const > { > return call_method< std::string > ( m_self, "name" ); > } > virtual ~PythonFilter(){} > private: > PyObject * m_self; > bool m_initialized; > }; > > But I am still missing something because I cannot get > the following python code without the comments to > work: If you want help, please always specify precisely: * what you tried to do (i.e. what you did with SpecificFilter) * the result you expected * the result you actually got Just syaing "I can't get this to work", especially when it's just a declaration, doesn't give us much to go on. > from embedded_Filter import * > class SpecificFilter( Filter ): > def name( self ): > return 'SpecificFilterA' > def doFilter( self, result ): > print("In SpecificFilter.doFilter\n") > print( len( self.data ) ) ; #self.data is a normal python list > print( len( result ) ); #So is result > p = [x.clone() for x in self.data] #The members of self.data can > #have their methods called > result = p #result can be modified as a python list > result.reverse() #another modification to result. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From djowel at gmx.co.uk Thu Jan 9 01:24:52 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Thu, 9 Jan 2003 08:24:52 +0800 Subject: [C++-sig] Presenting a Python embedding tutorial for Boost.Python References: Message-ID: <008501c2b775$f4580120$fdd117d2@kim> ----- Original Message ----- From: "David Abrahams" > Dirk Gerrits writes: > > > I've finally finished the first draft of the embedding tutorial I was > > writing for Boost.Python. I guess I underestimated the task, because > > it took several days longer than I anticipated, but here it is: > > > > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/libs/python/do c/tutorial/doc/embedding.html > > > > Note that I am neither an experienced writer, nor an experienced > > Pythoneer. Any and all proof reading will be greatly appreciated. > > Dirk, you did a wonderful job! I am so embarrassed that I didn't look > at this before. > > Joel, what do you think? Can you integrate it into the tutorial? Sure. I need close coordination with you guys. How shall we proceed? Where shall we put it? Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com From n_lelong at hotmail.com Thu Jan 9 10:31:04 2003 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Thu, 9 Jan 2003 10:31:04 +0100 Subject: [C++-sig] weird bug of addressof in MSVC 7 References: Message-ID: > Definitely a compiler bug. I've checked in a workaround to > boost/utility/addressof.hpp. Works fine (of course), thanks ! I once more discovered new boost stuff - so many things to look at ! Regards, Nicolas. From bscott at iastate.edu Thu Jan 9 15:40:29 2003 From: bscott at iastate.edu (Ben Scott) Date: Thu, 09 Jan 2003 08:40:29 -0600 Subject: [C++-sig] passing raw pointers of interface impls Message-ID: <3E1D89DD.7080308@vrac.iastate.edu> I have been quite happily enjoying the ease at which Boost.Python v2 has been allowing me to export C++ libraries to Python. Thank you Dave for your excellent work! However, I've gotten stumped on the attached bit of code. I'm unfortunately getting the ambiguous "bad argument type for built-in operation" TypeError. I've reviewed the tutorial and references (including the last couple months of this list) but am at a loss to explain why c is of the wrong type. Any ideas on the matter would be most helpful. Here's the output of simple.py: Traceback (most recent call last): File "./simple.py", line 12, in ? factory.reg(c) TypeError: bad argument type for built-in operation cheers, ----- Ben Scott Research Assistant VR Juggler Team Virtual Reality Applications Center bscott at vrac.iastate.edu -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: simple.py URL: From rwgk at yahoo.com Thu Jan 9 22:35:18 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 9 Jan 2003 13:35:18 -0800 (PST) Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) Message-ID: <20030109213518.54295.qmail@web20203.mail.yahoo.com> --- David Abrahams wrote: > Are you sure it wouldn't work to just expose > std::vector > using class_ and > write all the neccessary methods so that it looks like > a Python List? If you decide to go down that road have a look at the file scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h which could be useful as a template for a std::vector<> wrapper. (flex_wrapper.h is for reference-counted C++ container types.) Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From rwgk at yahoo.com Thu Jan 9 23:05:13 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 9 Jan 2003 14:05:13 -0800 (PST) Subject: [C++-sig] passing raw pointers of interface impls In-Reply-To: <3E1D89DD.7080308@vrac.iastate.edu> Message-ID: <20030109220513.17289.qmail@web20205.mail.yahoo.com> --- Ben Scott wrote: > class CreatorImpl(Creator): > def __init__(self): > return What happens if you remove this __init__ function or have it call Creator.__init__ explicitly? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dirk at gerrits.homeip.net Thu Jan 9 20:29:43 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 09 Jan 2003 20:29:43 +0100 Subject: [C++-sig] Re: PyObject * self member in class wrappers. In-Reply-To: <20030108173516.30991.qmail@web40605.mail.yahoo.com> References: <20030108173516.30991.qmail@web40605.mail.yahoo.com> Message-ID: David Sankel wrote: > When a python class is being inherited from a c++ > class, one must write a c++ wrapper around the c++ > class. > > This wrapper must have a pointer to a PyObject called > self. > > I was wondering, what exactly is this PyObject? Python provides a 'Python/C API' that allows you to create C/C++ extension modules and to embed the Python interpreter in your C/C++ programs. Pointers to PyObjects are the Python/C API's way to use Python objects from the C/C++ side. Boost.Python uses advanced C++ techniques to provide a much easier interface to the Python/C API. One manifestation of this is in python::object which is basically a (very) convenient, high-level wrapper around PyObject*. A lower level wrapping around PyObject* is python::handle. > Say I have the following scenario: > > class Cloneable > { > public: > virtual Cloneable * Clone()=0; > }; > > class PythonCloneable > { > public: > PyObject * self; > PythonCloneable( PyObject * self_ ) : self(self_) {} > > Cloneable * Clone() > { > PythonCloneable * theCopy; > //... What goes here? > return theCopy; > } > }; > > I would like Clone to return a copy (not instance) of > the original. This way, both the clone and the > original could be modified independently. How would I > manipulate the self member to do this? Well I'm afraid that I'm not too sure myself. Here's what I thought up: You can wrap a PyObject* in a python::handle<>, create a python::object out of it and then copy that. Calling the copy's ptr() method gives you it's PyObject*. I'm just not totally sure whether you should construct the python::handle from self or from python::borrowed(self). I think it is the latter, resulting in: Cloneable * Clone() { object theObject( handle(borrowed(self)) ); object theCopy(theObject); return new PythonClonable(theCopy.ptr()); } The problem with this however, is that theCopy falls out of scope at the end of the function body so the clone will have a dangling self pointer. Very bad! To fix this, I think you could do this: class PythonCloneable { object self_object; public: PyObject* self; PythonCloneable( PyObject * self_ ) : self(self_) {} PythonCloneable( handle<> self_ ) : self_object(self_) { self = self_object.ptr(); } Cloneable* Clone() { object theObject( handle(borrowed(self)) ); object theCopy(theObject); return new PythonClonable(theCopy); } }; I believe that should work. But I have not tested this. And it rather feels like a hack. I can't help but think that Boost.Python should provide a better way to do this. If it is there, then I just didn't think of it. If not, then I think it should be added, whatever 'it' may be. Regards, Dirk Gerrits From dave at boost-consulting.com Thu Jan 9 18:58:35 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 12:58:35 -0500 Subject: [C++-sig] Wrapping opaque pointers returned from API functions In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A64D@BEREXCH> (Gottfried.Ganssauge@HAUFE.DE's message of "Wed, 8 Jan 2003 14:39:25 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A64D@BEREXCH> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: > I am trying to wrap an API like the following: > typedef struct workspace_ *workspace; > > workspace osr_init (const char *) { return 0; } > void osr_exit (workspace ws) { std::cerr << ws << std::endl; } > > My first attempt at wrapping that API was > BOOST_PYTHON_MODULE(_pyOSR) > { > def ("osr_init", &::osr_init, return_value_policy()); > def ("osr_exit", &::osr_exit); > } > > That compiled fine, but (of course) failed miserably when run with the > following test script: > import _pyOSR > > ws = _pyOSR.osr_init(".") > print ws > _pyOSR.osr_exit(ws) > > Here is the traceback: > Traceback (most recent call last): > File > "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Release\test.py", > line 3, in ? > ws = _pyOSR.osr_init(".") > TypeError: No to_python (by-value) converter found for C++ type: struct workspace_ * Right. You asked it to dereference the workspace_ pointer and return a copy of the result inside a Python object. > Now I thought: ok, let's register a converter > extern "C" void > dealloc(PyObject* self) { > PyObject_Del(self); > } > > struct workspace_wrapper : PyObject { workspace x; }; > > PyTypeObject workspaceType = { > PyObject_HEAD_INIT(NULL) > 0, > "workspace", > sizeof(workspace_wrapper), > 0, > dealloc > }; > > struct p_from_workspace { > static workspace &execute (workspace_wrapper &p_) { ^^^^^^^^^^^ Should be workspace_& > return p_.x; Likewise, should be return *p_.x; [see caveat below] > } > }; > > struct pworkspace_to_python > : to_python_converter > { > static PyObject* convert(workspace x) { > workspace_wrapper *o = > PyObject_New (workspace_wrapper, &workspaceType); > o->x = x; > return ((PyObject*) o); > } > }; > > BOOST_PYTHON_MODULE(_pyOSR) > { > pworkspace_to_python(); > lvalue_from_pytype(); > > def ("osr_init", &::osr_init, return_value_policy()); > def ("osr_exit", &::osr_exit); > } > > This time the output changed: > > Traceback (most recent call last): > File > "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Release\test.py", > line 5, in ? > _pyOSR.osr_exit(ws) > TypeError: bad argument type for built-in operation > > The call to osr_init() succeeded and produced the expected result: a > workspace object. > Unfortunately the library is unable to find the proper converter for > converting that object back to my workspace pointer. I'm sure, there is > something obvious I'm doing wrong, but what? I'm impressed with how close you got, especially considering that most of the tools you had to use are undocumented! When converting from_python to a C++ pointer type, the library looks for an lvalue converter for the *pointee*. In other words, to convert to a Foo*, the source Python object must contain a Foo. Obviously, wrapping opaque pointers is a common thing to want to do, and the library should provide a better facility for it. Caveat: The code I've suggested above technically invokes undefined behavior if p_.x is 0, but I'm not aware of any platform which will have a problem with it. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Jan 9 22:46:49 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 16:46:49 -0500 Subject: [C++-sig] PyObject * self member in class wrappers. In-Reply-To: <20030108173516.30991.qmail@web40605.mail.yahoo.com> (David Sankel's message of "Wed, 8 Jan 2003 09:35:16 -0800 (PST)") References: <20030108173516.30991.qmail@web40605.mail.yahoo.com> Message-ID: David Sankel writes: > When a python class is being inherited from a c++ > class, one must write a c++ wrapper around the c++ > class. > > This wrapper must have a pointer to a PyObject called > self. > > I was wondering, what exactly is this PyObject? Its the Python object which contains the C++ object instance. > Say I have the following scenario: > > class Cloneable > { > public: > virtual Cloneable * Clone()=0; > }; > > class PythonCloneable > { > public: > PyObject * self; > PythonCloneable( PyObject * self_ ) : self(self_) {} > > Cloneable * Clone() > { > PythonCloneable * theCopy; > //... What goes here? ordinarily, return call_method(self, "Clone"); > return theCopy; > } > }; > > I would like Clone to return a copy (not instance) of > the original. This way, both the clone and the > original could be modified independently. How would I > manipulate the self member to do this? You wouldn't. This is one of those interfaces which can't be wrapped as is (not a Boost.Python limitation; it's the nature of the interface and Python's reference-counting GC). The problem is that there's no way to keep the Python object that results from calling Clone on a derived class alive. If you try the code above, and call Clone on such a class, you'll get a nice, descriptive exception in python that says your result pointer would be dangling. An interface that you *can* wrap reliably would have you returning boost::shared_ptr from your Clone() function, which is a much better design from the C++ side anyway. [Actually, there's a way to hack your way around it: make all derived Clone functions stick the result instance in a global list, so they live forever] -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Jan 9 19:33:21 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 13:33:21 -0500 Subject: [C++-sig] passing raw pointers of interface impls In-Reply-To: <3E1D89DD.7080308@vrac.iastate.edu> (Ben Scott's message of "Thu, 09 Jan 2003 08:40:29 -0600") References: <3E1D89DD.7080308@vrac.iastate.edu> Message-ID: Ben Scott writes: > I have been quite happily enjoying the ease at which Boost.Python v2 > has been allowing me to export C++ libraries to Python. Thank you Dave > for your excellent work! > > However, I've gotten stumped on the attached bit of code. I'm > unfortunately getting the ambiguous "bad argument type for built-in > operation" TypeError. I've reviewed the tutorial and references > (including the last couple months of this list) but am at a loss to > explain why c is of the wrong type. Any ideas on the matter would be > most helpful. > > Here's the output of simple.py: > Traceback (most recent call last): > File "./simple.py", line 12, in ? > factory.reg(c) > TypeError: bad argument type for built-in operation > > > class CreatorImpl(Creator): > def __init__(self): Right here, you need to call Creator.__init__(self) to create the C++ base class instance. Of course, you could just leave out the __init__ function here altogether and let the base __init__ get called. > return > def create(self, b): > return A(b) > > factory = Factory() > c = CreatorImpl() > factory.reg(c) > > b = B() > a = factory.create(b) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Jan 9 18:41:18 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 12:41:18 -0500 Subject: [C++-sig] Re: v2 def_raw ? In-Reply-To: (Jacek Generowicz's message of "08 Jan 2003 13:03:17 +0100") References: Message-ID: Jacek Generowicz writes: > David Abrahams writes: > >> What we /do/ have is the ability to specify optional arguments > >> and keyword expressions > >> Does that cover your needs? > > I don't think so. But it's possible that I have missed the point. > > I have a C++ function (which came in a v1 interface to a C++ library, > which I am migrating to v2 - I hope to lose this function by the time > I've finished, but I'm stuck with it for now): > > return_type function(PyObject* tuple, PyObject* dict) { > // Igrone dict. > // Mess around with the elements of tuple. > } > > IOW, what I really want would be written in python as > > def function( *args ): > # Mess arount with elements of args. > > I was wondering whether it might be done with a precall CallPolicy, > but I'm finding the documentation of that area a little too cryptic > and abstract. CallPolicies are really not intended for that purpose; they're for specifying how pointer/reference return types will be converted to python, and for helping with lifetime management issues (so that Python can't easily delete objects which your C++ code is holding pointers to). I looked a little bit at the library code a few days ago to see what would be needed to support a "raw" function; I don't have a pretty interface for you, but I can tell you how to make one with the library's implementation details. Be warned that these interfaces may change, but hopefully we'll have an "official" interface for what you want to do by then. python::objects::function_object( f // must be py_function compatible , 0, std::numeric_limits::max() // arity range , python::detail::keyword_range()); // no keywords Will create a Python callable object. f is any function pointer, function reference, or function object which can be invoked with two PyObject* arguments and returns something convertible to a PyObject*. You can add this to your module namespace with: scope().attr("name") = function_object(f, ... ); HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Jan 9 19:01:49 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 13:01:49 -0500 Subject: [C++-sig] how do i wrap enums defined in a struct/class In-Reply-To: <001601c2b720$f6607bf0$c7d33b3d@hdsl001p4> ("horace\'s message of "Wed, 8 Jan 2003 22:19:31 +0800") References: <001601c2b720$f6607bf0$c7d33b3d@hdsl001p4> Message-ID: "horace\(seednet\)" writes: > Could anybody be so kind to tell me how to wrap this code snippet (or where can I find the example) by Boost.Python : > // > struct NeedToBeWrapped > { > enum color { eRed = 0, > eGreen = 1, > eBlue = 2 > }; > enum ErrorStatus { eES1 = 0, > eES2 = 1, > eES3 = 2 > }; > ... > }; { scope in_class( // establish new scope for definitions class_("NeedToBeWrapped") ); enum_< NeedToBeWrapped::color >("color") .value("eRed", NeedToBeWrapped::eRed) .value("eGreen", NeedToBeWrapped::eGreen) .value("eBlue", NeedToBeWrapped::eBlue) ; // similarly for ErrorStatus } HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Thu Jan 9 18:13:14 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 9 Jan 2003 09:13:14 -0800 (PST) Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: Message-ID: <20030109171314.56646.qmail@web20205.mail.yahoo.com> --- David Abrahams wrote: > Are you sure it wouldn't work to just expose > std::vector > using class_ and > write all the neccessary methods so that it looks like > a Python List? The only way your Python code could > tell the difference would be if you inspected its > __class__ or did isinstance(x, list) or the like. If you decide to go down that road have a look at the file scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h This could serve as a template for a std::vector<> wrapper. You could also use flex_wrapper.h directly since it is designed to be used in other packages. It is clearly not a light-weight approach and you'd have to switch to a reference-counted container type, but it leads to streamlined Python/C++ integration. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From rwgk at yahoo.com Thu Jan 9 19:44:51 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 9 Jan 2003 10:44:51 -0800 (PST) Subject: [C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :) In-Reply-To: Message-ID: <20030109184451.19560.qmail@web20209.mail.yahoo.com> --- David Abrahams wrote: > Are you sure it wouldn't work to just expose > std::vector > using class_ and > write all the neccessary methods so that it looks like > a Python List? If you decide to go down that road have a look at the file scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h which could be useful as a template for a std::vector<> wrapper. (flex_wrapper.h is for reference-counted C++ container types.) Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nickm at sitius.com Fri Jan 10 00:18:14 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Thu, 09 Jan 2003 18:18:14 -0500 Subject: [C++-sig] static methods Message-ID: <3E1E0336.226EA1B6@sitius.com> An HTML attachment was scrubbed... URL: From sauer at programmatic.de Thu Jan 9 23:23:25 2003 From: sauer at programmatic.de (Joerg Sauer) Date: Thu, 09 Jan 2003 22:23:25 GMT Subject: [C++-sig] Re: Can't build boost::python release lib on msvc-stlport References: <3e1c7d1e.1043373371@192.168.1.200> Message-ID: <3e1df59c.1139755591@192.168.1.200> Hi, sorry, but I thought msvc-stlport is a comon platform and someone would have had the problem too. I changed the optimization setting from "optimize speed" to "default" and it compiles. Regards Joerg PS: I just stepped a little deeper into v2 and well I'm really impressed! Great job! From bscott at iastate.edu Fri Jan 10 05:02:23 2003 From: bscott at iastate.edu (Ben Scott) Date: Thu, 09 Jan 2003 22:02:23 -0600 Subject: [C++-sig] passing raw pointers of interface impls References: <3E1D89DD.7080308@vrac.iastate.edu> Message-ID: <3E1E45CF.7060209@vrac.iastate.edu> David Abrahams wrote: > Ben Scott writes: > > >>I have been quite happily enjoying the ease at which Boost.Python v2 >>has been allowing me to export C++ libraries to Python. Thank you Dave >>for your excellent work! >> >>However, I've gotten stumped on the attached bit of code. I'm >>unfortunately getting the ambiguous "bad argument type for built-in >>operation" TypeError. I've reviewed the tutorial and references >>(including the last couple months of this list) but am at a loss to >>explain why c is of the wrong type. Any ideas on the matter would be >>most helpful. >> >>Here's the output of simple.py: >>Traceback (most recent call last): >> File "./simple.py", line 12, in ? >> factory.reg(c) >>TypeError: bad argument type for built-in operation >> >> >>class CreatorImpl(Creator): >> def __init__(self): > > > Right here, you need to call Creator.__init__(self) to create the C++ > base class instance. Of course, you could just leave out the __init__ > function here altogether and let the base __init__ get called. Yeah, I had tried that, but since Creator is an abstract type it can't be instantiated as you are suggesting. This of course causes the "RuntimeError: This class cannot be instantiated from Python" error from the default __init__ in Creator that BPL defines. > > >> return >> def create(self, b): >> return A(b) >> >>factory = Factory() >>c = CreatorImpl() >>factory.reg(c) >> >>b = B() >>a = factory.create(b) > > cheers, ----- Ben Scott Research Assistant VR Juggler Team Virtual Reality Applications Center bscott at vrac.iastate.edu From dave at boost-consulting.com Fri Jan 10 05:15:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 09 Jan 2003 23:15:00 -0500 Subject: [C++-sig] passing raw pointers of interface impls In-Reply-To: <3E1E45CF.7060209@vrac.iastate.edu> (Ben Scott's message of "Thu, 09 Jan 2003 22:02:23 -0600") References: <3E1D89DD.7080308@vrac.iastate.edu> <3E1E45CF.7060209@vrac.iastate.edu> Message-ID: Ben Scott writes: > David Abrahams wrote: >> Ben Scott writes: >> >>>I have been quite happily enjoying the ease at which Boost.Python v2 >>>has been allowing me to export C++ libraries to Python. Thank you Dave >>>for your excellent work! >>> >>>However, I've gotten stumped on the attached bit of code. I'm >>>unfortunately getting the ambiguous "bad argument type for built-in >>>operation" TypeError. I've reviewed the tutorial and references >>>(including the last couple months of this list) but am at a loss to >>>explain why c is of the wrong type. Any ideas on the matter would be >>>most helpful. >>> >>>Here's the output of simple.py: >>>Traceback (most recent call last): >>> File "./simple.py", line 12, in ? >>> factory.reg(c) >>>TypeError: bad argument type for built-in operation >>> >>> >>>class CreatorImpl(Creator): >>> def __init__(self): >> Right here, you need to call Creator.__init__(self) >> to create the C++ >> base class instance. Of course, you could just leave out the __init__ >> function here altogether and let the base __init__ get called. > > Yeah, I had tried that, but since Creator is an > abstract type it can't be instantiated as you are > suggesting. You have to remove the no_init from the class_ declaration. > This of course causes the "RuntimeError: > This class cannot be instantiated from Python" error > from the default __init__ in Creator that BPL defines. One of these days, we'll have the __init__ function generated by no_init check the actual Python class being created to make sure it's not the base type (Creator, in this case). Until then, just leave out no_init and you'll be fine. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From bscott at iastate.edu Fri Jan 10 05:30:43 2003 From: bscott at iastate.edu (Ben Scott) Date: Thu, 09 Jan 2003 22:30:43 -0600 Subject: [C++-sig] passing raw pointers of interface impls References: <3E1D89DD.7080308@vrac.iastate.edu> <3E1E45CF.7060209@vrac.iastate.edu> Message-ID: <3E1E4C73.9010405@vrac.iastate.edu> >> >>Yeah, I had tried that, but since Creator is an >>abstract type it can't be instantiated as you are >>suggesting. > > > You have to remove the no_init from the class_ > declaration. > > >>This of course causes the "RuntimeError: >>This class cannot be instantiated from Python" error >>from the default __init__ in Creator that BPL defines. > > > One of these days, we'll have the __init__ function generated by > no_init check the actual Python class being created to make sure it's > not the base type (Creator, in this case). Until then, just leave out > no_init and you'll be fine. > Well that's reasonable. I guess I was trying to keep it so that python users could not instantiate the Creator in order to mirror the C++ side. It sounds that your proposed change to BPL would certainly eliminate the issue I was seeing. Either way, the removal of no_init will solve my near-term problems. Thanks for you quick replies and help! cheers, ----- Ben Scott Research Assistant VR Juggler Team Virtual Reality Applications Center bscott at vrac.iastate.edu From Gottfried.Ganssauge at HAUFE.DE Fri Jan 10 11:22:27 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Fri, 10 Jan 2003 11:22:27 +0100 Subject: AW: [C++-sig] Wrapping opaque pointers returned from API function s Message-ID: <2040C0A1CA23D51181A30050BAAC990274A65C@berexch.ber.haufemg.com> Hi Dave, I knew it was something simple (although not entirely obvious :-)) Thanks a lot, Gottfried > -----Ursprungliche Nachricht----- > Von: David Abrahams [mailto:dave at boost-consulting.com] > Gesendet: Donnerstag, 9. Januar 2003 18:59 > An: c++-sig at python.org > Betreff: Re: [C++-sig] Wrapping opaque pointers returned from API > functions > > > Gottfried.Ganssauge at HAUFE.DE writes: > > > I am trying to wrap an API like the following: > > typedef struct workspace_ *workspace; > > > > workspace osr_init (const char *) { return 0; } > > void osr_exit (workspace ws) { std::cerr << ws << std::endl; } > > > > My first attempt at wrapping that API was > > BOOST_PYTHON_MODULE(_pyOSR) > > { > > def ("osr_init", &::osr_init, > return_value_policy()); > > def ("osr_exit", &::osr_exit); > > } > > > > That compiled fine, but (of course) failed miserably when > run with the > > following test script: > > import _pyOSR > > > > ws = _pyOSR.osr_init(".") > > print ws > > _pyOSR.osr_exit(ws) > > > > Here is the traceback: > > Traceback (most recent call last): > > File > > > "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Releas > e\test.py", > > line 3, in ? > > ws = _pyOSR.osr_init(".") > > TypeError: No to_python (by-value) converter found for C++ > type: struct workspace_ * > > Right. You asked it to dereference the workspace_ pointer and return > a copy of the result inside a Python object. > > > Now I thought: ok, let's register a converter > > extern "C" void > > dealloc(PyObject* self) { > > PyObject_Del(self); > > } > > > > struct workspace_wrapper : PyObject { workspace x; }; > > > > PyTypeObject workspaceType = { > > PyObject_HEAD_INIT(NULL) > > 0, > > "workspace", > > sizeof(workspace_wrapper), > > 0, > > dealloc > > }; > > > > struct p_from_workspace { > > static workspace &execute (workspace_wrapper &p_) { > ^^^^^^^^^^^ > Should be workspace_& > > > return p_.x; > > Likewise, should be return *p_.x; > [see caveat below] > > > } > > }; > > > > struct pworkspace_to_python > > : to_python_converter > > { > > static PyObject* convert(workspace x) { > > workspace_wrapper *o = > > PyObject_New (workspace_wrapper, &workspaceType); > > o->x = x; > > return ((PyObject*) o); > > } > > }; > > > > BOOST_PYTHON_MODULE(_pyOSR) > > { > > pworkspace_to_python(); > > lvalue_from_pytype(); > > > > def ("osr_init", &::osr_init, > return_value_policy()); > > def ("osr_exit", &::osr_exit); > > } > > > > This time the output changed: > > > > Traceback (most recent call last): > > File > > > "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Releas > e\test.py", > > line 5, in ? > > _pyOSR.osr_exit(ws) > > TypeError: bad argument type for built-in operation > > > > The call to osr_init() succeeded and produced the expected result: a > > workspace object. > > Unfortunately the library is unable to find the proper converter for > > converting that object back to my workspace pointer. I'm > sure, there is > > something obvious I'm doing wrong, but what? > > I'm impressed with how close you got, especially considering that most > of the tools you had to use are undocumented! > > When converting from_python to a C++ pointer type, the library looks > for an lvalue converter for the *pointee*. In other words, to convert > to a Foo*, the source Python object must contain a Foo. > > Obviously, wrapping opaque pointers is a common thing to want to do, > and the library should provide a better facility for it. > > Caveat: The code I've suggested above technically invokes undefined > behavior if p_.x is 0, but I'm not aware of any platform which will > have a problem with it. > > -- > David Abrahams > dave at boost-consulting.com * http://www.boost-consulting.com > Boost support, enhancements, training, and commercial distribution > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jacek.generowicz at cern.ch Fri Jan 10 12:13:38 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 10 Jan 2003 12:13:38 +0100 Subject: [C++-sig] Re: v2 def_raw ? References: Message-ID: David Abrahams writes: > CallPolicies are really not intended for that purpose; they're for > specifying how pointer/reference return types will be converted to > python, and for helping with lifetime management issues (so that > Python can't easily delete objects which your C++ code is holding > pointers to). That's pretty much what I understood, but the phrase "precall - Python argument tuple management before the wrapped object is invoked" made me wonder whether there was more that could be done with it. > I looked a little bit at the library code a few days ago to see what > would be needed to support a "raw" function; I don't have a pretty > interface for you, but I can tell you how to make one with the > library's implementation details. Be warned that these interfaces may > change, but hopefully we'll have an "official" interface for what you > want to do by then. Are there any plans to release a next version with all sort of new goodies, or is it all open for now ? > python::objects::function_object( > f // must be py_function compatible > , 0, std::numeric_limits::max() // arity range > , python::detail::keyword_range()); // no keywords > scope().attr("name") = function_object(f, ... ); Great ... and I can do class_("foo") .def("bar",function_object(f, ... ) ); aswell, but I don't seem to be able to do function_object bar(f, ... ); ... class_("foo") .def("bar",bar); because the first line gives a parse error. Anyway, thanks very much for your solution. From dave at boost-consulting.com Fri Jan 10 14:17:21 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 08:17:21 -0500 Subject: [C++-sig] Re: v2 def_raw ? In-Reply-To: (Jacek Generowicz's message of "10 Jan 2003 12:13:38 +0100") References: Message-ID: Jacek Generowicz writes: > David Abrahams writes: > >> CallPolicies are really not intended for that purpose; they're for >> specifying how pointer/reference return types will be converted to >> python, and for helping with lifetime management issues (so that >> Python can't easily delete objects which your C++ code is holding >> pointers to). > > That's pretty much what I understood, but the phrase "precall - Python > argument tuple management before the wrapped object is invoked" made > me wonder whether there was more that could be done with it. > >> I looked a little bit at the library code a few days ago to see what >> would be needed to support a "raw" function; I don't have a pretty >> interface for you, but I can tell you how to make one with the >> library's implementation details. Be warned that these interfaces may >> change, but hopefully we'll have an "official" interface for what you >> want to do by then. > > Are there any plans to release a next version Yes. > with all sort of new goodies, or is it all open for now ? The only very solid plans for new goodies are to release a new mechanisms for users to define C++<->Python type converters, and to scope them in a way that avoids certain conflicts. I would like to be able to do more work on the library, but it's hard to commit to that without more funding... >> python::objects::function_object( >> f // must be py_function compatible >> , 0, std::numeric_limits::max() // arity range >> , python::detail::keyword_range()); // no keywords > >> scope().attr("name") = function_object(f, ... ); > > Great ... and I can do > > class_("foo") > .def("bar",function_object(f, ... ) ); > > aswell, but I don't seem to be able to do > > function_object bar(f, ... ); > ... > class_("foo") > .def("bar",bar); > > because the first line gives a parse error. Because function_object is a function, not a class. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Gottfried.Ganssauge at HAUFE.DE Fri Jan 10 14:58:07 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Fri, 10 Jan 2003 14:58:07 +0100 Subject: AW: [C++-sig] Wrapping opaque pointers returned from API function s Message-ID: <2040C0A1CA23D51181A30050BAAC990274A663@berexch.ber.haufemg.com> ... > Obviously, wrapping opaque pointers is a common thing to want to do, > and the library should provide a better facility for it. I made one up for my own use, see below. This reduces my sample to # include "pointer_converter.h" # include # include # include # include using namespace boost::python; # include typedef struct workspace_ *workspace; workspace osr_init (const char *) { return ((workspace) 0x47110815); } void osr_exit (workspace ws) { std::cerr << ws << std::endl; } BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(workspace_) DEFINE_POINTER_CONVERTER(workspace) BOOST_PYTHON_MODULE(_pyOSR) { REGISTER_POINTER_CONVERTER(workspace); def ("osr_init", &::osr_init, return_value_policy()); def ("osr_exit", &::osr_exit); } I'm not really content with the macro implementation but couldn't see another implementation easily. Cheers, Gottfried -------------><-----------------------><------------------------><---------- ----------><------------- /* * file: pointer_converter.h * date: 2003-01-10 * Copyright C 2003 Haufe Mediengruppe * * Generic Conversion of opaque C++-pointers to a Python- * Wrapper. * * $Id$ */ # include # include # include /** * Declare a converter which will convert a C++-Pointer to an * opaque structure to a Python object containing the pointer * and vice versa. * * @param P * Pointer type to wrap * * @note * In addition you need to define specializations for type_traits * using BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION * * @see type_traits documentation */ # define DEFINE_POINTER_CONVERTER(P) \ namespace { \ template \ struct pointer_converter \ : PyObject, \ to_python_converter< \ typename Pointer, pointer_converter > \ { \ \ pointer_converter() { \ lvalue_from_pytype< \ pointer_converter, &pointer_converter::type>(); \ } \ \ static PyObject* convert(Pointer x) { \ pointer_converter *o = \ PyObject_New ( \ pointer_converter, &pointer_converter::type); \ \ o->x = x; \ return ((PyObject*) o); \ } \ \ static boost::python::pointee::type &execute ( \ pointer_converter &p_) { \ return *p_.x; \ } \ \ static void dealloc(PyObject* self) { \ PyObject_Del(self); \ } \ private: \ typename Pointer x; \ static PyTypeObject type; \ }; \ \ PyTypeObject pointer_converter

::type = { \ PyObject_HEAD_INIT(NULL) \ 0, \ # P, \ sizeof(pointer_converter

), \ 0, \ pointer_converter

::dealloc \ }; \ } /** * register a pointer converter with the boost.python * converter registry. * This needs to go into the _init function. * * @param P * Pointer type wrapped by a pointer converter with * DEFINE_POINTER_CONVERTER. * * @see DEFINE_POINTER_CONVERTER */ # define REGISTER_POINTER_CONVERTER(P) pointer_converter

() -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Fri Jan 10 15:28:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 09:28:50 -0500 Subject: [C++-sig] static methods In-Reply-To: <3E1E0336.226EA1B6@sitius.com> (Nikolay Mladenov's message of "Thu, 09 Jan 2003 18:18:14 -0500") References: <3E1E0336.226EA1B6@sitius.com> Message-ID: Nikolay Mladenov writes: > Hi, > > I started migrating from v1 to v2 couple of days ago, and got to the point to realize that the static methods > do not translate anymore. > So I searched the news groups, collected all the hints I managed to find and tried to implement support for > "staticmethod". > > What I did so far is: > 1. added is_static member of boost::python::function which is set to true based on policies > 2. changed the function "function_descr_get" like that > ??? static PyObject * > ??? function_descr_get(PyObject *func, PyObject *obj, PyObject *type_) > ??? { > ??????? if(static_cast(func)->is_static()){ > ??????????? PyObject *res = PyStaticMethod_New(func); > ??????????? return res; > ??????? } > ??????? if (obj == Py_None) > ??????????? obj = NULL; > ??????? return PyMethod_New(func, obj, type_); > ??? } > > now from python I get: > >>>> Object.some_static_method > > > but: >>>> Object.some_static_method(params) > Traceback (most recent call last): > ? File "", line 1, in ? > TypeError: 'staticmethod' object is not callable > > Some debugging showed me that PyStaticMethod_New returns PyObject * > that has tp_call==0. That's because a staticmethod is a descriptor type, not a callable type directly. You get something callable when you access the attribute through a class or instance, just as you do when accessing function objects. > I find this very strange and I have no idea how to continue around > it. > > Can somebody help with suggestion? This is not the strategy I would've taken. I think you should do something which mirrors pure Python: def foo(object): def f(x,y): return x*y f = staticmethod(f) So in C++, it would be something like: class_("foo") .def("f", &foo::f) .staticmethod("f") // ** ; Where the marked line would be implemented something like this: self& staticmethod(char const* name) { this->attr(name) = object(handle<>( PyStaticMethod_New(this->attr(name).ptr()) )); } -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Gottfried.Ganssauge at HAUFE.DE Fri Jan 10 15:33:24 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Fri, 10 Jan 2003 15:33:24 +0100 Subject: [C++-sig] Wrapping opaque pointers returned from API function s Message-ID: <2040C0A1CA23D51181A30050BAAC990274A664@berexch.ber.haufemg.com> ... > # include "pointer_converter.h" that implementation worked only in that toy example, as soon as I added a second converter it botched. Here is a better one Cheers, Gottfried --------------><------------------><----------------><-----------------><--- ------------- /* * file: pointer_converter.h * date: 2003-01-10 * Copyright C 2003 Haufe Mediengruppe * * Generic Conversion of opaque C++-pointers to a Python- * Wrapper. * * $Id$ * $Log$ */ # include # include # include template struct pointer_converter : PyObject, ::boost::python::to_python_converter< typename Pointer, pointer_converter > { pointer_converter() { boost::python::lvalue_from_pytype< pointer_converter, &pointer_converter::type>(); } static PyObject* convert(Pointer x) { pointer_converter *o = PyObject_New ( pointer_converter, &pointer_converter::type); o->x = x; return ((PyObject*) o); } static boost::python::pointee::type &execute ( pointer_converter &p_) { return *p_.x; } static void dealloc(PyObject* self) { PyObject_Del(self); } private: typename Pointer x; static PyTypeObject type; }; /** * Declare a converter which will convert a C++-Pointer to an * opaque structure to a Python object containing the pointer * and vice versa. * * @param P * Pointer type to wrap * * @note * In addition you need to define specializations for type_traits * using BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION * * @see type_traits documentation */ # define DEFINE_POINTER_CONVERTER(P) \ PyTypeObject pointer_converter

::type = { \ PyObject_HEAD_INIT(NULL) \ 0, \ # P, \ sizeof(pointer_converter

), \ 0, \ pointer_converter

::dealloc \ }; \ /** * register a pointer converter with the boost.python * converter registry. * This needs to go into the _init function. * * @param P * Pointer type wrapped by a pointer converter with * DEFINE_POINTER_CONVERTER. * * @see DEFINE_POINTER_CONVERTER */ # define REGISTER_POINTER_CONVERTER(P) pointer_converter

() -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Fri Jan 10 15:35:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 09:35:19 -0500 Subject: [C++-sig] Re: PyObject * self member in class wrappers. In-Reply-To: (Dirk Gerrits's message of "Thu, 09 Jan 2003 20:29:43 +0100") References: <20030108173516.30991.qmail@web40605.mail.yahoo.com> Message-ID: Dirk Gerrits writes: > Well I'm afraid that I'm not too sure myself. Here's what I thought up: > > > You can wrap a PyObject* in a python::handle<>, create > a python::object out of it and then copy that. copying an instance of class object just does what it does in Python; it makes a copy of the reference. > Calling the copy's ptr() method gives you it's PyObject*. > > I'm just not totally sure whether you should construct > the python::handle from self or from > python::borrowed(self). I think it is the latter, > resulting in: > > Cloneable * Clone() > { > object theObject( handle(borrowed(self)) ); > object theCopy(theObject); > return new PythonClonable(theCopy.ptr()); > } There's no way this would work. It just makes a new C++ object which refers to the same Python object. > The problem with this however, is that theCopy falls > out of scope at the end of the function body so the > clone will have a dangling self pointer. Very bad! That's the least of the problems. > To fix this, I think you could do this: > > class PythonCloneable > { > object self_object; > public: > PyObject* self; > PythonCloneable( PyObject * self_ ) : self(self_) {} > PythonCloneable( handle<> self_ ) : self_object(self_) > { self = self_object.ptr(); } > > Cloneable* Clone() > { > object theObject( handle(borrowed(self)) ); > object theCopy(theObject); > return new PythonClonable(theCopy); > } > }; > > I believe that should work. But I have not tested > this. And it rather feels like a hack. No coincidence; you can't get there that way. > I can't help but think that Boost.Python should provide > a better way to do this. If it is there, then I just > didn't think of it. If not, then I think it should be > added, whatever 'it' may be. It's an important use case, but you can't get around the ownership issue. Either the C++ object owns the Python object or it's the other way around. Conceivably we could hook up Python's cycle GC to this and allow them to keep references to one-another, but if you start passing around raw Cloneable*s instead of proper smart pointers, it's almost certainly going to get messed up anyway. The only thing I think Boost.Python can reasonably provide is a way to do it with Clone() returning boost::shared_ptr... and we already provide that. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Jan 10 16:04:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 10:04:40 -0500 Subject: [C++-sig] Re: Can't build boost::python release lib on msvc-stlport In-Reply-To: <3e1df59c.1139755591@192.168.1.200> (sauer@programmatic.de's message of "Thu, 09 Jan 2003 22:23:25 GMT") References: <3e1c7d1e.1043373371@192.168.1.200> <3e1df59c.1139755591@192.168.1.200> Message-ID: sauer at programmatic.de (Joerg Sauer) writes: > Hi, > sorry, but I thought msvc-stlport is a comon platform and someone > would have had the problem too. Someone did. They never bothered to narrow down the cause for us, though. > > I changed the optimization setting from "optimize speed" to "default" > and it compiles. OK, I've tuned the Jamfile and msvc toolset file to improve optimization for regular MSVC builds and to work around the msvc-stlport problem. > Regards > Joerg > > PS: I just stepped a little deeper into v2 and well I'm really > impressed! Great job! Thanks very much! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Fri Jan 10 16:39:53 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 10 Jan 2003 10:39:53 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> Message-ID: <3E1EE949.A382D75B@sitius.com> An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Fri Jan 10 16:44:30 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 10:44:30 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E1EE949.A382D75B@sitius.com> (Nikolay Mladenov's message of "Fri, 10 Jan 2003 10:39:53 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1EE949.A382D75B@sitius.com> Message-ID: Nikolay Mladenov writes: > Thank you David, > > But isn't this going to mess up the overloading? No. > I also don't know how to create overloaded staticmethods in python. Don't worry about it. First you overload, then you make it static. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Fri Jan 10 17:21:41 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Fri, 10 Jan 2003 17:21:41 +0100 Subject: [C++-sig] Re: PyObject * self member in class wrappers. In-Reply-To: References: <20030108173516.30991.qmail@web40605.mail.yahoo.com> Message-ID: David Abrahams wrote: > Dirk Gerrits writes: > > >>Well I'm afraid that I'm not too sure myself. Here's what I thought up: >> >> >>You can wrap a PyObject* in a python::handle<>, create >>a python::object out of it and then copy that. > > > copying an instance of class object just does what it does in Python; > it makes a copy of the reference. DOH! You're right of course. That pretty much makes my whole post incorrect. Dirk Gerrits From nickm at sitius.com Fri Jan 10 19:45:27 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 10 Jan 2003 13:45:27 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> Message-ID: <3E1F14C7.D26F2D9B@sitius.com> An HTML attachment was scrubbed... URL: From nickm at sitius.com Fri Jan 10 19:52:01 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 10 Jan 2003 13:52:01 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> Message-ID: <3E1F1651.B6863E88@sitius.com> An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Fri Jan 10 20:10:03 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 14:10:03 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E1F1651.B6863E88@sitius.com> (Nikolay Mladenov's message of "Fri, 10 Jan 2003 13:52:01 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> Message-ID: Nikolay Mladenov writes: > From python only: > >>>> class C: > ...? def f(): > ...?? return 0 > ... >>>> C.f > >>>> C.f = staticmethod(C.f) >>>> C.f > >>>> C.f() > Traceback (most recent call last): > ? File "", line 1, in ? > TypeError: unbound method f() must be called with C instance as first argument ( > got nothing instead) > > What am I missing? I just figured it out; my instructions missed this point as well. Note the difference between what you did above and : >>> class C: ... def f(): ... return 0 ... f = staticmethod(f) >>> C.f() 0 The difference is that when you do this from Python, everything after the first colon goes into a plain dictionary first, and the class is built around it. When you do what I told you to do, it is building a class and adding things one-by-one to its dictionary. Once "f" is added as a regular function, accesses to it through C, and of course the descriptor functionality of f takes over. Now try this: >>> class C(object): ... def f(): ... return 0 ... >>> C.f = staticmethod(C.__dict__['f']) >>> C.f() 0 So we could use that approach in Boost.Python HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Jan 10 20:13:09 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 14:13:09 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E1F14C7.D26F2D9B@sitius.com> (Nikolay Mladenov's message of "Fri, 10 Jan 2003 13:45:27 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1F14C7.D26F2D9B@sitius.com> Message-ID: Nikolay Mladenov writes: > David, > > I implemented what you suggested but it did not work > "f" was still an unbound method. Right see my other message. > Even more. If I write: > > ?? class_("foo") > ??????? .def("f", &foo::f); //no staticmethod("foo") call > > and from python: > >>>>foo.f = staticmethod(foo.f) >>>>foo.f(0,0) > Traceback (most recent call last): > ? File "", line 1, in ? > TypeError: unbound method Boost.Python.function object must be called with Foo > instance as first argument (got nothing instead) > > What is the purpose of the "function_descr_get" in the function_type > struct? To make functions and methods work as they do in Python. If you want to read about descriptors and how they work, see: http://python.sourceforge.net/peps/pep-0252.txt > I tried substituting it with 0, and the things started working as in v1. I seriously doubt it would work for ordinary methods which need an initial 'self' argument with that change. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Fri Jan 10 20:53:39 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 10 Jan 2003 14:53:39 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> Message-ID: <3E1F24C3.98553581@sitius.com> An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Fri Jan 10 21:06:44 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 15:06:44 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E1F24C3.98553581@sitius.com> (Nikolay Mladenov's message of "Fri, 10 Jan 2003 14:53:39 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> <3E1F24C3.98553581@sitius.com> Message-ID: Nikolay Mladenov writes: > I am going to read the PEP. > But I think I am getting closer with: > ??? self& staticmethod(char const* name) > ??? { > ??????? PyObject *method = pytype_check(&PyMethod_Type, ((object)(this->attr(name))).ptr()); > ??????? this->attr(name) = object(handle<>( > ???????????? PyStaticMethod_New(PyMethod_GET_FUNCTION(method) ) > ??????????? )); > ??????? return *this; > ??? } > I guess PyMethod_GET_FUNCTION corresponds to "C.__dict__['f']" since > it extracts the function from the PyMethod Descriptor . It's similar, but I would prefer it if you would get it from the class' __dict__. One day I may have a reason not to build a true Python Method wrapper, and use something else instead; that would break your code. You can reach the class' dict very simply via: detail::downcast(this->ptr())->tp_dict -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Fri Jan 10 23:49:19 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 10 Jan 2003 17:49:19 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> <3E1F24C3.98553581@sitius.com> Message-ID: <3E1F4DEF.78AF8177@sitius.com> An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Sat Jan 11 01:19:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 10 Jan 2003 19:19:53 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E1F4DEF.78AF8177@sitius.com> (Nikolay Mladenov's message of "Fri, 10 Jan 2003 17:49:19 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> <3E1F24C3.98553581@sitius.com> <3E1F4DEF.78AF8177@sitius.com> Message-ID: Nikolay Mladenov writes: > David, > > In object dict_base::get(object_cref k) const > isn't it better to have expect_non_null? > Because otherwise wrong key leads to access violation. > > Best regards. > Nikolay There's definitely a bug, good catch. That's the wrong fix for it, but I've checked in the right one. Thanks, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From leo4ever22 at yahoo.com Sat Jan 11 11:55:29 2003 From: leo4ever22 at yahoo.com (Leonard Dick) Date: Sat, 11 Jan 2003 02:55:29 -0800 (PST) Subject: [C++-sig] Re: static methods In-Reply-To: <3E1F1651.B6863E88@sitius.com> Message-ID: <20030111105529.21507.qmail@web21303.mail.yahoo.com> Dear, thank for your information. Can you please, remove my e-mail address from your mailing list, I don't need them any more, I'm okey with the once i have. Thanks a lot for your co-operation. bye leo --- Nikolay Mladenov wrote:


From dave at boost-consulting.com Sun Jan 12 01:05:37 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 11 Jan 2003 19:05:37 -0500 Subject: [C++-sig] Wrapping opaque pointers returned from API function s In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A664@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Fri, 10 Jan 2003 15:33:24 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A664@berexch.ber.haufemg.com> Message-ID: Gottfried, This is a pretty nice implementation! However, there are a few slight problems that will show up on very conformant C++ implementations: firstly, pointer_converter

::dealloc has C++ linkage, so you can't stick it in the tp_dealloc slot, which has to be a function pointer with 'C' linkage. Second, a few things you are doing with pointer_converter depend on it having an initial section which is layout-compatible with PyObject. Unfortunately, the C++ standard doesn't guarantee anything about object layout for classes with bases, constructors, or private members (non-POD types). Third, your use of the typename keyword in the declaration of the 'x' member is illegal. You can only use typename for dependent types; paradoxically, template arguments themselves are not dependent. You also left out a typename on the execute function. Finally, I think your DEFINE_POINTER_CONVERTER macro is likely to make a Python type name containing illegal characters like '*', though I guess you are passing a typedef here so it's probably not a big deal. Allow me to suggest the following modification (untested): <-------------> // convert_opaque_pointer -- // // usage: convert_opaque_pointer("name") // // registers to- and from- python conversions for a type pointer_type, // and a corresponding Python type called "name". // namespace detail { extern "C" inline void dealloc(PyObject* self) { PyObject_Del(self); } } template struct convert_opaque_pointer : ::boost::python::to_python_converter< Pointer, convert_opaque_pointer > { // This is a POD so we can use PyObject_Del on it, for example. struct instance { PyObject_HEAD Pointer x; }; convert_opaque_pointer(char const* name) { type_object.tp_name = name; boost::python::lvalue_from_pytype< opaque_pointer_converter, &opaque_pointer_converter::type >(); } static PyObject* convert(Pointer x) { instance *o = PyObject_New (instance, &type_object); o->x = x; return boost::python::detail::upcast(o); } static typename boost::remove_pointer::type& execute(instance &p_) { return *p_.x; } static PyTypeObject type_object; }; template PyTypeObject convert_opaque_pointer::type_object = { PyObject_HEAD_INIT(NULL) 0, 0, sizeof(typename convert_opaque_pointer::instance), 0, detail::dealloc }; <-------------> After we settle on something, I'd like to put it in the library, or at least in the FAQ. Gottfried.Ganssauge at HAUFE.DE writes: > ... >> # include "pointer_converter.h" > > that implementation worked only in that toy example, as soon as I added a > second converter it botched. > Here is a better one > -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sun Jan 12 01:27:36 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 11 Jan 2003 16:27:36 -0800 Subject: [C++-sig] Building boost.python on Mac OS X Message-ID: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> I want to build boost.python on a Mac OS X platform. There doesn't appear to be any prebuilt boost.Jam executable available from the boost web pages. So I follow the instructions to run make in tools/build/jam_src subdirectory. It appears to work, but there's still no bjam executable resulting form the build. The only executable is a `jam0' file. Is that it? From dave at boost-consulting.com Sun Jan 12 02:17:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 11 Jan 2003 20:17:46 -0500 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Sat, 11 Jan 2003 16:27:36 -0800") References: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: > I want to build boost.python on a Mac OS X platform. There > doesn't appear to be any prebuilt boost.Jam executable available from > the boost web pages. So I follow the instructions to run make in > tools/build/jam_src subdirectory. It appears to work, but there's > still no bjam executable resulting form the build. The only > executable is a `jam0' file. Is that it? Did you look for a bin/ directory? bjam is supposed to end up there. I should warn you that nobody's succeeded in building it for OSX to date. Apple's dynamic linking model and C++ do not seem to be cooperating yet. Rene Rivera has done the most work on this, to my knowledge. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sun Jan 12 03:04:27 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 11 Jan 2003 18:04:27 -0800 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: References: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> Message-ID: <200301120204.h0C24RT08131@libra3.slac.stanford.edu> >>>>> On Sat, 11 Jan 2003 20:17:46 -0500, David Abrahams said: > Did you look for a bin/ directory? bjam is > supposed to end up there. I find no `bin' directory. Maybe its buried deeper than I looked. > I should warn you that nobody's succeeded in building it for OSX to > date. Apple's dynamic linking model and C++ do not seem to be > cooperating yet. Rene Rivera has done the most work on this, to my > knowledge. That sounds bad for my cross-platform distribution. I've got Unix distribution and Windows in spite of Bill Gates' perverse build envirnoment. Are you telling me that Steve Jobs has given me even more difficult build enviroment even its all built on Free BSD?. Iknow these guys complete, but do they compete on who can make the most difficult buld environment? From dave at boost-consulting.com Sun Jan 12 03:11:51 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 11 Jan 2003 21:11:51 -0500 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <200301120204.h0C24RT08131@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Sat, 11 Jan 2003 18:04:27 -0800") References: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> <200301120204.h0C24RT08131@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: >>>>>> On Sat, 11 Jan 2003 20:17:46 -0500, David Abrahams said: > >> Did you look for a bin/ directory? bjam is >> supposed to end up there. > > I find no `bin' directory. Maybe its buried deeper than I looked. Sorry, it's not bin/..., it's: $BOOST_ROOT/tools/build/jam_src/bin./bjam If you don't have that, what happens when you run jam0 from the jam_src directory? >> I should warn you that nobody's succeeded in building it for OSX to >> date. Apple's dynamic linking model and C++ do not seem to be >> cooperating yet. Rene Rivera has done the most work on this, to my >> knowledge. > > That sounds bad for my cross-platform distribution. I've got > Unix distribution and Windows in spite of Bill Gates' perverse build > envirnoment. Are you telling me that Steve Jobs has given me even > more difficult build enviroment even its all built on Free BSD?. > Iknow these guys complete, but do they compete on who can make the > most difficult buld environment? Windows in some ways has the sanest of all dynamic library systems. I don't know what to tell you about Apple. I think they want to fix the situation with dynamic linking and C++, but last I checked they didn't have their act together. The good news is that Rene has done most of the hard work of tuning Boost.Build to work for OSX, so when/if Apple has fixed something, the groundwork has already been laid. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Sun Jan 12 04:46:09 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 11 Jan 2003 19:46:09 -0800 (PST) Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <200301120204.h0C24RT08131@libra3.slac.stanford.edu> Message-ID: <20030112034609.84528.qmail@web20202.mail.yahoo.com> --- "Paul F. Kunz" wrote: > > I should warn you that nobody's succeeded in building it for OSX to > > date. Apple's dynamic linking model and C++ do not seem to be > > cooperating yet. Rene Rivera has done the most work on this, to my > > knowledge. Here is the latest I know of: http://mail.python.org/pipermail/c++-sig/2002-October/002407.html You will need Python 2.3 to reproduce this. > That sounds bad for my cross-platform distribution. I've got Unix > distribution and Windows in spite of Bill Gates' perverse build > envirnoment. Are you telling me that Steve Jobs has given me even > more difficult build enviroment even its all built on Free BSD?. > Iknow these guys complete, but do they compete on who can make the > most difficult buld environment? Building under Windows is easy if you use bjam or scons. Apple is definitely the hardest platform to deal with. Please let us know if you make any progress. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From paul at pfdubois.com Sun Jan 12 07:55:34 2003 From: paul at pfdubois.com (Paul F Dubois) Date: Sat, 11 Jan 2003 22:55:34 -0800 Subject: [C++-sig] RE: static methods In-Reply-To: <20030111170008.17508.11102.Mailman@mail.python.org> Message-ID: <000801c2ba07$9ac22f70$6601a8c0@NICKLEBY> I found it hard to read the thread due to html embedded in my digest, but one thing I did notice was that in Python you did not have your class C inherit from object. If you use property, staticmethod, or classmethod in an old-style class, they work but they don't work, if you get my drift. They execute at class compile time but don't function properly. Here is a correct example. I hope this is the source of your difficulty. Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32 Type "copyright", "credits" or "license" for more information. IDLE 0.8 -- press F1 for help >>> class C (object): def f(x,y): return x + y f = staticmethod(f) >>> C.f(3,2) 5 >>> c=C() >>> c.f(3,2) 5 Note that the call to staticmethod is at the same level of indentation as the def f. This happens during class definition. Moral: metaclasses make your head explode. From dave at boost-consulting.com Sun Jan 12 14:58:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 12 Jan 2003 08:58:20 -0500 Subject: [C++-sig] RE: static methods In-Reply-To: <000801c2ba07$9ac22f70$6601a8c0@NICKLEBY> ("Paul F Dubois"'s message of "Sat, 11 Jan 2003 22:55:34 -0800") References: <000801c2ba07$9ac22f70$6601a8c0@NICKLEBY> Message-ID: "Paul F Dubois" writes: > I found it hard to read the thread due to html embedded in my digest, but > one thing I did notice was that in Python you did not have your class C > inherit from object. If you use property, staticmethod, or classmethod in an > old-style class, they work but they don't work, if you get my drift. They > execute at class compile time but don't function properly. Can you show an example where that's the case? It seems to work just fine AFAICT: >>> class C: ... def f(x,y): ... return x+y ... f = staticmethod(f) ... >>> C.f(2,3) 5 >>> C().f(2,3) 5 > Here is a correct example. I hope this is the source of your > difficulty. > It wouldn't be an issue for Boost.Python extension classes anyway, since they are all derived from object. > Note that the call to staticmethod is at the same level of > indentation as the def f. This happens during class definition. > > Moral: metaclasses make your head explode. This has nothing to do with metaclasses, though. It's all about descriptors. What's so conceptually difficult about metaclasses? With all due respect, I think "metaclasses make your head explode" is in general a bad lesson for people to learn and we should stop promulgating it. It leads to misapprehensions like the one you show above, that any seemingly mysterious behavior has to do with metaclasses. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sun Jan 12 16:54:14 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sun, 12 Jan 2003 07:54:14 -0800 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: References: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> <200301120204.h0C24RT08131@libra3.slac.stanford.edu> Message-ID: <200301121554.h0CFsEw18042@libra3.slac.stanford.edu> >>>>> On Sat, 11 Jan 2003 21:11:51 -0500, David Abrahams said: > $BOOST_ROOT/tools/build/jam_src/bin./bjam In /Users/pfkeb/boost_1_29_0/tools/build/jam_src/bin.macosxppc: lots of .o files, no executable. > If you don't have that, what happens when you run jam0 from the > jam_src directory? [libra2:tools/build/jam_src] pfkeb% pwd /Users/pfkeb/boost_1_29_0/tools/build/jam_src [libra2:tools/build/jam_src] pfkeb% jam0 ...found 202 targets... ...using 30 temp targets... ...updating 3 targets... ...using command.o... < lots more using messages> Archive bin.macosxppc/libjam.a libtool: unrecognized option `-o' Try `libtool --help' for more information. libtool -o bin.macosxppc/libjam.a bin.macosxppc/command.o < and more .o's > ...failed Archive bin.macosxppc/libjam.a... ...skipped jam for lack of libjam.a... ...skipped bjam for lack of jam... ...failed updating 1 target... ...skipped 2 targets... [libra2:tools/build/jam_src] pfkeb% From Paul_Kunz at SLAC.Stanford.EDU Sun Jan 12 17:00:26 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sun, 12 Jan 2003 08:00:26 -0800 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: References: <200301120027.h0C0Ram07849@libra3.slac.stanford.edu> <200301120204.h0C24RT08131@libra3.slac.stanford.edu> Message-ID: <200301121600.h0CG0Qw18071@libra3.slac.stanford.edu> >>>>> On Sat, 11 Jan 2003 21:11:51 -0500, David Abrahams said: > I don't know what to tell you about Apple. I think they want to fix > the situation with dynamic linking and C++, but last I checked they > didn't have their act together. Hmmm. When I was active on the NeXT platform over 10 years ago, the problem was building shared libraries with any compiled language. > The good news is that Rene has done > most of the hard work of tuning Boost.Build to work for OSX, so > when/if Apple has fixed something, the groundwork has already been > laid. I got Qt (commerical edition) to build and run on OS X. So maybe there's some hope. From Gottfried.Ganssauge at haufe.de Sun Jan 12 23:47:20 2003 From: Gottfried.Ganssauge at haufe.de (=?iso-8859-1?Q?Gottfried_Gan=DFauge?=) Date: Sun, 12 Jan 2003 23:47:20 +0100 Subject: [C++-sig] Wrapping opaque pointers returned from API function s References: <2040C0A1CA23D51181A30050BAAC990274A664@berexch.ber.haufemg.com> Message-ID: <009101c2ba8c$90870230$44a837c2@gieke> > Gottfried, > > This is a pretty nice implementation! Thanks. > > However, there are a few slight problems that will show up on very > conformant C++ implementations: firstly, pointer_converter

::dealloc > has C++ linkage, so you can't stick it in the tp_dealloc slot, which > has to be a function pointer with 'C' linkage. Second, a few things Thought about that myself, but as my compiiler (msvc) didn't complain ... > you are doing with pointer_converter depend on it having an initial > section which is layout-compatible with PyObject. Unfortunately, the > C++ standard doesn't guarantee anything about object layout for > classes with bases, constructors, or private members (non-POD types). Didn't know that. Just for curiosity: Are there real implementations making a difference here? > Third, your use of the typename keyword in the declaration of the 'x' > member is illegal. You can only use typename for dependent types; > paradoxically, template arguments themselves are not dependent. You > also left out a typename on the execute function. I'll make it better the next time. promised :-) > > Finally, I think your DEFINE_POINTER_CONVERTER macro is likely to make > a Python type name containing illegal characters like '*', though I > guess you are passing a typedef here so it's probably not a big deal. As I said: I wasn't really happy with that macro; I like your your solution much better. > > Allow me to suggest the following modification (untested): I like it - especially as it does away with my macros - , and I took the freedom to make it work (on MSVC that is, see below): > > <-------------> > // convert_opaque_pointer -- > // > // usage: convert_opaque_pointer("name") > // > // registers to- and from- python conversions for a type pointer_type, > // and a corresponding Python type called "name". > // > namespace detail ^^^^^ Both mscv compilers (6.0 and 7) agree that this is ambigous (probably with boost::python::detail !?). The complaint, alas, occurs when using detail::dealloc! > { > extern "C" inline void dealloc(PyObject* self) ^^^^^ We're using a pointer to this function; therefore this function can't be expanded inline, right? > { > PyObject_Del(self); > } > } > > template > struct convert_opaque_pointer > : ::boost::python::to_python_converter< > Pointer, convert_opaque_pointer > > { > // This is a POD so we can use PyObject_Del on it, for example. I see your point, but msvc doesn't accept your upcast below; and anyway; who guarantees that PyObject won't be declared differently in the next python release? What about struct instance : public PyObject { Pointer x; }; ? > struct instance > { > PyObject_HEAD > Pointer x; > }; > > convert_opaque_pointer(char const* name) > { > type_object.tp_name = name; ^^^^^ should be const_cast (name), as tp_name is declared char * > > boost::python::lvalue_from_pytype< > opaque_pointer_converter, &opaque_pointer_converter::type ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ I take it you mean convert_opaque_pointer, convert_opaque_pointer::type_object > >(); > } > > static PyObject* convert(Pointer x) > { > instance *o = PyObject_New (instance, &type_object); > o->x = x; > return boost::python::detail::upcast(o); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MSVC6 produces a compiler error here (error C2780: 'Target *__cdecl boost::python::detail::upcast(Source *,int *,int *,Target *)' : expected 4 arguments - 1 supported), but it works, when I derive instance publicly from PyObject. > } > > static typename boost::remove_pointer::type& > execute(instance &p_) > { > return *p_.x; > } > > static PyTypeObject type_object; > }; > > template > PyTypeObject convert_opaque_pointer::type_object = > { > PyObject_HEAD_INIT(NULL) > 0, > 0, > sizeof(typename convert_opaque_pointer::instance), > 0, > detail::dealloc > }; > <-------------> > > After we settle on something, I'd like to put it in the library, or at I would be more than glad about that. > least in the FAQ. > Finally my edition of your implementation: // convert_opaque_pointer -- // // usage: convert_opaque_pointer("name") // // registers to- and from- python conversions for a type pointer_type, // and a corresponding Python type called "name". // namespace cop_detail { extern "C" void dealloc(PyObject* self) { PyObject_Del(self); } } template struct convert_opaque_pointer : ::boost::python::to_python_converter< Pointer, convert_opaque_pointer > { // This is a POD so we can use PyObject_Del on it, for example. struct instance : public PyObject { Pointer x; }; convert_opaque_pointer(char const* name) { type_object.tp_name = const_cast (name); boost::python::lvalue_from_pytype< convert_opaque_pointer, &convert_opaque_pointer::type_object >(); } static PyObject* convert(Pointer x) { instance *o = PyObject_New (instance, &type_object); o->x = x; return o; } static typename boost::remove_pointer::type& execute(instance &p_) { return *p_.x; } static PyTypeObject type_object; }; template PyTypeObject convert_opaque_pointer::type_object = { PyObject_HEAD_INIT(NULL) 0, 0, sizeof(typename convert_opaque_pointer::instance), 0, cop_detail::dealloc }; Cheers, Gottfried From dave at boost-consulting.com Mon Jan 13 00:43:20 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 12 Jan 2003 18:43:20 -0500 Subject: [C++-sig] Wrapping opaque pointers returned from API function s In-Reply-To: <009101c2ba8c$90870230$44a837c2@gieke> (Gottfried =?iso-8859-1?q?Gan=DFauge's?= message of "Sun, 12 Jan 2003 23:47:20 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A664@berexch.ber.haufemg.com> <009101c2ba8c$90870230$44a837c2@gieke> Message-ID: Gottfried Gan?auge writes: >> Gottfried, >> >> This is a pretty nice implementation! > Thanks. > >> >> However, there are a few slight problems that will show up on very >> conformant C++ implementations: firstly, pointer_converter

::dealloc >> has C++ linkage, so you can't stick it in the tp_dealloc slot, which >> has to be a function pointer with 'C' linkage. Second, a few things > > Thought about that myself, but as my compiiler (msvc) didn't complain ... It is a bit too permissive in that department. >> you are doing with pointer_converter depend on it having an initial >> section which is layout-compatible with PyObject. Unfortunately, the >> C++ standard doesn't guarantee anything about object layout for >> classes with bases, constructors, or private members (non-POD >> types). > > Didn't know that. Just for curiosity: Are there real implementations > making a difference here? Not to my knowledge. It's unfortunate that the C++ standard gave implementors so much leeway they don't even seem to use :( >> Third, your use of the typename keyword in the declaration of the 'x' >> member is illegal. You can only use typename for dependent types; >> paradoxically, template arguments themselves are not dependent. You >> also left out a typename on the execute function. > > I'll make it better the next time. promised :-) > >> >> Finally, I think your DEFINE_POINTER_CONVERTER macro is likely to make >> a Python type name containing illegal characters like '*', though I >> guess you are passing a typedef here so it's probably not a big >> deal. > > As I said: I wasn't really happy with that macro; I like your your solution > much better. > >> >> Allow me to suggest the following modification (untested): > > I like it - especially as it does away with my macros - , and I took > the freedom to make it work (on MSVC that is, see below): > >> >> <-------------> >> // convert_opaque_pointer -- >> // >> // usage: convert_opaque_pointer("name") >> // >> // registers to- and from- python conversions for a type pointer_type, >> // and a corresponding Python type called "name". >> // >> namespace detail > ^^^^^ > Both mscv compilers (6.0 and 7) agree that this is ambigous (probably with > boost::python::detail !?). The complaint, alas, occurs when using > detail::dealloc! You must have a using directive lying around somewhere, or you put all of this into boost::python, which I didn't expect. Anyway, we can pick a different name. There is probably a dealloc in boost::python::detail already. >> { >> extern "C" inline void dealloc(PyObject* self) > ^^^^^ > We're using a pointer to this function; therefore this function can't be > expanded inline, right? Right; the inline declaration just prevents the linker from seeing multiple definitions. >> { >> PyObject_Del(self); >> } >> } >> >> template >> struct convert_opaque_pointer >> : ::boost::python::to_python_converter< >> Pointer, convert_opaque_pointer > >> { >> // This is a POD so we can use PyObject_Del on it, for example. > I see your point, but msvc doesn't accept your upcast below; I didn't say I tested the code ;-) > and anyway; who guarantees that PyObject won't be declared > differently in the next python release? Guido does. > What about struct instance : public PyObject { Pointer x; }; ? No, that's non-POD. It has a base class. >> struct instance >> { >> PyObject_HEAD >> Pointer x; >> }; >> >> convert_opaque_pointer(char const* name) >> { >> type_object.tp_name = name; > ^^^^^ should be > const_cast (name), as tp_name is declared char * >> >> boost::python::lvalue_from_pytype< >> opaque_pointer_converter, &opaque_pointer_converter::type > ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ > I take it you mean > convert_opaque_pointer, > convert_opaque_pointer::type_object Right. >> >(); >> } >> >> static PyObject* convert(Pointer x) >> { >> instance *o = PyObject_New (instance, &type_object); >> o->x = x; >> return boost::python::detail::upcast(o); > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > MSVC6 produces a compiler error here (error C2780: 'Target *__cdecl > boost::python::detail::upcast(Source *,int *,int *,Target *)' : expected 4 > arguments - 1 supported), but it works, when I derive instance publicly from > PyObject. Sorry, remove the ::detail qualification. Should be boost::python::upcast(o). >> } >> >> static typename boost::remove_pointer::type& >> execute(instance &p_) >> { >> return *p_.x; >> } >> >> static PyTypeObject type_object; >> }; >> >> template >> PyTypeObject convert_opaque_pointer::type_object = >> { >> PyObject_HEAD_INIT(NULL) >> 0, >> 0, >> sizeof(typename convert_opaque_pointer::instance), >> 0, >> detail::dealloc >> }; >> <-------------> >> >> After we settle on something, I'd like to put it in the library, or at > I would be more than glad about that. > >> least in the FAQ. >> > Finally my edition of your implementation: -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Gottfried.Ganssauge at HAUFE.DE Mon Jan 13 09:44:43 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 13 Jan 2003 09:44:43 +0100 Subject: AW: [C++-sig] Wrapping opaque pointers returned from API function s Message-ID: <2040C0A1CA23D51181A30050BAAC990274A666@berexch.ber.haufemg.com> ... > >> namespace detail > > ^^^^^ > > Both mscv compilers (6.0 and 7) agree that this is ambigous > (probably with > > boost::python::detail !?). The complaint, alas, occurs when using > > detail::dealloc! > > You must have a using directive lying around somewhere, or you put > all of this into boost::python, which I didn't expect. Anyway, we can You are right: I had "using namespace boost::python" after the #include for pointer_converter.h. > pick a different name. There is probably a dealloc in > boost::python::detail already. Nope. > > >> { > >> extern "C" inline void dealloc(PyObject* self) > > ^^^^^ > > We're using a pointer to this function; therefore this > function can't be > > expanded inline, right? ok. > > Right; the inline declaration just prevents the linker from seeing > multiple definitions. > ... > >> // This is a POD so we can use PyObject_Del on it, for example. > > > I see your point, but msvc doesn't accept your upcast below; > > I didn't say I tested the code ;-) Of course. Anyway, your upcast is probably invalid anyway, because PyObject ist not a base class of instance. > > > and anyway; who guarantees that PyObject won't be declared > > differently in the next python release? > > Guido does. > > > What about struct instance : public PyObject { Pointer x; }; ? > > No, that's non-POD. It has a base class. I think I have a solution that is hopefully more conforming but doesn't rely on the Python implementation details (and it even resembles a bit to real inheritance) struct instance { PyObject base_; Pointer x; }; ... static PyObject* convert(Pointer x) { instance *o = PyObject_New (instance, &type_object); o->x = x; return &o->base_; } I can't lookup the paragraph in the standard, but I found something in the draft of "C++ in a nutshell". In Chapter 7 it says: """ A POD class can contain padding between data members, but no padding appears before the first member. Therefore, a pointer to the POD object can be converted (with reinterpret_cast<>) to a pointer to the first element. """ My next draft follows below Cheers, Gottfried -----------><------------------------><-----------------------><------------ ---------><-------------- # ifndef pointer_converter_h_ # define pointer_convert_h_ # include # include // convert_opaque_pointer -- // // usage: convert_opaque_pointer("name") // // registers to- and from- python conversions for a type pointer_type, // and a corresponding Python type called "name". // // Note: // In addition you may need to define specializations for type_traits // on the base class of pointer_type using // BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION // namespace opc_detail { extern "C" inline void dealloc(PyObject* self) { PyObject_Del(self); } } template struct convert_opaque_pointer : ::boost::python::to_python_converter< Pointer, convert_opaque_pointer > { // This is a POD so we can use PyObject_Del on it, for example. struct instance { PyObject base_; Pointer x; }; convert_opaque_pointer(char const* name) { type_object.tp_name = const_cast (name); boost::python::lvalue_from_pytype< convert_opaque_pointer, &convert_opaque_pointer::type_object >(); } static PyObject* convert(Pointer x) { instance *o = PyObject_New (instance, &type_object); o->x = x; return &o->base_; } static typename boost::remove_pointer::type& execute(instance &p_) { return *p_.x; } static PyTypeObject type_object; }; template PyTypeObject convert_opaque_pointer::type_object = { PyObject_HEAD_INIT(NULL) 0, 0, sizeof(typename convert_opaque_pointer::instance), 0, opc_detail::dealloc }; # endif // pointer_convert_h_ -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Mon Jan 13 13:46:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 13 Jan 2003 07:46:43 -0500 Subject: AW: [C++-sig] Wrapping opaque pointers returned from API function s In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A666@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Mon, 13 Jan 2003 09:44:43 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A666@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: >> I didn't say I tested the code ;-) > > Of course. > Anyway, your upcast is probably invalid anyway, because PyObject ist not a > base class of instance. No, it is not invalid. My upcast template is specially designed to deal with this. Please try doing as I suggested. >> No, that's non-POD. It has a base class. > > I think I have a solution that is hopefully more conforming but doesn't rely > on the Python implementation details (and it even resembles a bit to real > inheritance) > struct instance { > PyObject base_; > Pointer x; > }; The contents of PyObject are still Python implementation details. This one is no better than my proposal, and may in fact take extra storage for alignment. > static PyObject* convert(Pointer x) > { > instance *o = PyObject_New (instance, &type_object); > o->x = x; > return &o->base_; > } > I can't lookup the paragraph in the standard, but I found something in the > draft of "C++ in a nutshell". > In Chapter 7 it says: > """ > A POD class can contain padding between data members, but no padding appears > before the first member. Therefore, a pointer to the POD object can be > converted (with reinterpret_cast<>) to a pointer to the first element. > """ They're wrong about reinterpret_cast<>, as far as the standard goes. That performs an implementation-defined mapping. The only thing you can do portably with it is convert a pointer to a different type and back again, without using it in between. Please, just try it the way I suggested! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Harri.Hakula at hut.fi Mon Jan 13 14:46:25 2003 From: Harri.Hakula at hut.fi (Harri Hakula) Date: Mon, 13 Jan 2003 15:46:25 +0200 Subject: [C++-sig] Building boost.python on Mac OS X Message-ID: <68C12473-26FD-11D7-8268-0050E4601908@hut.fi> I've followed this thread with interest. Here's what I've done: I had missed the post by Rivera http://mail.python.org/pipermail/c++-sig/2002-October/002407.html and ended up reproducing his work... My environment: Python 2.3a1 framework build Mac OS X 10.2.3 Apple Dec 2002 Development tools Snapshot of boost, Jan 5, 2003 I used the darwin toolset and Boost.Python compiles fine, including the examples. However, it appears that argument passing does not work. For instance the getting_started1.cpp compiles but hangs when imported to python. Replacing int square(int number) { return number * number; } with int square() { return 4; } compiles and runs as expected. Any ideas? Cheers, Harri Hakula From Gottfried.Ganssauge at HAUFE.DE Mon Jan 13 14:55:28 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 13 Jan 2003 14:55:28 +0100 Subject: AW: AW: [C++-sig] Wrapping opaque pointers returned from API func tion s Message-ID: <2040C0A1CA23D51181A30050BAAC990274A66B@berexch.ber.haufemg.com> > -----Ursprungliche Nachricht----- > Von: David Abrahams [mailto:dave at boost-consulting.com] > Gesendet: Montag, 13. Januar 2003 13:47 > An: c++-sig at python.org > Betreff: Re: AW: [C++-sig] Wrapping opaque pointers returned from API > function s > > > Gottfried.Ganssauge at HAUFE.DE writes: > > >> I didn't say I tested the code ;-) > > > > Of course. > > Anyway, your upcast is probably invalid anyway, because > PyObject ist not a > > base class of instance. > > No, it is not invalid. My upcast template is specially designed to > deal with this. Please try doing as I suggested. Here you are: c:\daten\devel\boost\boost\python\cast.hpp(31) : error C2039: 'type' : Ist kein Element von 'base_type_traits::instance>' c:\daten\devel\boost\boost\python\cast.hpp(52) : Siehe Verweis auf Instantiierung der kompilierten Funktionsvorlage 'struct _object *__cdecl boost::python::detail::upcast(struct convert_opaque_pointer::instance *,int *,int *,struct _object *)' I had seen that message before and concluded from it, that convert_opaque_pointer::instance * can't be converted to PyObject * using upcast<>. > > >> No, that's non-POD. It has a base class. > > > > I think I have a solution that is hopefully more conforming > but doesn't rely > > on the Python implementation details (and it even resembles > a bit to real > > inheritance) > > struct instance { > > PyObject base_; > > Pointer x; > > }; > > The contents of PyObject are still Python implementation details. True, but I don't use it. PyObject_HEAD may be the implementation of PyObject but there is no direct relationship between the two except Guido. (no criticism; just a fact) > This one is no better than my proposal, and may in fact take extra > storage for alignment. At least it doesn't need a cast :-) Why should there be extra alignment storage used after PyObject but not after PyObject_HEAD? > > > static PyObject* convert(Pointer x) > > { > > instance *o = PyObject_New (instance, &type_object); > > o->x = x; > > return &o->base_; > > } > > I can't lookup the paragraph in the standard, but I found > something in the > > draft of "C++ in a nutshell". > > In Chapter 7 it says: > > """ > > A POD class can contain padding between data members, but > no padding appears > > before the first member. Therefore, a pointer to the POD > object can be > > converted (with reinterpret_cast<>) to a pointer to the > first element. > > """ > > They're wrong about reinterpret_cast<>, as far as the standard goes. > That performs an implementation-defined mapping. The only thing you > can do portably with it is convert a pointer to a different type and > back again, without using it in between. Please, just try it the way > I suggested! My solution only uses the fact, that there is no extra padding before the base_ member so that a pointer to base_ may be returned from the convert method that can be converted back to a pointer to our instance struct. Cheers, Gottfried -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Mon Jan 13 15:04:37 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 13 Jan 2003 09:04:37 -0500 Subject: AW: AW: [C++-sig] Wrapping opaque pointers returned from API func tion s In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A66B@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's message of "Mon, 13 Jan 2003 14:55:28 +0100") References: <2040C0A1CA23D51181A30050BAAC990274A66B@berexch.ber.haufemg.com> Message-ID: Gottfried.Ganssauge at HAUFE.DE writes: >> -----Ursprungliche Nachricht----- >> Von: David Abrahams [mailto:dave at boost-consulting.com] >> Gesendet: Montag, 13. Januar 2003 13:47 >> An: c++-sig at python.org >> Betreff: Re: AW: [C++-sig] Wrapping opaque pointers returned from API >> function s >> >> >> Gottfried.Ganssauge at HAUFE.DE writes: >> >> >> I didn't say I tested the code ;-) >> > >> > Of course. >> > Anyway, your upcast is probably invalid anyway, because >> PyObject ist not a >> > base class of instance. >> >> No, it is not invalid. My upcast template is specially designed to >> deal with this. Please try doing as I suggested. > Here you are: > c:\daten\devel\boost\boost\python\cast.hpp(31) : error C2039: 'type' : Ist > kein Element von 'base_type_traits workspace_ *>::instance>' > c:\daten\devel\boost\boost\python\cast.hpp(52) : Siehe Verweis auf > Instantiierung der kompilierten Funktionsvorlage 'struct _object *__cdecl > boost::python::detail::upcast(struct convert_opaque_pointer workspace_ *>::instance *,int *,int *,struct _object *)' > > I had seen that message before and concluded from it, that > convert_opaque_pointer::instance * can't be converted > to PyObject * using upcast<>. Ah, sorry. You'd need to specialize boost::python::base_type_traits... and that comes with portability complications of its own. So a plain C-style cast is just fine. >> >> >> No, that's non-POD. It has a base class. >> > >> > I think I have a solution that is hopefully more conforming >> but doesn't rely >> > on the Python implementation details (and it even resembles >> a bit to real >> > inheritance) >> > struct instance { >> > PyObject base_; >> > Pointer x; >> > }; >> >> The contents of PyObject are still Python implementation details. > True, but I don't use it. PyObject_HEAD may be the implementation of > PyObject but there is no direct relationship between the two except Guido. > (no criticism; just a fact) > >> This one is no better than my proposal, and may in fact take extra >> storage for alignment. > At least it doesn't need a cast :-) OK. > Why should there be extra alignment storage used after PyObject but not > after PyObject_HEAD? Because sizeof(PyObject) has to be arranged so that the first element of the next PyObject in an array can be aligned. That could imply padding at the end which the Pointer element might have fit into. It's a minor detail. > My solution only uses the fact, that there is no extra padding before the > base_ member so that a pointer to base_ may be returned from the convert > method that can be converted back to a pointer to our instance struct. Your solution is fine. Thanks for all your work on this! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Mon Jan 13 15:21:53 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Mon, 13 Jan 2003 09:21:53 -0500 Subject: [C++-sig] Re: static methods References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> <3E1F24C3.98553581@sitius.com> <3E1F4DEF.78AF8177@sitius.com> Message-ID: <3E22CB81.7FEF781B@sitius.com> David, It seems to me (I have not tested) that with your fix the following code will execute normaly: int main() { dict d; assert( d[0] == object() ); return 0; } But in python: >>> d=dict() >>> d[0] Traceback (most recent call last): File("?stdin>", line1, in? KeyError: 0 >>> Regards, Nikolay David Abrahams wrote: > Nikolay Mladenov ?nickm at sitius.com? writes: > > ? David, > ? > ? In object dict_base::get(object_cref k) const > ? isn't it better to have expect_non_null? > ? Because otherwise wrong key leads to access violation. > ? > ? Best regards. > ? Nikolay > > There's definitely a bug, good catch. That's the wrong fix for it, > but I've checked in the right one. > > Thanks, > Dave > > -- > David Abrahams > dave at boost-consulting.com * http://www.boost-consulting.com > Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Jan 13 15:48:51 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 13 Jan 2003 09:48:51 -0500 Subject: [C++-sig] Re: static methods In-Reply-To: <3E22CB81.7FEF781B@sitius.com> (Nikolay Mladenov's message of "Mon, 13 Jan 2003 09:21:53 -0500") References: <3E1E0336.226EA1B6@sitius.com> <3E1F1651.B6863E88@sitius.com> <3E1F24C3.98553581@sitius.com> <3E1F4DEF.78AF8177@sitius.com> <3E22CB81.7FEF781B@sitius.com> Message-ID: Nikolay Mladenov writes: > David, > > It seems to me (I have not tested) that with your fix the following code > will execute normaly: > int main() > { > dict d; > assert( d[0] == object() ); > return 0; > } No, that will throw. int main() { dict d; assert(d.get(0) == object() ); return 0; } > But in python: >>>> d=dict() >>>> d[0] > Traceback (most recent call last): > File("?stdin>", line1, in? > KeyError: 0 >>>> >>> dict().get(0) is None 1 -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Mon Jan 13 21:55:05 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 13 Jan 2003 12:55:05 -0800 (PST) Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <68C12473-26FD-11D7-8268-0050E4601908@hut.fi> Message-ID: <20030113205505.43456.qmail@web20206.mail.yahoo.com> --- Harri Hakula wrote: > Replacing > int square(int number) { return number * number; } > with > int square() { return 4; } > compiles and runs as expected. A few months ago one of my regression tests uncovered that some objects are double-destructed. Maybe this is related. I sent a bug report to Apple but never got a confirmation that the issue is resolved. Would you be interested in trying the regression test? I could give you a self-contained tar file and a tiny script, so it shouldn't take more than a few minutes to find out if the double-destruction problem still exists. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nickm at sitius.com Mon Jan 13 22:00:19 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Mon, 13 Jan 2003 16:00:19 -0500 Subject: [C++-sig] static method implementation Message-ID: <3E2328E3.63FD2643@sitius.com> An HTML attachment was scrubbed... URL: From ron_clarke at hp.com Mon Jan 13 22:28:01 2003 From: ron_clarke at hp.com (CLARKE,RON (HP-Vancouver,ex1)) Date: Mon, 13 Jan 2003 16:28:01 -0500 Subject: [C++-sig] Continuing Pointer Issue Message-ID: <6D805D4C4567D411AF32009027B683510E66E3C8@xvan02.vcd.hp.com> David - thanks for the response on the previous message regarding wrapping a pointer member variable. (see below) class car > { > public: > car(void); > virtual ~car(void); > private: > ... > }; > > class garage{ > public: > garage(void); > ~garage(void); > car* pCar; > }; > > Class garage contains a public pointer to a car object (I don't have the > option of changing the C++ code; it would negatively affect too many users). > I can create garage and car objects OK and Python understands each one: > c=car() > g=garage() > > However, if I try something like this: > g.pCar = car() > the resulting object is null and trying to simply print the object yields a > "TypeError: bad argument for built-in operation". > > What have I missed? Can someone please provide an example (other than what > is in the documentation)? I think this might work for you: class_("garage") .add_property( make_getter(&garage::pCar, with_custodian_and_ward<1,2>()) , make_setter(&garage::pCar, return_internal_reference<>())) However, if garage::~garage() does "delete pCar" you're going to have big problems. Let me know if that's the case and we can try something else. ------(end of response) ---------- I tried the code as specified, but it did not compile. So based on the example, I did some more reading of the documentation and source code, and tried to figure something out, but I'm getting nowhere. I cannot get the code (or several variations on the them) to compile, much less test successfully in Python. Here is the code that fails to compile: BOOST_PYTHON_MODULE(house) { class_("garage") .add_property("pCar" , make_getter(&garage::pCar, with_custodian_and_ward<1,2>()) , make_setter(&garage::pCar, return_internal_reference<>() ) ) ; } The Visual Studio .NET compiler emits these messages: f:\Downloads\Python etc\Boost2\boost_1_29_0\boost\python\data_members.hpp(34) : error C2079: 'cr' uses undefined struct 'boost::python::detail::specify_a_result_policy_to_wrap_functions_returning< T>' with [ T=source ] f:\Downloads\Python etc\Boost2\boost_1_29_0\boost\python\data_members.hpp(27) : while compiling class-template member function 'PyObject *boost::python::detail::member::get(Data garage::* ,PyObject *,PyObject *,const boost::python::with_custodian_and_ward &)' with [ Data=car *, Class=garage, Policies=boost::python::with_custodian_and_ward<1,2,boost::python::default_c all_policies>, custodian=1, ward=2, BasePolicy_=boost::python::default_call_policies ] f:\Downloads\Python etc\Boost2\boost_1_29_0\boost\python\data_members.hpp(83) : see reference to class template instantiation 'boost::python::detail::member' being compiled with [ Data=car *, Class=garage, Policies=boost::python::with_custodian_and_ward<1,2,boost::python::default_c all_policies> ] f:\boost_tests\simple1\house_boostwrapper\house_boostwrapper.cpp(48) : see reference to function template instantiation 'boost::python::api::object boost::python::make_getter(D garage::* ,const boost::python::with_custodian_and_ward &)' being compiled with [ D=car *, custodian=1, ward=2, BasePolicy_=boost::python::default_call_policies ] f:\Downloads\Python etc\Boost2\boost_1_29_0\boost\python\data_members.hpp(35) : error C2228: left of '.convertible' must have class/struct/union type f:\Downloads\Python etc\Boost2\boost_1_29_0\boost\python\data_members.hpp(39) : error C2064: term does not evaluate to a function ---- (end compiler output) ---- The error message implies I need a result policy, but I cannot find anything in the documentation that says what a result policy is. Is it the same as a Call Policy? If so, isn't that what I have in the code being compiled (re: with_custodian_and_ward and return_internal_reference)? I would like to be able to do this in Python: from vehicles import car from house import * from parkinglot import * g = garage() #in house module; garage contains car pointer allocated in garage constructor Print "the color of the car is %s", g.pCar.getColor() pl = parkingLot() pl.parkTheCar(g.pCar) Is there a way to make this work in Boost.Python? Thanks in advance for the assistance. -Ron _________________________________________ Ron Clarke Digital Printing Technologies Hewlett-Packard Company ron_clarke at hp.com 360-212-0193 From dave at boost-consulting.com Mon Jan 13 22:39:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 13 Jan 2003 16:39:23 -0500 Subject: [C++-sig] static method implementation In-Reply-To: <3E2328E3.63FD2643@sitius.com> (Nikolay Mladenov's message of "Mon, 13 Jan 2003 16:00:19 -0500") References: <3E2328E3.63FD2643@sitius.com> Message-ID: Nikolay Mladenov writes: > I am posting the diffs of my implementation of class_.static method. > I'd appreciate any comments that you may have. > > Thanks a lot to David Abrahams, for pointing me in the right direction and, > of course, for the amazing library! > > Regards, > > Nikolay > > Index: src/object/class.cpp > =================================================================== > RCS file: /cvsroot/boost/boost/libs/python/src/object/class.cpp,v > retrieving revision 1.48 > diff -r1.48 class.cpp > 442a443,454 >>?? extern PyTypeObject function_type; >>?? void class_base::make_method_static(const char * method_name) >>?? { >>???????? dict d(handle<>(borrowed(downcast(this->ptr())->tp_dict))); >> >>???????? object method = (object)(d[method_name]); >> >>???????? this->attr(method_name) = object(handle<>( >>???????????? PyStaticMethod_New(expect_non_null(pytype_check(&function_type, method.ptr())) ) >>???????????? )); >>?? } It's good; maybe a little stylistically awkward. Is pytype_check really needed? I think it's a little too strict. Maybe you should just check that the thing is callable. You could consider: ?? extern PyTypeObject function_type; ?? void class_base::make_method_static(const char * method_name) ?? { dict d(detail::borrowed_reference(downcasttp_dict)); ????????object method(d[method_name]); ??????? this-attr(method_name) = object( detail::new_reference( ???????????? PyStaticMethod_New(expect_non_null(callable_check(method.ptr())) ) )); ?? } Of course you'd have to write callable_check. I'm not sure mine is much better than yours anyway. Note that detail::[borrowed|new]_reference are implementation details, but you're working on the implementation so it's OK! > Index: src/object/function.cpp > =================================================================== > RCS file: /cvsroot/boost/boost/libs/python/src/object/function.cpp,v > retrieving revision 1.26 > diff -r1.26 function.cpp > 264a265,273 >>???????????? else if (existing->ob_type == &PyStaticMethod_Type){ >>???????????????? //this can probably be made a lot better >>???????????????? ::PyErr_Format( >>???????????????????? PyExc_RuntimeError >>???????????????????? , "Boost.Python - All overloads of \"%s\" must be exported before calling > \"class_.staticmethod\"" >>???????????????????? , name_ >>???????????????????? ); >>???????????????? throw_error_already_set(); I'm not sure this is technically neccessary, but I don't know if I could improve it. The behavior without it might just work anyway. > Index: class.hpp > =================================================================== > RCS file: /cvsroot/boost/boost/boost/python/class.hpp,v > retrieving revision 1.64 > diff -r1.64 class.hpp > 354a355,359 >>???? self& staticmethod(char const* name) >>???? { >>???????? make_method_static(name); >>???????? return *this; >>???? } > > Index: object/class.hpp > =================================================================== > RCS file: /cvsroot/boost/boost/boost/python/object/class.hpp,v > retrieving revision 1.31 > diff -r1.31 class.hpp > 50a51,52 >> >>???? void make_method_static(const char *method_name); Looks like a damned fine patch! Tests and documentation are still needed, of course. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Jan 13 22:42:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 13 Jan 2003 16:42:53 -0500 Subject: [C++-sig] Continuing Pointer Issue In-Reply-To: <6D805D4C4567D411AF32009027B683510E66E3C8@xvan02.vcd.hp.com> ("CLARKE,RON's message of "Mon, 13 Jan 2003 16:28:01 -0500") References: <6D805D4C4567D411AF32009027B683510E66E3C8@xvan02.vcd.hp.com> Message-ID: "CLARKE,RON (HP-Vancouver,ex1)" writes: > David - thanks for the response on the previous message regarding wrapping a > pointer member variable. (see below) > class car >> { >> public: >> car(void); >> virtual ~car(void); >> private: >> ... >> }; >> >> class garage{ >> public: >> garage(void); >> ~garage(void); >> car* pCar; >> }; >> >> Class garage contains a public pointer to a car object (I don't have the >> option of changing the C++ code; it would negatively affect too many > users). >> I can create garage and car objects OK and Python understands each one: >> c=car() >> g=garage() >> >> However, if I try something like this: >> g.pCar = car() >> the resulting object is null and trying to simply print the object yields > a >> "TypeError: bad argument for built-in operation". >> >> What have I missed? Can someone please provide an example (other than what >> is in the documentation)? > > I think this might work for you: > > class_("garage") > .add_property( > make_getter(&garage::pCar, with_custodian_and_ward<1,2>()) > , make_setter(&garage::pCar, return_internal_reference<>())) > > However, if garage::~garage() does "delete pCar" you're going to have > big problems. Let me know if that's the case and we can try something > else. > > > ------(end of response) ---------- > > I tried the code as specified, but it did not compile. Uhm sorry! Please exchange the call policies! BOOST_PYTHON_MODULE(house) { class_("garage") .add_property("pCar" , make_getter(&garage::pCar, return_internal_reference<>()) , make_setter(&garage::pCar, with_custodian_and_ward<1,2>()) ) ; } > > Is there a way to make this work in Boost.Python? > > Thanks in advance for the assistance. > > -Ron > > > _________________________________________ > Ron Clarke > Digital Printing Technologies > Hewlett-Packard Company > ron_clarke at hp.com > 360-212-0193 > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Harri.Hakula at hut.fi Tue Jan 14 04:16:56 2003 From: Harri.Hakula at hut.fi (Harri Hakula) Date: Tue, 14 Jan 2003 05:16:56 +0200 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <20030113205505.43456.qmail@web20206.mail.yahoo.com> Message-ID: On Monday, January 13, 2003, at 10:55 PM, Ralf W. Grosse-Kunstleve wrote: > --- Harri Hakula wrote: >> Replacing >> int square(int number) { return number * number; } >> with >> int square() { return 4; } >> compiles and runs as expected. > > A few months ago one of my regression tests uncovered that some objects > are double-destructed. Maybe this is related. I sent a bug report to > Apple but never got a confirmation that the issue is resolved. Would > you be interested in trying the regression test? Yes, of course. > I could give you > a self-contained tar file and a tiny script, so it shouldn't take > more than a few minutes to find out if the double-destruction problem > still exists. Sounds reasonable :-) Cheers, Harri From rwgk at yahoo.com Tue Jan 14 09:21:51 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 14 Jan 2003 00:21:51 -0800 (PST) Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: Message-ID: <20030114082151.7497.qmail@web20202.mail.yahoo.com> --- Harri Hakula wrote: > > A few months ago one of my regression tests uncovered that some objects > > are double-destructed. Maybe this is related. I sent a bug report to > > Apple but never got a confirmation that the issue is resolved. Would > > you be interested in trying the regression test? > Yes, of course. Create an empty directory somewhere on your Mac (e.g. /var/tmp/debug) and download these two files: http://cci.lbl.gov/~rwgk/bugs/mac_os/test_for_double_destruction_csh http://cci.lbl.gov/~rwgk/bugs/mac_os/test_for_double_destruction.tar.gz Then chmod 755 test_for_double_destruction_csh ./test_for_double_destruction_csh This should unpack the tar file (contains boost, scons and some of our code) and compiles, links and runs one of our regression tests. On our Mac OS 10.2.? (? = 1, I think) with the Jun or Jul developer's kit + Aug patch the output ends with: Total OK: 1300 a_value_allocation: -12 The last line indicates the double-destruction problem. If you don't see the last line there is no such problem. Please let me know how it goes. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nickm at sitius.com Tue Jan 14 16:46:23 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 14 Jan 2003 10:46:23 -0500 Subject: [C++-sig] Re: static method implementation References: <3E2328E3.63FD2643@sitius.com> Message-ID: <3E2430CF.129C2417@sitius.com> David Abrahams wrote: > Nikolay Mladenov writes: > > > I am posting the diffs of my implementation of class_.static method. > > I'd appreciate any comments that you may have. > > > > Thanks a lot to David Abrahams, for pointing me in the right direction and, > > of course, for the amazing library! > > > > Regards, > > > > Nikolay > > > > Index: src/object/class.cpp > > =================================================================== > > RCS file: /cvsroot/boost/boost/libs/python/src/object/class.cpp,v > > retrieving revision 1.48 > > diff -r1.48 class.cpp > > 442a443,454 > >> extern PyTypeObject function_type; > >> void class_base::make_method_static(const char * method_name) > >> { > >> dict d(handle<>(borrowed(downcast(this->ptr())->tp_dict))); > >> > >> object method = (object)(d[method_name]); > >> > >> this->attr(method_name) = object(handle<>( > >> PyStaticMethod_New(expect_non_null(pytype_check(&function_type, method.ptr())) ) > >> )); > >> } > > It's good; maybe a little stylistically awkward. Is pytype_check > really needed? I think it's a little too strict. Maybe you should > just check that the thing is callable. You could consider: > > extern PyTypeObject function_type; > void class_base::make_method_static(const char * method_name) > { > dict d(detail::borrowed_reference(downcasttp_dict)); > > object method(d[method_name]); > > this-attr(method_name) = object( > detail::new_reference( > PyStaticMethod_New(expect_non_null(callable_check(method.ptr())) ) > )); > } > > Of course you'd have to write callable_check. I'm not sure mine is > much better than yours anyway. I agree here, and wrote callable_check (PyCallable_Check wrapper) > > > Note that detail::[borrowed|new]_reference are implementation > details, but you're working on the implementation so it's OK! > > > Index: src/object/function.cpp > > =================================================================== > > RCS file: /cvsroot/boost/boost/libs/python/src/object/function.cpp,v > > retrieving revision 1.26 > > diff -r1.26 function.cpp > > 264a265,273 > >> else if (existing->ob_type == &PyStaticMethod_Type){ > >> //this can probably be made a lot better > >> ::PyErr_Format( > >> PyExc_RuntimeError > >> , "Boost.Python - All overloads of \"%s\" must be exported before calling > > \"class_.staticmethod\"" > >> , name_ > >> ); > >> throw_error_already_set(); > > I'm not sure this is technically neccessary, but I don't know if I > could improve it. The behavior without it might just work anyway. I tried without this check and if one exports method with the same name after staticmethod call, than the static method is not visible from python. I am not exactly sure how the things work here. As I understend Boost.Python is taking care of the overloading. Right? If yes, than a better thing to do is to try extracting the Boost.Python.Function from the staticmethod and add_overload. If no, meaning that python is also taking part in the resolving of overloads, than python does not do very good job when mixing static and unbounded methods. And since I could not find a way to extract the function from the staticmethod I throw an exception. Q: How can I get the name_space name? > > > > Index: class.hpp > > =================================================================== > > RCS file: /cvsroot/boost/boost/boost/python/class.hpp,v > > retrieving revision 1.64 > > diff -r1.64 class.hpp > > 354a355,359 > >> self& staticmethod(char const* name) > >> { > >> make_method_static(name); > >> return *this; > >> } > > > > Index: object/class.hpp > > =================================================================== > > RCS file: /cvsroot/boost/boost/boost/python/object/class.hpp,v > > retrieving revision 1.31 > > diff -r1.31 class.hpp > > 50a51,52 > >> > >> void make_method_static(const char *method_name); > > Looks like a damned fine patch! > Tests and documentation are still needed, of course. I am using it already for exporting static methods, and so far looks fine. I will check what I can do for documentation. How do I submit a patch? Posting diffs to the list? > > -- > David Abrahams > dave at boost-consulting.com * http://www.boost-consulting.com > Boost support, enhancements, training, and commercial distribution Regards, Nikolay From Harri.Hakula at hut.fi Tue Jan 14 16:55:50 2003 From: Harri.Hakula at hut.fi (Harri Hakula) Date: Tue, 14 Jan 2003 17:55:50 +0200 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <20030114082151.7497.qmail@web20202.mail.yahoo.com> Message-ID: On Tuesday, January 14, 2003, at 10:21 AM, Ralf W. Grosse-Kunstleve wrote: > On our Mac OS 10.2.? (? = 1, I think) with the Jun or Jul developer's > kit + Aug patch the output ends with: > > Total OK: 1300 > a_value_allocation: -12 > > The last line indicates the double-destruction problem. If you don't > see the last line there is no such problem. Apparently this problem remains: *** malloc[762]: Deallocation of a pointer not malloced: 0x2b84c0; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug Total OK: 1300 a_value_allocation: -12 Harri From dave at boost-consulting.com Tue Jan 14 17:37:47 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 11:37:47 -0500 Subject: [C++-sig] Re: static method implementation In-Reply-To: <3E2430CF.129C2417@sitius.com> (Nikolay Mladenov's message of "Tue, 14 Jan 2003 10:46:23 -0500") References: <3E2328E3.63FD2643@sitius.com> <3E2430CF.129C2417@sitius.com> Message-ID: Nikolay Mladenov writes: > I agree here, and wrote callable_check (PyCallable_Check wrapper) OK, thanks! >> Note that detail::[borrowed|new]_reference are implementation >> details, but you're working on the implementation so it's OK! >> >> > Index: src/object/function.cpp >> > =================================================================== >> > RCS file: /cvsroot/boost/boost/libs/python/src/object/function.cpp,v >> > retrieving revision 1.26 >> > diff -r1.26 function.cpp >> > 264a265,273 >> >> else if (existing->ob_type == &PyStaticMethod_Type){ >> >> //this can probably be made a lot better >> >> ::PyErr_Format( >> >> PyExc_RuntimeError >> >> , "Boost.Python - All overloads of \"%s\" must be exported before calling >> > \"class_.staticmethod\"" >> >> , name_ >> >> ); >> >> throw_error_already_set(); >> >> I'm not sure this is technically neccessary, but I don't know if I >> could improve it. The behavior without it might just work anyway. > > I tried without this check and if one exports method with the same > name after staticmethod call, than the static method is not visible > from python. Of course, you're right. > I am not exactly sure how the things work here. As I understend Boost.Python is taking care of the > overloading. Right? Right. Function objects with the same name get chained. Overloading just walks down the chain until it finds a match. > If yes, than a better thing to do is to try extracting the > Boost.Python.Function from the staticmethod and add_overload. > > If no, meaning that python is also taking part in the resolving of > overloads, than python does not do very good job when mixing static > and unbounded methods. > > And since I could not find a way to extract the function from the > staticmethod I throw an exception. I actually think your solution is best. I don't think restricting the order in which the user invokes staticmethod, or preventing overloading of static/non-static methods is so terrible. > Q: How can I get the name_space name? What name_space are you referring to? >> > Index: class.hpp >> > =================================================================== >> > RCS file: /cvsroot/boost/boost/boost/python/class.hpp,v >> > retrieving revision 1.64 >> > diff -r1.64 class.hpp >> > 354a355,359 >> >> self& staticmethod(char const* name) >> >> { >> >> make_method_static(name); >> >> return *this; >> >> } >> > >> > Index: object/class.hpp >> > =================================================================== >> > RCS file: /cvsroot/boost/boost/boost/python/object/class.hpp,v >> > retrieving revision 1.31 >> > diff -r1.31 class.hpp >> > 50a51,52 >> >> >> >> void make_method_static(const char *method_name); >> >> Looks like a damned fine patch! >> Tests and documentation are still needed, of course. > > I am using it already for exporting static methods, and so far looks > fine. I will check what I can do for documentation. > > How do I submit a patch? Posting diffs to the list? The best thing you can do is post a cvs diff as an attachment. cvs diff -NR -c Thanks! Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Tue Jan 14 17:47:50 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 14 Jan 2003 11:47:50 -0500 Subject: [C++-sig] Re: static method implementation References: <3E2328E3.63FD2643@sitius.com> <3E2430CF.129C2417@sitius.com> Message-ID: <3E243F36.170C8297@sitius.com> An HTML attachment was scrubbed... URL: From bruce_lowery at yahoo.com Tue Jan 14 17:56:01 2003 From: bruce_lowery at yahoo.com (Bruce Lowery) Date: Tue, 14 Jan 2003 08:56:01 -0800 (PST) Subject: [C++-sig] Solaris build errors Message-ID: <20030114165601.61814.qmail@web10902.mail.yahoo.com> In building the CVS version (as of Sun 2003-01-12) of boost.python library on solaris using v6.2.p2 of the sunpro compiler, two compile-time errors occur, one in 'cast.hpp' and the other in 'inheritance.hpp'. Details are below. --bruce ----------------- 1 -------------------- boost/boost/python/cast.hpp: line 65: Error: Default arguments cannot be added in later declarations of the template function in the same scope. 57 template 58 inline Target* downcast(Source* p, yes_convertible) 59 { 60 return static_cast(p); 61 } 62 63 template 64 inline Target* downcast(Source* p, no_convertible, boost::type* = 0) *** 65 { *** 66 typedef typename base_type_traits::type base; 67 return (Target*)detail::downcast(p, convertible::check((base*)0)); 68 } ----------------- 2 -------------------- boost/boost/python/object/inheritance.hpp: line 134: Error: ")" expected instead of ">". 130 template 131 inline void register_conversion( 132 // We need this parameter because CWPro7 can't determine 133 // which is the base reliably. *** 134 bool is_downcast = !cast_generator::is_upcast *** 132 133 // These parameters shouldn't be used, they're an MSVC bug workaround 134 , Source* = 0, Target* = 0) 135 { 136 typedef typename cast_generator::type generator; 137 138 add_cast(python::type_id() 139 , python::type_id() 140 , &generator::execute 141 , is_downcast); 142 } __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dave at boost-consulting.com Tue Jan 14 18:09:22 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 12:09:22 -0500 Subject: [C++-sig] Re: static method implementation In-Reply-To: <3E243F36.170C8297@sitius.com> (Nikolay Mladenov's message of "Tue, 14 Jan 2003 11:47:50 -0500") References: <3E2328E3.63FD2643@sitius.com> <3E2430CF.129C2417@sitius.com> <3E243F36.170C8297@sitius.com> Message-ID: Nikolay Mladenov writes: > ? > > ? > > > Q: How can I get the name_space name? > > What name_space are you referring to? > > in Function::add_to_namespace, the name_space parameter. Inside staticmethod(), that's just the class object, *this. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Jan 14 18:15:12 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 12:15:12 -0500 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: (Harri Hakula's message of "Tue, 14 Jan 2003 17:55:50 +0200") References: Message-ID: Harri Hakula writes: > On Tuesday, January 14, 2003, at 10:21 AM, Ralf W. Grosse-Kunstleve wrote: > >> On our Mac OS 10.2.? (? = 1, I think) with the Jun or Jul developer's >> kit + Aug patch the output ends with: >> >> Total OK: 1300 >> a_value_allocation: -12 >> >> The last line indicates the double-destruction problem. If you don't >> see the last line there is no such problem. > > Apparently this problem remains: > *** malloc[762]: Deallocation of a pointer not malloced: 0x2b84c0; This could be a double free(), or > free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see > tools to help debug > Total OK: 1300 > a_value_allocation: -12 Ralf, Could you add an item to the FAQ about "does BPL work with MacOSX", which has a link to your bug reproduction code? Thanks, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Tue Jan 14 18:20:13 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Tue, 14 Jan 2003 12:20:13 -0500 Subject: [C++-sig] Re: static method implementation References: <3E2328E3.63FD2643@sitius.com> <3E2430CF.129C2417@sitius.com> <3E243F36.170C8297@sitius.com> Message-ID: <3E2446CD.66B1E543@sitius.com> An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Tue Jan 14 18:24:36 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 12:24:36 -0500 Subject: [C++-sig] Re: static method implementation In-Reply-To: <3E2446CD.66B1E543@sitius.com> (Nikolay Mladenov's message of "Tue, 14 Jan 2003 12:20:13 -0500") References: <3E2328E3.63FD2643@sitius.com> <3E2430CF.129C2417@sitius.com> <3E243F36.170C8297@sitius.com> <3E2446CD.66B1E543@sitius.com> Message-ID: Nikolay Mladenov writes: > Well, yes, but in general if I have: > python::object name_space; //which I imagine narrows the posibilities for the name_space class > what would be the implamentation of: > std::string getNameSpaceName(const object &name_space); > shuch that: > assert(getNameSpaceName(class_("SM")) == std::string("SM")); > ? std::string getNameSpaceName(const object &name_space) { return extract(name_space.attr("__name__")); } ?? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Jan 14 18:56:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 12:56:34 -0500 Subject: [C++-sig] Solaris build errors In-Reply-To: <20030114165601.61814.qmail@web10902.mail.yahoo.com> (Bruce Lowery's message of "Tue, 14 Jan 2003 08:56:01 -0800 (PST)") References: <20030114165601.61814.qmail@web10902.mail.yahoo.com> Message-ID: Bruce Lowery writes: > In building the CVS version (as of Sun 2003-01-12) of boost.python library on > solaris using v6.2.p2 of the sunpro compiler, two compile-time errors occur, > one in 'cast.hpp' and the other in 'inheritance.hpp'. Details are below. > > --bruce I think you should report these to Sun. I'm really surprised you only see two errors. The last time I tried to get Boost libraries to work with a released Sun compiler (a couple of months ago), I was able to make Sun pass around 50% of all boost regression tests. It's ability to handle standard C++ constructs was so bad that I don't think there's any hope of getting it to work with Boost.Python. I've heard reports that their pre-release compiler implements a lot of bug fixes needed to work with Boost. Is that what you're using? If so, I still don't have access to this compiler so it's unlikely I'll be able to come up with a workaround for its bugs. If you come up with something that makes it work, pleas submit a patch! -Dave > ----------------- 1 -------------------- > > boost/boost/python/cast.hpp: line 65: > Error: Default arguments cannot be added in later > declarations of the template function in > the same scope. > > 57 template > 58 inline Target* downcast(Source* p, yes_convertible) > 59 { > 60 return static_cast(p); > 61 } > 62 > 63 template > 64 inline Target* downcast(Source* p, no_convertible, > boost::type* = 0) > *** > 65 { > *** > 66 typedef typename base_type_traits::type base; > 67 return (Target*)detail::downcast(p, > convertible::check((base*)0)); > 68 } > > > ----------------- 2 -------------------- > > boost/boost/python/object/inheritance.hpp: line 134: > Error: ")" expected instead of ">". > > > 130 template > 131 inline void register_conversion( > 132 // We need this parameter because CWPro7 can't determine > 133 // which is the base reliably. > *** > 134 bool is_downcast = !cast_generator::is_upcast > *** > 132 > 133 // These parameters shouldn't be used, they're an MSVC bug > workaround > 134 , Source* = 0, Target* = 0) > 135 { > 136 typedef typename cast_generator::type > generator; > 137 > 138 add_cast(python::type_id() > 139 , python::type_id() > 140 , &generator::execute > 141 , is_downcast); > 142 } > > > > __________________________________________________ > Do you Yahoo!? > Yahoo! Mail Plus - Powerful. Affordable. Sign up now. > http://mailplus.yahoo.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Tue Jan 14 19:56:13 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 14 Jan 2003 10:56:13 -0800 (PST) Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: Message-ID: <20030114185613.73377.qmail@web20205.mail.yahoo.com> --- David Abrahams wrote: > Harri Hakula writes: > > > > Apparently this problem remains: > > *** malloc[762]: Deallocation of a pointer not malloced: 0x2b84c0; This > could be a double free(), or > > free() called with the middle of an allocated block; Try setting > environment variable MallocHelp to see > > tools to help debug > > Total OK: 1300 > > a_value_allocation: -12 Ouch! > Ralf, > > Could you add an item to the FAQ about "does BPL work with MacOSX", > which has a link to your bug reproduction code? > > Thanks, > Dave Will do. Can you imagine how this double-destruction problem affects Boost.Python? Is there any chance that we could #ifdef out certain destructors which don't tolerate being called twice (memory leaks seem better than nothing at all)? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From bruce_lowery at yahoo.com Tue Jan 14 20:23:07 2003 From: bruce_lowery at yahoo.com (Bruce Lowery) Date: Tue, 14 Jan 2003 11:23:07 -0800 (PST) Subject: [C++-sig] Wrapping internal references to std::string Message-ID: <20030114192307.97775.qmail@web10902.mail.yahoo.com> On the Boost Users' list, it was explained to me that for a case like the following: class Bar { public: const std::string& get() { return _s; } private: std::string _s; }; BOOST_PYTHON_MODULE( Foo ) { class_("Bar") .def( "get", &Bar::get, return_internal_reference<>() ) ; } the return_internal_reference<>() would try to wrap a pointer to the returned var (_s above) in a Python object, and so something like a class_ would have to be defined to avoid raising an exception. It was also explained that the result wouldn't really act like a python string without additional work. What I think I'd like to do is introduce an extra class, say FooString, that would encapsulate the std::string pointer and have methods matching those of the python string class except that they'd be implemented in terms of std::string methods and act on the underlying std::string object. I've been looking at the Python and Boost.Python documentation related to introducing new types (e.g the 'noddy' example). Then, I'd introduce a function that would intercept the call to (say) Bar::get, invoke Bar::get and wrap the return value in an instance of my new (say) FooString type. The aim would be, from python, to have Foo.Bar.get return a python object that acted like a python string even though it wasn't. Does this seem reasonable? I'm only a few days old in the worlds of both Python and Boost.Python, so your advice is well received. Is there an easier way to do this? BTW, it's forbidden for me to change the actual API that I'm wrapping, in order to avoid problems like this, so I really need a solution. --bruce __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dave at boost-consulting.com Tue Jan 14 23:10:04 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 17:10:04 -0500 Subject: [C++-sig] Wrapping internal references to std::string In-Reply-To: <20030114192307.97775.qmail@web10902.mail.yahoo.com> (Bruce Lowery's message of "Tue, 14 Jan 2003 11:23:07 -0800 (PST)") References: <20030114192307.97775.qmail@web10902.mail.yahoo.com> Message-ID: Bruce Lowery writes: > On the Boost Users' list, it was explained to me that for a case like the > following: > > class Bar { > public: > const std::string& get() { return _s; } > private: > std::string _s; > }; > > BOOST_PYTHON_MODULE( Foo ) > { > class_("Bar") > .def( "get", &Bar::get, return_internal_reference<>() ) > ; > } > > the return_internal_reference<>() would try to wrap a pointer to the returned > var (_s above) in a Python object, and so something like a class_ > would have to be defined to avoid raising an exception. It was also explained > that the result wouldn't really act like a python string without additional > work. > > What I think I'd like to do is introduce an extra class, say FooString, that > would encapsulate the std::string pointer and have methods matching those of > the python string class except that they'd be implemented in terms of > std::string methods and act on the underlying std::string object. > > I've been looking at the Python and Boost.Python documentation related to > introducing new types (e.g the 'noddy' example). Why not just use class_ for this? > The aim would be, from python, to have Foo.Bar.get return a python object that > acted like a python string even though it wasn't. > > Does this seem reasonable? I'm only a few days old in the worlds of both > Python and Boost.Python, so your advice is well received. > > Is there an easier way to do this? It would be trivial (though tedious) to do it with class_. Why don't you just do that? > BTW, it's forbidden for me to change the actual API that I'm > wrapping, in order to avoid problems like this, so I really need a > solution. Understood. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Jan 15 02:46:47 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 14 Jan 2003 20:46:47 -0500 Subject: [C++-sig] Building boost.python on Mac OS X In-Reply-To: <20030114185613.73377.qmail@web20205.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Tue, 14 Jan 2003 10:56:13 -0800 (PST)") References: <20030114185613.73377.qmail@web20205.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> Harri Hakula writes: >> > >> > Apparently this problem remains: >> > *** malloc[762]: Deallocation of a pointer not malloced: 0x2b84c0; This >> could be a double free(), or >> > free() called with the middle of an allocated block; Try setting >> environment variable MallocHelp to see >> > tools to help debug >> > Total OK: 1300 >> > a_value_allocation: -12 > > Ouch! > >> Ralf, >> >> Could you add an item to the FAQ about "does BPL work with MacOSX", >> which has a link to your bug reproduction code? >> >> Thanks, >> Dave > > Will do. > > Can you imagine how this double-destruction problem affects > Boost.Python? No, but then again I don't know what characterizes the conditions that cause the problem. > Is there any chance that we could #ifdef out certain destructors > which don't tolerate being called twice (memory leaks seem better > than nothing at all)? Maybe. I have no idea. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From bruce_lowery at yahoo.com Wed Jan 15 15:23:03 2003 From: bruce_lowery at yahoo.com (Bruce Lowery) Date: Wed, 15 Jan 2003 06:23:03 -0800 (PST) Subject: [C++-sig] Wrapping internal references to std::string In-Reply-To: Message-ID: <20030115142303.40652.qmail@web10901.mail.yahoo.com> --- David Abrahams wrote: > Bruce Lowery writes: > > > On the Boost Users' list, it was explained to me that for a case like the > > following: > > > > class Bar { > > public: > > const std::string& get() { return _s; } > > private: > > std::string _s; > > }; > > > > BOOST_PYTHON_MODULE( Foo ) > > { > > class_("Bar") > > .def( "get", &Bar::get, return_internal_reference<>() ) > > ; > > } > > > > the return_internal_reference<>() would try to wrap a pointer to the > returned > > var (_s above) in a Python object, and so something like a > class_ > > would have to be defined to avoid raising an exception. It was also > explained > > that the result wouldn't really act like a python string without additional > > work. > > > > What I think I'd like to do is introduce an extra class, say FooString, > that > > would encapsulate the std::string pointer and have methods matching those > of > > the python string class except that they'd be implemented in terms of > > std::string methods and act on the underlying std::string object. > > > > I've been looking at the Python and Boost.Python documentation related to > > introducing new types (e.g the 'noddy' example). > > Why not just use class_ for this? > > > The aim would be, from python, to have Foo.Bar.get return a python object > that > > acted like a python string even though it wasn't. > > > > Does this seem reasonable? I'm only a few days old in the worlds of both > > Python and Boost.Python, so your advice is well received. > > > > Is there an easier way to do this? > > It would be trivial (though tedious) to do it with > class_. Why don't you just do that? I believe you had indicated this in a response to an earlier posting. Since the std::string methods and python string methods do not line up well, I can't map like this: class_("string") .def( "find", &std::string::find ) .def( "capitalize", &std::string::?? ) etc which is the only way I know how to map at this point (also learned how to handle overloading from someone else's posting). Obviously you are more familiar with this than I am. Can you show an example that I could use to figure out the other mappings? For instance, how would the python string 'find' method be mapped using '.def'? I would much prefer to do it this way rather than the other way (introducing a new type) if possible. --bruce > > > BTW, it's forbidden for me to change the actual API that I'm > > wrapping, in order to avoid problems like this, so I really need a > > solution. > > Understood. > > -- > David Abrahams > dave at boost-consulting.com * http://www.boost-consulting.com > Boost support, enhancements, training, and commercial distribution > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From bruce_lowery at yahoo.com Wed Jan 15 15:33:55 2003 From: bruce_lowery at yahoo.com (Bruce Lowery) Date: Wed, 15 Jan 2003 06:33:55 -0800 (PST) Subject: [C++-sig] Wrapping internal references to std::string In-Reply-To: <20030115142303.40652.qmail@web10901.mail.yahoo.com> Message-ID: <20030115143355.26305.qmail@web10908.mail.yahoo.com> David, I only just saw your response to my question (below) on the Users' list where I had posted this question before I realized that boost.pythons questions were preferred on this list. Sorry for the noise. --bruce --- Bruce Lowery wrote: > > --- David Abrahams wrote: > > Bruce Lowery writes: > > > > > On the Boost Users' list, it was explained to me that for a case like the > > > following: > > > > > > class Bar { > > > public: > > > const std::string& get() { return _s; } > > > private: > > > std::string _s; > > > }; > > > > > > BOOST_PYTHON_MODULE( Foo ) > > > { > > > class_("Bar") > > > .def( "get", &Bar::get, return_internal_reference<>() ) > > > ; > > > } > > > > > > the return_internal_reference<>() would try to wrap a pointer to the > > returned > > > var (_s above) in a Python object, and so something like a > > class_ > > > would have to be defined to avoid raising an exception. It was also > > explained > > > that the result wouldn't really act like a python string without > additional > > > work. > > > > > > What I think I'd like to do is introduce an extra class, say FooString, > > that > > > would encapsulate the std::string pointer and have methods matching those > > of > > > the python string class except that they'd be implemented in terms of > > > std::string methods and act on the underlying std::string object. > > > > > > I've been looking at the Python and Boost.Python documentation related to > > > introducing new types (e.g the 'noddy' example). > > > > Why not just use class_ for this? > > > > > The aim would be, from python, to have Foo.Bar.get return a python object > > that > > > acted like a python string even though it wasn't. > > > > > > Does this seem reasonable? I'm only a few days old in the worlds of both > > > Python and Boost.Python, so your advice is well received. > > > > > > Is there an easier way to do this? > > > > It would be trivial (though tedious) to do it with > > class_. Why don't you just do that? > > > I believe you had indicated this in a response to an earlier posting. > > Since the std::string methods and python string methods do not line up well, > I > can't map like this: > > class_("string") > .def( "find", &std::string::find ) > .def( "capitalize", &std::string::?? ) > etc > > which is the only way I know how to map at this point (also learned how to > handle overloading from someone else's posting). > > Obviously you are more familiar with this than I am. Can you show an example > that I could use to figure out the other mappings? For instance, how would > the > python string 'find' method be mapped using '.def'? I would much prefer to > do > it this way rather than the other way (introducing a new type) if possible. > > --bruce > > > > > > > BTW, it's forbidden for me to change the actual API that I'm > > > wrapping, in order to avoid problems like this, so I really need a > > > solution. > > > > Understood. > > > > -- > > David Abrahams > > dave at boost-consulting.com * http://www.boost-consulting.com > > Boost support, enhancements, training, and commercial distribution > > > > > > _______________________________________________ > > C++-sig mailing list > > C++-sig at python.org > > http://mail.python.org/mailman/listinfo/c++-sig > > > __________________________________________________ > Do you Yahoo!? > Yahoo! Mail Plus - Powerful. Affordable. Sign up now. > http://mailplus.yahoo.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From bruce_lowery at yahoo.com Wed Jan 15 18:36:43 2003 From: bruce_lowery at yahoo.com (Bruce Lowery) Date: Wed, 15 Jan 2003 09:36:43 -0800 (PST) Subject: [C++-sig] Solaris build errors Message-ID: <20030115173643.78431.qmail@web10904.mail.yahoo.com> >>Bruce Lowery writes: >> >> In building the CVS version (as of Sun 2003-01-12) of boost.python library on >> solaris using v6.2.p2 of the sunpro compiler, two compile-time errors occur, >> one in 'cast.hpp' and the other in 'inheritance.hpp'. Details are below. >> >> --bruce > I think you should report these to Sun. > I'm really surprised you only see two errors. The last time I tried > to get Boost libraries to work with a released Sun compiler (a couple > of months ago), I was able to make Sun pass around 50% of all boost > regression tests. It's ability to handle standard C++ constructs was > so bad that I don't think there's any hope of getting it to work with > Boost.Python. > There were other errors from other boost libs, but these two were the only ones reported from just the boost/python build. They were actually reported many times (same errors) since they are in headers. > I've heard reports that their pre-release compiler implements a lot of > bug fixes needed to work with Boost. Is that what you're using? If > so, I still don't have access to this compiler so it's unlikely I'll > be able to come up with a workaround for its bugs. If you come up > with something that makes it work, pleas submit a patch! I'm not using the forte 7 compiler. I'm using v6.2 corresponds to version 6 of the toolset, I believe. I've been told I may be able to use the GNU compiler - which I did recently, and boost.python finally built on solaris (with gcc-tools.jam). However, the threads library failed to build. --bruce > -Dave __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From achim.domma at syynx.de Thu Jan 16 08:42:47 2003 From: achim.domma at syynx.de (Achim Domma) Date: Thu, 16 Jan 2003 08:42:47 +0100 Subject: [C++-sig] cvs not available Message-ID: Hi, since yesterday I get always a 'Connection reset by peer' error if I try to update my boost version from cvs. Has somebody else this problem? regards, Achim From rwgk at yahoo.com Thu Jan 16 11:48:48 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 16 Jan 2003 02:48:48 -0800 (PST) Subject: [C++-sig] cvs not available In-Reply-To: Message-ID: <20030116104848.12727.qmail@web20202.mail.yahoo.com> --- Achim Domma wrote: > since yesterday I get always a 'Connection reset by peer' error if I try to > update my boost version from cvs. Has somebody else this problem? "cvs update" worked for me one minute ago. Only the html view of the cvs trees doesn't seem to work for me... Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From toon.knapen at si-lab.com Thu Jan 16 12:31:49 2003 From: toon.knapen at si-lab.com (Toon Knapen) Date: Thu, 16 Jan 2003 12:31:49 +0100 Subject: [C++-sig] cvs not available In-Reply-To: <20030116104848.12727.qmail@web20202.mail.yahoo.com> References: <20030116104848.12727.qmail@web20202.mail.yahoo.com> Message-ID: <200301161231.49496.toon.knapen@si-lab.com> On Thursday 16 January 2003 11:48, Ralf W. Grosse-Kunstleve wrote: > --- Achim Domma wrote: > > since yesterday I get always a 'Connection reset by peer' error if I try > > to update my boost version from cvs. Has somebody else this problem? > > "cvs update" worked for me one minute ago. > Only the html view of the cvs trees doesn't seem to work for me... > Ralf I'm experiencing trouble though the whole morning : poisson:/home/tk/boost/boost >cvs -z9 update -d cvs [update aborted]: connect to cvs.boost.sourceforge.net(66.35.250.207):2401 failed: Connection refused poisson:/home/tk/boost/boost > If Ralf does not have the same problem, could it be due to the sourceforge mirror here in europe ? toon From bdash at gmx.net Thu Jan 16 12:44:43 2003 From: bdash at gmx.net (Mark Rowe) Date: Fri, 17 Jan 2003 00:44:43 +1300 Subject: [C++-sig] cvs not available In-Reply-To: Message-ID: On Thursday, Jan 16, 2003, at 20:42 Pacific/Auckland, Achim Domma wrote: > Hi, > > since yesterday I get always a 'Connection reset by peer' error if I > try to > update my boost version from cvs. Has somebody else this problem? Sourceforge has taken the CVS pserver and ViewCVS offline at present. See http://sourceforge.net/docman/display_doc.php?docid=2352&group_id=1#cvs for more info. -- Mark Rowe bdash at clear.net.nz From dave at boost-consulting.com Thu Jan 16 14:09:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 16 Jan 2003 08:09:29 -0500 Subject: [C++-sig] cvs not available In-Reply-To: <200301161231.49496.toon.knapen@si-lab.com> (Toon Knapen's message of "Thu, 16 Jan 2003 12:31:49 +0100") References: <20030116104848.12727.qmail@web20202.mail.yahoo.com> <200301161231.49496.toon.knapen@si-lab.com> Message-ID: Toon Knapen writes: > On Thursday 16 January 2003 11:48, Ralf W. Grosse-Kunstleve wrote: >> --- Achim Domma wrote: >> > since yesterday I get always a 'Connection reset by peer' error if I try >> > to update my boost version from cvs. Has somebody else this problem? >> >> "cvs update" worked for me one minute ago. >> Only the html view of the cvs trees doesn't seem to work for me... >> Ralf > > I'm experiencing trouble though the whole morning : > > poisson:/home/tk/boost/boost >cvs -z9 update -d > cvs [update aborted]: connect to cvs.boost.sourceforge.net(66.35.250.207):2401 > failed: Connection refused > poisson:/home/tk/boost/boost > > > If Ralf does not have the same problem, could it be due to the sourceforge > mirror here in europe ? http://sourceforge.net/docman/display_doc.php?docid=2352&group_id=1 explains all. Only project developers seem to be able to get at it. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From nickm at sitius.com Fri Jan 17 20:09:46 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Fri, 17 Jan 2003 14:09:46 -0500 Subject: [C++-sig] staticmethod diffs Message-ID: <3E2854FA.E773C7DC@sitius.com> An HTML attachment was scrubbed... URL: -------------- next part -------------- Index: boost/python/class.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/python/class.hpp,v retrieving revision 1.64 diff -c -r1.64 class.hpp *** boost/python/class.hpp 20 Dec 2002 00:04:39 -0000 1.64 --- boost/python/class.hpp 17 Jan 2003 17:19:19 -0000 *************** *** 352,357 **** --- 352,362 ---- return *this; } + self& staticmethod(char const* name) + { + make_method_static(name); + return *this; + } private: // helper functions inline void register_() const; Index: boost/python/object/class.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/python/object/class.hpp,v retrieving revision 1.31 diff -c -r1.31 class.hpp *** boost/python/object/class.hpp 3 Oct 2002 12:41:22 -0000 1.31 --- boost/python/object/class.hpp 17 Jan 2003 17:19:19 -0000 *************** *** 48,53 **** --- 48,55 ---- // Implementation detail. Hiding this in the private section would // require use of template friend declarations. void enable_pickling(bool getstate_manages_dict); + + void make_method_static(const char *method_name); }; }}} // namespace boost::python::objects Index: libs/python/doc/v2/class.html =================================================================== RCS file: /cvsroot/boost/boost/libs/python/doc/v2/class.html,v retrieving revision 1.19 diff -c -r1.19 class.html *** libs/python/doc/v2/class.html 14 Nov 2002 02:09:42 -0000 1.19 --- libs/python/doc/v2/class.html 17 Jan 2003 17:19:24 -0000 *************** *** 242,247 **** --- 242,250 ---- template <class Fn, class A1, class A2, class A3> class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&); + // declaring method as static + class_& staticmethod(char const* name); + // exposing operators template <unspecified> class_& def(Returns: *this +

+ class_& staticmethod(char const* name);
+ 
+ +
+
Requires: name is an ntbs which conforms to Python's identifier + naming rules, and corresponds to a method which has already been completely overloaded.
+ +
Effects: Specifies that the corresponding method is static and + therefore object instance will not be passed to it.
+ +
Returns: *this
+
+
+
  template <unspecified>
  class_& def(ob_type->tp_name
+             );
+         throw_error_already_set();
+ 
+         return 0;
+       }
+ 
+   }
+   void class_base::make_method_static(const char * method_name)
+   {
+         dict d(handle<>(borrowed(downcast(this->ptr())->tp_dict)));
+ 
+         object method(d[method_name]);
+ 
+         this->attr(method_name) = object(
+             handle<>(
+                 PyStaticMethod_New(callable_check(method.ptr()) )
+                 ));
+   }
+ 
    BOOST_PYTHON_DECL type_handle registered_class_object(class_id id)
    {
        return query_class(id);
Index: libs/python/src/object/function.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/python/src/object/function.cpp,v
retrieving revision 1.26
diff -c -r1.26 function.cpp
*** libs/python/src/object/function.cpp	21 Dec 2002 22:12:31 -0000	1.26
--- libs/python/src/object/function.cpp	17 Jan 2003 17:19:25 -0000
***************
*** 12,17 ****
--- 12,18 ----
  #include 
  #include 
  #include 
+ #include 
  
  #include 
  #include 
***************
*** 262,267 ****
--- 263,279 ----
          {
              if (existing->ob_type == &function_type)
                  new_func->add_overload(existing);
+             else if (existing->ob_type == &PyStaticMethod_Type){
+                 //this can probably be made a lot better
+                 std::string name_space_name = extract(name_space.attr("__name__"));
+                 ::PyErr_Format(
+                     PyExc_RuntimeError
+                     , "Boost.Python - All overloads of \"%s\" must be exported before calling \'class_(\"%s\").staticmethod\'"
+                     , name_
+                     , name_space_name.c_str()
+                     );
+                 throw_error_already_set();
+             }
          }
          else if (is_binary_operator(name_))
          {

From mike at bindkey.com  Fri Jan 17 22:39:53 2003
From: mike at bindkey.com (Mike Rovner)
Date: Fri, 17 Jan 2003 13:39:53 -0800
Subject: [C++-sig] map key
Message-ID: 

I'm trying to wrap a std::map  with

template
struct map_item

{

typedef typename T::key_type Key;

typedef typename T::mapped_type Value;


static Value const& get(T& x, const Key n)

{

if( x.find(n) != x.end() ) return x[n];

PyErr_SetString(PyExc_KeyError,"Map key not found");
throw_error_already_set();

}


static void set(T& x, const Key n, const Value& val) { x[n]=val; }


static void del(T& x, const Key n) { x.erase(n); }


static bool in(T const& x, const Key n) { return x.find(n) != x.end(); }


static list keys(T const& x)

{ list t;

for(T::const_iterator it=x.begin(); it!=x.end(); ++it)

t.append( object(it->first) );

return t;

}

static list values(T const& x)

{ list t;

for(T::const_iterator it=x.begin(); it!=x.end(); ++it)

t.append( object(it->second) );

return t;

}

static list items(T const& x)

{ list t;

for(T::const_iterator it=x.begin(); it!=x.end(); ++it)

t.append( make_tuple(object(it->first), object(it->second)) );

return t;

}

};

typedef std::map Map;
class_("Key", no_init) /*...*/;

class_("Value") /*...*/;

class_("Map")

.def("keys", &map_item::keys)

;

My problem is to return keys:

>>> m=Map(...)

>>> m.keys()

TypeError: No to_python (by-value) converter found for C++ type: class Key

Other functions returning const Key* are just fine with
return_internal_reference.

Can I specify return_internal_reference when constructing keys list? How?
Will it solve the problem?

Thanks in advance,

Mike






From dave at boost-consulting.com  Fri Jan 17 23:29:28 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 17 Jan 2003 17:29:28 -0500
Subject: [C++-sig] map key
In-Reply-To:  ("Mike Rovner"'s message of "Fri,
 17 Jan 2003 13:39:53 -0800")
References: 
Message-ID: 

"Mike Rovner"  writes:

> I'm trying to wrap a std::map  with
>
> template
> struct map_item
>
> {
>
> typedef typename T::key_type Key;



Mike, lots of mailers don't respond well to indentation with tabs.

Cleaning up your code, I get:

template
struct map_item
{
    typedef typename T::key_type Key;
    typedef typename T::mapped_type Value;

    static Value const& get(T& x, const Key n)
    {
        if( x.find(n) != x.end() ) return x[n];
        PyErr_SetString(PyExc_KeyError,"Map key not found");
        throw_error_already_set();
    }

    static void set(T& x, const Key n, const Value& val) { x[n]=val; }

    static void del(T& x, const Key n) { x.erase(n); }

    static bool in(T const& x, const Key n) { return x.find(n) != x.end(); }

    static list keys(T const& x)
    {
        list t;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it)
            t.append( object(it->first) );
You don't need this---^^^^^^^---------^
        return t;
    }

    static list values(T const& x)
    {
        list t;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it)
            t.append( object(it->second) );
You don't need this---^^^^^^^----------^
        return t;
    }
    static list items(T const& x)
    {
        list t;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it)
            t.append( make_tuple(object(it->first), object(it->second)) );
You don't need this--------------^^^^^^^---------^--^^^^^^^----------^
        return t;
    }
};

typedef std::map Map;
class_("Key", no_init) /*...*/;
class_("Value") /*...*/;

class_("Map")
    .def("keys", &map_item::keys)
    ;
--

> My problem is to return keys:
>
>>>> m=Map(...)
>>>> m.keys()
>
> TypeError: No to_python (by-value) converter found for C++ type:
> class Key
>
> Other functions returning const Key* are just fine with
> return_internal_reference.

There is no function returning const Key* being invoked, but I see
what you mean.  The problem occurs where you try to convert a ``const
Key*'' to a Python object.

> Can I specify return_internal_reference when constructing keys list? 

Hum, that's an interesting question.  I guess you'd like each of the
items in the keys list to keep the map object alive so that they will
remain valid.  You could use t.append(ptr(it->second)), which would
build an object around the pointer and stick it in the list, but that
would not have the desired lifetime-management properties.

One approach would be to wrap a function which could convert
the pointer with the lifetime management you want:

    Key const* managed(object map, Key const* x) { return x; }
    object py_managed = make_function(managed, return_internal_reference<>());

Then you need to get ahold of the map's Python object in your keys
function:

    static list keys(python::back_reference xx)
    {
        T const& x = xx.get();
        list t;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it)
            t.append( py_managed(xx.source(), it->first) );
        return t;
    }

> How?  Will it solve the problem?

I think that would solve it.

Mike, I think this would make a really good tutorial case study for
the Boost.Python documentation.  Is there any way I could persuade you
to write it up so that others can benefit?

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Sat Jan 18 00:28:07 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 17 Jan 2003 18:28:07 -0500
Subject: [C++-sig] staticmethod diffs
In-Reply-To: <3E2854FA.E773C7DC@sitius.com> (Nikolay Mladenov's message of
 "Fri, 17 Jan 2003 14:09:46 -0500")
References: <3E2854FA.E773C7DC@sitius.com>
Message-ID: 

Nikolay Mladenov  writes:

> Attached is the static method diffs (diff -NR -c)
> I have not done much testing, but it works for me and compiles with MSVC6/STLPort4.5

This is great, Nikolay!  Can you post a small test module and script
for the libs/python/test directory?  That would put the icing on the
cake.

Thanks again for your contribution!

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From mike at bindkey.com  Sat Jan 18 00:37:53 2003
From: mike at bindkey.com (Mike Rovner)
Date: Fri, 17 Jan 2003 15:37:53 -0800
Subject: [C++-sig] Re: map key
References:  
Message-ID: 

"David Abrahams"  wrote in message
news:usmvrh0l3.fsf at boost-consulting.com...
> "Mike Rovner"  writes:
>
> 
>
> Mike, lots of mailers don't respond well to indentation with tabs.

I'm sorry for the formatting. There was no tabs but something strange
happened with pasting from VC7.

> There is no function returning const Key* being invoked, but I see
> what you mean.  The problem occurs where you try to convert a ``const
> Key*'' to a Python object.

That's correct.

> > Can I specify return_internal_reference when constructing keys list?
>
> Hum, that's an interesting question.  I guess you'd like each of the
> items in the keys list to keep the map object alive so that they will
> remain valid.  You could use t.append(ptr(it->second)), which would
> build an object around the pointer and stick it in the list, but that
> would not have the desired lifetime-management properties.

It is working, but I still don't understand it. ;)
I have a map, so map<>::iterator it->first shall
return const Key* or at least const Key* const&. So we already have a
pointer,
why we need a ptr() call around it?

I'd like to have a lifetime-management, but I'm still shallow on it.
I don't need to keep a map, because map keys are pointers to an object
elsewhere and
manupulating them can be a potential disaster but I'm limited by existing
library I'm wrapping. :(

But while it's great at hand-maid keys() and items() lists, there's still a
problem with
iterator >(). Obviosly it doesn't know about ptr().

> One approach would be to wrap a function which could convert
> the pointer with the lifetime management you want:

I have a host object Host which holds all Keys and cleaning them on
desruction.
Host can return const Key* and I'd like to keep that (wrapped) host instead.

> I think that would solve it.

Thanks a lot, Dave. BPL already saved us a week debugging and more is on the
way.

> Mike, I think this would make a really good tutorial case study for
> the Boost.Python documentation.  Is there any way I could persuade you
> to write it up so that others can benefit?

(side note) I'm constantly adding some stuff from that list to the wiki.
OK, if you think I can do it, I can do it. :)
You mean that http://www.boost.org/libs/python/doc/tutorial/index.html
tutorial?
I need a few lines guidelines like a few questions that my future text will
answer
and I'll go for it.







From dave at boost-consulting.com  Sat Jan 18 01:00:11 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 17 Jan 2003 19:00:11 -0500
Subject: [C++-sig] Re: map key
In-Reply-To:  ("Mike Rovner"'s message of "Fri,
 17 Jan 2003 15:37:53 -0800")
References:  
	
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:usmvrh0l3.fsf at boost-consulting.com...
>> "Mike Rovner"  writes:
>>
>> 
>>
>> Mike, lots of mailers don't respond well to indentation with tabs.
>
> I'm sorry for the formatting. There was no tabs but something strange
> happened with pasting from VC7.
>
>> There is no function returning const Key* being invoked, but I see
>> what you mean.  The problem occurs where you try to convert a ``const
>> Key*'' to a Python object.
>
> That's correct.
>
>> > Can I specify return_internal_reference when constructing keys list?
>>
>> Hum, that's an interesting question.  I guess you'd like each of the
>> items in the keys list to keep the map object alive so that they will
>> remain valid.  You could use t.append(ptr(it->second)), which would
>> build an object around the pointer and stick it in the list, but that
>> would not have the desired lifetime-management properties.
>
> It is working, but I still don't understand it. ;)
> I have a map, so map<>::iterator it->first shall
> return const Key* or at least const Key* const&. So we already have a
> pointer,
> why we need a ptr() call around it?

Because, in general, building a Python object around a pointer
(instead of a copy of the pointee) is unsafe, we don't do it by
default.  You have to ask for it explicitly.  Of course
return_internal_reference makes it safe, but it's not known that
you're using it at that point in the code.

> I'd like to have a lifetime-management, but I'm still shallow on it.
> I don't need to keep a map, because map keys are pointers to an object
> elsewhere 

Oh, good point. return_internal_reference is ineffectual here.

> and manupulating them can be a potential disaster but I'm limited by
> existing library I'm wrapping. :(

You can only do what you can do.

> But while it's great at hand-maid keys() and items() lists, there's
> still a problem with iterator >(). Obviosly
> it doesn't know about ptr().

I think it doesn't know about std::pair, which is
the iterator's value type ;-)

A Python map's iterator just iterates the keys, so you might need to
build the iterator by hand if you want it to do the same thing.

>> One approach would be to wrap a function which could convert
>> the pointer with the lifetime management you want:
>
> I have a host object Host which holds all Keys and cleaning them on
> desruction.  Host can return const Key* and I'd like to keep that
> (wrapped) host instead.

Fine; I think you can figure out how to make that work, yes?

>> I think that would solve it.
>
> Thanks a lot, Dave. BPL already saved us a week debugging and more
> is on the way.

That's great!  I'm curious, though: how can you tell it saved you a
week?

>> Mike, I think this would make a really good tutorial case study for
>> the Boost.Python documentation.  Is there any way I could persuade
>> you to write it up so that others can benefit?
>
> (side note) I'm constantly adding some stuff from that list to the wiki.
> OK, if you think I can do it, I can do it. :)

I have complete faith!

> You mean that http://www.boost.org/libs/python/doc/tutorial/index.html
> tutorial?

No, I think we'll probably build up a bunch of these case studies, and
they would just weigh down the tutorial.

> I need a few lines guidelines like a few questions that my future
> text will answer and I'll go for it.

Sorry, I don't understand what it is you need to know.  Just let me
know; I really appreciate your willingness to contribute!

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Sat Jan 18 01:24:14 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 17 Jan 2003 19:24:14 -0500
Subject: [C++-sig] Re: map key
In-Reply-To:  (David Abrahams's message
 of "Fri, 17 Jan 2003 19:00:11 -0500")
References:  
	 
Message-ID: 

David Abrahams  writes:

> "Mike Rovner"  writes:
>
>> But while it's great at hand-maid keys() and items() lists, there's
>> still a problem with iterator >(). Obviosly
>> it doesn't know about ptr().
>
> I think it doesn't know about std::pair, which is
> the iterator's value type ;-)
>
> A Python map's iterator just iterates the keys, so you might need to
> build the iterator by hand if you want it to do the same thing.

You could use the Boost transform iterator adaptor with std::select1st
to build an iterator over keys and expose it with class_<...>.range().

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From nickm at sitius.com  Sun Jan 19 07:20:53 2003
From: nickm at sitius.com (Nikolay Mladenov)
Date: Sun, 19 Jan 2003 01:20:53 -0500
Subject: [C++-sig] Re: staticmethod diffs
References: <3E2854FA.E773C7DC@sitius.com> 
Message-ID: <3E2A43C5.D5926865@sitius.com>

An HTML attachment was scrubbed...
URL: 
-------------- next part --------------
'''
>>> from static_method import *

>>> class X1(X):
...     pass


>>> x = X(16)
>>> x1 = X1(17)



>>> x1.count()
2

>>> x.count()
2

>>> X1.count()
2

>>> X.count()
2


>>> x1.magic()
7654321

>>> x.magic()
7654321

>>> X1.magic()
7654321

>>> X.magic()
7654321


'''

def run(args = None):
    import sys
    import doctest

    if args is not None:
        sys.argv = args
    return doctest.testmod(sys.modules.get(__name__))
    
if __name__ == '__main__':
    print "running..."
    import sys
    sys.exit(run()[0])
-------------- next part --------------
A non-text attachment was scrubbed...
Name: static_methods.cpp
Type: application/x-unknown-content-type-cppfile
Size: 1430 bytes
Desc: not available
URL: 

From dave at boost-consulting.com  Sun Jan 19 20:13:38 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Sun, 19 Jan 2003 14:13:38 -0500
Subject: [C++-sig] Re: staticmethod diffs
In-Reply-To: <3E2A43C5.D5926865@sitius.com> (Nikolay Mladenov's message of
 "Sun, 19 Jan 2003 01:20:53 -0500")
References: <3E2854FA.E773C7DC@sitius.com>
	 <3E2A43C5.D5926865@sitius.com>
Message-ID: 

Thanks very much, Nikolay!

I've integrated your changes to CVS and added your name to the
acknowledgements page.

Nikolay Mladenov  writes:

> I was not sure how exactly the doctest scripts work, and I followed
> the virtual function example.  Attached are the test files.


-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From nickm at sitius.com  Mon Jan 20 17:05:35 2003
From: nickm at sitius.com (Nikolay Mladenov)
Date: Mon, 20 Jan 2003 11:05:35 -0500
Subject: [C++-sig] customizing return_from_python
Message-ID: <3E2C1E4F.DF786794@sitius.com>

An HTML attachment was scrubbed...
URL: 

From dave at boost-consulting.com  Mon Jan 20 17:13:23 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Mon, 20 Jan 2003 11:13:23 -0500
Subject: [C++-sig] customizing return_from_python
In-Reply-To: <3E2C1E4F.DF786794@sitius.com> (Nikolay Mladenov's message of
 "Mon, 20 Jan 2003 11:05:35 -0500")
References: <3E2C1E4F.DF786794@sitius.com>
Message-ID: 

Nikolay Mladenov  writes:

> I want to customize call_method is such way, that if the python call returns "None",
> call_method to return some default value.
> I tried specializing return_from_python and returnable, but I had two problems with that:
> ?1. MSVC6 did not compile the return_from_python specialization
> ?2. returnable is in the "detail" namespace.
>
> Can someone suggest me how to do this?

Not sure what you are trying to accomplish exactly.  Might I suggest:

    object result = call_method(  );
    if (result.ptr() == object.ptr())
    {
        // handle None case
    }
    else
    {
        X x = extract(result);
        ...
    }

> Thanks,
>
> Nikolay Mladenov
>
> PS. is this code valid?
>
> template 
> struct templ{};
>
> template 
> struct templ_param{};
>
> template 
> struct templ< templ_param > : templ{};

Yes, and it will compile if your compiler supports partial
specialization. http://www.comeaucomputing.com/tryitout

P.S. Something is odd about the way your postings show up.  Maybe
adding a newline at the end would help formatting (?)

 _______________________________________________ 
C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig 

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From nickm at sitius.com  Mon Jan 20 17:25:55 2003
From: nickm at sitius.com (Nikolay Mladenov)
Date: Mon, 20 Jan 2003 11:25:55 -0500
Subject: [C++-sig] Re: customizing return_from_python
References: <3E2C1E4F.DF786794@sitius.com> 
Message-ID: <3E2C2313.B408B64@sitius.com>

An HTML attachment was scrubbed...
URL: 

From mike at bindkey.com  Mon Jan 20 21:44:02 2003
From: mike at bindkey.com (Mike Rovner)
Date: Mon, 20 Jan 2003 12:44:02 -0800
Subject: [C++-sig] Re: Re: map key
References:   
Message-ID: <007701c2c0c4$aab707c0$1500a8c0@MIKE>

> > "David Abrahams"  wrote in message
> > news:usmvrh0l3.fsf at boost-consulting.com...
> >> "Mike Rovner"  writes:
> >>
> > I have a host object Host which holds all Keys and cleaning them on
> > desruction.  Host can return const Key* and I'd like to keep that
> > (wrapped) host instead.
>
> Fine; I think you can figure out how to make that work, yes?

Yeh, it's already done.

> > Thanks a lot, Dave. BPL already saved us a week debugging and more
> > is on the way.
>
> That's great!  I'm curious, though: how can you tell it saved you a
> week?

I estimate my debugging effort without BPL. ;)

> > I need a few lines guidelines like a few questions that my future
> > text will answer and I'll go for it.
>
> Sorry, I don't understand what it is you need to know.  Just let me
> know; I really appreciate your willingness to contribute!

I mean a short example of the same style. i.e. what it shall looks like - an
essay, a faq entry, a short how-to, you name it...
You know, I fall into the same trap all the time - when thing is obvious for
me, it's hard to find questions to answer. When it still not - it hard to
grok it from existing texts. :)




From mike at bindkey.com  Mon Jan 20 21:46:15 2003
From: mike at bindkey.com (Mike Rovner)
Date: Mon, 20 Jan 2003 12:46:15 -0800
Subject: [C++-sig] Re: Re: map key
References:    
Message-ID: 

"David Abrahams"  wrote in message
news:uadhzfgpd.fsf at boost-consulting.com...
> David Abrahams  writes:
>
> > I think it doesn't know about std::pair, which is
> > the iterator's value type ;-)

Of cause, you are right!

> > A Python map's iterator just iterates the keys, so you might need to
> > build the iterator by hand if you want it to do the same thing.
>
> You could use the Boost transform iterator adaptor with std::select1st
> to build an iterator over keys and expose it with class_<...>.range().

I decided to leave them out. I already have keys(), values() and items(),
so I can live without iter...().






From mike at bindkey.com  Mon Jan 20 22:19:38 2003
From: mike at bindkey.com (Mike Rovner)
Date: Mon, 20 Jan 2003 13:19:38 -0800
Subject: [C++-sig] Re: passig lifetime control to C++
Message-ID: <00e101c2c0c9$a4795610$1500a8c0@MIKE>

"jochen"  wrote in message
news:8de825c2.0301200859.4b89cee3 at posting.google.com...
> I have class EventQueue that takes control over the lifetime of Events
> that are passed to it. Now I wan't to export this functionality to
> python using boost_python.

It's better to ask boost_python questions in c++-sig mailing list.

> int EventQueue::PostEvent( Event* i_pEvent )
>
> to python, how do I keep Python from deleting the Event after the
> script has finished? Can this be done with call policies ?

By default it will create new Event object with Event(*i_pEvent), so you can
delete it.
If you expose it as
.def("PostEvent", &EventQueue::PostEvent, with_custodian_and_ward<1,2>())
then Event will not be deleted while EventQueue is alive.






From dave at boost-consulting.com  Tue Jan 21 00:24:16 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Mon, 20 Jan 2003 18:24:16 -0500
Subject: [C++-sig] Re: Re: map key
In-Reply-To: <007701c2c0c4$aab707c0$1500a8c0@MIKE> ("Mike Rovner"'s message
 of "Mon, 20 Jan 2003 12:44:02 -0800")
References:  
	 
	<007701c2c0c4$aab707c0$1500a8c0@MIKE>
Message-ID: 

"Mike Rovner"  writes:

> I mean a short example of the same style. i.e. what it shall looks like - an
> essay, a faq entry, a short how-to, you name it...
> You know, I fall into the same trap all the time - when thing is obvious for
> me, it's hard to find questions to answer. When it still not - it hard to
> grok it from existing texts. :)

Well, I guess I don't have an example of anything like this sitting
around.  You'll have to be the pioneer.

I suggest you just describe the problem you're trying to solve, the
thought process you went through and rationale for your choices, and
show the code.  If you want to use the FAQ as a template I guess it
would be OK, but I predict it will be a little too long for a FAQ.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Tue Jan 21 00:25:26 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Mon, 20 Jan 2003 18:25:26 -0500
Subject: [C++-sig] Re: Re: map key
In-Reply-To:  ("Mike Rovner"'s message of "Mon,
 20 Jan 2003 12:46:15 -0800")
References:  
	 
	 
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:uadhzfgpd.fsf at boost-consulting.com...
>> David Abrahams  writes:
>>
>> > I think it doesn't know about std::pair, which is
>> > the iterator's value type ;-)
>
> Of cause, you are right!
>
>> > A Python map's iterator just iterates the keys, so you might need to
>> > build the iterator by hand if you want it to do the same thing.
>>
>> You could use the Boost transform iterator adaptor with std::select1st
>> to build an iterator over keys and expose it with class_<...>.range().
>
> I decided to leave them out. I already have keys(), values() and items(),
> so I can live without iter...().

Too bad; transform iterator adaptor with std::select1st + range()
would've been an easy and clean solution.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From mike at bindkey.com  Tue Jan 21 15:13:43 2003
From: mike at bindkey.com (Mike Rovner)
Date: Tue, 21 Jan 2003 06:13:43 -0800
Subject: [C++-sig] Re: Re: Re: map key
References:   <007701c2c0c4$aab707c0$1500a8c0@MIKE> 
Message-ID: 

"David Abrahams"  wrote in message
news:ud6mre76n.fsf at boost-consulting.com...
>
> I suggest you just describe the problem you're trying to solve, the
> thought process you went through and rationale for your choices, and
> show the code.  If you want to use the FAQ as a template I guess it
> would be OK, but I predict it will be a little too long for a FAQ.
>

Please take a look at the first take at
http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fStlContainers
It's still a work in progress.






From rwgk at yahoo.com  Tue Jan 21 18:45:00 2003
From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve)
Date: Tue, 21 Jan 2003 09:45:00 -0800 (PST)
Subject: [C++-sig] Re: Re: Re: map key
In-Reply-To: 
Message-ID: <20030121174500.31631.qmail@web20206.mail.yahoo.com>

--- Mike Rovner  wrote:
> Please take a look at the first take at
> http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fStlContainers
> It's still a work in progress.

> use scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h to wrap
them or 

I'd take that out because flex_wrapper.h never was intended for direct
application to other types than scitbx::af::versa<> . For other container types
it is only good as a source of ideas. Your digest of flex_wrapper.h (I dare
say) in the Wiki is a perfect replacement for this purpose.

Maybe further down in your page you could write something like "to see an
example of a more-or-less fully featured multi-dimensional array wrapper look
at flex_wrapper.h".

> It's a pity that BPL doesn't wrap STL containers out of the box. It would be
good to have "batteries included". 

This is not entirely fair for two reasons:

- As flex_wrapper.h shows, a fully featured container wrapper is a lot of code
and will take very long to compile. If you compile scitbx with an EDG compiler
(worst case in terms of compile times) you will see that it takes about two
minutes per element type even on very fast CPUs (g++ is much better in this
respect, but...). Multiply this with a handful of element types one might want
and you are looking at substantial compile times. I don't think many people
will easily buy into this kind of overhead. At least not at the moment, but
maybe in 5-10 years time when we have computers an order of magnitude faster
than today. I'd guess until then most people will prefer your very own "strip
it down to what I need" approach.

- It is a major research project to develop "a best" fully featured container
wrapper. flex_wrapper.h really is only a simple case, and see all the stuff
that one might want already. Note that what you want depends on the element
type (e.g. what makes sense for std::complex<> as an element type does not
necessarily make sense for double, what makes sense for double might not make
sense for int and vice versa, etc. etc.)! I cannot even imagine what a
comprehensive solution for std::map<> could look like since it will have to
deal with combinations of two types.

In summary, I think the best Boost.Python could realistically hope to do for
some years to come is provide higher-level building blocks for conveniently
composing custom container wrappers. I am sure David will enthusiastically
welcome contributions of this kind (incl. regression tests & full
documentation, of course ;-). Alternatively, allocation of funding for David
will help him create the space that he needs to be able to tackle problems
important to you (it sure did for us).

Ralf

P.S.: I attach two relevant sections from an article I am currently working on
(for a non-CS audience). Comments are very welcome.

=================
 A balancing act
=================

Python's **convenience of use** is directly related to the way the
Python type system works: all type information is evaluated at runtime.
For example consider this trivial function::

  def plus(a, b):
    return a + b

It works instantly for many different argument types::

  >>> plus(1, 2) # integer values
  3
  >>> plus(1+2j, 2+3j) # complex values
  (3+5j)
  >>> plus(['a', 'b'], ['c', 'd']) # lists
  ['a', 'b', 'c', 'd']

It works because the meaning of ``a + b`` is determined at runtime
based on the actual types of ``a`` and ``b``.

The **runtime efficiency** of C++ code is directly related to the way
the C++ type system works: type information is usually evaluated at
compile-time (virtual functions are an exception which we will not
consider here). Fortunately C++ has a very powerful mechanism that
helps us avoid explicitly coding polymorphic functions over and over
again::

  template 
  T plus(T const& a, T const& b)
  {
    return a + b;
  }

This template function is automatically *instantiated* for a given type
``T`` as used::

  int a = 1;
  int b = 2;
  int c = plus(a, b); // implicitly instantiates plus with T==int

Given a system that is based on both Python and C++ we have the freedom
of choosing the quick-and-easy runtime polymorphism offered by Python,
or the more efficient compile-time polymorphism offered by C++.

An important consideration in deciding which solution is the most
appropriate for a given problem is that a polymorphic Python function
requires very little memory at runtime. In contrast, each new
instantiation of a template function eventually results in a complete
copy of the corresponding machine language instructions tailored for
the specific types involved. This point may seem subtle at first, but
being overly generous with the use of C++ compile-time polymorphism can
lead to very large executable sizes and excessive compile times.

A comparison of the ``plus`` Python function and its C++ counterpart
shows that the notational overhead of the C++ syntax can easily double
the size of the source code. Therefore a programmer, given the choice,
will naturally lean towards the Python solution until the runtime
penalty due to the dynamic typing is prohibitive for a given
application. However, when putting a dynamically typed system and a
statically typed system together there are situations where it is
important to carefully consider the best balance.

================
 Hybrid systems
================

Considerations of the type discussed in the previous section directly
lead to the following situation::

  >>> a = flex.int((1,2,3))
  >>> b = flex.double((2,3,4))
  >>> a * b
  TypeError: unsupported operand type(s) for *:
  'scitbx_boost.array_family.flex_scitbx_ext.int' and
  'scitbx_boost.array_family.flex_scitbx_ext.double'

In passing we note that there is a simple solution which will produce
the desired result::

  a.as_double() * b

However, for the purpose of this discussion let's pretend that this
solution does not exist. Of course the first question is: what is
the reason for the apparently stupid limitation?

As mentioned before, the Python ``flex`` types are implemented as
instantiations of C++ class templates. This ensures that all array
operations are very fast. However, from the discussion in the previous
section it follows that exposing the full class with its many member
functions to Python **for each element type** (``int``, ``double``,
``miller::index<>``, etc.) creates very sizable object files. If only
*homogeneous* operators (``int * int``, ``double * double``, etc.) are
used the combined size of the object files scales linearly with the
number of element types involved. However, if the library is expanded
to support *heterogeneous* operators (``int * double``, ``double *
int``, etc.) the combined object files grow proportional to the square
of the number of array element types involved! With current technology
this is simply prohibitive.

Limitations of the kind discussed here will apply to any hybrid
dynamically/statically typed system. In the broader picture the
limitation shown above is just one typical example. If we want to enjoy
the many benefits of using Python *and* have a system that produces
results with a reasonable runtime efficiency we have to adopt the
approach of sparsely sampling the space of possible C++ template
instantiations. For this idea to work in practice we need a powerful
and easy to use language-integration tool.


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com



From mike at bindkey.com  Wed Jan 22 02:29:13 2003
From: mike at bindkey.com (Mike Rovner)
Date: Tue, 21 Jan 2003 17:29:13 -0800
Subject: [C++-sig] Re: Re: Re: map key
References:     
Message-ID: 

"David Abrahams"  wrote in message
news:u8yxfe74p.fsf at boost-consulting.com...
> "Mike Rovner"  writes:
>
> > I decided to leave them out. I already have keys(), values() and
items(),
> > so I can live without iter...().
>
> Too bad; transform iterator adaptor with std::select1st + range()
> would've been an easy and clean solution.

Not so clean, though. :(

std::select1st
"This function object is an SGI extension; it is not part of the C++
standard." (http://sgi.com/tech/stl/select1st.html)

MSVC7 std:: doesn't have it.

Nevertheless should it be like that
...
.def("__iter__", range<>(
  boost::make_transform_iterator(&StdMap::begin,std::select1st),
  boost::make_transform_iterator(&StdMap::end,std::select1st)
)
?

And how I can insert ptr() call inside that iterator; with return policy?






From BeetleHoHo at hotmail.com  Wed Jan 22 13:43:44 2003
From: BeetleHoHo at hotmail.com (Beetle)
Date: Wed, 22 Jan 2003 20:43:44 +0800
Subject: [C++-sig] functions whose return type is a pointer
Message-ID: 

Dear All :
    I have several C++ class member functions, whose return type is a pointer. For example, consider this snippet :

class A : 
{
public :
// function getAttributeX returns a pointer of class B 
    B * getAttributeX(int x, int y);
//...
}

// boost.python
    class ("A")
        .def("getAttributeX",(B (A::*)(int,int)) A ::getAttributeX)

   If I do this : 
    >>> a = A()
    >>> px = a.getAttributeX()
    what is the data type of px anyway,  or I simply can't do this kind of wrapping ?
    Can anybody be so kind to tell me ?

Regards

Horace (T.L.Ho)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From rwgk at yahoo.com  Wed Jan 22 15:55:40 2003
From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve)
Date: Wed, 22 Jan 2003 06:55:40 -0800 (PST)
Subject: [C++-sig] functions whose return type is a pointer
In-Reply-To: 
Message-ID: <20030122145540.78821.qmail@web20201.mail.yahoo.com>

--- Beetle  wrote:
>    If I do this : 
>     >>> a = A()
>     >>> px = a.getAttributeX()
>     what is the data type of px anyway,  or I simply can't do this kind of
> wrapping ?

You can, but you have to deal with life-time issues explicitly. This is
explained very nicely in the tutorial:

http://www.boost.org/libs/python/doc/tutorial/doc/call_policies.html

For this you will have to have a class_ statement also.

Ralf

P.S.: Recently there was a thread on wrapping "opaque pointers":

http://mail.python.org/pipermail/c++-sig/2003-January/003207.html

I am not sure what the current status of the corresponding patch is. Please
check the archive for the whole story if this sounds interesting.


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com



From nickm at sitius.com  Wed Jan 22 16:03:15 2003
From: nickm at sitius.com (Nikolay Mladenov)
Date: Wed, 22 Jan 2003 10:03:15 -0500
Subject: [C++-sig] Return existing instance
Message-ID: <3E2EB2B3.A026F60D@sitius.com>

An HTML attachment was scrubbed...
URL: 

From Gottfried.Ganssauge at HAUFE.DE  Wed Jan 22 17:06:47 2003
From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE)
Date: Wed, 22 Jan 2003 17:06:47 +0100
Subject: [C++-sig] functions whose return type is a pointer
Message-ID: <2040C0A1CA23D51181A30050BAAC9902019016@berexch.ber.haufemg.com>

I would love to prepare a patch for the opaque pointer issue if someone
could explain the proper procedure to me.

Cheers,

G.Gan?auge

> -----Original Message-----
> From: Ralf W. Grosse-Kunstleve [mailto:rwgk at yahoo.com] 
> Sent: Wednesday, January 22, 2003 3:56 PM
> To: c++-sig at python.org
> Subject: Re: [C++-sig] functions whose return type is a pointer
> 
> 
> --- Beetle  wrote:
> >    If I do this : 
> >     >>> a = A()
> >     >>> px = a.getAttributeX()
> >     what is the data type of px anyway,  or I simply can't do this 
> > kind of wrapping ?
> 
> You can, but you have to deal with life-time issues 
> explicitly. This is explained very nicely in the tutorial:
> 
http://www.boost.org/libs/python/doc/tutorial/doc/call_policies.html

For this you will have to have a class_ statement also.

Ralf

P.S.: Recently there was a thread on wrapping "opaque pointers":

http://mail.python.org/pipermail/c++-sig/2003-January/003207.html

I am not sure what the current status of the corresponding patch is. Please
check the archive for the whole story if this sounds interesting.


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

_______________________________________________
C++-sig mailing list
C++-sig at python.org
http://mail.python.org/mailman/listinfo/c++-sig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From sdfrost at ucsd.edu  Thu Jan 23 00:56:01 2003
From: sdfrost at ucsd.edu (Simon Frost)
Date: Wed, 22 Jan 2003 15:56:01 -0800
Subject: [C++-sig] Newbie boost query
Message-ID: <5.1.0.14.0.20030122154606.01ee8dd8@popmail.ucsd.edu>

An HTML attachment was scrubbed...
URL: 

From dave at boost-consulting.com  Thu Jan 23 01:19:33 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Wed, 22 Jan 2003 19:19:33 -0500
Subject: [C++-sig] Newbie boost query
In-Reply-To: <5.1.0.14.0.20030122154606.01ee8dd8@popmail.ucsd.edu> (Simon
 Frost's message of "Wed, 22 Jan 2003 15:56:01 -0800")
References: <5.1.0.14.0.20030122154606.01ee8dd8@popmail.ucsd.edu>
Message-ID: 

Simon Frost  writes:

> Hi folks,

> I'm trying to feel my way around Boost.Python, and I've come unstuck
> whenever I've tried to wrap classes. For example, when I try to wrap
> a test function ((in my case, RandMT, a Mersenne twister class from
> Paul Gresham, from http://www.math.keio.ac.jp/~matumoto/july00.html)

FWIW, we have a mersenne twister in Boost's "Random" library.

> with the following functions:

> (i.e. just exposing the default constructor and the randomMT
> function)

The problems don't have anything to do with the code you used for wrapping.

> I get a bunch of errors abput undefined references:

These are linker errors due to the fact that you're not bringing in
the Boost.Python DLL's import lib.  Are you following the instructions
at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/building.html#building_ext
??

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From sdfrost at ucsd.edu  Thu Jan 23 02:22:54 2003
From: sdfrost at ucsd.edu (Simon Frost)
Date: Wed, 22 Jan 2003 17:22:54 -0800
Subject: [C++-sig] Newbie boost query
In-Reply-To: 
References: <5.1.0.14.0.20030122154606.01ee8dd8@popmail.ucsd.edu>
 <5.1.0.14.0.20030122154606.01ee8dd8@popmail.ucsd.edu>
Message-ID: <5.1.0.14.0.20030122171833.01ef4790@popmail.ucsd.edu>

Dear David,

At 07:19 PM 1/22/2003 -0500, you wrote:
>Simon Frost  writes:
>
> > Hi folks,
>
> > I'm trying to feel my way around Boost.Python, and I've come unstuck
> > whenever I've tried to wrap classes. For example, when I try to wrap
> > a test function ((in my case, RandMT, a Mersenne twister class from
> > Paul Gresham, from http://www.math.keio.ac.jp/~matumoto/july00.html)
>
>FWIW, we have a mersenne twister in Boost's "Random" library.

I'll give it a go; how does it compare with the C Mersenne Twister in 
Python 2.3?

> > with the following functions:
>
> > (i.e. just exposing the default constructor and the randomMT
> > function)
>
>The problems don't have anything to do with the code you used for wrapping.
>
> > I get a bunch of errors abput undefined references:
>
>These are linker errors due to the fact that you're not bringing in
>the Boost.Python DLL's import lib.  Are you following the instructions
>at
>http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/building.html#building_ext
>??

I did when I first installed (and the examples worked fine); for some 
reason, since I last played with Boost, my installation broke. I 
reinstalled, and now the class wraps happily.

I'm now trying to wrap an AVL Tree (using William McKee's implementation):

template 
class Tree
{
private :
     Node * root;
public :
     Tree ()
     {
         root = NULL;
     }
     ~Tree ()
     {
         delete root;
     }
     void insert (const T & inData)
     {
         root = root -> insert_node (inData);
     }
     const T * find (const T & inData) const
     {
         const Node * found = root -> find_node (inData);
         if (found != NULL)
             return & found -> data;
         else
             return NULL;
     }
     void remove (const T & inData)
     {
         root = root -> remove_node (inData);
     }
     void print (std::ostream & co) const
     {
         root -> print_node (co);
     }
};

Any pointers/similar examples on how to wrap these kinds of structures?

Best,
Simon

Simon D.W. Frost, M.A., D.Phil.
Department of Pathology
University of California, San Diego
Antiviral Research Center
150 W. Washington St., Suite 100
San Diego, CA 92103
USA

Tel: +1 619 543 8080 x275
Fax: +1 619 298 0177
Email: sdfrost at ucsd.edu

Register for the 10th International Discussion meeting on HIV Dynamics and 
Evolution:
http://ari.ucsd.edu/cfar/hivdynamics






From tim.one at comcast.net  Thu Jan 23 02:56:07 2003
From: tim.one at comcast.net (Tim Peters)
Date: Wed, 22 Jan 2003 20:56:07 -0500
Subject: [C++-sig] Newbie boost query
In-Reply-To: <5.1.0.14.0.20030122171833.01ef4790@popmail.ucsd.edu>
Message-ID: 

[David Abrahams]
> FWIW, we have a mersenne twister in Boost's "Random" library.

[Simon Frost]
> I'll give it a go; how does it compare with the C Mersenne Twister in
> Python 2.3?

Python's uses the inventors' original code, with recently improved
initialiation code, wrapped inside a Python object.  The Boost docs say
theirs was "implemented from scratch" and doesn't use the inventors'
original code.  Other than that, looks like the Python version is Pythonic
and the Boost version is C++ic:  random.random() versus a 12-argument
template class .




From dave at boost-consulting.com  Thu Jan 23 03:38:37 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Wed, 22 Jan 2003 21:38:37 -0500
Subject: [C++-sig] Newbie boost query
In-Reply-To:  (Tim
 Peters's message of "Wed, 22 Jan 2003 20:56:07 -0500")
References: 
Message-ID: 

Tim Peters  writes:

> [David Abrahams]
>> FWIW, we have a mersenne twister in Boost's "Random" library.
>
> [Simon Frost]
>> I'll give it a go; how does it compare with the C Mersenne Twister in
>> Python 2.3?
>
> Python's uses the inventors' original code, with recently improved
> initialiation code, wrapped inside a Python object.  The Boost docs say
> theirs was "implemented from scratch" and doesn't use the inventors'
> original code.  

And, in fairness, "However, it was verified that both produce
identical output."

> Other than that, looks like the Python version is Pythonic
> and the Boost version is C++ic:  random.random() versus a 12-argument
> template class

And, in fairness, the doc also says: "The quality of the generator
crucially depends on the choice of the parameters. User code should
employ one of the sensibly parameterized generators such as mt19937
instead.  The generator requires considerable amounts of memory for
the storage of its state array. For example, mt11213b requires about
1408 bytes and mt19937 requires about 2496 bytes."

mt19937 and mt11213b are simple typedefs for useful instantiations of
the 12-argument template, so you don't need to worry about dealing
with those template paramters directly, and the result is just a
callable function object.

None of this is to say that you should use Boost's version; I don't
even know what substantive differences there might be.  Just letting
you know that there are choices available as long as you're determined
to wrap some C/C++ implementation.

-Dave

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From bscott at iastate.edu  Thu Jan 23 03:53:11 2003
From: bscott at iastate.edu (Ben Scott)
Date: Wed, 22 Jan 2003 20:53:11 -0600
Subject: [C++-sig] Wrapping a factory
Message-ID: <3E2F5917.90404@vrac.iastate.edu>

Hi again. I'm playing around with the factory code I asked for help on 
before 
(http://mail.python.org/pipermail/c++-sig/2003-January/003217.html) and 
have changed things around a bit (as my library has changed). You'll 
notice that the only difference from before is that the creator no 
longer requires an argument to the create() method.

Unfortunately, I've gotten stuck again and am looking for somebody to 
point me in the right direction. I just can't seem to get my C++ Factory 
object to see the correct type of my python Creator object as you can 
see in the following output. It appears to only know about the Creator 
base type and be unable to call into the implementation's method.

$ ./simple.py
Name: P7Creator
pure virtual method called
Aborted (core dumped)

cheers,
-----
Ben Scott
Research Assistant
VR Juggler Team
Virtual Reality Applications Center
bscott at vrac.iastate.edu
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test.cpp
URL: 
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: simple.py
URL: 

From dave at boost-consulting.com  Thu Jan 23 05:19:29 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Wed, 22 Jan 2003 23:19:29 -0500
Subject: [C++-sig] Wrapping a factory
In-Reply-To: <3E2F5917.90404@vrac.iastate.edu> (Ben Scott's message of "Wed,
 22 Jan 2003 20:53:11 -0600")
References: <3E2F5917.90404@vrac.iastate.edu>
Message-ID: 

Ben Scott  writes:

> Hi again. I'm playing around with the factory code I
> asked for help on before
> (http://mail.python.org/pipermail/c++-sig/2003-January/003217.html)
> and have changed things around a bit (as my library has
> changed). You'll notice that the only difference from
> before is that the creator no longer requires an
> argument to the create() method.
>
> Unfortunately, I've gotten stuck again and am looking
> for somebody to point me in the right direction. I just
> can't seem to get my C++ Factory object to see the
> correct type of my python Creator object as you can see
> in the following output. It appears to only know about
> the Creator base type and be unable to call into the
> implementation's method.

You've uncovered a bug in Boost.Python.  Thank you!

I've got a fix; I'm just testing it now to make sure it doesn't break
anything else and I'll let you know when it's checked in.

-Dave

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 05:32:54 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Wed, 22 Jan 2003 23:32:54 -0500
Subject: [C++-sig] Wrapping a factory
In-Reply-To:  (David Abrahams's message
 of "Wed, 22 Jan 2003 23:19:29 -0500")
References: <3E2F5917.90404@vrac.iastate.edu>
	
Message-ID: 

David Abrahams  writes:

> Ben Scott  writes:
>
>> Hi again. I'm playing around with the factory code I
>> asked for help on before
>> (http://mail.python.org/pipermail/c++-sig/2003-January/003217.html)
>> and have changed things around a bit (as my library has
>> changed). You'll notice that the only difference from
>> before is that the creator no longer requires an
>> argument to the create() method.
>>
>> Unfortunately, I've gotten stuck again and am looking
>> for somebody to point me in the right direction. I just
>> can't seem to get my C++ Factory object to see the
>> correct type of my python Creator object as you can see
>> in the following output. It appears to only know about
>> the Creator base type and be unable to call into the
>> implementation's method.
>
> You've uncovered a bug in Boost.Python.  Thank you!
>
> I've got a fix; I'm just testing it now to make sure it doesn't break
> anything else and I'll let you know when it's checked in.

OK, done.  Thanks again for the report.

-Dave

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 18:25:46 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 12:25:46 -0500
Subject: [C++-sig] Return existing instance
In-Reply-To: <3E2EB2B3.A026F60D@sitius.com> (Nikolay Mladenov's message of
 "Wed, 22 Jan 2003 10:03:15 -0500")
References: <3E2EB2B3.A026F60D@sitius.com>
Message-ID: 

Nikolay Mladenov  writes:

> Hi,
>
> Is there a way to find the existing PyObject that holds given C++ object?
> I need a return policy for functions that always return pointer to already held C++ object.


Hi Nikolay,

One way to do that is to hijack the mechanisms used for wrapping a
class with virtual functions.  If you make a wrapper class with an
initial PyObject* constructor argument and store that PyObject* as
"self", you can get back to it by casting down to that wrapper type in
a thin wrapper function.  For example:

  class X { X(int); virtual ~X(); ... };
  X* f();  // known to return Xs that are managed by Python objects


  // wrapping code
  
  struct X_wrap : X
  {
      X_wrap(PyObject* self, int v) : self(self), X(v) {}
      PyObject* self;
  };

  handle<> f_wrap()
  {
      X_wrap* xw = dynamic_cast(f());
      assert(xw != 0);
      return handle<>(borrowed(xw->self));
  }

  ...

  def("f", f_wrap());
  class_("X", init())
     ...
     ;

  
Of course, if X has no virtual functions you'll have to use
static_cast instead of dynamic_cast with no runtime check that it's
valid.  This approach also only works if the X object was constructed
from Python, because Xs constructed from C++ are of course never
X_wrap objects.

Another approach to this requires some work from me, but it's work
I've been meaning to get to anyway.  Currently, when a shared_ptr
is converted from Python, the shared_ptr actually manages a reference
to the containing Python object.  I plan to make it so that when a
shared_ptr is converted back to Python, the library checks to see
if it's one of those "Python object managers" and if so just returns
the original Python object.  To exploit this you'd have to be able to
change the C++ code you're wrapping so that it deals with shared_ptr
instead of raw pointers.

There are other approaches too.  The functions that receive the Python
object that you eventually want to return could be wrapped with a thin
wrapper that records the correspondence between the object address and
its containing Python object, and you could have your f_wrap function
look in that mapping to get the Python object out.

Lots of options, HTH...

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 19:20:21 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 13:20:21 -0500
Subject: [C++-sig] functions whose return type is a pointer
In-Reply-To: <2040C0A1CA23D51181A30050BAAC9902019016@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's
 message of "Wed, 22 Jan 2003 17:06:47 +0100")
References: <2040C0A1CA23D51181A30050BAAC9902019016@berexch.ber.haufemg.com>
Message-ID: 

Gottfried.Ganssauge at HAUFE.DE writes:

> I would love to prepare a patch for the opaque pointer issue if someone
> could explain the proper procedure to me.

And I'd love to apply such a patch.

All you have to do is make the changes in your CVS tree, and then use
"cvs diff -NR -u" from the boost root directory.  Stick the result in
an enclosure and post it.

Thanks,
Dave

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From Pere.Mato at cern.ch  Thu Jan 23 19:40:40 2003
From: Pere.Mato at cern.ch (Pere Mato Vila)
Date: Thu, 23 Jan 2003 19:40:40 +0100
Subject: [C++-sig] Interfacing pure abstract classes with Boost.Python
Message-ID: 

Hi all,

  I have problems interfacing pure abstract classes, which I do not
intend to extent from the Python side, with version 2 of Boost.Python.

The class IHistogram is defined as

class IHistogram   {
public: 
  virtual int dimension (  ) const = 0;
  ...
};

I expose it as

  python::class_ ("IHistogram",
python::no_init )
    .def("dim",   &IHistogram::dimension )
  ...

And I provide the method iHistogramSvc::book1D(...) which returns an
IHistogram* and is exposed as

  python::class_
     ( "IHistogramSvc", python::init() )
    .def("book",       &GaudiPython::iHistogramSvc::book1D )

So far so good. I am able to compile and produce the Python extension
module. But, when I run the Python code I get:

>>> gaudi.IHistogram1D

>>> h1 = his.book('1', 'histogram title', 10, 0, 10)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: No to_python (by-value) converter found for C++ type: class
IHistogram1D


  What I am doing wrong? In the old version I was able to work around
the problem by adding the lines in the C++ module extension 

PyObject* to_python(IHistogram* p) {
    return
boost::python::python_extension_class_converters::smart_ptr_
to_python(p);
}

  And obviously this is not working.

------------------------------------------------------------
Pere Mato  CERN, EP Division, CH 1211 Geneva 23, Switzerland
           e-mail: Pere.Mato at cern.ch    tel: +41 22 76 78696
           fax:  +41 22 76 79425        gsm: +41 79 20 10855

 



From dave at boost-consulting.com  Thu Jan 23 19:57:27 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 13:57:27 -0500
Subject: [C++-sig] Re: Re: Re: map key
In-Reply-To:  ("Mike Rovner"'s message of "Tue,
 21 Jan 2003 17:29:13 -0800")
References:  
	 
	 
	 
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:u8yxfe74p.fsf at boost-consulting.com...
>> "Mike Rovner"  writes:
>>
>> > I decided to leave them out. I already have keys(), values() and
> items(),
>> > so I can live without iter...().
>>
>> Too bad; transform iterator adaptor with std::select1st + range()
>> would've been an easy and clean solution.
>
> Not so clean, though. :(
>
> std::select1st
> "This function object is an SGI extension; it is not part of the C++
> standard." (http://sgi.com/tech/stl/select1st.html)
>
> MSVC7 std:: doesn't have it.

It's trivial to write your own, or you can use Boost.Bind to build one:

     boost::bind(&StdMap::value_type::first)

> Nevertheless should it be like that
> ...
> .def("__iter__", range<>(
>   boost::make_transform_iterator(&StdMap::begin,std::select1st),
>   boost::make_transform_iterator(&StdMap::end,std::select1st)
> )
> ?
>
> And how I can insert ptr() call inside that iterator; with return policy?

I'm confused; why would you want to?  There's no pointer involved.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 19:59:19 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 13:59:19 -0500
Subject: [C++-sig] Re: Re: Re: map key
In-Reply-To: <20030121174500.31631.qmail@web20206.mail.yahoo.com> ("Ralf W.
 Grosse-Kunstleve"'s message of "Tue, 21 Jan 2003 09:45:00 -0800 (PST)")
References: <20030121174500.31631.qmail@web20206.mail.yahoo.com>
Message-ID: 

"Ralf W. Grosse-Kunstleve"  writes:

> --- Mike Rovner  wrote:

> P.S.: I attach two relevant sections from an article I am currently
> working on (for a non-CS audience). Comments are very welcome.

It's a nice article!


>
> Considerations of the type discussed in the previous section directly
> lead to the following situation::
>
>   >>> a = flex.int((1,2,3))
>   >>> b = flex.double((2,3,4))
>   >>> a * b
>   TypeError: unsupported operand type(s) for *:
>   'scitbx_boost.array_family.flex_scitbx_ext.int' and
>   'scitbx_boost.array_family.flex_scitbx_ext.double'
>
> In passing we note that there is a simple solution which will produce
> the desired result::
>
>   a.as_double() * b
>
> However, for the purpose of this discussion let's pretend that this
> solution does not exist. Of course the first question is: what is
> the reason for the apparently stupid limitation?
>
> As mentioned before, the Python ``flex`` types are implemented as
> instantiations of C++ class templates. This ensures that all array
> operations are very fast. However, from the discussion in the previous
> section it follows that exposing the full class with its many member
> functions to Python **for each element type** (``int``, ``double``,
> ``miller::index<>``, etc.) creates very sizable object files. If only
> *homogeneous* operators (``int * int``, ``double * double``, etc.) are
> used the combined size of the object files scales linearly with the
> number of element types involved. However, if the library is expanded
> to support *heterogeneous* operators (``int * double``, ``double *
> int``, etc.) the combined object files grow proportional to the square
> of the number of array element types involved! With current technology
> this is simply prohibitive.

You might consider the impact of using something like weave for a case
like this.  It generates and compiles different instantiations of the
same code on demand.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From mike at bindkey.com  Thu Jan 23 20:08:46 2003
From: mike at bindkey.com (Mike Rovner)
Date: Thu, 23 Jan 2003 11:08:46 -0800
Subject: [C++-sig] "unknown dependent target" error
Message-ID: 

Hi,

I'm trying to build python extension outside boost tree with MSVC7.

Command line:
bjam -s"TOOLS=vc7" -n -a

gives me an error:
unknown dependent target boost_python.dll

boost_python.dll is there in s:/boost/libs/python/build.

What is my problem?

I have following config files:
>>> boost-build.jam file:
----------------------------------------------------------------------------
------
boost-build s:/boost/tools/build ;

>>> Jamfile file:
----------------------------------------------------------------------------
------
project-root ;

# Include definitions needed for Python modules
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;

include python.jam ;

# Declare a Python extension
extension ext
:  # sources
   ext.cpp
   # dependencies
   s:/boost/libs/python/build/boost_python
  ;

# Declare a test for the extension module
boost-python-runtest test_ext
    :  # Python test driver
    t_ext.py
    # extension modules to use
    ext ;

>>> Jamrules file (copied from boost root, otherwise bjam complains):
----------------------------------------------------------------------------
------
# Boost.Build top level Jamrules

# See tools/build/index.html for documentation.

# Set some important global variables if they haven't already been set by
the
# user on the command-line or in the environment

# Establish this as the root of the boost installation. Most targets will
want
# $(BOOST_ROOT) in their #include path.  $(gTOP) is the name of the variable
# containing the path from the invocation directory to the project root.
path-global BOOST_ROOT : $($(gTOP)) ;

# The current version of Boost.
BOOST_VERSION ?= 1.30.0 ;

Thank in advance,
Mike






From mike at bindkey.com  Thu Jan 23 20:27:26 2003
From: mike at bindkey.com (Mike Rovner)
Date: Thu, 23 Jan 2003 11:27:26 -0800
Subject: [C++-sig] Re: Re: Re: Re: map key
References:      
Message-ID: 

"David Abrahams"  wrote in message
news:uel73k82w.fsf at boost-consulting.com...
> > Nevertheless should it be like that
> > ...
> > .def("__iter__", range<>(
> >   boost::make_transform_iterator(&StdMap::begin,std::select1st),
> >   boost::make_transform_iterator(&StdMap::end,std::select1st)
> > )
> > ?
> >
> > And how I can insert ptr() call inside that iterator; with return
policy?
>
> I'm confused; why would you want to?  There's no pointer involved.

Oh, I'm sorry. That was two different questions.
The second is
Can I use return_police to force range<>() iterator apply ptr() to the
argument before converting it to object.

That is not related to map::iterator problem, that is consequences of my
another problem when I use some T* holded elsewhere and passing along as
internal_reference.

Mike






From dave at boost-consulting.com  Thu Jan 23 20:39:47 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 14:39:47 -0500
Subject: [C++-sig] Interfacing pure abstract classes with Boost.Python
In-Reply-To:  ("Pere
 Mato Vila"'s message of "Thu, 23 Jan 2003 19:40:40 +0100")
References: 
Message-ID: 

"Pere Mato Vila"  writes:

> Hi all,
>
>   I have problems interfacing pure abstract classes, which I do not
> intend to extent from the Python side, with version 2 of Boost.Python.
>
> The class IHistogram is defined as
>
> class IHistogram   {
> public: 
>   virtual int dimension (  ) const = 0;
>   ...
> };
>
> I expose it as
>
>   python::class_ ("IHistogram",
> python::no_init )
>     .def("dim",   &IHistogram::dimension )
>   ...
>
> And I provide the method iHistogramSvc::book1D(...) which returns an
> IHistogram* and is exposed as
>
>   python::class_
>      ( "IHistogramSvc", python::init() )
>     .def("book",       &GaudiPython::iHistogramSvc::book1D )
>
> So far so good. I am able to compile and produce the Python extension
> module. But, when I run the Python code I get:
>
>>>> gaudi.IHistogram1D
> 
>>>> h1 = his.book('1', 'histogram title', 10, 0, 10)
> Traceback (most recent call last):
>   File "", line 1, in ?
> TypeError: No to_python (by-value) converter found for C++ type: class
> IHistogram1D
>
>
>   What I am doing wrong? 

To begin with, you're not showing enough of your code, or you're not
showing it accurately.  Where is "IHistogram1D" coming from, for
example?  That's not mentioned anywhere in your C++ code.


-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 20:44:45 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 14:44:45 -0500
Subject: [C++-sig] "unknown dependent target" error
In-Reply-To:  ("Mike Rovner"'s message of "Thu,
 23 Jan 2003 11:08:46 -0800")
References: 
Message-ID: 

"Mike Rovner"  writes:

> Hi,
>
> I'm trying to build python extension outside boost tree with MSVC7.
>
> Command line:
> bjam -s"TOOLS=vc7" -n -a
>
> gives me an error:
> unknown dependent target boost_python.dll
>
> boost_python.dll is there in s:/boost/libs/python/build.
>
> What is my problem?

You didn't follow the instructions at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/building.html#outside,
in particular the part about starting with the archive at
http://www.boost.org/libs/python/example/project.zip

> I have following config files:
>>>> boost-build.jam file:
> ----------------------------------------------------------------------------
> ------
> boost-build s:/boost/tools/build ;
>
>>>> Jamfile file:
> ----------------------------------------------------------------------------
> ------
> project-root ;
>
> # Include definitions needed for Python modules
> SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
>
> include python.jam ;
>
> # Declare a Python extension
> extension ext
> :  # sources
>    ext.cpp
>    # dependencies
>    s:/boost/libs/python/build/boost_python

You can't refer to it that way.  Instead you have to put it in the
requirements section with  and .

>   ;
>
> # Declare a test for the extension module
> boost-python-runtest test_ext
>     :  # Python test driver
>     t_ext.py
>     # extension modules to use
>     ext ;
>
>>>> Jamrules file (copied from boost root, otherwise bjam complains):

Not a very good idea; if you want to silence the warning just use an
empty Jambase.

HTH,
-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 23 20:57:45 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 14:57:45 -0500
Subject: [C++-sig] Re: Re: Re: Re: map key
In-Reply-To:  ("Mike Rovner"'s message of "Thu,
 23 Jan 2003 11:27:26 -0800")
References:  
	 
	 
	 
	 
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:uel73k82w.fsf at boost-consulting.com...
>> > Nevertheless should it be like that
>> > ...
>> > .def("__iter__", range<>(
>> >   boost::make_transform_iterator(&StdMap::begin,std::select1st),
>> >   boost::make_transform_iterator(&StdMap::end,std::select1st)
>> > )
>> > ?
>> >
>> > And how I can insert ptr() call inside that iterator; with return
> policy?
>>
>> I'm confused; why would you want to?  There's no pointer involved.

BTW, the above doesn't quite work as it stands.  The arguments to
range have to satisfy the accessor requirements described at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/iterator.html#range-spec

> Oh, I'm sorry. That was two different questions.
> The second is
> Can I use return_police to force range<>() iterator apply ptr() to the
> argument before converting it to object.

To the argument?  Which argument?  The link above describes how to use
CallPolicies to deal with the result of the iterator's next()
function, if that's any help.

> That is not related to map::iterator problem, that is consequences of my
> another problem when I use some T* holded elsewhere and passing along as
> internal_reference.

More details would be needed.  Complete code samples are ideal.  But
first, please read the docs.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From nickm at sitius.com  Thu Jan 23 22:54:04 2003
From: nickm at sitius.com (Nikolay Mladenov)
Date: Thu, 23 Jan 2003 16:54:04 -0500
Subject: [C++-sig] Re: Return existing instance
References: <3E2EB2B3.A026F60D@sitius.com> 
Message-ID: <3E30647C.C8511B24@sitius.com>

An HTML attachment was scrubbed...
URL: 

From mike at bindkey.com  Thu Jan 23 23:03:17 2003
From: mike at bindkey.com (Mike Rovner)
Date: Thu, 23 Jan 2003 14:03:17 -0800
Subject: [C++-sig] Re: "unknown dependent target" error
References:  
Message-ID: 

"David Abrahams"  wrote in message
news:un0lrirbm.fsf at boost-consulting.com...

> You didn't follow the instructions at
>
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p
ython/doc/building.html#outside,
> in particular the part about starting with the archive at
> http://www.boost.org/libs/python/example/project.zip

Thank you. That fix it.

But I ran into old problem with diagnostics: "don't know how to make"

Here is (relevant) part of bjam -d3 output:
make -- all
time -- all: unbound
make --  shell
time --  shell: unbound
make --   first
time --   first: unbound
made stable   first
made stable  shell
make --  files
time --  files: unbound
make --   first
made stable  files
make --  lib
time --  lib: unbound
make --   first
made stable  lib
make --  dll
time --  dll: unbound
make --   first
make --   ext.pyd
bind --   ext.pyd:
bin\ext.pyd\vc7\debug\runtime-link-dynamic\ext.pyd
time --   ext.pyd: missing
make --    C:\Python22\libs\python22.lib
time --    C:\Python22\libs\python22.lib: Mon Apr 15 09:28:48 2002
made newer    C:\Python22\libs\python22.lib
make --
time --    : missing
don't know how to make
made+ nofind
make --    bin\ext.pyd\vc7\debug\runtime-link-dynamic
bind --    bin\ext.pyd\vc7\debug\runtime-link-dynamic:
bin\ext.pyd\vc7\debug\runtime-link-dynamic
time --    bin\ext.pyd\vc7\debug\runtime-link-dynamic: Thu
Jan 23 13:25:55 2003
[skip]
make --     C:\Python22\libs\python22.lib
make --
made+ nomake    ext.CMD
make --    ext.obj
make --    ext.lib
bind --    ext.lib:
bin\ext.pyd\vc7\debug\runtime-link-dynamic\ext.lib
time --    ext.lib: missing
make --     C:\Python22\libs\python22.lib
make --
make --     bin\ext.pyd\vc7\debug\runtime-link-dynamic
make --     ext.CMD
make --     ext.obj
make --     ext.pyd
made+ nomake    ext.lib
made+ nomake   ext.pyd
make --   ext.lib
made nomake  dll
make --  exe
time --  exe: unbound
make --   first
made stable  exe
make --  obj
time --  obj: unbound
make --   first
make --   ext.obj
made stable  obj
make --  first
made nomake all
...found 966 targets...
...can't find 1 target...
...can't make 3 targets...
...skipped ext.CMD for lack of ...
...skipped ext.lib for lack of ...
...skipped ext.pyd for lack of ...
...skipped 3 targets...

May be now it can be solved.

Thanks,
Mike






From mike at bindkey.com  Thu Jan 23 23:28:52 2003
From: mike at bindkey.com (Mike Rovner)
Date: Thu, 23 Jan 2003 14:28:52 -0800
Subject: [C++-sig] extractor
Message-ID: 

I'm trying to implement an extractor.
Unfortunately I couldn't find an example of it.
Please point me to a simple one.

My code:
#include 
#include 
#include 
using namespace boost::python;

template 
struct vec_extractor
{
  static std::vector& execute(PyObject* obj)
  {
    int size=PySequence_Size(obj);
    std::vector *vec=new std::vector(size);
    for(int i=0; i(PySequence_GetItem(obj,i));
    return *vec;
  }
};

static std::string test_ext(std::vector& v)
{
  std::string cout("[");
  for(int i=0; i,&PyTuple_Type>();
  lvalue_from_pytype,&PyList_Type>();

  def("test", test_ext);
}

dies in execute, because it get an invalid obj pointer(0x1).
In normalized_extractor::execute(pyobj) I got PyObj just fine,
but return from
template 
inline U& void_ptr_to_reference(
    void const volatile* p,
    U&(*)())
{ return *(U*)p;}
gives me an 1.

Can you please direct me a little bit futher.

Mike

PS. I'm studying
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p
ython/doc/v2/reference.html every minute and the reason I'm asking is my
lack of understanding. :(






From rwgk at yahoo.com  Fri Jan 24 06:41:50 2003
From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve)
Date: Thu, 23 Jan 2003 21:41:50 -0800 (PST)
Subject: [C++-sig] Re: Re: Re: map key
In-Reply-To: 
Message-ID: <20030124054150.84418.qmail@web20205.mail.yahoo.com>

--- David Abrahams  wrote:
> It's a nice article!

Thanks!

> You might consider the impact of using something like weave for a case
> like this.  It generates and compiles different instantiations of the
> same code on demand.

That's a very interesting idea. But our users don't even know how to spell the
word compiler. It would be a major problem to establish a working compilation
environment on all the platforms that we support (e.g. we couldn't ship Visual
C++ with our package). Also, it is my feeling that this would eventually lead
to PSYCO II, a large research project in its own right.
Ralf

P.S.: The darker parts of my ego make me hope that a mature, fully featured and
universally available PSYCO isn't a reality before I retire. Somehow I think my
chances are pretty good ;-)


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com



From eric at enthought.com  Fri Jan 24 08:10:52 2003
From: eric at enthought.com (eric jones)
Date: Fri, 24 Jan 2003 01:10:52 -0600
Subject: [C++-sig] Re: Re: Re: map key
In-Reply-To: <20030124054150.84418.qmail@web20205.mail.yahoo.com>
Message-ID: <010901c2c377$bdebb1a0$8901a8c0@ERICDESKTOP>

 
> > You might consider the impact of using something like weave for a
case
> > like this.  It generates and compiles different instantiations of
the
> > same code on demand.
> 
> That's a very interesting idea. But our users don't even know how to
spell
> the word compiler. It would be a major problem to establish a working
> compilation environment on all the platforms that we support (e.g. we 
> couldn't ship Visual C++ with our package). 

Yep.  This is a real problem.  Mingw is really easy to install now and
works fine with weave.  But requiring the installation of an extra tool
-- especially on windows -- is a non-starter except for geeks.  I've
often wondered how hard it would be to distribute a stripped down
version of mingw inside the weave setup.exe for windows.  That would
ease things markedly.

The other thing I tried to get working a while back is a means of
running a test suite in setup.py that calls all the weave code fragments
with all the types you wish your module to support.  It would then
bundle all the compiled versions into the distribution you create.
This, I think, is a great solution, but, after an evening of work, I
realized it was several days effort to make it robust -- it requires a
re-think of the cataloging mechanism.  I hope to find the time to do
it... before I retire. :-)

eric

> Also, it is my feeling that 
> this would eventually lead to PSYCO II, a large research project in
its
> own right.
> Ralf
> 
> P.S.: The darker parts of my ego make me hope that a mature, fully
> featured and universally available PSYCO isn't a reality before I
retire. 
> Somehow I think my chances are pretty good ;-)





From dave at boost-consulting.com  Fri Jan 24 15:48:44 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 09:48:44 -0500
Subject: [C++-sig] extractor
In-Reply-To:  ("Mike Rovner"'s message of "Thu,
 23 Jan 2003 14:28:52 -0800")
References: 
Message-ID: 

"Mike Rovner"  writes:

> I'm trying to implement an extractor.
> Unfortunately I couldn't find an example of it.
> Please point me to a simple one.
>
> My code:
> #include 
> #include 
> #include 
> using namespace boost::python;
>
> template 
> struct vec_extractor
> {
>   static std::vector& execute(PyObject* obj)
>   {
>     int size=PySequence_Size(obj);
>     std::vector *vec=new std::vector(size);
>     for(int i=0; i       (*vec)[i]=extract(PySequence_GetItem(obj,i));
>     return *vec;
>   }
> };
>
> static std::string test_ext(std::vector& v)
> {
>   std::string cout("[");
>   for(int i=0; i     cout += (v[i]? 'T': 'F') << ' ';
>   cout += ']';
>   //delete &v;
>   return cout;
> }
>
> BOOST_PYTHON_MODULE(ext)
> {
>   lvalue_from_pytype,&PyTuple_Type>();
>   lvalue_from_pytype,&PyList_Type>();
>
>   def("test", test_ext);
> }

Mike, 

In this case your source Python object does not contain a vector, so
you should not expect to be able to extract a vector lvalue.  You need
an rvalue from-python converter.  Ralf' solutions in the FAQ are what
you want:

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Fri Jan 24 16:07:01 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 10:07:01 -0500
Subject: [C++-sig] Re: "unknown dependent target" error
In-Reply-To:  ("Mike Rovner"'s message of "Thu,
 23 Jan 2003 14:03:17 -0800")
References:  
	
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:un0lrirbm.fsf at boost-consulting.com...
>
>> You didn't follow the instructions at
>>
> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/p
> ython/doc/building.html#outside,
>> in particular the part about starting with the archive at
>> http://www.boost.org/libs/python/example/project.zip
>
> Thank you. That fix it.

Let's see your Jamfile.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From Gottfried.Ganssauge at HAUFE.DE  Fri Jan 24 16:15:11 2003
From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE)
Date: Fri, 24 Jan 2003 16:15:11 +0100
Subject: AW: [C++-sig] functions whose return type is a pointer
Message-ID: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com>

Here you are.
I made a test program in the test directory and ran it successfully with
msvc.

Unfortunately I wasn't as successful with gcc :-(
Neither gcc-2.95.2 nor gcc-3.2 would accept the code:
With gcc-3.2 the following messages were generated:
cd /home/gotti/temp/boost/libs/python/test/
bjam opaque
...found 1773 targets...
...updating 4 targets...
gcc-C++-action
../../../libs/python/test/bin/opaque_ext.so/gcc3.2/debug/runtime-link-dynami
c/shared-linkable-true/opaque.o
/home/gotti/temp/boost/boost/python/type_id.hpp: In function 
   `boost::python::type_info boost::python::type_id(boost::type*) [with T
= opaque_]':
/home/gotti/temp/boost/boost/python/lvalue_from_pytype.hpp:22:
instantiated from `boost::python::type_info
boost::python::detail::extractor_type_id(T&(*)(U)) [with T = opaque_, U =
boost::python::convert_opaque_pointer::instance&]'
/home/gotti/temp/boost/boost/python/lvalue_from_pytype.hpp:87:
instantiated from `boost::python::lvalue_from_pytype::lvalue_from_pytype() [with Extractor =
boost::python::convert_opaque_pointer, const
PyTypeObject*python_type =
(&boost::python::convert_opaque_pointer::type_object)]'
/home/gotti/temp/boost/boost/python/opaque_pointer_converter.hpp:40:
instantiated from
`boost::python::convert_opaque_pointer::convert_opaque_pointer(cons
t char*) [with Pointer = opaque_*]'
opaque.cpp:26:   instantiated from here
/home/gotti/temp/boost/boost/python/type_id.hpp:56: invalid use of undefined
type `struct opaque_'
opaque.cpp:7: forward declaration of `struct opaque_'
/home/gotti/temp/boost/boost/python/type_id.hpp: In function 
   `boost::python::type_info boost::python::type_id(boost::type*) [with T
= const volatile opaque_&]':
/home/gotti/temp/boost/boost/python/converter/registered.hpp:50:
instantiated from `const
boost::python::converter::registration&boost::python::converter::detail::reg
istered_base::converters'
/home/gotti/temp/boost/boost/python/converter/arg_from_python.hpp:276:
instantiated from
`boost::python::converter::pointer_arg_from_python::pointer_arg_from_pyth
on(PyObject*) [with T = opaque_*]'
/home/gotti/temp/boost/boost/python/arg_from_python.hpp:79:   instantiated
from `boost::python::arg_from_python::arg_from_python(PyObject*) [with T
= opaque_*]'
/home/gotti/temp/boost/boost/python/arg_from_python.hpp:51:   instantiated
from `boost::python::detail::nullary::nullary(PyObject*) [with T =
boost::python::arg_from_python]'
/home/gotti/temp/boost/boost/python/detail/caller.hpp:35:   instantiated
from `PyObject* boost::python::detail::caller_arity<1>::impl::operator()(PyObject*, PyObject*) [with
F = void (*)(opaque_*), ConverterGenerators =
boost::python::detail::args_from_python, Policies =
boost::python::default_call_policies, Sig = boost::mpl::list2]'
/home/gotti/temp/boost/boost/function/function_template.hpp:117:
instantiated from `static R
boost::detail::function::function_obj_invoker2::invoke(boost::detail::function::any_pointer, T0, T1) [with FunctionObj
= boost::python::detail::caller >, R
= PyObject*, T0 = PyObject*, T1 = PyObject*]'
/home/gotti/temp/boost/boost/function/function_template.hpp:481:
instantiated from `void boost::function2::assign_to(FunctionObj,
boost::detail::function::function_obj_tag) [with FunctionObj =
boost::python::detail::caller >, R
= PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator =
std::allocator]'
/home/gotti/temp/boost/boost/function/function_template.hpp:432:
instantiated from `void boost::function2::assign_to(Functor) [with Functor =
boost::python::detail::caller >, R
= PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator =
std::allocator]'
/home/gotti/temp/boost/boost/function/function_template.hpp:293:
instantiated from `boost::function2::function2(Functor,
boost::detail::function::enable_if::value>::value, int>::type) [with Functor =
boost::python::detail::caller >, R
= PyObject*, T0 = PyObject*, T1 = PyObject*, Allocator =
std::allocator]'
/home/gotti/temp/boost/boost/python/make_function.hpp:36:   instantiated
from `boost::python::api::object boost::python::detail::make_function_aux(F,
const CallPolicies&, const ConverterGenerators&, const Sig&) [with F = void
(*)(opaque_*), CallPolicies = boost::python::default_call_policies,
ConverterGenerators = boost::python::detail::args_from_python, Sig =
boost::mpl::list2]'
/home/gotti/temp/boost/boost/python/make_function.hpp:76:   instantiated
from `boost::python::api::object boost::python::make_function(F) [with F =
void (*)(opaque_*)]'
/home/gotti/temp/boost/boost/python/def.hpp:84:   instantiated from `void
boost::python::def(const char*, Fn) [with Fn = void (*)(opaque_*)]'
opaque.cpp:32:   instantiated from here
/home/gotti/temp/boost/boost/python/type_id.hpp:56: invalid use of undefined
type `struct opaque_'
opaque.cpp:7: forward declaration of `struct opaque_'

Cheers,

Gottfried

> -----Ursprungliche Nachricht-----
> Von: David Abrahams [mailto:dave at boost-consulting.com]
> Gesendet: Donnerstag, 23. Januar 2003 19:20
> An: c++-sig at python.org
> Betreff: Re: [C++-sig] functions whose return type is a pointer
> 
> 
> Gottfried.Ganssauge at HAUFE.DE writes:
> 
> > I would love to prepare a patch for the opaque pointer 
> issue if someone
> > could explain the proper procedure to me.
> 
> And I'd love to apply such a patch.
> 
> All you have to do is make the changes in your CVS tree, and then use
> "cvs diff -NR -u" from the boost root directory.  Stick the result in
> an enclosure and post it.
> 
> Thanks,
> Dave
> 
> -- 
>                        David Abrahams
>    dave at boost-consulting.com * http://www.boost-consulting.com
> Boost support, enhancements, training, and commercial distribution
> 
> 
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: opaque_pointer_converter.patch
Type: application/octet-stream
Size: 5516 bytes
Desc: not available
URL: 

From dave at boost-consulting.com  Fri Jan 24 17:05:37 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 11:05:37 -0500
Subject: AW: [C++-sig] functions whose return type is a pointer
In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's
 message of "Fri, 24 Jan 2003 16:15:11 +0100")
References: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com>
Message-ID: 

Gottfried.Ganssauge at HAUFE.DE writes:

> Here you are.
> I made a test program in the test directory and ran it successfully with
> msvc.
>
> Unfortunately I wasn't as successful with gcc :-(
> Neither gcc-2.95.2 nor gcc-3.2 would accept the code:
> With gcc-3.2 the following messages were generated:

Gottfried,

I appreciate your efforts, but please don't dump reams of unreadable
error messages on the other list participants!

> cd /home/gotti/temp/boost/libs/python/test/
> bjam opaque
> ...found 1773 targets...
> ...updating 4 targets...
> gcc-C++-action
> ../../../libs/python/test/bin/opaque_ext.so/gcc3.2/debug/runtime-link-dynami
> c/shared-linkable-true/opaque.o
> /home/gotti/temp/boost/boost/python/type_id.hpp: In function 
>    `boost::python::type_info boost::python::type_id(boost::type*) [with T
> = opaque_]':
> /home/gotti/temp/boost/boost/python/lvalue_from_pytype.hpp:22:
> instantiated from `boost::python::type_info
> boost::python::detail::extractor_type_id(T&(*)(U)) [with T = opaque_, U =
> boost::python::convert_opaque_pointer::instance&]'
> /home/gotti/temp/boost/boost/python/lvalue_from_pytype.hpp:87:
> instantiated from `boost::python::lvalue_from_pytype python_type>::lvalue_from_pytype() [with Extractor =
> boost::python::convert_opaque_pointer, const
> PyTypeObject*python_type =
> (&boost::python::convert_opaque_pointer::type_object)]'
> /home/gotti/temp/boost/boost/python/opaque_pointer_converter.hpp:40:
> instantiated from
> `boost::python::convert_opaque_pointer::convert_opaque_pointer(cons
> t char*) [with Pointer = opaque_*]'
> opaque.cpp:26:   instantiated from here
> /home/gotti/temp/boost/boost/python/type_id.hpp:56: invalid use of undefined
> type `struct opaque_'



This means serious trouble for your approach, and probably also that
an architectural change in Boost.Python is called for.  Basically,
typeid(X) is illegal when X is a pointer type.

We'll have to re-think this :(


-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Fri Jan 24 17:22:27 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 11:22:27 -0500
Subject: AW: [C++-sig] functions whose return type is a pointer
In-Reply-To:  (David Abrahams's message
 of "Fri, 24 Jan 2003 11:05:37 -0500")
References: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com>
	
Message-ID: 

David Abrahams  writes:

> This means serious trouble for your approach, and probably also that
> an architectural change in Boost.Python is called for.  Basically,
> typeid(X) is illegal when X is a pointer type.

Uhm, sorry, I meant to say "when X is an INCOMPLETE type".

> We'll have to re-think this :(

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From ganssauge at gmx.de  Fri Jan 24 18:18:08 2003
From: ganssauge at gmx.de (=?iso-8859-1?Q?Gottfried_Gan=DFauge?=)
Date: Fri, 24 Jan 2003 18:18:08 +0100
Subject: AW: [C++-sig] functions whose return type is a pointer
References: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com> 
Message-ID: <00c901c2c3cc$909e8dd0$44a837c2@gieke>

> > I appreciate your efforts, but please don't dump reams of unreadable
> > error messages on the other list participants!
You are right of course, please accept my excuse, everyone.

> > This means serious trouble for your approach, and probably also that
> > an architectural change in Boost.Python is called for.  Basically,
> > typeid(X) is illegal when X is a pointer type.
> Uhm, sorry, I meant to say "when X is an INCOMPLETE type".
> > 
> > We'll have to re-think this :(
> > 
Obviously you already solved this for msvc...

Cheers,

Gottfried






From dave at boost-consulting.com  Fri Jan 24 21:05:24 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 15:05:24 -0500
Subject: AW: [C++-sig] functions whose return type is a pointer
In-Reply-To: <00c901c2c3cc$909e8dd0$44a837c2@gieke> (Gottfried
 =?iso-8859-1?q?Gan=DFauge's?= message of "Fri, 24 Jan 2003 18:18:08
 +0100")
References: <2040C0A1CA23D51181A30050BAAC990274A6EC@berexch.ber.haufemg.com>
	
	<00c901c2c3cc$909e8dd0$44a837c2@gieke>
Message-ID: 

Gottfried Gan?auge  writes:

>> > I appreciate your efforts, but please don't dump reams of unreadable
>> > error messages on the other list participants!
> You are right of course, please accept my excuse, everyone.
>
>> > This means serious trouble for your approach, and probably also that
>> > an architectural change in Boost.Python is called for.  Basically,
>> > typeid(X) is illegal when X is a pointer type.
>> Uhm, sorry, I meant to say "when X is an INCOMPLETE type".
>> > 
>> > We'll have to re-think this :(
>> > 
> Obviously you already solved this for msvc...

By exploiting its bug which allows typeid(T) where T is incomplete?  I
wouldn't call that "solved" in any useful sense.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From chris at gidayu.stw.uni-duisburg.de  Sat Jan 25 04:51:34 2003
From: chris at gidayu.stw.uni-duisburg.de (Christian Loth)
Date: Sat, 25 Jan 2003 04:51:34 +0100
Subject: [C++-sig] Using Boost.Python for embedding python
Message-ID: <20030125045134.B4715@60-4.stw.uni-duisburg.de>

Hi everyone,

  I have the following problem: I am trying to write an application,
which is a multi-user network server. Users should be able to pass
their python scripts as text input, and the server should execute
it (no security concerns, its in a proof-of-concept stage at the
moment).

  I'm initializing a module which exposes functions which the
user should be able to use. This works pretty fine. The problem
is to pass 'default' arguments to the script the user wants to
execute.

At the moment the code looks like this (initmymodule is the function
created by the module-macro of boost.python).

--->

PyThreadState *tstate = Py_NewInterpreter();
initmymodule();
PyRun_SimpleString(user_script);

<---

Per se this works, however now I want to add a list of strings
which is dynamically built to the current scope of PyRun_SimpleString.

I try to do it as follows:

--->

std::vector args; // fill args with some strings...
PyThreadState *tstate = Py_NewInterpreter();
initmymodule();
python::list argumentlist;
for (unsigned int i = 0; i < args.size(); ++i) {
	argumentlist.append(python::str(args[i].c_str()));
}
// Now I want to add the argumentlist to the scope...
scope().attr("argumentlist") = argumentlist;
PyRun_SimpleString(user_script);

<---

User-script should then be something like this:

--->
for a in argumentlist:
  print a

<---

Where argumentlist is the "injected" argumentlist.

I'm sure this is wrong, as the program aborts at the line
when calling scope().attr(...) , however, how can I correctly
achieve what I want to achieve (adding a python object to the
scope of the script which is later executed)?

Thanks in advance,
- Chris

-- 
Christian Loth
Coder of 'Project Gidayu'
Computer Science Student, University of Dortmund
chris at gidayu.mud.de - http://gidayu.mud.de



From nicodemus at globalite.com.br  Sat Jan 25 17:42:41 2003
From: nicodemus at globalite.com.br (Nicodemus)
Date: Sat, 25 Jan 2003 13:42:41 -0300
Subject: [C++-sig] Using Boost.Python for embedding python
In-Reply-To: <20030125045134.B4715@60-4.stw.uni-duisburg.de>
References: <20030125045134.B4715@60-4.stw.uni-duisburg.de>
Message-ID: <3E32BE81.8080600@globalite.com.br>

Hail Christian,

You should use PyRun_String, because it allows you to pass the context 
where the command will be executed:

PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject 
*locals)
    Return value: New reference.
    Execute Python source code from str in the context specified by the 
dictionaries
    globals and locals. The parameter start specifies the start token 
that should be
    used to parse the source code.

    Returns the result of executing the code as a Python object, or NULL 
if an exception was raised.


Try something like this (untested):

dict context;
context[str("argumentlist")] = argumentlist;
PyObject* res = PyRun_String(user_script, Py_file_input, context.ptr(), 
context.ptr());
if (res != NULL){
    // now context contains all the attributes created/changed by the 
user script   
}
else {
    // exception ocurred
}


Hope this helps,
Nicodemus.


Christian Loth wrote:

>Hi everyone,
>
>  I have the following problem: I am trying to write an application,
>which is a multi-user network server. Users should be able to pass
>their python scripts as text input, and the server should execute
>it (no security concerns, its in a proof-of-concept stage at the
>moment).
>
>  I'm initializing a module which exposes functions which the
>user should be able to use. This works pretty fine. The problem
>is to pass 'default' arguments to the script the user wants to
>execute.
>
>At the moment the code looks like this (initmymodule is the function
>created by the module-macro of boost.python).
>
>--->
>
>PyThreadState *tstate = Py_NewInterpreter();
>initmymodule();
>PyRun_SimpleString(user_script);
>
><---
>
>Per se this works, however now I want to add a list of strings
>which is dynamically built to the current scope of PyRun_SimpleString.
>
>I try to do it as follows:
>
>--->
>
>std::vector args; // fill args with some strings...
>PyThreadState *tstate = Py_NewInterpreter();
>initmymodule();
>python::list argumentlist;
>for (unsigned int i = 0; i < args.size(); ++i) {
>	argumentlist.append(python::str(args[i].c_str()));
>}
>// Now I want to add the argumentlist to the scope...
>scope().attr("argumentlist") = argumentlist;
>PyRun_SimpleString(user_script);
>
><---
>
>User-script should then be something like this:
>
>--->
>for a in argumentlist:
>  print a
>
><---
>
>Where argumentlist is the "injected" argumentlist.
>
>I'm sure this is wrong, as the program aborts at the line
>when calling scope().attr(...) , however, how can I correctly
>achieve what I want to achieve (adding a python object to the
>scope of the script which is later executed)?
>
>Thanks in advance,
>- Chris
>
>





From bscott at iastate.edu  Sun Jan 26 01:55:31 2003
From: bscott at iastate.edu (Ben Scott)
Date: Sat, 25 Jan 2003 18:55:31 -0600
Subject: [C++-sig] Wrapping a factory
References: <3E2F5917.90404@vrac.iastate.edu>	 
Message-ID: <3E333203.3080705@vrac.iastate.edu>

David Abrahams wrote:
> David Abrahams  writes:
> 
> 
>>Ben Scott  writes:
>>
>>
>>>Hi again. I'm playing around with the factory code I
>>>asked for help on before
>>>(http://mail.python.org/pipermail/c++-sig/2003-January/003217.html)
>>>and have changed things around a bit (as my library has
>>>changed). You'll notice that the only difference from
>>>before is that the creator no longer requires an
>>>argument to the create() method.
>>>
>>>Unfortunately, I've gotten stuck again and am looking
>>>for somebody to point me in the right direction. I just
>>>can't seem to get my C++ Factory object to see the
>>>correct type of my python Creator object as you can see
>>>in the following output. It appears to only know about
>>>the Creator base type and be unable to call into the
>>>implementation's method.
>>
>>You've uncovered a bug in Boost.Python.  Thank you!
>>
>>I've got a fix; I'm just testing it now to make sure it doesn't break
>>anything else and I'll let you know when it's checked in.
> 
> 
> OK, done.  Thanks again for the report.
> 
> -Dave
> 

Thanks for the incredibly quick response and turnaround time! It appears 
to work well over here.

-Ben





From mike at bindkey.com  Sun Jan 26 07:23:39 2003
From: mike at bindkey.com (Mike Rovner)
Date: Sat, 25 Jan 2003 22:23:39 -0800
Subject: [C++-sig] Re: Re: "unknown dependent target" error
References:   
Message-ID: 

"David Abrahams"  wrote in message
news:uptqma8oa.fsf at boost-consulting.com...
> > Thank you. That fix it.
>
> Let's see your Jamfile.

Here:

project-root ;

# Include definitions needed for Python modules
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;

include python.jam ;

# Declare a Python extension
extension ext
:  # sources
   ext.cpp
  :  # requirements

     # link to the appropriate library for the build variant.
    boost_python
    boost_python_d
    boost_python_pyd

  # library path required for linking to boost_python shared lib. You
  # may need to edit this for your installation
    $(BOOST_ROOT)/libs/python/build/VisualStudio/bin
  ;

# Declare a test for the extension module
boost-python-runtest test_ext
    :  # Python test driver
    t_ext.py
    # extension modules to use
    ext ;

An error is
LINK : fatal error LNK1181: cannot open input file 'C:\Python22\libs.obj'






From dave at boost-consulting.com  Sun Jan 26 18:31:22 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Sun, 26 Jan 2003 12:31:22 -0500
Subject: [C++-sig] Re: Re: "unknown dependent target" error
In-Reply-To:  ("Mike Rovner"'s message of "Sat,
 25 Jan 2003 22:23:39 -0800")
References:  
	 
	
Message-ID: 

What's the value of BOOST_ROOT?

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:uptqma8oa.fsf at boost-consulting.com...
>> > Thank you. That fix it.
>>
>> Let's see your Jamfile.
>
> Here:
>
> project-root ;
>
> # Include definitions needed for Python modules
> SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
>
> include python.jam ;
>
> # Declare a Python extension
> extension ext
> :  # sources
>    ext.cpp
>   :  # requirements
>
>      # link to the appropriate library for the build variant.
>     boost_python
>     boost_python_d
>     boost_python_pyd
>
>   # library path required for linking to boost_python shared lib. You
>   # may need to edit this for your installation
>     $(BOOST_ROOT)/libs/python/build/VisualStudio/bin
>   ;
>
> # Declare a test for the extension module
> boost-python-runtest test_ext
>     :  # Python test driver
>     t_ext.py
>     # extension modules to use
>     ext ;
>
> An error is
> LINK : fatal error LNK1181: cannot open input file 'C:\Python22\libs.obj'
>
>
>
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From mike at bindkey.com  Sun Jan 26 19:16:27 2003
From: mike at bindkey.com (Mike Rovner)
Date: Sun, 26 Jan 2003 10:16:27 -0800
Subject: [C++-sig] Re: Re: Re: "unknown dependent target" error
References:    
Message-ID: 

"David Abrahams"  wrote in message
news:uy957om1h.fsf at boost-consulting.com...

> What's the value of BOOST_ROOT?

File boost-build.jam has:
BOOST_ROOT = s:/boost ;
boost-build s:/boost/tools/build ;

Generated ext.CMD:
"bin\ext.pyd\vc7\debug\runtime-link-dynamic\ext.obj"
"C:\Python22\libs"

Last line is aparently incorrect, it shall be
"C:\Python22\libs\Python22.lib"

If I manualy change it, all is fine.
Unfortunately bjam doesn't check validity of ENV variables.
The error in very begining of the thread was due to ugly mix of old ENV.

Now I cleared that (my) mess a little bit:
ALLUSERSPROFILE=C:\Documents and Settings\All Users
APPDATA=C:\Documents and Settings\mike\Application Data
CLIENTNAME=Console
CommonProgramFiles=C:\Program Files\Common Files
COMPUTERNAME=MIKE
ComSpec=C:\WIN\system32\cmd.exe
FARLANG=English
HOMEDRIVE=C:
HOMEPATH=\Documents and Settings\mike
INCLUDE=C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\include\
LIB=C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Lib\
LOGONSERVER=\\MIKE
NUMBER_OF_PROCESSORS=1
OS=Windows_NT
Path=C:\Tcl\bin;C:\Python22;C:\WIN\system32;C:\WIN;C:\WIN\System32\Wbem;c:\b
in;C:\PROGRA~1
\ATT\Graphviz\bin;C:\PROGRA~1\ATT\Graphviz\bin\tools;C:\Program
Files\Rational\common;C:\q
t\bin;C:\Program Files\Far
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.py;.pyc;.pyo;.pyw;
.pys;.tcl
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 8 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0801
ProgramFiles=C:\Program Files
PROMPT=$P$G
PYTHON_INCLUDE=C:\Python22\include
PYTHON_ROOT=c:\Python22
QTDIR=C:\qt
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\WIN
TEMP=C:\DOCUME~1\mike\LOCALS~1\Temp
TMAKEPATH=C:\qt\tmake\lib\win32-msvc
TMP=C:\DOCUME~1\mike\LOCALS~1\Temp
USERDOMAIN=MIKE
USERNAME=mike
USERPROFILE=C:\Documents and Settings\mike
VSCOMNTOOLS="C:\Program Files\Microsoft Visual Studio .NET\Common7\Tools\"






From dave at boost-consulting.com  Sun Jan 26 19:34:18 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Sun, 26 Jan 2003 13:34:18 -0500
Subject: [C++-sig] Re: Re: Re: "unknown dependent target" error
In-Reply-To:  ("Mike Rovner"'s message of "Sun,
 26 Jan 2003 10:16:27 -0800")
References:  
	 
	 
	
Message-ID: 

"Mike Rovner"  writes:

> "David Abrahams"  wrote in message
> news:uy957om1h.fsf at boost-consulting.com...
>
>> What's the value of BOOST_ROOT?
>
> File boost-build.jam has:
> BOOST_ROOT = s:/boost ;
> boost-build s:/boost/tools/build ;
>
> Generated ext.CMD:
> "bin\ext.pyd\vc7\debug\runtime-link-dynamic\ext.obj"
> "C:\Python22\libs"
>
> Last line is aparently incorrect, it shall be
> "C:\Python22\libs\Python22.lib"
>
> If I manualy change it, all is fine.
> Unfortunately bjam doesn't check validity of ENV variables.
> The error in very begining of the thread was due to ugly mix of old ENV.
>
> Now I cleared that (my) mess a little bit:

I can't see anything obviously wrong.  If you're still having a
problem, please add -d+5 to your bjam command-line, redirect it into a
temporary file, compress that, and send it to me personally (not this
list).  I'll see if I can figure it out.

-Dave

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From mike at bindkey.com  Sun Jan 26 20:19:08 2003
From: mike at bindkey.com (Mike Rovner)
Date: Sun, 26 Jan 2003 11:19:08 -0800
Subject: [C++-sig] Re: Re: Re: Re: "unknown dependent target" error
References:     
Message-ID: 

"David Abrahams"  wrote in message
news:uy957n4k5.fsf at boost-consulting.com...
> "Mike Rovner"  writes:

> I can't see anything obviously wrong.  If you're still having a
> problem, please add -d+5 to your bjam command-line, redirect it into a
> temporary file, compress that, and send it to me personally (not this
> list).  I'll see if I can figure it out.

Thanks a lot, Dave. You scared the bugs away. :)
After regenerating .cmd all went fine.
Sorry for disturbance.

Mike






From Gottfried.Ganssauge at HAUFE.DE  Mon Jan 27 12:16:37 2003
From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE)
Date: Mon, 27 Jan 2003 12:16:37 +0100
Subject: AW: AW: [C++-sig] functions whose return type is a pointer
Message-ID: <2040C0A1CA23D51181A30050BAAC990274A6F0@berexch.ber.haufemg.com>



> -----Urspr?ngliche Nachricht-----
> Von: David Abrahams [mailto:dave at boost-consulting.com]
> Gesendet: Freitag, 24. Januar 2003 21:05
> An: c++-sig at python.org
> Betreff: Re: AW: [C++-sig] functions whose return type is a pointer
> 
> 
> Gottfried Gan?auge  writes:
> 
> >> > I appreciate your efforts, but please don't dump reams 
> of unreadable
> >> > error messages on the other list participants!
> > You are right of course, please accept my excuse, everyone.
> >
> >> > This means serious trouble for your approach, and 
> probably also that
> >> > an architectural change in Boost.Python is called for.  
> Basically,
> >> > typeid(X) is illegal when X is a pointer type.
> >> Uhm, sorry, I meant to say "when X is an INCOMPLETE type".
> >> > 
> >> > We'll have to re-think this :(
> >> > 
> > Obviously you already solved this for msvc...
> 
> By exploiting its bug which allows typeid(T) where T is incomplete?  I
> wouldn't call that "solved" in any useful sense.
true, just couldn't resist ...

I tried a workaround for the problem by specializing the type_id function
template:
namespace boost { namespace python {
	template<>
	inline type_info type_id(boost::type*) {
	    return type_info (typeid (opaque_ *));
	}
	template<>
	inline type_info type_id(boost::type*) {
	    return type_info (typeid (opaque_ *));
	}
}}

This works quite well for gcc-3.2 but unfortunately I have no solution for
gcc-2.95.
That compiler chokes on a missing argument to type_id().
Do you have an idea how to make it work on the older gcc as well.

Cheers,

Gottfried
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From datafeed at SoftHome.net  Mon Jan 27 22:53:27 2003
From: datafeed at SoftHome.net (M. Evans)
Date: Mon, 27 Jan 2003 14:53:27 -0700
Subject: [C++-sig] Pycaml
Message-ID: <6060844289.20030127145327@SoftHome.net>

OCaml is an awesome, very high-performance, RAD language. This linkage
to Python may interest those doing C/C++ for performance reasons.
http://pycaml.sourceforge.net/

Performance comparisons at
http://www.bagley.org/~doug/shootout/craps.shtml

Mark




From Gottfried.Ganssauge at HAUFE.DE  Tue Jan 28 13:19:37 2003
From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE)
Date: Tue, 28 Jan 2003 13:19:37 +0100
Subject: [C++-sig] New implementation for opaque_pointer_converter
Message-ID: <2040C0A1CA23D51181A30050BAAC990274A6FB@berexch.ber.haufemg.com>

After the last failure with gcc I enhanced the implementation of
opaque_pointer_converter<>, added a
return_opaque_pointer-ResultConverterGenerator and wrote some documentation.
This implementation fails to compile with gcc-2.95 but works on msvc and on
gcc-3.2.

Please see the attached patch.

Cheers,

Gottfried

-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: opaque_pointer.patch
Type: application/octet-stream
Size: 22469 bytes
Desc: not available
URL: 

From okuda1 at llnl.gov  Tue Jan 28 20:08:04 2003
From: okuda1 at llnl.gov (chuzo okuda)
Date: Tue, 28 Jan 2003 11:08:04 -0800
Subject: [C++-sig] Building problem on OSF1 platform.
References: <009401c2a70f$bf2d24b0$0a01a8c0@fractalgraphics.com.au> 
Message-ID: <3E36D514.A6D8C2AB@llnl.gov>

Hello,
I was building boost on alpha cluster using g++ and I get many errors of
this sort:

/usr/include/pthread.h:312:4: #error "Please compile the module
including pthread.h with -pthread"

I am wondering how to turn pthread on instead of tampering with
gcc-tools.jam, and I am not sure how.

There is a line in gcc-tools.jam:

	flags gcc CFLAGS multi : -pthread ;

Thank you
Chuzo



From dave at boost-consulting.com  Tue Jan 28 21:52:23 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Tue, 28 Jan 2003 15:52:23 -0500
Subject: [C++-sig] Building problem on OSF1 platform.
In-Reply-To: <3E36D514.A6D8C2AB@llnl.gov> (chuzo okuda's message of "Tue, 28
 Jan 2003 11:08:04 -0800")
References: <009401c2a70f$bf2d24b0$0a01a8c0@fractalgraphics.com.au>
	 <3E36D514.A6D8C2AB@llnl.gov>
Message-ID: 

chuzo okuda  writes:

> Hello,
> I was building boost on alpha cluster using g++ and I get many errors of
> this sort:
>
> /usr/include/pthread.h:312:4: #error "Please compile the module
> including pthread.h with -pthread"
>
> I am wondering how to turn pthread on instead of tampering with
> gcc-tools.jam, and I am not sure how.
>
> There is a line in gcc-tools.jam:
>
> 	flags gcc CFLAGS multi : -pthread ;

Adding "-sBUILD=multi" to your bjam command-line is one
good way to achieve it.

BTW, I was under the impression your group wasn't using Boost.Python
anymore (?)

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From ssmith at magnet.fsu.edu  Tue Jan 28 23:24:06 2003
From: ssmith at magnet.fsu.edu (Scott A. Smith)
Date: Tue, 28 Jan 2003 17:24:06 -0500
Subject: [C++-sig] Boost.Python RPM
In-Reply-To: <3E36D514.A6D8C2AB@llnl.gov>
Message-ID: 

Greetings,

Does anyone know if there is an RPM around to install Boost(.Python) on
a Linux box? If not, would that be a good thing to have, akin to the
recently submitted MSVC++ project that builds it? It is not that I have
any problems building it with Jam, that works quite smoothly.

The reason I do ask:

I just made an RPM of my own C++ software package and
and am now thinking of making an RPM for this same package
exported into Python using BP. The Pythonized package
will depend upon BP and the RPM package manager would/should
know that. Hence there should be a Boost.Python RPM that would
install BP and satisfy that dependency (by registering itself in the
RPM database).

Scott




From dave at boost-consulting.com  Wed Jan 29 00:28:32 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Tue, 28 Jan 2003 18:28:32 -0500
Subject: [C++-sig] Boost.Python RPM
In-Reply-To:  ("Scott A.
 Smith"'s message of "Tue, 28 Jan 2003 17:24:06 -0500")
References: 
Message-ID: 

"Scott A. Smith"  writes:

> Greetings,
>
> Does anyone know if there is an RPM around to install Boost(.Python) on
> a Linux box? 

Scott, meet Benjamin Koznik.  Benjamin, Scott.  Benjamin was just
asking me the same question a few weeks back.

> If not, would that be a good thing to have

Yes!

> akin to the recently submitted MSVC++ project that builds it? It is
> not that I have any problems building it with Jam, that works quite
> smoothly.
>
> The reason I do ask:
>
> I just made an RPM of my own C++ software package and
> and am now thinking of making an RPM for this same package
> exported into Python using BP. The Pythonized package
> will depend upon BP and the RPM package manager would/should
> know that. Hence there should be a Boost.Python RPM that would
> install BP and satisfy that dependency (by registering itself in the
> RPM database).

Sounds like a good thing to have.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From bkoz at redhat.com  Wed Jan 29 19:01:04 2003
From: bkoz at redhat.com (Benjamin Kosnik)
Date: Wed, 29 Jan 2003 12:01:04 -0600
Subject: [C++-sig] Boost.Python RPM
In-Reply-To: 
References: 
	
Message-ID: <20030129120104.6aae6cd6.bkoz@redhat.com>

On Tue, 28 Jan 2003 18:28:32 -0500
David Abrahams  wrote:

>"Scott A. Smith"  writes:
>
>> Greetings,
>>
>> Does anyone know if there is an RPM around to install Boost(.Python) on
>> a Linux box? 
>
>Scott, meet Benjamin Koznik.  Benjamin, Scott.  Benjamin was just
>asking me the same question a few weeks back.
>
>> If not, would that be a good thing to have
>
>Yes!

Agreed.

Scott, if you do this please let me know.

-benjamin



From Pere.Mato at cern.ch  Thu Jan 30 16:08:25 2003
From: Pere.Mato at cern.ch (Pere Mato Vila)
Date: Thu, 30 Jan 2003 16:08:25 +0100
Subject: [C++-sig] VC++ Warnings
Message-ID: 

Hi All,

  On compiling with VC++ 6.0 our extension module based on Boost.Python
2.0, we are getting the following warnings. Is it something to be
worried about?


C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(431) : warning
C4700: local variable 'x' used without having been initialized
C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(159) : warning
C4700: local variable 'x' used without having been initialized
C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(159) : warning
C4700: local variable 'x' used without having been initialized
C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(420) : warning
C4700: local variable 'x' used without having been initialized
C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(420) : warning
C4700: local variable 'x' used without having been initialized
C:/ExtSoft/Boost/boost_1_29_0\boost/mpl/for_each.hpp(73) : warning
C4700: local variable 'x' used without having been initialized

------------------------------------------------------------
Pere Mato  CERN, EP Division, CH 1211 Geneva 23, Switzerland
           e-mail: Pere.Mato at cern.ch    tel: +41 22 76 78696
           fax:  +41 22 76 79425        gsm: +41 79 20 10855

 



From dave at boost-consulting.com  Thu Jan 30 16:28:50 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 30 Jan 2003 10:28:50 -0500
Subject: [C++-sig] New implementation for opaque_pointer_converter
In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A6FB@berexch.ber.haufemg.com> (Gottfried.Ganssauge@HAUFE.DE's
 message of "Tue, 28 Jan 2003 13:19:37 +0100")
References: <2040C0A1CA23D51181A30050BAAC990274A6FB@berexch.ber.haufemg.com>
Message-ID: 

Hi Gottfried,

Not ignoring this; I've been sick and busy in combination.  I'll try
to look at it soon.

-Dave

Gottfried.Ganssauge at HAUFE.DE writes:

> After the last failure with gcc I enhanced the implementation of
> opaque_pointer_converter<>, added a
> return_opaque_pointer-ResultConverterGenerator and wrote some documentation.
> This implementation fails to compile with gcc-2.95 but works on msvc and on
> gcc-3.2.


-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From dave at boost-consulting.com  Thu Jan 30 16:55:33 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 30 Jan 2003 10:55:33 -0500
Subject: [C++-sig] VC++ Warnings
In-Reply-To:  ("Pere
 Mato Vila"'s message of "Thu, 30 Jan 2003 16:08:25 +0100")
References: 
Message-ID: 

"Pere Mato Vila"  writes:

> Hi All,
>
>   On compiling with VC++ 6.0 our extension module based on Boost.Python
> 2.0, we are getting the following warnings. Is it something to be
> worried about?
>
>
> C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(431) : warning
> C4700: local variable 'x' used without having been initialized
> C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(159) : warning
> C4700: local variable 'x' used without having been initialized
> C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(159) : warning
> C4700: local variable 'x' used without having been initialized
> C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(420) : warning
> C4700: local variable 'x' used without having been initialized
> C:/ExtSoft/Boost/boost_1_29_0\boost/python/class.hpp(420) : warning
> C4700: local variable 'x' used without having been initialized
> C:/ExtSoft/Boost/boost_1_29_0\boost/mpl/for_each.hpp(73) : warning
> C4700: local variable 'x' used without having been initialized

Maybe.  It looks like an interaction with some VC++ bug to me, but
it's hard to be sure.  Only the last one makes any sense to me; that
problem (along with quite a few others) is fixed in the Boost CVS.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From opinderjit.bhella at hp.com  Thu Jan 30 20:52:19 2003
From: opinderjit.bhella at hp.com (BHELLA,OPINDERJIT (HP-Vancouver,ex1))
Date: Thu, 30 Jan 2003 11:52:19 -0800
Subject: [C++-sig] Converting from SWIG to Boost.Python
Message-ID: <6D805D4C4567D411AF32009027B683510B307214@xvan02.vcd.hp.com>

Hi, 

I have been using SWIG 1.5p for about a year with good success. However, I
was interested in the newer functionality
that Boost.Python provides. I have read through the tutorial and was unable
to figure out how to reproduce the
following SWIG logic that uses the Py_BEGIN_ALLOW_THREADS and
Py_END_ALLOW_THREADS macros.

Thanks.

SWIG example:
%except(python)
{
    Py_BEGIN_ALLOW_THREADS
    try
    {
        $function
    }
    catch(BlackstoneErrorObject &e)
    {
        PyEval_RestoreThread(_save);
        switch(e.getCode())
        {
            case SUCCESS: ...                 break;
            case GENERAL_ERROR:        break;
            default: ...break;
        }
        return NULL;
    }
    catch (...)
    {
        PyEval_RestoreThread(_save);
        PyErr_SetString(BlackstoneError,"...");
        return NULL;
    }
    Py_END_ALLOW_THREADS
}



From dave at boost-consulting.com  Thu Jan 30 21:07:35 2003
From: dave at boost-consulting.com (David Abrahams)
Date: Thu, 30 Jan 2003 15:07:35 -0500
Subject: [C++-sig] Converting from SWIG to Boost.Python
In-Reply-To: <6D805D4C4567D411AF32009027B683510B307214@xvan02.vcd.hp.com> ("BHELLA,OPINDERJIT's
 message of "Thu, 30 Jan 2003 11:52:19 -0800")
References: <6D805D4C4567D411AF32009027B683510B307214@xvan02.vcd.hp.com>
Message-ID: 

"BHELLA,OPINDERJIT (HP-Vancouver,ex1)"  writes:

I have read through the tutorial and was unable
> to figure out how to reproduce the
> following SWIG logic that uses the Py_BEGIN_ALLOW_THREADS and
> Py_END_ALLOW_THREADS macros.
>


Can you explain what it does?

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution




From opinderjit.bhella at hp.com  Fri Jan 31 02:02:52 2003
From: opinderjit.bhella at hp.com (BHELLA,OPINDERJIT (HP-Vancouver,ex1))
Date: Thu, 30 Jan 2003 20:02:52 -0500
Subject: [C++-sig] FW: Converting from SWIG to Boost.Python
Message-ID: <6D805D4C4567D411AF32009027B683510B307215@xvan02.vcd.hp.com>

In the example below, every function is wrapped with in a
Py_BEGIN_ALLOW_THREADS/
Py_END_ALLOW_THREADS macro. This macro allows each function to be able to
run in 
multiple threads in Python. Because Py_END_ALLOW_THREADS must be called to 
acquire the interpreter lock when the function is completed, 
the PyEval_RestoreThread(_save); is also called before each catch, if an
excepting occurs
and we return NULL.

Thanks for your help David!



"BHELLA,OPINDERJIT (HP-Vancouver,ex1)" < opinderjit.bhella at hp.com
> writes:

I have read through the tutorial and was unable
> to figure out how to reproduce the
> following SWIG logic that uses the Py_BEGIN_ALLOW_THREADS and
> Py_END_ALLOW_THREADS macros.
>


Can you explain what it does?

-- 
                       David Abrahams
    dave at boost-consulting.com  *

Boost support, enhancements, training, and commercial distribution

 -----Original Message-----
> From: 	BHELLA,OPINDERJIT (HP-Vancouver,ex1)  
> Sent:	Thursday, January 30, 2003 11:52 AM
> To:	'c++-sig at python.org'
> Subject:	Converting from SWIG to Boost.Python
> 
> 
> Hi, 
> 
> I have been using SWIG 1.5p for about a year with good success. However, I
> was interested in the newer functionality
> that Boost.Python provides. I have read through the tutorial and was
> unable to figure out how to reproduce the
> following SWIG logic that uses the Py_BEGIN_ALLOW_THREADS and
> Py_END_ALLOW_THREADS macros.
> 
> Thanks.
> 
> SWIG example:
> %except(python)
> {
>     Py_BEGIN_ALLOW_THREADS
>     try
>     {
>         $function
>     }
>     catch(BlackstoneErrorObject &e)
>     {
>         PyEval_RestoreThread(_save);
>         switch(e.getCode())
>         {
>             case SUCCESS: ...                 break;
>             case GENERAL_ERROR:        break;
>             default: ...break;
>         }
>         return NULL;
>     }
>     catch (...)
>     {
>         PyEval_RestoreThread(_save);
>         PyErr_SetString(BlackstoneError,"...");
>         return NULL;
>     }
>     Py_END_ALLOW_THREADS
> }