From pth at suse.de Thu Dec 1 17:19:31 2005 From: pth at suse.de (Philipp Thomas) Date: Thu, 1 Dec 2005 17:19:31 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules Message-ID: <20051201161931.GU7473@paradies.suse.de> We use a patch for gcc 4.1 that also makes it warn about violations of the C/C++ aliasing rules in C++ code (stock gcc only warns for C code). For the code in boost 1.33.1 I get warning: dereferencing type-punned pointer will break strict-aliasing rules for the following files: /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/long.cpp: 12,19, 26 /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/dict.cpp: 32 /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/tuple.cpp:12 /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/str.cpp: 12 /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/object/class.cpp:543,553 /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/list.cpp: 15 As our package build system treats this type of warning as errors, I will use -fno-strict-aliasing for gcc as I'm not familiar with that code and I want to get the package built. For boost you should also consider either using said gcc switch or fix the code to not break strict-aliasing rules as such code leads gcc to opmize in a way it shouldn't (for instance by eliminating variables which makes access through a type-punned pointer return garbage). Philipp -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From rwgk at yahoo.com Thu Dec 1 18:40:02 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 1 Dec 2005 09:40:02 -0800 (PST) Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051201161931.GU7473@paradies.suse.de> Message-ID: <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> --- Philipp Thomas wrote: > > We use a patch for gcc 4.1 that also makes it warn about violations of the > C/C++ aliasing > rules in C++ code (stock gcc only warns for C code). For the code in boost > 1.33.1 I get > > warning: dereferencing type-punned pointer will break strict-aliasing rules > > for the following files: > > /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/long.cpp: > 12,19, 26 > /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/dict.cpp: 32 > /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/tuple.cpp:12 > /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/str.cpp: 12 Thanks for pointing out the aliasing problems! Could you help us understanding how the problem could be fixed? E.g., this is the code in str.cpp: return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyString_Type, "(O)", arg_.ptr()); Line 12 is (PyObject*)&PyString_Type. Is this what we have to look at? Both types are defined in Python headers. AFAIK the cast above is standard practice in Python code... Thank you in advance! Cheers, Ralf __________________________________ Yahoo! Mail - PC Magazine Editors' Choice 2005 http://mail.yahoo.com From dave at boost-consulting.com Thu Dec 1 19:55:33 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Dec 2005 13:55:33 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules References: <20051201161931.GU7473@paradies.suse.de> <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- Philipp Thomas wrote: > >> >> We use a patch for gcc 4.1 that also makes it warn about violations of the >> C/C++ aliasing >> rules in C++ code (stock gcc only warns for C code). For the code in boost >> 1.33.1 I get >> >> warning: dereferencing type-punned pointer will break strict-aliasing rules >> >> for the following files: >> >> /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/long.cpp: >> 12,19, 26 >> /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/dict.cpp: 32 >> /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/tuple.cpp:12 >> /usr/src/packages/BUILD/boost_1_33_1/libs/python/build/../src/str.cpp: 12 > > Thanks for pointing out the aliasing problems! Could you help us understanding > how the problem could be fixed? E.g., this is the code in str.cpp: > > return (detail::new_reference)PyObject_CallFunction( > (PyObject*)&PyString_Type, "(O)", > arg_.ptr()); > > Line 12 is (PyObject*)&PyString_Type. Is this what we have to look at? > > Both types are defined in Python headers. AFAIK the cast above is standard > practice in Python code... I'm pretty sure this warning is bogus, since there are no two pointers being passed here that the compiler can deduce point into the same object. http://lists.gnu.org/archive/html/discuss-gnustep/2003-05/msg00423.html The patch may be bogus, too, at least as far as standard C++ is concerned. C++ doesn't support the C99 restrict feature. C++ is built on C89 or C90 (I forget which). Does Python even support being compiled with C99? If not, this whole thing is a red herring. Can Philipp explain why we should invest energy in trying to make these warnings go away? -- Dave Abrahams Boost Consulting www.boost-consulting.com From ricardokirkner at gmail.com Thu Dec 1 23:52:50 2005 From: ricardokirkner at gmail.com (Ricardo Kirkner) Date: Thu, 1 Dec 2005 19:52:50 -0300 Subject: [C++-sig] boost forward declaration error Message-ID: <5e44108d0512011452i33ab73d5p4a5e8daf41a6954f@mail.gmail.com> Hi: I am getting an error while compiling some library wrappers. The overall structure of the error producing code is: A.h ----- ... struct MyStruct; //forward declaration typedef struct MyStruct *MyStructID; ... B.h ----- #include A.h #include A1.h #include A2.h ... C.h ----- #include B.h class MyClass { public: MyClass(MyStructID id); .... }; Now, I am getting an error due to the forward declaration in A.h. However, A.h and B.h belong to some library that is working correctly (and which library C, for which I am trying to write a wrapper, depends on). I don't know if this information (I tried to abstract and simplify the problem the most I could) is enough for anybody to figure out what is going on... if anyone needs some more detail in order to help me out, please ask for it. So the question is: does anyone know why I am getting the forward declaration error, while using boost (note that the A library -- owner of A.h and B.h -- is installed and compiles correctly). Does anyone know how to get around this problem? Thanks, Ricardo Kirkner From jeremy at alum.mit.edu Fri Dec 2 21:01:21 2005 From: jeremy at alum.mit.edu (Jeremy Hylton) Date: Fri, 2 Dec 2005 15:01:21 -0500 Subject: [C++-sig] working around the non-const Python C API Message-ID: I was curious if anyone had advice on how to work around the fact that much of the Python C API asks for char* when it really intends to treat it as a const char*. An example of this behavior is the PyMethodDef struct, which has char* ml_name and char* ml_doc parameters. If you use a string literal, you get a warning about casting a const char* to a char*. I can add a cast around each literal, but that's really ugly. Is there a good way to avoid the warnings? Secondarily, I know that python-dev is a bit hesitant about const correctness, but we did get some const char* types added with the new bytecode compiler. Perhaps it's worthwhile to try changing a few of the most egregious cases to use const char*. Jeremy From tim.peters at gmail.com Fri Dec 2 21:22:59 2005 From: tim.peters at gmail.com (Tim Peters) Date: Fri, 2 Dec 2005 15:22:59 -0500 Subject: [C++-sig] working around the non-const Python C API In-Reply-To: References: Message-ID: <1f7befae0512021222s34171b9bh4b9dd7579b42c4b1@mail.gmail.com> [Jeremy Hylton] > ... > Secondarily, I know that python-dev is a bit hesitant about const > correctness, but we did get some const char* types added with the new > bytecode compiler. Perhaps it's worthwhile to try changing a few of > the most egregious cases to use const char*. Nobody will complain about adding const where its lack gets in the way. What python-dev doesn't want is another of those massive checkins where someone more-or-less mindlessly adds const to every place they can find, introducing a handful of subtle bugs along the way that create new problems for years. If you're actively working on a specific area where adding const eases the pain, that's fine -- then you're really thinking about each const you add, and testing it right away too. That's all good. From dave at boost-consulting.com Sat Dec 3 00:35:29 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 02 Dec 2005 18:35:29 -0500 Subject: [C++-sig] working around the non-const Python C API References: Message-ID: Jeremy Hylton writes: > I was curious if anyone had advice on how to work around the fact that > much of the Python C API asks for char* when it really intends to > treat it as a const char*. An example of this behavior is the > PyMethodDef struct, which has char* ml_name and char* ml_doc > parameters. If you use a string literal, you get a warning about > casting a const char* to a char*. In C++, anyway, these are really supposed to be hard errors. The type of a string literal is char const(&)[N]. > I can add a cast around each literal, but that's really ugly. > > Is there a good way to avoid the warnings? Fix Python :) > Secondarily, I know that python-dev is a bit hesitant about const > correctness, but we did get some const char* types added with the new > bytecode compiler. Perhaps it's worthwhile to try changing a few of > the most egregious cases to use const char*. If you can't do that, the next most good approach is to use const_cast instead of a C-style cast. Just to drive the point home :) -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Dec 3 00:39:41 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 02 Dec 2005 18:39:41 -0500 Subject: [C++-sig] working around the non-const Python C API References: <1f7befae0512021222s34171b9bh4b9dd7579b42c4b1@mail.gmail.com> Message-ID: Tim Peters writes: > [Jeremy Hylton] >> ... >> Secondarily, I know that python-dev is a bit hesitant about const >> correctness, but we did get some const char* types added with the new >> bytecode compiler. Perhaps it's worthwhile to try changing a few of >> the most egregious cases to use const char*. > > Nobody will complain about adding const where its lack gets in the > way. What python-dev doesn't want is another of those massive > checkins where someone more-or-less mindlessly adds const to every > place they can find, introducing a handful of subtle bugs along the > way that create new problems for years. I'm not, by any means, advocating slash-and-burn checkins, but... unless 'C' has adopted overloading while I wasn't looking (and no, I don't mean the new magic C99 builtin numeric function overloads), it's hard to imagine what kind of problems you could introduce in `C' code by changing char* to char const* that wouldn't be caught at compile-time. -- Dave Abrahams Boost Consulting www.boost-consulting.com From jonathan.liger at wanadoo.fr Sat Dec 3 17:45:27 2005 From: jonathan.liger at wanadoo.fr (jonathan liger) Date: Sat, 03 Dec 2005 17:45:27 +0100 Subject: [C++-sig] Pyste and pointers on const data Message-ID: <4391CBA7.4070600@wanadoo.fr> I found something odd using pyste : From the header myHeader.h | class A | { | public: | void f(); | void f(const int* const arg); | }; and the corresponding interface file | Class("A", "myHeader.h") Pyste generates the following wrapper code | void Export_myHeader() | { | boost::python::class_< A >("A", boost::python::init< >()) | .def(boost::python::init< const A& >()) | .def("f", (void (A::*)() )&A::f) | .def("f", (void (A::*)(const int*) )&A::f) | ; | } This problem is that A::f(const int* const) can not be casted into void(A::*)(const int*) (the second const is missing). This problem seems to come from Pyste itself as the xml description generated by gccxml is correct (leads to a const pointer on a const int). _john. From roman.yakovenko at gmail.com Sun Dec 4 13:36:47 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 4 Dec 2005 14:36:47 +0200 Subject: [C++-sig] wrapping abstract classes question Message-ID: <7465b6170512040436u5a5fc701r60880ecb6fb3532c@mail.gmail.com> Hi. What is the right way to wrap next abstract classes? struct base{ virtual int do_smth() = 0; }; struct derived : base{ virtual int do_smth_else() = 0; }; It is obvious to me that I should create wrapper classes for base and derived. My question is what is definition of derived wrapper? struct base_wrapper : base, boost::python::wrapper< base > { ... } The are 2 approaches to create wrapper for derived class 1. struct derived_wrapper : derived, boost::python::wrapper< derived >{ virtual int do_smth( ){ boost::python::override do_smth = this->get_override( "do_smth" ); return do_smth( ); } virtual int do_smth_else( ){ boost::python::override do_smth_else = this->get_override( "do_smth_else" ); return do_smth_else( ); } } 2. struct derived_wrapper : derived, base_wrapper, boost::python::wrapper< derived >{ virtual int do_smth_else( ){ boost::python::override do_smth_else = this->get_override( "do_smth_else" ); return do_smth_else( ); } } It seems to me that both approaches will work, but I do not know which one is better ( right ) and which one is not. Thanks for help. Roman Yakovenko From dave at boost-consulting.com Sun Dec 4 15:37:15 2005 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 04 Dec 2005 09:37:15 -0500 Subject: [C++-sig] wrapping abstract classes question References: <7465b6170512040436u5a5fc701r60880ecb6fb3532c@mail.gmail.com> Message-ID: Roman Yakovenko writes: > The are 2 approaches to create wrapper for derived class > 1. > > struct derived_wrapper > : derived, boost::python::wrapper< derived >{ > > virtual int do_smth( ){ > boost::python::override do_smth = this->get_override( "do_smth" ); > return do_smth( ); > } > > virtual int do_smth_else( ){ > boost::python::override do_smth_else = this->get_override( > "do_smth_else" ); > return do_smth_else( ); > } > > } > > 2. > > struct derived_wrapper : derived, base_wrapper, > boost::python::wrapper< derived >{ > > virtual int do_smth_else( ){ > boost::python::override do_smth_else = this->get_override( > "do_smth_else" ); > return do_smth_else( ); > } > > } > > It seems to me that both approaches will work, but I do not know which > one is better > ( right ) and which one is not. This one is tricky. I think this is probably the best you can do. template struct wrap_base : B { int do_smth() { return this->get_override("do_smth")(); }; }; struct base_wrapper : wrap_base, boost::python::wrapper { }; struct derived_wrapper : wrap_base, boost::python::wrapper { int do_smth_else() { return this->get_override("do_smth_else")(); }; }; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From mjkeyes at sbcglobal.net Mon Dec 5 07:02:13 2005 From: mjkeyes at sbcglobal.net (Matt) Date: Mon, 5 Dec 2005 00:02:13 -0600 Subject: [C++-sig] Creating new instances of an object's contained value Message-ID: Hey all, This is probably a newbie question, but I'm curious if it's possible to create a new instance of an object's contained value into another object variable in an extension module I'm working on. For example, I am trying to create a factory method of sorts that will create a python object and return it. Rather than load up the dictionary and module and call Py_RunString each time the method is called, I would like to only do this once (I'm not worried about reloading this python object after the extension module is loaded). Thus, I was thinking of keeping an object variable that I can "clone", so to speak, and return the cloned value. Is this possible? Thanks! Matt From seefeld at sympatico.ca Mon Dec 5 07:16:52 2005 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 05 Dec 2005 01:16:52 -0500 Subject: [C++-sig] Creating new instances of an object's contained value In-Reply-To: References: Message-ID: <4393DB54.6040709@sympatico.ca> Matt wrote: > Hey all, > > This is probably a newbie question, but I'm curious if it's possible to > create a new instance of an object's contained value into another object > variable in an extension module I'm working on. > > For example, I am trying to create a factory method of sorts that will > create a python object and return it. Rather than load up the dictionary > and module and call Py_RunString each time the method is called, I would > like to only do this once (I'm not worried about reloading this python > object after the extension module is loaded). Thus, I was thinking of > keeping an object variable that I can "clone", so to speak, and return the > cloned value. Is this possible? Python has a 'copy' module that may do what you want. However, there might be a far simpler way to achieve the same thing: In Python, types are objects, too. So, your factory may read in the python script you are referring to once, and then extract the type objects which the parser instantiates from the global dictionary. Then, each time you call 'factory->create()' (or however it is spelled), you simply call operator() on the appropriate type object (with suitable arguments) and return the result. Would that work for you ? HTH, Stefan From roman.yakovenko at gmail.com Mon Dec 5 07:21:48 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 5 Dec 2005 08:21:48 +0200 Subject: [C++-sig] Creating new instances of an object's contained value In-Reply-To: References: Message-ID: <7465b6170512042221o32f94fe5ka46d54c3993ce322@mail.gmail.com> On 12/5/05, Matt wrote: > Hey all, > > This is probably a newbie question, but I'm curious if it's possible to > create a new instance of an object's contained value into another object > variable in an extension module I'm working on. > > For example, I am trying to create a factory method of sorts that will > create a python object and return it. Rather than load up the dictionary > and module and call Py_RunString each time the method is called, I would > like to only do this once (I'm not worried about reloading this python > object after the extension module is loaded). Thus, I was thinking of > keeping an object variable that I can "clone", so to speak, and return the > cloned value. Is this possible? It is not clear, what you are trying to do. After you load your module you can keep reference to it and to call what ever function you want. > Thanks! > Matt Roman Yakovenko From mjkeyes at sbcglobal.net Mon Dec 5 07:35:59 2005 From: mjkeyes at sbcglobal.net (Matt) Date: Mon, 5 Dec 2005 00:35:59 -0600 Subject: [C++-sig] Creating new instances of an object's contained value References: <4393DB54.6040709@sympatico.ca> Message-ID: Stefan, I didn't even think of that! That's a perfect solution. Many thanks, Matt "Stefan Seefeld" wrote in message news:4393DB54.6040709 at sympatico.ca... > Matt wrote: >> Hey all, >> >> This is probably a newbie question, but I'm curious if it's possible to >> create a new instance of an object's contained value into another object >> variable in an extension module I'm working on. >> >> For example, I am trying to create a factory method of sorts that will >> create a python object and return it. Rather than load up the dictionary >> and module and call Py_RunString each time the method is called, I would >> like to only do this once (I'm not worried about reloading this python >> object after the extension module is loaded). Thus, I was thinking of >> keeping an object variable that I can "clone", so to speak, and return >> the >> cloned value. Is this possible? > > Python has a 'copy' module that may do what you want. However, there might > be a far simpler way to achieve the same thing: > > In Python, types are objects, too. So, your factory may read in the python > script you are referring to once, and then extract the type objects which > the parser instantiates from the global dictionary. > Then, each time you call 'factory->create()' (or however it is spelled), > you simply call operator() on the appropriate type object (with suitable > arguments) > and return the result. > > Would that work for you ? > > HTH, > Stefan From pth at suse.de Mon Dec 5 12:07:23 2005 From: pth at suse.de (Philipp Thomas) Date: Mon, 5 Dec 2005 12:07:23 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> References: <20051201161931.GU7473@paradies.suse.de> <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> Message-ID: <20051205110723.GV7473@paradies.suse.de> * Ralf W. Grosse-Kunstleve (rwgk at yahoo.com) [20051201 18:42]: > > Thanks for pointing out the aliasing problems! Could you help us understanding > how the problem could be fixed? E.g., this is the code in str.cpp: > > return (detail::new_reference)PyObject_CallFunction( > (PyObject*)&PyString_Type, "(O)", > arg_.ptr()); > > Line 12 is (PyObject*)&PyString_Type. Is this what we have to look at? Yes, the cast is what triggers the warning. C aliasing rules say, that basically an object may only be accessed by a pointer of the same type. Only char or void pointers may point to anything. These rules also apply to C++, of cause expanded by the needs of C++. AFAICS, PyObject and PyString_Type aren't related types, i.e. somehow derived from one another. > Both types are defined in Python headers. AFAIK the cast above is standard > practice in Python code... Yes, that's because up until now no compiler complained. Philipp From pth at suse.de Mon Dec 5 14:17:55 2005 From: pth at suse.de (Philipp Thomas) Date: Mon, 5 Dec 2005 14:17:55 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: References: <20051201161931.GU7473@paradies.suse.de> <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> Message-ID: <20051205131755.GX7473@paradies.suse.de> * David Abrahams (dave at boost-consulting.com) [20051201 20:06]: > > return (detail::new_reference)PyObject_CallFunction( > > (PyObject*)&PyString_Type, "(O)", > > arg_.ptr()); > > > I'm pretty sure this warning is bogus It's not. AFAICS, PyObject and PyString_Type aren't related in any way. So casting &PyString_Type to 'PyObject *' breaks aliasing rules and dereferencing the type-punned pointer does break strict-aliasing analysis. > The patch may be bogus, too, at least as far as standard C++ is > concerned. C++ doesn't support the C99 restrict feature. It doesn't have to anything with restrict! It's the simple rule that an object (non-C++ meaning) may only be accessed by either a pointer of the same type or a char/void pointer. >C++ is built on C89 or C90 (I forget which). Does Python even support being > compiled with C99? If not, this whole thing is a red herring. The aliasing issue is the same in C89, it just isn't spelled out as precisely as C99 does. That's also why gcc since 3.0 gives this warning for all C code, no matter if it's C89 or C99. > Can Philipp explain why we should invest energy in trying to make > these warnings go away? gcc bases parts of its optimisations on the result of the strict-alias analysis. So for instance objects (still non-C++ sense) will be eliminated if gcc determines that they aren't accessed by a pointer of the allowed type. So an access via a type-punned pointer will return garbage in this case. Philipp From meine at kogs1.informatik.uni-hamburg.de Mon Dec 5 17:47:11 2005 From: meine at kogs1.informatik.uni-hamburg.de (Hans Meine) Date: Mon, 5 Dec 2005 17:47:11 +0100 Subject: [C++-sig] boost.python: modifying class getattr In-Reply-To: References: <437932D7.7000402@videotron.ca> Message-ID: <200512051747.11878.meine@kogs.informatik.uni-hamburg.de> On Wednesday 16 November 2005 18:37, David Abrahams wrote: > > is there a way to modify the type object associated with Foo_ instances > > so that instead of calling PyObject_GenericGetAttr when an attribute is > > requested, Python calls a function > > PyObject * > > Foo_GetAttr(PyObject *obj, PyObject *name) > > ? > > PyTypeObject* Foo_t = (PyTypeObject*)Foo_.ptr(); > Foo_t->tp_getattro = Foo_GetAttr; Interesting. In a desperate attempt to make accessing (2-dimensional) point elements from my Polygon class faster (a native python list of these objects is twice as fast), I tried to manually set (PyTypeObject*)Foo_.ptr() ->tp_as_sequence->sq_item to my hand-crafted __getitem__ implementation... which made it *slower*. ;-) Obviously, my __getitem__ using extract(self)() is doing an extra type-checking which my previously used boost::python function did not do (since boost knew that self contained my object), and - I should have had a little more confidence in the power of boost::python - was already registered in the special tp_as_sequence->sq_item slot (which triggered an assert I had put in before overwriting sq_item). ;-} That's cool. What a pity that I spent my afternoon trying to optimize where it was already done optimally. ;-/ Obviously, the only remaining advantage of a python list is that it contains readily-wrapped python objects that can simply be returned (after an incref())?! -- Ciao, / / /--/ / / ANS From rwgk at yahoo.com Mon Dec 5 17:51:24 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 5 Dec 2005 08:51:24 -0800 (PST) Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051205131755.GX7473@paradies.suse.de> Message-ID: <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> --- Philipp Thomas wrote: > * David Abrahams (dave at boost-consulting.com) [20051201 20:06]: > > > > return (detail::new_reference)PyObject_CallFunction( > > > (PyObject*)&PyString_Type, "(O)", > > > arg_.ptr()); > > > > > > I'm pretty sure this warning is bogus > > It's not. AFAICS, PyObject and PyString_Type aren't related in any way. So > casting &PyString_Type to 'PyObject *' breaks aliasing rules and > dereferencing the type-punned pointer does break strict-aliasing analysis. I don't think we can do anything about this in boost. It looks to me like you are effectively asking for a re-write of C Python. Since there is no inheritance in C you are probably suggesting C++ Python, a.k.a. Python 4000. Cheers, Ralf __________________________________________ Yahoo! DSL ? Something to write home about. Just $16.99/mo. or less. dsl.yahoo.com From dave at boost-consulting.com Mon Dec 5 21:45:38 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 05 Dec 2005 15:45:38 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules References: <20051201161931.GU7473@paradies.suse.de> <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> <20051205131755.GX7473@paradies.suse.de> Message-ID: Philipp Thomas writes: >> Can Philipp explain why we should invest energy in trying to make >> these warnings go away? > > gcc bases parts of its optimisations on the result of the > strict-alias analysis. So for instance objects (still non-C++ sense) > will be eliminated if gcc determines that they aren't accessed by a > pointer of the allowed type. So an access via a type-punned pointer > will return garbage in this case. But we can't control it, can we? Python is going to access that data, and you can't use Python without that sort of punning. If Python is compiled with optimizations that take advantage of those aliasing rules, everybody who uses it will have the same problem. What alternative do we have? -- Dave Abrahams Boost Consulting www.boost-consulting.com From seefeld at sympatico.ca Mon Dec 5 22:10:40 2005 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 05 Dec 2005 16:10:40 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: References: <20051201161931.GU7473@paradies.suse.de> <20051201174002.40216.qmail@web31509.mail.mud.yahoo.com> <20051205131755.GX7473@paradies.suse.de> Message-ID: <4394ACD0.3020902@sympatico.ca> David Abrahams wrote: > Philipp Thomas writes: > > >>>Can Philipp explain why we should invest energy in trying to make >>>these warnings go away? >> >>gcc bases parts of its optimisations on the result of the >>strict-alias analysis. So for instance objects (still non-C++ sense) >>will be eliminated if gcc determines that they aren't accessed by a >>pointer of the allowed type. So an access via a type-punned pointer >>will return garbage in this case. > > > But we can't control it, can we? Python is going to access that data, > and you can't use Python without that sort of punning. If Python is > compiled with optimizations that take advantage of those aliasing > rules, everybody who uses it will have the same problem. What > alternative do we have? I thought the problem here was that C++ allows more alias analysis (and thus, optimimzation) due to its type-safety, meaning that the potentially wrong code would be generated from compiling boost.python together with whatever is available through python headers. At least that's my interpretation of the issue... Regards, Stefan From Bill at SynectixLtd.com Tue Dec 6 19:34:48 2005 From: Bill at SynectixLtd.com (Bill Davy) Date: Tue, 6 Dec 2005 18:34:48 -0000 Subject: [C++-sig] boost_python_debug pulls in python24.dll => "ImportError: Module use of python24.dll conflicts with this version of Python" ? Message-ID: <200512061834.DPH72829@c2bthomr04.btconnect.com> I am having trouble using boost_python. The final error is: >>> import PIF # trying PIF_d.pyd h:\kestrel\version1\pif\pif.cpp: process attached h:\kestrel\version1\pif\pif.cpp: process detached Traceback (most recent call last): File "", line 1, in ? ImportError: Module use of python24.dll conflicts with this version of Python. [19235 refs] >>> But let me start a bit earlier ... My main() loads a couple of DLL by hand using LoadLibraryEx(), successfully. The first is the DLL I intend to wrap, the second is boost_python: Trying LoadLibraryEx(H:\Kestrel\Version1\Machine\Debug\Machine.dll) h:\kestrel\version1\machine\machine.cpp: process attached <<<<<< message from DllMain() in Machine.dll LoadLibraryEx(H:\Kestrel\Version1\Machine\Debug\Machine.dll) loaded Trying LoadLibraryEx(H:\Boost\boost_1_33_0\libs\python\build\bin-stage\boost_python _debug.dll) LoadLibraryEx(H:\Boost\boost_1_33_0\libs\python\build\bin-stage\boost_python _debug.dll) loaded And then I call PyMain(): Calling Py_Main() # installing zipimport hook import zipimport # builtin # installed zipimport hook # trying H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.zip\site_d.pyd # trying H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.zip\site_d.dll # trying H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.zip\site.py # trying H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.zip\site.pyw # trying H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.zip\site.pyc # trying C:\Python24\Lib\site_d.pyd # trying C:\Python24\Lib\site_d.dll # trying C:\Python24\Lib\site.py # C:\Python24\Lib\site.pyc matches C:\Python24\Lib\site.py Snip snip I just want to get the encoding out of the way so let's say "hello": >>> "hello" # trying C:\Python24\Lib\encodings\cp850_d.pyd # trying C:\Python24\Lib\encodings\cp850_d.dll # trying C:\Python24\Lib\encodings\cp850.py # C:\Python24\Lib\encodings\cp850.pyc matches C:\Python24\Lib\encodings\cp850.py import encodings.cp850 # precompiled from C:\Python24\Lib\encodings\cp850.pyc 'hello' [19197 refs] And now to trigger the error: >>> import PIF # trying PIF_d.pyd h:\kestrel\version1\pif\pif.cpp: process attached <<<<<< message from DllMain() in PIF_d.pyd h:\kestrel\version1\pif\pif.cpp: process detached <<<<<< message from DllMain() in PIF_d.pyd Traceback (most recent call last): File "", line 1, in ? ImportError: Module use of python24.dll conflicts with this version of Python. [19235 refs] >>> In the meantime, the MSVC window has noted the following comings and goings: 'RunPy.exe': Loaded 'H:\Kestrel\Version1\RunPy\Debug\RunPy.exe', Symbols loaded. 'RunPy.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'RunPy.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. 'RunPy.exe': Loaded 'H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.dll', Symbols loaded. <<< Here is the Python interpreter 'RunPy.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded. 'RunPy.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded. Snip snip 'RunPy.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll', No symbols loaded. 'RunPy.exe': Unloaded 'C:\WINDOWS\system32\shimeng.dll' 'RunPy.exe': Loaded 'H:\Kestrel\Version1\Machine\Debug\Machine.dll', Symbols loaded. 'RunPy.exe': Loaded 'H:\Boost\boost_1_33_0\libs\python\build\bin-stage\boost_python_debug.dll', No symbols loaded. 'RunPy.exe': Loaded 'H:\Husky\HostPC\Python-2.4.1\PCbuild\python24.dll', Symbols loaded. <<<< Why this is loaded? 'RunPy.exe': Loaded 'C:\WINDOWS\system32\msvcr71.dll', Symbols loaded. 'RunPy.exe': Loaded 'C:\WINDOWS\system32\msvcp71d.dll', Symbols loaded. 'RunPy.exe': Loaded 'H:\Kestrel\Version1\RunPy\PIF_d.pyd', Symbols loaded. 'RunPy.exe': Unloaded 'H:\Kestrel\Version1\RunPy\PIF_d.pyd' H:\Husky\HostPC\Python-2.4.1\PCbuild\python24_d.dll 07/06/2005 15:36 H:\Boost\boost_1_33_0\libs\python\build\bin-stage\boost_python_debug.dll 05/12/2005 15:25 H:\Husky\HostPC\Python-2.4.1\PCbuild\python24.dll 22/06/2005 11:33 I built boost_python_debug.dll using the following batch file: H:\Boost\boost-jam-3.1.11-1-ntx86\bjam "-sVC71_ROOT=C:\Program Files\Microsoft Visual Studio.NET 2003\Vc7" "-sPYTHON_VERSION=2.4" --with-python-root=H:\Kestrel\Python-2.4.1 The batch files runs in the directory H:\Boost\ boost_1_33_0 So: (1) boost_python_debug should be a debug version but it seems to pull in python24.dll even though python24_d.dll was already loaded. (2) I am getting "ImportError: Module use of python24.dll conflicts with this version of Python", possibly as a result of (1). I would be truly grateful for any assistance. Thanks in advance, Bill PS If there is a UK genius I am happy to pack up my laptop for a spot of consultancy. If I can get past these first few stumbling blocks, all will be well. ~*""*~.,,.~*""*~.,,~*""*~.,,.~*""*~.,,~*""*~.,,.~*""*~.,,.~*""*~., Privileged/Confidential information may be contained in this message. If you are not the addressee indicated in this message (or responsible for delivery of the message to such person), you may not copy or deliver this message to anyone. In such case, you should destroy this message, and please notify us immediately. Please advise immediately if you or your employer does not consent to Internet e-mail for messages of this kind. Opinions, conclusions and other information expressed in this message are not given or endorsed by my firm or employer unless otherwise indicated by an authorised representative independent of this message. Although we utilise the most up to date virus checking procedures you should carry out your own virus check before opening any attachment. We accept no liability for any loss or damage which may be caused by software viruses. ~*""*~.,,.~*""*~.,,~*""*~.,,.~*""*~.,,~*""*~.,,.~*""*~.,,.~*""*~., Bill Davy, Synectix Limited, 12 King Alfred Way, Cheltenham, GL52 6QP, England Telephone: +44 (0)1242 254411, Mobile: +44 (0)7866 451568, Fax: +44 (0)1242 256611 Work: mailto:Bill at SynectixLtd.com Home: mailto:Bill at XchelSys.co.uk Web: http://www.synectixltd.com/ -------------- next part -------------- A non-text attachment was scrubbed... Name: winmail.dat Type: application/ms-tnef Size: 7966 bytes Desc: not available URL: From dave at boost-consulting.com Tue Dec 6 20:02:02 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 06 Dec 2005 14:02:02 -0500 Subject: [C++-sig] boost_python_debug pulls in python24.dll => "ImportError: Module use of python24.dll conflicts with this version of Python" ? References: <200512061834.DPH72829@c2bthomr04.btconnect.com> Message-ID: "Bill Davy" writes: > So: > (1) boost_python_debug should be a debug version but it seems to pull in > python24.dll even though python24_d.dll was already loaded. > (2) I am getting "ImportError: Module use of python24.dll conflicts with > this version of Python", possibly as a result of (1). > > I would be truly grateful for any assistance. Please read http://www.boost.org/libs/python/doc/building.html#variants and also the admonition at http://www.boost.org/libs/python/doc/tutorial/doc/html/python/hello.html Since ActiveState will be making the Python debug DLL readily available in the future, Boost.Python will no longer have this build oddity in its next release; we'll just have a release and a debug version. (http://news.gmane.org/find-root.php?message_id=%3cumzjjtxki.fsf%40boost%2dconsulting.com%3e) HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Dec 6 20:21:59 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 06 Dec 2005 14:21:59 -0500 Subject: [C++-sig] Serialization/pickle In-Reply-To: <716621DCB4468F46BBCC1BCFBED45C120129D94F@XCH-NW-2V2.nw.nos.boeing.com> (Michael Drumheller's message of "Tue, 6 Dec 2005 08:58:11 -0800") References: <716621DCB4468F46BBCC1BCFBED45C120129D94F@XCH-NW-2V2.nw.nos.boeing.com> Message-ID: The following message is a courtesy copy of an article that has been posted to gmane.comp.lib.boost.user as well. "Drumheller, Michael" writes: >>> From: David Abrahams boost-consulting.com> >>> Subject: Re: Boost.python serialization >>> Newsgroups: gmane.comp.lib.boost.user >>> Date: 2005-11-29 23:28:17 GMT (6 days, 17 hours and 9 minutes ago) >>> >>> "Drumheller, Michael" boeing.com> writes: >>> >>> > Thank you for the help. I have seen that link (the one you supplied) >>> > before, but I posted my question because that link in particular does >>> > not mention the words "Boost.Serialization" or "Archive" at all. >>> >>> That's because the Boost Serialization library is unrelated. > > I understand that it is technically unrelated. I am asking for > information about about patterns of actual usage. I'm afraid I don't know that. >>> > I suppose what I was really getting at, and was probably not very >>> > clear about (sorry :| ) was whether the specific approach (by >>> > N. Becker) of using a stringstream wrapped with a >>> > boost::archive::binary_oarchive is a standard idiom. >>> >>> "Standard?" > > OK: "common," "popular," "preferred," "regarded-as-best-practice," > "effective." Ditto. >>> > (Basically, I would have thought that "python pickle boost::archive" >>> > would be a million-hit Google query, but it's only about a dozen. I >>> > find that weird. Do people just not serialize their C++ extensions >>> > very often?) >>> >>> Yes, they do it very often. There's usually no need to touch >>> Boost.Serialization in order to do so, though. > > My extensions refer to one another, i.e., they form a significant object > hierarchy in and of themselves. E.g., on the C++ side I might have an > instance x of class X, which contains a vector of shared_ptrs p1,...,pn > to instances y1,...,yn of another C++ class Y. At pickle-time there may > be Python object z with a member u bound to to x and members w1,...,wm > bound to a subset of the y1,...,yn. Is it even feasible to expect to be > able to simple pickle.dump z and have it all work? Yes. Of course you have to do some work in your wrapping code to say how X gets pickled. > Please keep in mind: I am just getting started wading into serializing > a pretty complicated set of strongly interdependent Python and C++ > objects and I am just trying to get my bearings. If this is the wrong > forum to be asking these questions, please tell me. Well, the C++-sig _might_ be more appropriate: http://www.boost.org/more/mailing_lists.htm#cplussig (cross-posted there) We (Boost Consulting) are actually planning to do something like this with one of our clients, but we haven't gotten started with it yet. I think everything should "just work" as long as you take care not to try to serialize the same object both from the C++ side (using Boost.Serialization) and from the Python side (using pickle). Because each system implements its own object tracking, you could end up representing the same object twice. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From ricardokirkner at gmail.com Tue Dec 6 20:51:01 2005 From: ricardokirkner at gmail.com (Ricardo Kirkner) Date: Tue, 6 Dec 2005 16:51:01 -0300 Subject: [C++-sig] call policies help needed Message-ID: <5e44108d0512061151i244a50c7u91d3c5024662c70f@mail.gmail.com> hi. I am trying to wrap a method that returns a new object (allocated with new)). As far as I know, I have to use the return_value_policy() construct, to tell the wrapper to hold that pointer. The wrapper compiles ok, but when I call that method (from python) I get an error (from glib) and the python interpreter exits. What am I missing? The error I am getting is: *** glibc detected *** malloc(): memory corruption: Abort Thanks, Ricardo Kirkner From dave at boost-consulting.com Tue Dec 6 21:40:41 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 06 Dec 2005 15:40:41 -0500 Subject: [C++-sig] call policies help needed References: <5e44108d0512061151i244a50c7u91d3c5024662c70f@mail.gmail.com> Message-ID: Ricardo Kirkner writes: > hi. I am trying to wrap a method that returns a new object (allocated > with new)). As far as I know, I have to use the > return_value_policy() construct, to tell the > wrapper to hold that pointer. > > The wrapper compiles ok, but when I call that method (from python) I > get an error (from glib) and the python interpreter exits. What am I > missing? It's unclear. Are you *certain* this object was allocated with new? If that's the case, I can't imagine that the problem is coming from that particular wrapped function. My advice (as usual) is to reduce your program to the simplest possible case that still exhibits the problem. That almost always immediately reveals the problem. I hear utilities like valgrind can be really useful for situations like this, too, though I've never used it myself. -- Dave Abrahams Boost Consulting www.boost-consulting.com From ndbecker2 at gmail.com Tue Dec 6 22:44:31 2005 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 06 Dec 2005 16:44:31 -0500 Subject: [C++-sig] Serialization/pickle References: <716621DCB4468F46BBCC1BCFBED45C120129D94F@XCH-NW-2V2.nw.nos.boeing.com> Message-ID: David Abrahams wrote: > The following message is a courtesy copy of an article > that has been posted to gmane.comp.lib.boost.user as well. > > "Drumheller, Michael" writes: > >>>> From: David Abrahams boost-consulting.com> >>>> Subject: Re: Boost.python serialization >>>> Newsgroups: gmane.comp.lib.boost.user >>>> Date: 2005-11-29 23:28:17 GMT (6 days, 17 hours and 9 minutes ago) >>>> >>>> "Drumheller, Michael" boeing.com> writes: >>>> >>>> > Thank you for the help. I have seen that link (the one you >>>> > supplied) before, but I posted my question because that link in >>>> > particular does not mention the words "Boost.Serialization" or >>>> > "Archive" at all. >>>> >>>> That's because the Boost Serialization library is unrelated. >> >> I understand that it is technically unrelated. I am asking for >> information about about patterns of actual usage. > > I'm afraid I don't know that. > >>>> > I suppose what I was really getting at, and was probably not very >>>> > clear about (sorry :| ) was whether the specific approach (by >>>> > N. Becker) of using a stringstream wrapped with a >>>> > boost::archive::binary_oarchive is a standard idiom. >>>> >>>> "Standard?" >> >> OK: "common," "popular," "preferred," "regarded-as-best-practice," >> "effective." > > Ditto. > >>>> > (Basically, I would have thought that "python pickle boost::archive" >>>> > would be a million-hit Google query, but it's only about a dozen. I >>>> > find that weird. Do people just not serialize their C++ extensions >>>> > very often?) >>>> >>>> Yes, they do it very often. There's usually no need to touch >>>> Boost.Serialization in order to do so, though. >> >> My extensions refer to one another, i.e., they form a significant object >> hierarchy in and of themselves. E.g., on the C++ side I might have an >> instance x of class X, which contains a vector of shared_ptrs p1,...,pn >> to instances y1,...,yn of another C++ class Y. At pickle-time there may >> be Python object z with a member u bound to to x and members w1,...,wm >> bound to a subset of the y1,...,yn. Is it even feasible to expect to be >> able to simple pickle.dump z and have it all work? > > Yes. Of course you have to do some work in your wrapping code to say > how X gets pickled. > >> Please keep in mind: I am just getting started wading into serializing >> a pretty complicated set of strongly interdependent Python and C++ >> objects and I am just trying to get my bearings. If this is the wrong >> forum to be asking these questions, please tell me. > > Well, the C++-sig _might_ be more appropriate: > http://www.boost.org/more/mailing_lists.htm#cplussig (cross-posted there) > > We (Boost Consulting) are actually planning to do something like this > with one of our clients, but we haven't gotten started with it yet. I > think everything should "just work" as long as you take care not to > try to serialize the same object both from the C++ side (using > Boost.Serialization) and from the Python side (using pickle). Because > each system implements its own object tracking, you could end up > representing the same object twice. > I have 2 examples that might interest you. I haven't looked at this code for a while, so I don't exactly remember it. The first is a wrapper for mersenne_twister. First, I patched mersenne_twisted.hpp, adding: friend class boost::serialization::access; template inline void save (Archive &ar, const unsigned int) const { for (int j = 0; j < state_size; ++j) { const UIntType x = compute (j); ar << boost::serialization::make_nvp("item", x); } } template inline void load (Archive &ar, const unsigned int) { for (int j = 0; j < state_size; ++j) { ar >> boost::serialization::make_nvp ("item", x[j]); } i = state_size; } template void serialize(Archive & ar, const unsigned int file_version) { boost::serialization::split_member(ar, *this, file_version); } Then, I use this in my wrapper: typedef boost::mt19937 rng_t; struct mt_pickle_suite : python::pickle_suite { static python::object getstate (const rng_t& rng) { std::ostringstream os; boost::archive::binary_oarchive oa(os); oa << rng; return python::str (os.str()); } static void setstate(rng_t& rng, python::object entries) { python::str s = python::extract (entries)(); std::string st = python::extract (s)(); std::istringstream is (st); boost::archive::binary_iarchive ia (is); ia >> rng; } }; The second example is a wrapper for boost ublas vector: namespace boost { namespace serialization { template struct implementation_level > { typedef mpl::integral_c_tag tag; // typedef mpl::int_ type; typedef mpl::int_ type; BOOST_STATIC_CONSTANT( int, value = implementation_level::type::value ); }; template struct tracking_level > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT( int, value = tracking_level::type::value ); }; } } namespace boost { namespace serialization { template inline void serialize (Archive &ar, std::complex& z, const unsigned int file_version) { ar & boost::serialization::make_nvp ("real", real(z)); ar & boost::serialization::make_nvp ("imag", imag(z)); // ar & real(z); // ar & imag(z); } } } namespace boost { namespace serialization { template struct implementation_level > { typedef mpl::integral_c_tag tag; // typedef mpl::int_ type; typedef mpl::int_ type; BOOST_STATIC_CONSTANT( int, value = implementation_level::type::value ); }; } } template inline void save (Archive &ar, const ublas::vector &v, const unsigned int) { unsigned int count = v.size(); ar << BOOST_SERIALIZATION_NVP (count); typename ublas::vector::const_iterator it = v.begin(); while (count-- > 0) { ar << boost::serialization::make_nvp ("item", *it++); } } template inline void load (Archive &ar, ublas::vector &v, const unsigned int) { unsigned int count; ar >> BOOST_SERIALIZATION_NVP (count); v.resize (count); typename ublas::vector::iterator it = v.begin(); while (count-- > 0) { ar >> boost::serialization::make_nvp ("item", *it++); } } namespace boost { namespace serialization { template inline void serialize (Archive &ar, ublas::vector& v, const unsigned int file_version) { boost::serialization::split_free (ar, v, file_version); } } } namespace python = boost::python; template struct vector_pickle_suite : pickle_suite { static tuple getinitargs(const MatrixType &m) { return make_tuple(m.size()); } static python::object getstate (const MatrixType& v) { std::ostringstream os; boost::archive::binary_oarchive oa(os); oa << v; return python::str (os.str()); } static void setstate(MatrixType& v, python::object entries) { python::str s = python::extract (entries)(); std::string st = python::extract (s)(); std::istringstream is (st); boost::archive::binary_iarchive ia (is); ia >> v; } }; From pth at suse.de Wed Dec 7 14:16:25 2005 From: pth at suse.de (Philipp Thomas) Date: Wed, 7 Dec 2005 14:16:25 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> Message-ID: <20051207131625.GG24228@paradies.suse.de> * Ralf W. Grosse-Kunstleve (rwgk at yahoo.com) [20051205 17:54]: > It looks to me like you are effectively asking for a re-write of C Python. I've now looked at the Python sources and the Python folks decided to use -fno-strict-aliasing instead of fixing the code ( http://sourceforge.net/tracker/index.php?func=detail&aid=766696&group_id=5470&atid=105470 ). > I don't think we can do anything about this in boost. Two things would be possible, both specific to gcc: 1) use -fno-strict-aliasing (valid for gcc >= 3.0), preferably only for the boost python libs 2) use a union for type punning, i.e. : *** str.cpp 2005/12/07 12:55:17 1.1 --- str.cpp 2005/12/07 13:02:18 *************** *** 8,16 **** detail::new_reference str_base::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( ! (PyObject*)&PyString_Type, "(O)", ! arg_.ptr()); } str_base::str_base() --- 8,17 ---- detail::new_reference str_base::call(object const& arg_) { + union { PyTypeObject *ptp; PyObject *pop; } pun = { &PyString_Type }; + return (detail::new_reference)PyObject_CallFunction( ! pun.pop, "(O)", arg_.ptr()); } using a union to pun a type is a gcc specific solution. I'll do a patch that changes all affected places that I can send here if there is interest to add it to boost. Otherwise I'll only use the patch for the version of boost in SUSE Linux. > Since there is no inheritance in C you are probably suggesting C++ Python, > a.k.a. Python 4000. You only need inheritance to really cleanly solve this problem. The other solution, like I said, would be to use generic pointers. But that would be something to discuss with the python folks. Philipp From pth at suse.de Wed Dec 7 17:16:28 2005 From: pth at suse.de (Philipp Thomas) Date: Wed, 7 Dec 2005 17:16:28 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051207131625.GG24228@paradies.suse.de> References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> Message-ID: <20051207161628.GA8047@paradies.suse.de> * Philipp Thomas (pth at suse.de) [20051207 14:27]: > I'll do a patch that changes all affected places And here is the patch I'm going to be using for SUSE Linux: --- libs/python/src/dict.cpp +++ libs/python/src/dict.cpp @@ -28,9 +28,9 @@ detail::new_reference dict_base::call(object const& arg_) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyDict_Type }; return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyDict_Type, "(O)", - arg_.ptr()); + pun.pop, "(O)", arg_.ptr()); } dict_base::dict_base() --- libs/python/src/list.cpp +++ libs/python/src/list.cpp @@ -9,10 +9,11 @@ detail::new_non_null_reference list_base::call(object const& arg_) { + union{ PyTypeObject *ptop; PyObject *pop; }pun = { &PyList_Type }; return (detail::new_non_null_reference) (expect_non_null)( PyObject_CallFunction( - (PyObject*)&PyList_Type, "(O)", + pun.pop, "(O)", arg_.ptr())); } --- libs/python/src/long.cpp +++ libs/python/src/long.cpp @@ -8,24 +8,25 @@ new_non_null_reference long_base::call(object const& arg_) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type }; return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(O)", - arg_.ptr()); + pun.pop, "(O)", arg_.ptr()); } new_non_null_reference long_base::call(object const& arg_, object const& base) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type }; return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(OO)", - arg_.ptr(), base.ptr()); + pun.pop, "(OO)", arg_.ptr(), base.ptr()); } long_base::long_base() - : object( - detail::new_reference( - PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) - ) -{} +{ + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type }; + object(detail::new_reference( + PyObject_CallFunction(pun.pop, "()"))); + +} long_base::long_base(object_cref arg) : object(long_base::call(arg)) --- libs/python/src/object/class.cpp +++ libs/python/src/object/class.cpp @@ -538,9 +538,11 @@ void class_base::add_property( char const* name, object const& fget, char const* docstr) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyProperty_Type }; + object property( (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr)); + PyObject_CallFunction(pun.pop, "Osss", fget.ptr(), 0, 0, docstr)); this->setattr(name, property); } @@ -548,9 +550,11 @@ void class_base::add_property( char const* name, object const& fget, object const& fset, char const* docstr) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyProperty_Type }; + object property( (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr)); + PyObject_CallFunction(pun.pop, "OOss", fget.ptr(), fset.ptr(), 0, docstr)); this->setattr(name, property); } --- libs/python/src/str.cpp +++ libs/python/src/str.cpp @@ -8,9 +8,10 @@ detail::new_reference str_base::call(object const& arg_) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyString_Type }; + return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyString_Type, "(O)", - arg_.ptr()); + pun.pop, "(O)", arg_.ptr()); } str_base::str_base() --- libs/python/src/tuple.cpp +++ libs/python/src/tuple.cpp @@ -8,9 +8,10 @@ detail::new_reference tuple_base::call(object const& arg_) { + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyTuple_Type }; + return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyTuple_Type, "(O)", - arg_.ptr()); + pun.pop, "(O)", arg_.ptr()); } tuple_base::tuple_base() -- Anything whose specification is too complicated to explain easily probably needs to be redesigned. David Abrahams on boost From shin1_morita at yahoo.co.jp Wed Dec 7 17:35:48 2005 From: shin1_morita at yahoo.co.jp (Shin-ichi MORITA) Date: Thu, 8 Dec 2005 01:35:48 +0900 (JST) Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject Message-ID: <20051207163548.20605.qmail@web2303.mail.yahoo.co.jp> Hi all, I have a problem that returning a wrapper instance exposed in the other module is not converted to its owner PyObject. This is my box: linux kernel-2.4.21 gcc-3.4.3 boost_1_33_1 I found that dynamic_cast returns 0 in boost::python::detail::wrapper_base_::owner_impl() for instances exposed by modules other than the module which instantiated owner_impl(). I googled about gcc and dynamic_cast, and found several articles about type_info, translation unit, shared object, etc. After several trials and errors, I finally found one solution which is: Add virtual destructor to wrapper_base to share type_info of wrapper_base in libboost_python.so. I'm not sure that this solution is right for all compilers. Could anyone help? Thanks. I attached a tar-ball which contains source codes and test cases to explain my problem. Its summary is as follows. In module0, I exposed a class Base and two functions: // exposed using boost::python::wrapper like Tutorial. struct Base { virtual ~Base(); virtual void f() = 0; }; Base* base = 0; // no care about dangling pointer for now. Base* GetBase() { return base; } void SetBase(Base* p) { base = p; } And in module1, I exposed a class Derived derived from Base. // exposed using boost::python::wrapper like Tutorial. struct Derived : Base { virtual f() { return 0; } }; Then I wrote following test case. >>> class Derived1(module1.Derived): ... def f(self): ... return 2 ... >>> b = Derived1() >>> module0.SetBase(b) >>> b is module0.GetBase() True In the last line above, I expected that GetBase() returned the PyObject which is identical to b. But GetBase() returned a pointer holder of DerivedWrap (Derived wrapper class). -------------------------------------- STOP HIV/AIDS. Yahoo! JAPAN Redribbon Campaign 2005 http://pr.mail.yahoo.co.jp/redribbon/ -------------- next part -------------- A non-text attachment was scrubbed... Name: test_owner.tar.bz2 Type: application/bzip2 Size: 1166 bytes Desc: test_owner.tar.bz2 URL: From pth at suse.de Wed Dec 7 17:44:51 2005 From: pth at suse.de (Philipp Thomas) Date: Wed, 7 Dec 2005 17:44:51 +0100 Subject: [C++-sig] Useless use of type attributes Message-ID: <20051207164451.GB8047@paradies.suse.de> boost/python/detail/wrapper_base.hpp and boost/python/detail/exception_handler.hpp needlessly uses type attributes in the forward declaration, which prompts gcc 4.1 to warn with warning: type attributes are honored only at type definition here's a patch to fix this: --- boost/python/detail/exception_handler.hpp +++ boost/python/detail/exception_handler.hpp @@ -11,7 +11,7 @@ namespace boost { namespace python { namespace detail { -struct BOOST_PYTHON_DECL exception_handler; +struct exception_handler; typedef function2 const&> handler_function; --- boost/python/detail/wrapper_base.hpp +++ boost/python/detail/wrapper_base.hpp @@ -14,7 +14,7 @@ namespace detail { - class BOOST_PYTHON_DECL wrapper_base; + class wrapper_base; namespace wrapper_base_ // ADL disabler { From dave at boost-consulting.com Thu Dec 8 06:35:12 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 08 Dec 2005 00:35:12 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> <20051207161628.GA8047@paradies.suse.de> Message-ID: Philipp Thomas writes: > * Philipp Thomas (pth at suse.de) [20051207 14:27]: > >> I'll do a patch that changes all affected places > > And here is the patch I'm going to be using for SUSE Linux: > > --- libs/python/src/dict.cpp > +++ libs/python/src/dict.cpp > @@ -28,9 +28,9 @@ > > detail::new_reference dict_base::call(object const& arg_) > { > + union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyDict_Type }; > return (detail::new_reference)PyObject_CallFunction( > - (PyObject*)&PyDict_Type, "(O)", > - arg_.ptr()); > + pun.pop, "(O)", arg_.ptr()); > } > That's unacceptable for Boost because, IIUC, it introduces undefined behavior in Boost.Python (reusing the bit pattern for one type of pointer as another type of pointer) where there is currently none (since Python will always be compiled with options that make such aliasing OK). Even if it works for GCC, it could break some other compiler, and the new code could cause warnings with another compiler where there currently is none. In fact, I don't see how this union trick can do anything other than suppress the warning. It can't possibly fix a real problem. If Python is compiled without -fno-strict-aliasing, it will be free to make invalid assumptions about these pointers aliasing one another, and the use of the union will do nothing to stop that. Fundametally, I need a solution that doesn't mess up other compilers. There is code in boost/python/cast.hpp that does the same kind of aliasing and yet apparently doesn't generate any warnings (or you'd have included it in your patch). So maybe the best solution would be just to use boost/python/cast.hpp. At least then all the "evil" is encapsulated in one place and can be tweaked for specific compilers. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Dec 8 06:37:16 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 08 Dec 2005 00:37:16 -0500 Subject: [C++-sig] Useless use of type attributes References: <20051207164451.GB8047@paradies.suse.de> Message-ID: Philipp Thomas writes: > boost/python/detail/wrapper_base.hpp and boost/python/detail/exception_handler.hpp > needlessly uses type attributes in the forward declaration, which > prompts gcc 4.1 to warn with > > warning: type attributes are honored only at type definition > > here's a patch to fix this: This is another GCC-specific patch. Those macros aren't type attributes, except on GCC, and only when targeting certain platforms. They expand to different things on different compilers. Are you sure that no supported platforms need them? I seem to recall that older versions of MinGW, in fact, had very odd requirements in terms of where those __declspecs were placed. > --- boost/python/detail/exception_handler.hpp > +++ boost/python/detail/exception_handler.hpp > @@ -11,7 +11,7 @@ > > namespace boost { namespace python { namespace detail { > > -struct BOOST_PYTHON_DECL exception_handler; > +struct exception_handler; > > typedef function2 const&> handler_function; > > --- boost/python/detail/wrapper_base.hpp > +++ boost/python/detail/wrapper_base.hpp > @@ -14,7 +14,7 @@ > > namespace detail > { > - class BOOST_PYTHON_DECL wrapper_base; > + class wrapper_base; > > namespace wrapper_base_ // ADL disabler > { -- Dave Abrahams Boost Consulting www.boost-consulting.com From mjkeyes at sbcglobal.net Thu Dec 8 06:18:31 2005 From: mjkeyes at sbcglobal.net (Matt) Date: Wed, 7 Dec 2005 23:18:31 -0600 Subject: [C++-sig] Boost tuple example? Message-ID: Hey all, Does anyone have an example of boost's use of tuples? For example, I am wanting to construct tuples in C++ and pass them on to Python (these will consist of basic types (const char*'s, integers, etc.) or object values. Thanks! Matt From dave at boost-consulting.com Thu Dec 8 06:27:09 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 08 Dec 2005 00:27:09 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> Message-ID: Philipp Thomas writes: > * Ralf W. Grosse-Kunstleve (rwgk at yahoo.com) [20051205 17:54]: > >> It looks to me like you are effectively asking for a re-write of C Python. > > I've now looked at the Python sources and the Python folks decided to use > -fno-strict-aliasing instead of fixing the code > ( http://sourceforge.net/tracker/index.php?func=detail&aid=766696&group_id=5470&atid=105470 ). Which, AFAICT, means that our casts aren't hurting anybody, regardless of whether we use -fno-strict-aliasing. Right? >> I don't think we can do anything about this in boost. > > Two things would be possible, both specific to gcc: > > 1) use -fno-strict-aliasing (valid for gcc >= 3.0), preferably only for the > boost python libs > > 2) use a union for type punning, i.e. : > > *** str.cpp 2005/12/07 12:55:17 1.1 > --- str.cpp 2005/12/07 13:02:18 > *************** > *** 8,16 **** > > detail::new_reference str_base::call(object const& arg_) > { > return (detail::new_reference)PyObject_CallFunction( > ! (PyObject*)&PyString_Type, "(O)", > ! arg_.ptr()); > } > > str_base::str_base() > --- 8,17 ---- > > detail::new_reference str_base::call(object const& arg_) > { > + union { PyTypeObject *ptp; PyObject *pop; } pun = { &PyString_Type }; > + > return (detail::new_reference)PyObject_CallFunction( > ! pun.pop, "(O)", arg_.ptr()); > } > > using a union to pun a type is a gcc specific solution. It's nonportable in other ways than you're indicating, as far as I can tell. I don't think there's any guarantee that the bit pattern for PyObject* is the same as the one for a PyTypeObject* at the same address. The (PyObject*) cast is essentially a reinterpret cast from PyTypeObject* to PyObject*, where the union performs, essentially, a reinterpret cast of a PyObject*& to a PyTypeObject*&, which could be a completely different thing. > I'll do a patch that changes all affected places that I can send > here if there is interest to add it to boost. Otherwise I'll only > use the patch for the version of boost in SUSE Linux. To avoid affecting other compilers I suppose your patch would require the addition of numerous #ifdef blocks, or it would have to turn all the CPythonish casts into macro invocations that expand into some compiler-specific construct... right? I would strongly oppose the former, but the latter might be no worse (and may be a little better) than leaving the C-style casts in there. -- Dave Abrahams Boost Consulting www.boost-consulting.com From pth at suse.de Thu Dec 8 18:01:16 2005 From: pth at suse.de (Philipp Thomas) Date: Thu, 8 Dec 2005 18:01:16 +0100 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> Message-ID: <20051208170116.GF8047@paradies.suse.de> * David Abrahams (dave at boost-consulting.com) [20051208 07:06]: > Which, AFAICT, means that our casts aren't hurting anybody, regardless > of whether we use -fno-strict-aliasing. Right? Right. Do you have an idea how to pass -fno-strict-aliasing *only* when build libboost_python? > where the union performs, essentially, a reinterpret cast of a PyObject*& > to a PyTypeObject*&, which could be a completely different thing. Please? I'm still passing a PyObject*, as the union is essentially a reinterpret_cast(PyTypeObject *). > I would strongly oppose the former, There's no disagreement as I hate #ifdef because it always makes code nearly unreadable. > but the latter might be no worse > (and may be a little better) than leaving the C-style casts in there. Hmm, I'll try to come up with a way to encapsulate it in macros. Philipp From pth at suse.de Thu Dec 8 18:06:26 2005 From: pth at suse.de (Philipp Thomas) Date: Thu, 8 Dec 2005 18:06:26 +0100 Subject: [C++-sig] Useless use of type attributes In-Reply-To: References: <20051207164451.GB8047@paradies.suse.de> Message-ID: <20051208170626.GG8047@paradies.suse.de> * David Abrahams (dave at boost-consulting.com) [20051208 06:41]: > They expand to different things on different compilers. The only other thing I see is the __declspec. > Are you sure that no supported platforms need them? No, I'm not sure. The only thing I remember is that MSVC only needs it at declaration. But I've been working on Linux for the last ten years, so my knowledge of other compilers is sparse at best. > I seem to recall that older versions of MinGW, in fact, had very odd > requirements in terms of where those __declspecs were placed. How do I get answers to this? Ask on the boost ml? Philipp From rwgk at yahoo.com Thu Dec 8 17:58:04 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 8 Dec 2005 08:58:04 -0800 (PST) Subject: [C++-sig] Boost tuple example? In-Reply-To: Message-ID: <20051208165804.85014.qmail@web31514.mail.mud.yahoo.com> --- Matt wrote: > Does anyone have an example of boost's use of tuples? For example, I am > wanting to construct tuples in C++ and pass them on to Python (these will > consist of basic types (const char*'s, integers, etc.) or object values. Look in the file: boost/libs/python/test/tuple.cpp You can probably learn a lot of tricks by spending 30 minutes to scan through all the *.cpp files in the boost/libs/python/test directory. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From koen_van_herck at yahoo.com Thu Dec 8 18:37:18 2005 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Thu, 8 Dec 2005 18:37:18 +0100 Subject: [C++-sig] How to create package structure in single extension module Message-ID: Hello, I would like to do something similar as the example in http://www.boost.org/libs/python/doc/tutorial/doc/html/python/techniques.htm l#python.creating_packages: >>> import sounds >>> import sounds.io >>> import sounds.filters >>> sound = sounds.io.open('file.mp3') >>> new_sound = sounds.filters.echo(sound, 1.0) but, contrary to the example, by providing only a single sounds.pyd module. The reason is that I'm wrapping a library that uses multiple namespaces and I would like to expose these namespaces to Python. It's not possible though to split the library into different compiled entities. How can I do this using Boost.Python ? Thanks for your help, Koen Van Herck. From tim.peters at gmail.com Thu Dec 8 18:38:15 2005 From: tim.peters at gmail.com (Tim Peters) Date: Thu, 8 Dec 2005 12:38:15 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules In-Reply-To: <20051207131625.GG24228@paradies.suse.de> References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> Message-ID: <1f7befae0512080938m1e3b8267j94e54e405501aaa6@mail.gmail.com> [Philipp Thomas] > ... > I've now looked at the Python sources and the Python folks decided to use > -fno-strict-aliasing instead of fixing the code > ( http://sourceforge.net/tracker/index.php?func=detail&aid=766696&group_id=5470&atid=105470 ). FYI, this was decided in 2003, in a long thread starting here (which branches out unhelpfully before getting back on track): http://mail.python.org/pipermail/python-dev/2003-July/036898.html From dave at boost-consulting.com Thu Dec 8 20:35:07 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 08 Dec 2005 14:35:07 -0500 Subject: [C++-sig] Boost tuple example? References: <20051208165804.85014.qmail@web31514.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- Matt wrote: > >> Does anyone have an example of boost's use of tuples? For example, I am >> wanting to construct tuples in C++ and pass them on to Python (these will >> consist of basic types (const char*'s, integers, etc.) or object values. > > Look in the file: > > boost/libs/python/test/tuple.cpp > > You can probably learn a lot of tricks by spending 30 minutes to scan through > all the *.cpp files in the boost/libs/python/test directory. I read the OP as asking about how to translate boost::tuple, a completely C++ generalization of std::pair (rather than boost::python::tuple, a wrapper for native Python tuples) to/from Python's tuples. Which is it? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Dec 8 21:52:45 2005 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 08 Dec 2005 15:52:45 -0500 Subject: [C++-sig] boost/python 1.33.1 breaks aliasing rules References: <20051205131755.GX7473@paradies.suse.de> <20051205165124.38002.qmail@web31502.mail.mud.yahoo.com> <20051207131625.GG24228@paradies.suse.de> <20051208170116.GF8047@paradies.suse.de> Message-ID: Philipp Thomas writes: > * David Abrahams (dave at boost-consulting.com) [20051208 07:06]: > >> Which, AFAICT, means that our casts aren't hurting anybody, regardless >> of whether we use -fno-strict-aliasing. Right? > > Right. Do you have an idea how to pass -fno-strict-aliasing *only* when > build libboost_python? Yes; we can put it in the Jamfile. >> where the union performs, essentially, a reinterpret cast of a PyObject*& >> to a PyTypeObject*&, which could be a completely different thing. > > Please? I'm still passing a PyObject*, as the union is essentially a > reinterpret_cast(PyTypeObject *). No. A reinterpret_cast is not required to simply interpret the same bits differently, as the union trick does. Aside from certain round-trip conversion guarantees, its effects are completely implementation-defined. To put it differently, what you're doing there is equivalent to: PyTypeObject* s = &PyString_Type; *reinterpret_cast(&s) which is another thing altogether. Boost.Python is doing ((PyObject*)&PyString_Type) and passes the result to Python. That is not yet undefined behavior. If Python internally casts that back to PyTypeObject*, it's free to use the pointer as it likes without undefined behavior. If I treat Python as a black box, I can assume it does something like that, since Python documents that we can pass such punned pointers. Instead Python uses -fno-strict-aliasing, exploiting a compiler-specific feature to avoid undefined behavior, but it's the same thing from my POV. So right now Boost.Python isn't doing anything unspecified or nonportable. However, the reinterpretation of bits as you are doing does introduce unspecified behavior at least, by 5.2.10, para 7: 7 A pointer to an object can be explicitly converted to a pointer to an object of different type. 65) Except that converting an rvalue of type ``pointer to T1'' to the type ``pointer to T2'' (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. >> I would strongly oppose the former, > > There's no disagreement as I hate #ifdef because it always makes code nearly > unreadable. > >> but the latter might be no worse >> (and may be a little better) than leaving the C-style casts in there. > > Hmm, I'll try to come up with a way to encapsulate it in macros. Forget the macros; we can do it with functions. See boost/python/cast.hpp. -- Dave Abrahams Boost Consulting www.boost-consulting.com From mcantor at stanford.edu Fri Dec 9 01:41:24 2005 From: mcantor at stanford.edu (mike cantor) Date: Thu, 08 Dec 2005 16:41:24 -0800 Subject: [C++-sig] printf from an extension Message-ID: <6.0.1.1.2.20051208163819.01eeb458@mcantor.pobox.stanford.edu> Hi, I am extending python with C and trying to debug with printf. The code below succssfully returns the string "hello" when compiled and called, but the "can print from in here phrase" does not reach python stdout. Is there something screwy with my environment or is there some trick to this that I don't know. Any help would be greatly appreciated! -mike #include static PyObject* helloworld(PyObject* self) { printf("can print from in here?"); return Py_BuildValue("s", "hello"); } static char hw_docstr[] = "hello docstr"; static PyMethodDef hw_funcs[] = { {"helloworld", (PyCFunction)helloworld, METH_NOARGS, hw_docstr}, {NULL} }; void inithelloworld(void) { Py_InitModule3("helloworld",hw_funcs, "simple module"); } From rwgk at yahoo.com Fri Dec 9 04:49:12 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 8 Dec 2005 19:49:12 -0800 (PST) Subject: [C++-sig] How to create package structure in single extension module In-Reply-To: Message-ID: <20051209034912.52625.qmail@web31513.mail.mud.yahoo.com> --- Koen Van Herck wrote: > I would like to do something similar as the example in > http://www.boost.org/libs/python/doc/tutorial/doc/html/python/techniques.htm > l#python.creating_packages: > > >>> import sounds > >>> import sounds.io > >>> import sounds.filters > >>> sound = sounds.io.open('file.mp3') > >>> new_sound = sounds.filters.echo(sound, 1.0) > > but, contrary to the example, by providing only a single sounds.pyd module. > The reason is that I'm wrapping a library that uses multiple namespaces and > I would like to expose these namespaces to Python. It's not possible though > to split the library into different compiled entities. > How can I do this using Boost.Python ? Boost.Python doesn't include support for what you want to do, but I think you can do it based on PyModule_New(): http://docs.python.org/api/moduleObjects.html#l2h-678 Caveat: I've never tried this myself. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From agross at irobot.com Fri Dec 9 05:33:37 2005 From: agross at irobot.com (Gross, Ashley) Date: Thu, 8 Dec 2005 23:33:37 -0500 Subject: [C++-sig] boost.python reference Message-ID: <712A2DEC228C7448978CBD7A7AD5B0900220EED7@fever.wardrobe.irobot.com> Does anyone know a good detailed reference for using boost.python? I've seen the tutorial on the boost website, and done some basic examples. But the code I'm trying to convert is very complex. Is there a better place to look? Ashley -------------- next part -------------- An HTML attachment was scrubbed... URL: From mjkeyes at sbcglobal.net Fri Dec 9 05:58:27 2005 From: mjkeyes at sbcglobal.net (Matt) Date: Thu, 8 Dec 2005 22:58:27 -0600 Subject: [C++-sig] Boost tuple example? References: <20051208165804.85014.qmail@web31514.mail.mud.yahoo.com> Message-ID: Basically, I'm wanting to be able to build a Python list object in C++ and pass it into Python. Similarly, I'd like to be able to receive one of these list objects back from Python and be able to extract values from it in C++. I'm sure this is a simple operation, and (since these are simple types) it looks like I can do the following (thanks Ralf for the pointer to the test directory): void SetValues(handle <> hObject) { object oObj(hObject); tuple Values("value 1", 2, 3.0); //call a python function to set the values, etc... in oObj } void GetValues(handle <>hObject) { object oObj(hObject); tuple oValues; //call Python function to retrieve a tuple object into oValues //not quite sure what this would look like - i know //tuple is an object, but should i try/catch a call to a python //function into a tuple variable? try { const char * szVal = extract(oValues[0]); int nVal = extract(oValues[1]); double nDblVal = extract(oValues[2]); } catch(...) { PyErr_Print(); } } Does that seem reasonable? Also, is there an easy way to determine the length of a tuple in C++? Thanks again you guys, Matt "David Abrahams" wrote in message news:uu0dj5qms.fsf at boost-consulting.com... > "Ralf W. Grosse-Kunstleve" writes: > >> --- Matt wrote: >> >>> Does anyone have an example of boost's use of tuples? For example, I am >>> wanting to construct tuples in C++ and pass them on to Python (these >>> will >>> consist of basic types (const char*'s, integers, etc.) or object values. >> >> Look in the file: >> >> boost/libs/python/test/tuple.cpp >> >> You can probably learn a lot of tricks by spending 30 minutes to scan >> through >> all the *.cpp files in the boost/libs/python/test directory. > > I read the OP as asking about how to translate boost::tuple, a > completely C++ generalization of std::pair (rather than > boost::python::tuple, a wrapper for native Python tuples) to/from > Python's tuples. > > Which is it? > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com From rwgk at yahoo.com Fri Dec 9 13:42:29 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 9 Dec 2005 04:42:29 -0800 (PST) Subject: [C++-sig] Boost tuple example? In-Reply-To: Message-ID: <20051209124229.13487.qmail@web31503.mail.mud.yahoo.com> --- Matt wrote: > void SetValues(handle <> hObject) > { > object oObj(hObject); I'd make this void SetValues(object& oObj) { > > tuple Values("value 1", 2, 3.0); Does this work? I was thinking you need tuple Values = make_tuple("value 1", 2, 3.0); but I am not sure. > //call a python function to set the values, etc... in oObj > } > > void GetValues(handle <>hObject) > { > object oObj(hObject); Same as above: void GetValues(object& oObj) { Or if you are expecting a tuple this may be even better: void GetValues(tuple oValues) > tuple oValues; > //call Python function to retrieve a tuple object into oValues > //not quite sure what this would look like - i know > //tuple is an object, but should i try/catch a call to a python > //function into a tuple variable? > > try > { I don't think it is advisable to use try + catch() here. Just let the exception propagate through to Python. > const char * szVal = extract(oValues[0]); > int nVal = extract(oValues[1]); > double nDblVal = extract(oValues[2]); I believe this works on most compilers, but not all. I always do it like this: const char * szVal = extract(oValues[0])(); I.e. with an additional "()" at the end. Similar for the two other extract<> statements. > } > catch(...) > { > PyErr_Print(); > } > } > > Does that seem reasonable? > > Also, is there an easy way to determine the length of a tuple in C++? David insisted on not giving us .size(), much to my dismay. Therefore you have to say: #include and then: boost::python::len(obj) David: I still believe we should add .size() to tuple, list, str. The current solution is a real productivity killer; you won't believe how much time I spent/wasted over the years digging out that silly include above again and again. Purity is not always a virtue. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From dave at boost-consulting.com Fri Dec 9 16:11:14 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 09 Dec 2005 10:11:14 -0500 Subject: [C++-sig] boost.python reference References: <712A2DEC228C7448978CBD7A7AD5B0900220EED7@fever.wardrobe.irobot.com> Message-ID: "Gross, Ashley" writes: > Does anyone know a good detailed reference for using boost.python? > I've seen the tutorial on the boost website, and done some basic > examples. But the code I'm trying to convert is very complex. Is > there a better place to look? http://www.boost.org/libs/python/doc/v2/reference.html -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Dec 9 16:19:28 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 09 Dec 2005 10:19:28 -0500 Subject: [C++-sig] Boost tuple example? References: <20051209124229.13487.qmail@web31503.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: >> tuple Values("value 1", 2, 3.0); > > Does this work? I was thinking you need > > tuple Values = make_tuple("value 1", 2, 3.0); > > but I am not sure. Ralf is right. >> try >> { > > I don't think it is advisable to use try + catch() here. Just let the exception > propagate through to Python. Ralf is right. >> const char * szVal = extract(oValues[0]); >> int nVal = extract(oValues[1]); >> double nDblVal = extract(oValues[2]); > > I believe this works on most compilers, but not all. I always do it like this: > > const char * szVal = extract(oValues[0])(); > > I.e. with an additional "()" at the end. Similar for the two other extract<> > statements. Ralf, I'm really surprised. AFAIK the only compilers that need that syntax are vc6/7, which IIUC your code doesn't support. >> } >> catch(...) >> { >> PyErr_Print(); >> } >> } >> >> Does that seem reasonable? >> >> Also, is there an easy way to determine the length of a tuple in C++? > > David insisted on not giving us .size(), much to my dismay. Therefore you have > to say: > > #include > > and then: > > boost::python::len(obj) > > David: I still believe we should add .size() to tuple, list, str. The current > solution is a real productivity killer; you won't believe how much time I > spent/wasted over the years digging out that silly include above again and > again. Purity is not always a virtue. You could go ahead and add it, but it's not going to work on boost::python::object (unless you add it there, which is *really* impure!) Wouldn't it be better just to make a single len function available in the same namespace as boost::python::object, and in the same header, so you can len(obj) without qualification? Seems more natural and broadly applicable to me. -- Dave Abrahams Boost Consulting www.boost-consulting.com From meine at kogs1.informatik.uni-hamburg.de Fri Dec 9 16:16:12 2005 From: meine at kogs1.informatik.uni-hamburg.de (Hans Meine) Date: Fri, 9 Dec 2005 16:16:12 +0100 Subject: [C++-sig] printf from an extension In-Reply-To: <6.0.1.1.2.20051208163819.01eeb458@mcantor.pobox.stanford.edu> References: <6.0.1.1.2.20051208163819.01eeb458@mcantor.pobox.stanford.edu> Message-ID: <200512091616.13205.meine@kogs.informatik.uni-hamburg.de> On Friday 09 December 2005 01:41, mike cantor wrote: > the "can print from in here phrase" does not reach python stdout. Is there > something screwy with my environment or is there some trick to this that I > don't know. Probably you're fooled by output buffering. Try appending \n . > static PyObject* > helloworld(PyObject* self) > { > printf("can print from in here?"); > return Py_BuildValue("s", "hello"); > } I'm using cerr/cout all the time. -- Ciao, / / /--/ / / ANS From beyer at fli-leibniz.de Fri Dec 9 17:25:51 2005 From: beyer at fli-leibniz.de (Andreas Beyer) Date: Fri, 09 Dec 2005 17:25:51 +0100 Subject: [C++-sig] printf from an extension In-Reply-To: <200512091616.13205.meine@kogs.informatik.uni-hamburg.de> References: <6.0.1.1.2.20051208163819.01eeb458@mcantor.pobox.stanford.edu> <200512091616.13205.meine@kogs.informatik.uni-hamburg.de> Message-ID: <4399B00F.10502@fli-leibniz.de> Hans Meine wrote: >On Friday 09 December 2005 01:41, mike cantor wrote: > > >>the "can print from in here phrase" does not reach python stdout. Is there >>something screwy with my environment or is there some trick to this that I >>don't know. >> >> >Probably you're fooled by output buffering. Try appending \n . > > > >>static PyObject* >>helloworld(PyObject* self) >>{ >> printf("can print from in here?"); >> return Py_BuildValue("s", "hello"); >>} >> >> > >I'm using cerr/cout all the time. > > > It also depends on the context where you call the function. If call from idle you won't see anything, because idle does not show the stdout output in its shell. If you call from the native python shell you should see something, at least after appending '\n'. (Or use fflush().) Andreas From rwgk at yahoo.com Sat Dec 10 03:20:04 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 9 Dec 2005 18:20:04 -0800 (PST) Subject: [C++-sig] Boost tuple example? In-Reply-To: Message-ID: <20051210022004.98193.qmail@web31515.mail.mud.yahoo.com> --- David Abrahams wrote: > Ralf, I'm really surprised. AFAIK the only compilers that need that > syntax are vc6/7, Could well be. I never tried out removing the (). It just stuck in my head for all the time that it is more robust with the (). > which IIUC your code doesn't support. Yes, true. I gave up on VC6 three years ago. > Wouldn't it be better just to make a single len function available in > the same namespace as boost::python::object, and in the same header, > so you can > > len(obj) > > without qualification? Seems more natural and broadly applicable to > me. Yes! I buy it in an instance, especially with the "in the same header file" provision. I put it on my list for the holiday break. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From roman.yakovenko at gmail.com Sun Dec 11 06:51:53 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 11 Dec 2005 07:51:53 +0200 Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject In-Reply-To: <20051207163548.20605.qmail@web2303.mail.yahoo.co.jp> References: <20051207163548.20605.qmail@web2303.mail.yahoo.co.jp> Message-ID: <7465b6170512102151q32609e67o950ca91d4806ab8f@mail.gmail.com> On 12/7/05, Shin-ichi MORITA wrote: > Hi all, > > I have a problem that returning a wrapper instance exposed > in the other module is not converted to its owner > PyObject. > > Then I wrote following test case. > > >>> class Derived1(module1.Derived): You are missing __init__ method. It is a must to call module1.Derived.__init__( self ) > ... def f(self): > ... return 2 > ... > > >>> b = Derived1() > > >>> module0.SetBase(b) > > >>> b is module0.GetBase() > True > > In the last line above, I expected that GetBase() returned > the PyObject which is identical to b. > But GetBase() returned a pointer holder of DerivedWrap > (Derived wrapper class). > > > > -------------------------------------- > STOP HIV/AIDS. > Yahoo! JAPAN Redribbon Campaign 2005 > http://pr.mail.yahoo.co.jp/redribbon/ > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > > > From roman.yakovenko at gmail.com Sun Dec 11 06:56:22 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 11 Dec 2005 07:56:22 +0200 Subject: [C++-sig] boost.python reference In-Reply-To: <712A2DEC228C7448978CBD7A7AD5B0900220EED7@fever.wardrobe.irobot.com> References: <712A2DEC228C7448978CBD7A7AD5B0900220EED7@fever.wardrobe.irobot.com> Message-ID: <7465b6170512102156v27ddfd53p4c0402d17d45d9a4@mail.gmail.com> On 12/9/05, Gross, Ashley wrote: > Does anyone know a good detailed reference for using boost.python? I've > seen the tutorial on the boost website, and done some basic examples. But > the code I'm trying to convert is very complex. Is there a better place to > look? You can take a look on pyplusplus examples: EasyBMP boost.date_time Qt.XML TnFOX http://sourceforge.net/projects/pygccxml/ > > Ashley > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > > From koen_van_herck at yahoo.com Mon Dec 12 14:20:25 2005 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Mon, 12 Dec 2005 14:20:25 +0100 Subject: [C++-sig] Return value policy for property Message-ID: Hello, I have a member function that I've wrapped as .def("getTime", &MyClass::getTime, return_value_policy()) Now I want to call the same function (getTime) as a Python property: .add_property("time", ???) How do I specify the 'manage_new_object' return value policy ? Regards, Koen Van Herck. From roman.yakovenko at gmail.com Mon Dec 12 14:36:22 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 12 Dec 2005 15:36:22 +0200 Subject: [C++-sig] Return value policy for property In-Reply-To: References: Message-ID: <7465b6170512120536tbc6d87brcc846d45ef1f9b54@mail.gmail.com> On 12/12/05, Koen Van Herck wrote: > Hello, > > I have a member function that I've wrapped as > .def("getTime", &MyClass::getTime, return_value_policy()) > > Now I want to call the same function (getTime) as a Python property: > .add_property("time", ???) > > How do I specify the 'manage_new_object' return value policy ? I think, that you can not do this, without modifying boost.python library. > Regards, > Koen Van Herck. > Roman Yakovenko From rwgk at yahoo.com Mon Dec 12 14:36:56 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 12 Dec 2005 05:36:56 -0800 (PST) Subject: [C++-sig] Return value policy for property In-Reply-To: Message-ID: <20051212133656.6833.qmail@web31511.mail.mud.yahoo.com> --- Koen Van Herck wrote: > I have a member function that I've wrapped as > .def("getTime", &MyClass::getTime, return_value_policy()) > > Now I want to call the same function (getTime) as a Python property: > .add_property("time", ???) > > How do I specify the 'manage_new_object' return value policy ? The trick is to use make_getter() and make_setter(). See the reference documentation or grep for make_getter in boost/libs/python/test to see some examples (you should get hits in properties.cpp and data_members.cpp). Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From koen_van_herck at yahoo.com Mon Dec 12 15:01:46 2005 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Mon, 12 Dec 2005 15:01:46 +0100 Subject: [C++-sig] Return value policy for property In-Reply-To: <20051212133656.6833.qmail@web31511.mail.mud.yahoo.com> Message-ID: --- Ralf wrote: > --- Koen Van Herck wrote: > > > I have a member function that I've wrapped as > > .def("getTime", &MyClass::getTime, > return_value_policy()) > > > > Now I want to call the same function (getTime) as a Python property: > > .add_property("time", ???) > > > > How do I specify the 'manage_new_object' return value policy ? > > The trick is to use make_getter() and make_setter(). See the reference > documentation or grep for make_getter in boost/libs/python/test > to see some > examples (you should get hits in properties.cpp and data_members.cpp). > I think this does the opposite of what I want. make_getter allows me to write 'x.time()' in Python which returns 'Myclass::time' data member. What I want is to write 'x.time' in Python which calls 'const Time *MyClass::getTime()', and takes ownership of the pointer. > Cheers, > Ralf > Regards, Koen. From shin1_morita at yahoo.co.jp Mon Dec 12 16:55:46 2005 From: shin1_morita at yahoo.co.jp (Shin-ichi MORITA) Date: Tue, 13 Dec 2005 00:55:46 +0900 (JST) Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject In-Reply-To: <7465b6170512102151q32609e67o950ca91d4806ab8f@mail.gmail.com> Message-ID: <20051212155546.92330.qmail@web2301.mail.yahoo.co.jp> Roman Yakovenko wrote: > You are missing __init__ method. It is a must to > call > module1.Derived.__init__( self ) I think that __init__() is implicitly called because __init__() is not overriden. In case that there is only one single module, everything is ok. My case has two modules: One exposes a function which signature contains a base class, the other exposes a derived class. Thanks. -------------------------------------- STOP HIV/AIDS. Yahoo! JAPAN Redribbon Campaign 2005 http://pr.mail.yahoo.co.jp/redribbon/ From jkankiewicz at advpubtech.com Mon Dec 12 16:54:36 2005 From: jkankiewicz at advpubtech.com (Jason Kankiewicz) Date: Mon, 12 Dec 2005 07:54:36 -0800 Subject: [C++-sig] Return value policy for property In-Reply-To: References: Message-ID: This type of construct works for me: .add_property( "Time" , make_function( &MyClass::getTime , return_value_policy() ) ) Koen Van Herck wrote: > Hello, > > I have a member function that I've wrapped as > .def("getTime", &MyClass::getTime, return_value_policy()) > > Now I want to call the same function (getTime) as a Python property: > .add_property("time", ???) > > How do I specify the 'manage_new_object' return value policy ? > > Regards, > Koen Van Herck. From davidhuebel at gmail.com Tue Dec 13 06:25:15 2005 From: davidhuebel at gmail.com (David Huebel) Date: Mon, 12 Dec 2005 23:25:15 -0600 Subject: [C++-sig] Compile error with tutorial Message-ID: <50c6b7b60512122125g4738a39dt40d413c70d4dc403@mail.gmail.com> Hi, I'm just getting started with Boost Python, using boost_1_32_0. The following code (which should look familiar) compiles and runs just fine: char const* greet() { return "hello, world"; } #include /* struct World { void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } std::string msg; }; */ #include #include using namespace boost::python; BOOST_PYTHON_MODULE(hello) { def("greet", greet); /* class_("World") .def("greet", &World::greet) .def("set", &World::set) ; */ } When I uncomment the two sections referring to World, I get the following compile error: ...found 652 targets... ...updating 2 targets... gcc-C++-action bin/tutorial/hello.so/gcc/debug/shared-linkable-true/hello.o hello.cpp: In function `void init_module_hello()': hello.cpp:26: wrong number of template arguments (1, should be 4) /home/cdt/lib/boost_1_32_0/boost/python/def_visitor.hpp:14: provided for ` template struct boost::python::class_ ' set -e "g++" -c -Wall -ftemplate-depth-255 -DBOOST_PYTHON_DYNAMIC_LIB -g -O0 -fno-inline -fPIC -I"bin/tutorial" -I "/usr/include/python2.2" -I "/home/cdt/lib/boost_1_32_0" -o "bin/tutorial/hello.so/gcc/debug/shared-linkable-true/hello.o" "hello.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "bin/tutorial/hello.so/gcc/debug/shared-linkable-true/hello.o" ...failed gcc-C++-action bin/tutorial/hello.so/gcc/debug/shared-linkable-true/hello.o... ...removing bin/tutorial/hello.so/gcc/debug/shared-linkable-true/hello.o ...skipped <@tutorial/hello.so/gcc/debug/shared-linkable-true>hello.so for lack of <@tutorial/hello.so/gcc/debug/shared-linkable-true>hello.o... ...failed updating 1 target... ...skipped 1 target... Line 26 is the line containing class_. I'm using gcc 3.2.3 and python 2.2.3 on Linux. What am I doing wrong? As an aside, I found it very difficult to figure out how to build extensions outside the Boost build tree and then how to build an extension based on a separately compiled object. My problem was that I started with no knowledge of Jam and no idea how much Jam I should learn before tackling Boost Python. I think it would be a good addition to the tutorial to recommend learning the Jam syntax and the basic Jambase rules for linking C++ projects before attempting to deviate from the tutorial build setup. Thanks, David Huebel From dave at boost-consulting.com Tue Dec 13 17:56:54 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 11:56:54 -0500 Subject: [C++-sig] Return value policy for property References: <20051212133656.6833.qmail@web31511.mail.mud.yahoo.com> Message-ID: "Koen Van Herck" writes: > --- Ralf wrote: >> --- Koen Van Herck wrote: >> >> > I have a member function that I've wrapped as >> > .def("getTime", &MyClass::getTime, >> return_value_policy()) >> > >> > Now I want to call the same function (getTime) as a Python property: >> > .add_property("time", ???) >> > >> > How do I specify the 'manage_new_object' return value policy ? >> >> The trick is to use make_getter() and make_setter(). See the reference >> documentation or grep for make_getter in boost/libs/python/test >> to see some >> examples (you should get hits in properties.cpp and data_members.cpp). >> > I think this does the opposite of what I want. make_getter allows me to > write 'x.time()' in Python which returns 'Myclass::time' data member. > What I want is to write 'x.time' in Python which calls 'const Time > *MyClass::getTime()', and takes ownership of the pointer. .add_property( "time" , make_function( &MyClass::getTime , return_value_policy() ) ) HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Dec 13 18:03:15 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 12:03:15 -0500 Subject: [C++-sig] How to create package structure in single extension module References: Message-ID: "Koen Van Herck" writes: > Hello, > > I would like to do something similar as the example in > http://www.boost.org/libs/python/doc/tutorial/doc/html/python/techniques.htm > l#python.creating_packages: > >>>> import sounds >>>> import sounds.io >>>> import sounds.filters >>>> sound = sounds.io.open('file.mp3') >>>> new_sound = sounds.filters.echo(sound, 1.0) > > but, contrary to the example, by providing only a single sounds.pyd module. > The reason is that I'm wrapping a library that uses multiple namespaces and > I would like to expose these namespaces to Python. It's not possible though > to split the library into different compiled entities. > How can I do this using Boost.Python ? Use the Python 'C' API to create module objects for io and filters, and then stick them in the scope of your sounds module as follows: scope().attr("io") = io; scope().attr("filters") = filters; And then you can go on to wrap things in those modules via: scope io_scope = io; class_("whatever") ... ; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Dec 13 17:57:31 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 11:57:31 -0500 Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject References: <7465b6170512102151q32609e67o950ca91d4806ab8f@mail.gmail.com> <20051212155546.92330.qmail@web2301.mail.yahoo.co.jp> Message-ID: Shin-ichi MORITA writes: > Roman Yakovenko wrote: >> You are missing __init__ method. It is a must to >> call >> module1.Derived.__init__( self ) > > I think that __init__() is implicitly called because > __init__() is not overriden. It is not. Listen to Roman. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Dec 13 19:03:21 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 13:03:21 -0500 Subject: [C++-sig] Compile error with tutorial References: <50c6b7b60512122125g4738a39dt40d413c70d4dc403@mail.gmail.com> Message-ID: David Huebel writes: > Hi, > > I'm just getting started with Boost Python, using boost_1_32_0. The > following code (which should look familiar) compiles and runs just > fine: > > char const* greet() > { > return "hello, world"; > } > > #include > > /* > struct World > { > > void set(std::string msg) { this->msg = msg; } > std::string greet() { return msg; } > std::string msg; > }; > */ > > #include > #include > using namespace boost::python; > > BOOST_PYTHON_MODULE(hello) > { > def("greet", greet); > /* > class_("World") > .def("greet", &World::greet) > .def("set", &World::set) > ; > */ > } It's missing #include -- Dave Abrahams Boost Consulting www.boost-consulting.com From davidhuebel at gmail.com Tue Dec 13 21:00:20 2005 From: davidhuebel at gmail.com (David Huebel) Date: Tue, 13 Dec 2005 14:00:20 -0600 Subject: [C++-sig] Compile error with tutorial In-Reply-To: References: <50c6b7b60512122125g4738a39dt40d413c70d4dc403@mail.gmail.com> Message-ID: <50c6b7b60512131200o1ccb1fb1wb3ed62a5b5dbbc5f@mail.gmail.com> On 12/13/05, David Abrahams wrote: > It's missing > > #include Ah! Finding the wrong class_ sent me off on the wrong track. This fixes both the example I submitted and the problem I based the example on; thanks! David Huebel From amohr at pixar.com Tue Dec 13 20:37:25 2005 From: amohr at pixar.com (Alex Mohr) Date: Tue, 13 Dec 2005 11:37:25 -0800 Subject: [C++-sig] Can't use make_function to wrap base class method? Message-ID: <439F22F5.6060303@pixar.com> Seems I can't wrap a base class method of a derived class if I use make_function. Is this expected? Here's an example. #include using namespace boost::python; class Base { public: int method() { return 1; } }; class Derived : public Base {}; BOOST_PYTHON_MODULE(Foo) { class_("Derived", "", init<>()) .def("method", make_function(&Derived::method)) .def("method2", &Derived::method) ; } >>> from Foo import * >>> Derived().method() Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in Derived.method(Derived) did not match C++ signature: method(Base {lvalue}) >>> Derived().method2() 1 Seems like this should work. Wrapping a method in make_function seems to make it not. This becomes cumbersome since the only way I know of to supply return_value_policies in .add_property is to use make_function. Thanks, Alex From JasonR at rainbowstudios.com Tue Dec 13 22:09:09 2005 From: JasonR at rainbowstudios.com (Jason Rego) Date: Tue, 13 Dec 2005 14:09:09 -0700 Subject: [C++-sig] python in console game development? Message-ID: <20FBBBCACA21D511B5C400B0D017706A03BC0745@TELETYPE> I'm interested in using python in some of our console games for scripting, etc. Has boost.python been used in console development? What platforms (xbox, ps2, xbox 360, ps3, etc.)? What are the licensing issues with boost python in commercial products? I see Civ4 has used it. Also if this is not the right solution for python integration in console development, would you suggest an alternative? Thanks for your help and assistance. /* Jason Rego Software Engineer Rainbow Studios jasonr at rainbowstudios.com */ -------------- next part -------------- An HTML attachment was scrubbed... URL: From amohr at pixar.com Tue Dec 13 22:36:27 2005 From: amohr at pixar.com (Alex Mohr) Date: Tue, 13 Dec 2005 13:36:27 -0800 Subject: [C++-sig] Determine C++ type held by object? Message-ID: <439F3EDB.4030903@pixar.com> extract() is awesome for getting C++ objects out of python objects. However, extract goes through the converters. I would like a way to determine whether an object is holding a particular C++ type without going through converters. Anyone know of a way to do this? For those interested, here's why I would like it: I am wrapping a boost::any-like object. 1. I want 'any' objects in python that are passed as arguments to wrapped C++ functions to convert to their held type if necessary. I have this working just fine with a custom converter. Call this converter #1. 2. I want to be able to call wrapped C++ functions that take 'any' objects with arbitrary python objects. That is, I want objects of all types to convert to 'any'. I have attempted to write this converter. Call it converter #2. Here's the problem. In #1's convertible() function, I have to check if the python object is holding an 'any', and if so, get it out and check if the type it's holding is a match. I use extract for this. However, #1's call to extract invokes converter #2. Converter #2 *always* says it can convert to 'any', and it does so by actually constructing an 'any' object holding what it was given. Unfortunately, this invokes converter #1 again during the 'any' constructor. Since #1 tries to extract from what it was passed, we get back into converter #2. To infinity and beyond. I can actually fix this by having converter #1 set a flag during its operation indicating that it, in fact, is trying to extract. Then converter #2 checks this flag and returns 0 in convertible() if it is set. This works, but is not very satisfying. Anyway, if I had the ability to ask if a python object was holding a particular wrapped C++ type (my 'any') without going through converters, then in converter #1 I could just check that and only convert in that case. Thanks, Alex From dave at boost-consulting.com Tue Dec 13 23:17:09 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 17:17:09 -0500 Subject: [C++-sig] Can't use make_function to wrap base class method? References: <439F22F5.6060303@pixar.com> Message-ID: Alex Mohr writes: > Seems I can't wrap a base class method of a derived class if I use > make_function. Is this expected? Here's an example. > > #include > using namespace boost::python; > > class Base { > public: > int method() { return 1; } > }; > > class Derived : public Base {}; > > BOOST_PYTHON_MODULE(Foo) { > class_("Derived", "", init<>()) > .def("method", make_function(&Derived::method)) > .def("method2", &Derived::method) > ; > } > > >>> from Foo import * > >>> Derived().method() > Traceback (most recent call last): > File "", line 1, in ? > Boost.Python.ArgumentError: Python argument types in > Derived.method(Derived) > did not match C++ signature: > method(Base {lvalue}) > > >>> Derived().method2() > 1 > > Seems like this should work. Wrapping a method in make_function > seems to make it not. This becomes cumbersome since the only way I > know of to supply return_value_policies in .add_property is to use > make_function. You either need to wrap Base or you need to .def( "method", make_function( (int (Derived::*)()) &Derived::method ) ) class_ has the information about the derived class (it's a template argument), so it can do the cast automagically. However, make_function is just a function, so it can't do anything fancy with Derived. The function pointer's type is int (Base::*)() even when you get it via &Derived::method. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Dec 13 23:21:20 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 13 Dec 2005 17:21:20 -0500 Subject: [C++-sig] Determine C++ type held by object? References: <439F3EDB.4030903@pixar.com> Message-ID: Alex Mohr writes: > extract() is awesome for getting C++ objects out of python objects. > However, extract goes through the converters. I would like a way to > determine whether an object is holding a particular C++ type without > going through converters. What do you mean by "going through converters," and why do you want to avoid it? > Anyone know of a way to do this? > > > For those interested, here's why I would like it: > > I am wrapping a boost::any-like object. > > 1. I want 'any' objects in python that are passed as arguments to > wrapped C++ functions to convert to their held type if necessary. I > have this working just fine with a custom converter. Call this > converter #1. > > 2. I want to be able to call wrapped C++ functions that take 'any' > objects with arbitrary python objects. That is, I want objects of all > types to convert to 'any'. I have attempted to write this converter. > Call it converter #2. > > Here's the problem. In #1's convertible() function, I have to check if > the python object is holding an 'any', and if so, get it out and check > if the type it's holding is a match. I use extract for this. > > However, #1's call to extract invokes converter #2. Converter #2 > *always* says it can convert to 'any', and it does so by actually > constructing an 'any' object holding what it was given. Why? You only need to check the convertible function. That would be extract().check() -- Dave Abrahams Boost Consulting www.boost-consulting.com From dueymk at everestkc.net Tue Dec 13 23:46:35 2005 From: dueymk at everestkc.net (dueymk) Date: Tue, 13 Dec 2005 16:46:35 -0600 Subject: [C++-sig] Pointer concept help Message-ID: <439F4F4B.2040901@everestkc.net> I've been reading docs and googling for 2 days trying to find an answer. With the following C++ definitions: struct MyStruct1 { int sample1; int sample2; } struct MyStruct2 { int first; char second; MyStruct1 *child; }; class MyClass { MyStruct2 *CreateStruct() { MyStruct2 *returnValue = new MyStruct2; returnValue->child = new MyStruct1; return returnValue; }; } I'd like to call 'CreateStruct' from Python and access the fields of the actual object that was created in 'CreateStruct', not a copy local to Python. Can I do that and how? Also, can I get access to the structure pointed to by the 'child' field? Thanks, Jim From roman.yakovenko at gmail.com Wed Dec 14 12:28:28 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Dec 2005 13:28:28 +0200 Subject: [C++-sig] Pointer concept help In-Reply-To: <439F4F4B.2040901@everestkc.net> References: <439F4F4B.2040901@everestkc.net> Message-ID: <7465b6170512140328n3ce28604s9514896f18277469@mail.gmail.com> On 12/14/05, dueymk wrote: > I've been reading docs and googling for 2 days trying to find an answer. > > With the following C++ definitions: > > struct MyStruct1 { > int sample1; > int sample2; > } > > struct MyStruct2 { > int first; > char second; > MyStruct1 *child; > }; > > class MyClass > { > MyStruct2 *CreateStruct() You'd better use std::auto_ptr, this will allow you to not specify call policies. > { > MyStruct2 *returnValue = new MyStruct2; > returnValue->child = new MyStruct1; > return returnValue; > }; > } > > I'd like to call 'CreateStruct' from Python and access the fields of the actual object that was created in 'CreateStruct', not a copy local to Python. Can I do that and how? What do you mean "access the fields of the actual object that was created in 'CreateStruct', not a copy local to Python." ? > > Also, can I get access to the structure pointed to by the 'child' field? Yes. You should expose MyStruct1 and MyStruct2 Next code hase been created by pyplusplus for your code: // std directories: [] // user defined directories: ['c:\\temp'] #include "boost/python.hpp" #include "x.h " namespace bp = boost::python; BOOST_PYTHON_MODULE(pyplusplus){ bp::class_< MyClass >( "MyClass" ) .def( "CreateStruct" , (::std::auto_ptr ( ::MyClass::* )( ) )(&MyClass::CreateStruct) , bp::default_call_policies() ); bp::class_< MyStruct2 >( "MyStruct2" ) .def_readwrite( "first", &MyStruct2::first ) .def_readwrite( "second", &MyStruct2::second ) .def_readwrite( "child", &MyStruct2::child ); bp::register_ptr_to_python< std::auto_ptr< MyStruct2 > >(); bp::class_< MyStruct1 >( "MyStruct1" ) .def_readwrite( "sample1", &MyStruct1::sample1 ) .def_readwrite( "sample2", &MyStruct1::sample2 ); } > Thanks, > Jim Roman Yakovenko From jeremy at alum.mit.edu Wed Dec 14 16:57:13 2005 From: jeremy at alum.mit.edu (Jeremy Hylton) Date: Wed, 14 Dec 2005 10:57:13 -0500 Subject: [C++-sig] working around the non-const Python C API In-Reply-To: References: Message-ID: I thought I'd let folks in C++ land know that I did make some improvements on the Python trunk. I updated all of the functions that commonly take string literals in extension modules -- PyMethodDef, the string tp slots of a type object, PyArg_ParseTuple and friends, Py_BuildValue, and PyObject_GetAttrString() and friends. Jeremy On 12/2/05, Jeremy Hylton wrote: > I was curious if anyone had advice on how to work around the fact that > much of the Python C API asks for char* when it really intends to > treat it as a const char*. An example of this behavior is the > PyMethodDef struct, which has char* ml_name and char* ml_doc > parameters. If you use a string literal, you get a warning about > casting a const char* to a char*. I can add a cast around each > literal, but that's really ugly. > > Is there a good way to avoid the warnings? > > Secondarily, I know that python-dev is a bit hesitant about const > correctness, but we did get some const char* types added with the new > bytecode compiler. Perhaps it's worthwhile to try changing a few of > the most egregious cases to use const char*. > > Jeremy > From mikeowen at llnl.gov Wed Dec 14 19:46:57 2005 From: mikeowen at llnl.gov (J. Michael Owen) Date: Wed, 14 Dec 2005 10:46:57 -0800 Subject: [C++-sig] Patch to build release 1.33.1 with g++ on AIX Message-ID: <8c698d45efa5bca111834a44cdc5dea4@llnl.gov> In order to build Boost.Python (most of boost actually) with g++ on AIX, it is necessary to patch tools/build/v1/gcc-tools.jam, adding some additional LINKFLAGS . Here is the patch that I find works: @@ -144,6 +144,11 @@ { # gcc on HP-UX does not support multi-threading, don't set anything here } + case AIX : + { + flags gcc LINKFLAGS : -lpthreads -Wl,-bexpall -Wl,-G -Wl,-brtl ; + # there is no -lrt on AIX? + } case QNX* : { # gcc/QCC on QNX is always? in multi-thread mode, don't set anything here I have verified this works on AIX 5.2 using g++ 3.4.3. I don't have to generate the crazy AIX import/export files anymore with the above set off magic linker flags, but you have to make sure and build your own Python extension shared libraries with the "-shared -Wl,-G -Wl,-brtl" flags as well. Just in case anyone else out there needs to do this... Mike. "Hey...where are the sunflower seeds?" | J. Michael Owen o_o / | (") | \/'\/ | ____(__(,_,)____________________________________________________________ ___ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 1310 bytes Desc: not available URL: From mikeowen at llnl.gov Wed Dec 14 22:34:36 2005 From: mikeowen at llnl.gov (J. Michael Owen) Date: Wed, 14 Dec 2005 13:34:36 -0800 Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS X? Message-ID: I am having problems compiling a piece of code using Boost.Python on Mac OS X (v10.3.9, using Apple g++ v3.3), even though this code compiles fine on several other platforms. Here is a standalone example that produces the problem: #include #include "boost/python.hpp" using namespace boost::python; / /----------------------------------------------------------------------- ------- // Template for wrapping pairs. / /----------------------------------------------------------------------- ------- template inline void wrapPairType(const char* name) { class_ >(name, init<>()) .def(init()) .def_readwrite("first", &std::pair::first) .def_readwrite("second", &std::pair::second) .def(self == self) .def(self != self) ; } / /----------------------------------------------------------------------- ------- // Define the module. / /----------------------------------------------------------------------- ------- BOOST_PYTHON_MODULE(Pair) { wrapPairType("pair_double_double"); wrapPairType("pair_double_string"); } The problem occurs with the attempt to wrap pair, which generates the following errors: /Volumes/Spheral-main/debug/include/boost/python/object/ inheritance.hpp:73: instantiated from `void boost::python::objects::register_dynamic_id(T*) [with T = std::pair]' /Volumes/Spheral-main/debug/include/boost/python/object/ class_metadata.hpp:97: instantiated from `void boost::python::objects::register_shared_ptr_from_python_and_casts(T*, Bases) [with T = std::pair, Bases = boost::python::bases]' /Volumes/Spheral-main/debug/include/boost/python/object/ class_metadata.hpp:225: instantiated from `static void boost::python::objects::class_metadata::register_aux2(T2*, Callback) [with T2 = std::pair, Callback = boost::integral_constant, T = std::pair, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /Volumes/Spheral-main/debug/include/boost/python/object/ class_metadata.hpp:219: instantiated from `static void boost::python::objects::class_metadata::register_aux(void*) [with T = std::pair, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /Volumes/Spheral-main/debug/include/boost/python/object/ class_metadata.hpp:205: instantiated from `static void boost::python::objects::class_metadata::register_() [with T = std::pair, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /Volumes/Spheral-main/debug/include/boost/python/class.hpp:496: instantiated from `void boost::python::class_::initialize(const DefVisitor&) [with DefVisitor = boost::python::init_base >, W = std::pair, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /Volumes/Spheral-main/debug/include/boost/python/class.hpp:208: instantiated from `boost::python::class_::class_(const char*, const boost::python::init_base&) [with DerivedT = boost::python::init, W = std::pair, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' Pair.cc:12: instantiated from `void wrapPairType(const char*) [with A = double, B = std::string]' Pair.cc:26: instantiated from here /Volumes/Spheral-main/debug/include/boost/python/object/ inheritance.hpp:43: error: cannot dynamic_cast `p' (of type `struct std::pair*') to type `void*' (source type is not polymorphic) make: *** [Pair.o] Error 1 It looks to me like for some reason the method that dispatches this call (dynamic_id_generator?) is sending this code down the wrong branch, perhaps because boost::is_polymorphic is somehow being fooled? Does anyone have any suggestions to remedy this? Mike. "Hey...where are the sunflower seeds?" | J. Michael Owen o_o / | (") | \/'\/ | ____(__(,_,)____________________________________________________________ ___ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 5217 bytes Desc: not available URL: From rwgk at yahoo.com Thu Dec 15 00:08:30 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 14 Dec 2005 15:08:30 -0800 (PST) Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS X? In-Reply-To: Message-ID: <20051214230830.62397.qmail@web31509.mail.mud.yahoo.com> Hi Mike, It is a bogus error message I have been struggling with for some time. Here is one of my typical workarounds: class something { // lots of code... private: #if defined(__APPLE__) && defined(__MACH__) \ && defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3 bool dummy_; #endif uctbx::unit_cell unit_cell_; fractional<> original_site_; const wyckoff::position* position_; rt_mx sym_op_; }; I.e. simply adding a dummy bool as a member is typically enough to make the compiler happy. I've not been able to figure out what exactly causes the bogus error message. If anyone knows I'd be glad to learn about it. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From mikeowen at llnl.gov Thu Dec 15 02:05:14 2005 From: mikeowen at llnl.gov (J. Michael Owen) Date: Wed, 14 Dec 2005 17:05:14 -0800 Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS Message-ID: Hi Ralf, Sadly the type I'm exposing is the std::pair, so I can't just modify its source in this way. I'm going to have to work around this problem by altering my code to not use std::pair. It turns out that std::pair works without a problem. ?? I notice your compiler guards only screen out Apple's gcc 3.3 version -- does that mean that the newer gcc you can get with OS X 10.4 does not have this issue? Thanks Ralf! Mike. > Hi Mike, > > It is a bogus error message I have been struggling with for some time. > Here is > one of my typical workarounds: > > class something > { > // lots of code... > private: > #if defined(__APPLE__) && defined(__MACH__) \ > && defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3 > bool dummy_; > #endif > uctbx::unit_cell unit_cell_; > fractional<> original_site_; > const wyckoff::position* position_; > rt_mx sym_op_; > }; > > I.e. simply adding a dummy bool as a member is typically enough to > make the > compiler happy. I've not been able to figure out what exactly causes > the bogus > error message. If anyone knows I'd be glad to learn about it. > > Cheers, > Ralf "Hey...where are the sunflower seeds?" | J. Michael Owen o_o / | (") | \/'\/ | ____(__(,_,)____________________________________________________________ ___ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 1617 bytes Desc: not available URL: From francescoqueirolo at yahoo.com Thu Dec 15 02:01:02 2005 From: francescoqueirolo at yahoo.com (Francesco Queirolo) Date: Wed, 14 Dec 2005 17:01:02 -0800 (PST) Subject: [C++-sig] jamfile vs. jamrule vs. boost-build.jam Message-ID: <20051215010102.84914.qmail@web60716.mail.yahoo.com> Greetings All, I have done some web searching (http://www.boost.org/tools/build/jam_src/ etc), and also searching the list via Gmane and could not find a satisfactory result to the following questions?: When should you edit the boost-build.jam instead of jamrules? Do you need a jamrules in the root directory of every project? You just need a boost-build.jam in the root directory of your project or somewhere further up the hierarch? What are the purposes of the three different files? Is the jamfile to specify depencies and what the target executable is? Is the jamrules file only for setting parameters such as TOOLS and PYTHON_ROOT so they don't have to be entered every time on the command line? Is the only reason to have a boost-build.jam to point to tools/build/v1 subdirectory? If someone could point me to another reference to answer these questions or answer them outright I would greatly appreciate it. Thank you, Francesco Queirolo --------------------------------- Yahoo! Shopping Find Great Deals on Holiday Gifts at Yahoo! Shopping -------------- next part -------------- An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Thu Dec 15 03:59:58 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 14 Dec 2005 18:59:58 -0800 (PST) Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS In-Reply-To: Message-ID: <20051215025958.18719.qmail@web31511.mail.mud.yahoo.com> --- "J. Michael Owen" wrote: > I notice your compiler guards only screen out Apple's gcc 3.3 version > -- does that mean that the newer gcc you can get with OS X 10.4 does > not have this issue? I checked all our relevant #ifdef's. All are specific to gcc 3.3. I know our code compiled under 10.4 a couple of months ago. I.e. it looks like the problem is solved under 10.4. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From dave at boost-consulting.com Thu Dec 15 05:22:52 2005 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 14 Dec 2005 23:22:52 -0500 Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS References: Message-ID: "J. Michael Owen" writes: > Hi Ralf, > > Sadly the type I'm exposing is the std::pair, so I can't just modify > its source in this way. I'm going to have to work around this problem > by altering my code to not use std::pair. It turns > out that std::pair works without a problem. ?? > > I notice your compiler guards only screen out Apple's gcc 3.3 version > -- does that mean that the newer gcc you can get with OS X 10.4 does > not have this issue? namespace boost { template struct is_polymorphic > : mpl::false_ {}; } Is probably the cleanest workaround. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Thu Dec 15 05:26:45 2005 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 14 Dec 2005 23:26:45 -0500 Subject: [C++-sig] jamfile vs. jamrule vs. boost-build.jam References: <20051215010102.84914.qmail@web60716.mail.yahoo.com> Message-ID: Francesco Queirolo writes: Francesco, you're in the wrong list. Try http://www.boost.org/more/mailing_lists.htm#jamboost > Greetings All, > > I have done some web searching (http://www.boost.org/tools/build/jam_src/ > etc), and also searching the list via Gmane and could not find a > satisfactory result to the following questions?: > > When should you edit the boost-build.jam The former points to the Boost.Build installation > instead of jamrules? The latter contains whatever definitions you need locally to your project. > Do you need a jamrules in the root directory of every project? Yes. > You just need a boost-build.jam in the root directory of your project or > somewhere further up the hierarch? Further up is fine. I put one above all my projects. > What are the purposes of the three different files? Three? > Is the jamfile to specify depencies and what the target executable > is? Yes. > Is > the jamrules file only for setting parameters such as TOOLS and > PYTHON_ROOT so they don't have to be entered every time on the > command line? Stuff like that, yeah. > Is the only reason to have a boost-build.jam to point to tools/build/v1 > subdirectory? Yeah. > If someone could point me to another reference to answer these questions > or answer them outright I would greatly appreciate it. http://www.boost.org/tools/build -- Dave Abrahams Boost Consulting www.boost-consulting.com From shin1_morita at yahoo.co.jp Thu Dec 15 18:04:08 2005 From: shin1_morita at yahoo.co.jp (Shin-ichi MORITA) Date: Fri, 16 Dec 2005 02:04:08 +0900 (JST) Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject In-Reply-To: Message-ID: <20051215170408.63262.qmail@web2305.mail.yahoo.co.jp> Hi David and Roman, I'm confused! You say "If you override __init__(), you must call module1.Derived.__init__()", don't you? But I do NOT override __init__() here. Again... everything is ok except for module1. Please check out "test_owner.tar.bz2" which I sent before. Anyway, my concern is "boost::python::detail::wrapper_base should be polymorphic? (or should have virtual destructor?)". Thanks. David Abrahams wrote: > > I think that __init__() is implicitly called > because > > __init__() is not overriden. > > It is not. Listen to Roman. -------------------------------------- STOP HIV/AIDS. Yahoo! JAPAN Redribbon Campaign 2005 http://pr.mail.yahoo.co.jp/redribbon/ From amohr at pixar.com Thu Dec 15 19:49:58 2005 From: amohr at pixar.com (Alex Mohr) Date: Thu, 15 Dec 2005 10:49:58 -0800 Subject: [C++-sig] Determine C++ type held by object? In-Reply-To: References: <439F3EDB.4030903@pixar.com> Message-ID: <43A1BAD6.3070201@pixar.com> >>extract() is awesome for getting C++ objects out of python objects. >>However, extract goes through the converters. I would like a way to >>determine whether an object is holding a particular C++ type without >>going through converters. > > What do you mean by "going through converters," and why do you want to > avoid it? Thanks for looking at this. Let me try to be a bit clearer. I will give some pseudocode which gives a sense of what the converters do. Then I will walk through a scenario which causes the infinite recursion. ---- Converter #1 -- Registered once for each of a set of types. Tries to convert any-holding-T to T. convertible(obj_ptr) { // Is obj_ptr holding an any, and is that any holding a T? if (extract(obj_ptr).check() and extract(obj_ptr)().isHolding()) { // Okay! can convert to T. return obj_ptr; } // Can't convert to T. return 0; } ---- Converter #2 -- Registered once for 'any'. Converts *anything* to 'any'. convertible(obj_ptr) { // Yes! can always convert to 'any'. return obj_ptr; } construct(obj_ptr, ...) { object anyObj = anyClassWrapper(obj_ptr); new (storage) any(extract(anyObj)); } ---- Given: T is a type for which Converter #1 has been registered. - I call a function which takes T, but I call it with something of a different type. Say Ellipsis. Converter #1's convertible() is invoked to try to produce a T. Converter #1 wants to know if it has an any-holding-T, so it does an extract(obj_ptr).check(). This invokes Converter #2 since it is registered to provide conversions to 'any'. Converter #2 can produce an any from *anything*, so its convertible() returns "true" and its construct() gets called. Construct() invokes the 'any' constructor, passing it the Ellipsis. Now resolution for the 'any' constructors occurs. Suppose the first signature it finds is for any(T). We already know that there's a Converter #1 registered for T, so that gets invoked. Again, it tries to determine if it's got an any-holding-T by calling extract(obj_ptr).check(), which invokes Converter #2 which again tries to create an any from the obj_ptr. And the cycle repeats, and repeats, and repeats. I claim that if I could, in Converter #1, check whether obj_ptr explicitly has an any (not whether there's some other converter than can produce an any from it), then this basic structure would work. In fact, the way I'm solving this now is to have a flag which gets set inside Converter #1 which effectively disables Converter #2. But like I said, that's sort of dissatisfying. >>However, #1's call to extract invokes converter #2. Converter #2 >>*always* says it can convert to 'any', and it does so by actually >>constructing an 'any' object holding what it was given. > > Why? You only need to check the convertible function. That would be > > extract().check() I'm not sure what you mean by, "You only need to check the convertible function." I am using extract(obj_ptr).check() in Converter #1, but this invokes Converter #2, which always says, "Yes I can make an any for you," and therefore is called to make one, which ends up getting back into Converter #1, which calls extract and gets back into #2, and so on. Thanks for the help! Alex From amohr at pixar.com Thu Dec 15 19:58:37 2005 From: amohr at pixar.com (Alex Mohr) Date: Thu, 15 Dec 2005 10:58:37 -0800 Subject: [C++-sig] Can't use make_function to wrap base class method? In-Reply-To: References: <439F22F5.6060303@pixar.com> Message-ID: <43A1BCDD.9070407@pixar.com> > You either need to wrap Base or you need to > > .def( > "method", > make_function( > (int (Derived::*)()) &Derived::method > ) > ) > > class_ has the information about the derived class (it's a template > argument), so it can do the cast automagically. However, > make_function is just a function, so it can't do anything fancy with > Derived. The function pointer's type is > > int (Base::*)() > > even when you get it via &Derived::method. Ahh, that makes perfect sense. Thanks! Does it make sense to add something like: make_method(&Derived::method) Which would just call make_function with the appropriate cast? Perhaps I could give it a shot if it seems like a good idea. Or perhaps it would be better to have a form of make_function like this? Alex From mikeowen at llnl.gov Thu Dec 15 20:28:58 2005 From: mikeowen at llnl.gov (J. Michael Owen) Date: Thu, 15 Dec 2005 11:28:58 -0800 Subject: [C++-sig] Problem with identifying polymorphic types on Mac OS Message-ID: <1e5d3b2b2869b35d70522a76f17bce8a@llnl.gov> Indeed, this fixes my problem very nicely without having to modify the C++ code. Thank you very much Dave! Mike. > namespace boost > { > template > struct is_polymorphic > > : mpl::false_ > {}; > } > > Is probably the cleanest workaround. > > HTH, > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com "Hey...where are the sunflower seeds?" | J. Michael Owen o_o / | (") | \/'\/ | ____(__(,_,)____________________________________________________________ ___ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 868 bytes Desc: not available URL: From dueymk at everestkc.net Fri Dec 16 20:36:34 2005 From: dueymk at everestkc.net (dueymk) Date: Fri, 16 Dec 2005 13:36:34 -0600 Subject: [C++-sig] Thread safety Message-ID: <43A31742.3020608@everestkc.net> Hi, I'm wrapping a multi-threaded C++ dll with Boost.Python. A thread is created when a wrapped structure is subclassed and instantiated in Python. This thread spends most of it's time in C++ but calls a virtual function which may be overridden by the Python subclass. I've done the following: class Original { int counter; virtual bool Process(int *count) { *count++; return true; } } struct PythonOriginal : Original, wrapper { bool Process(int *count) { if (override Process = this->get_override("Process")) { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); bool answer = call(Process.ptr(), boost::ref(count)); PyGILState_Release(gstate); return answer; } else return Original::Process(count); } bool default_Process(int *count) { return this->PleoraCamera::ProcessFrame(count); } } BOOST_PYTHON_MODULE(PythonOriginal) { class_("Original") .def("Process", &Original::Process, &PythonOriginal::default_Process) ; } Then in Python: class PyOrig(Original): def Process(self, count): count = count + 10 return True orig = PyOrig() The only thing I did for thread safety was to add the PyGILState calls to the virtual function wrapper around the call<>. After all that, my question is, is that sufficient? Also, are there any obvious problems with this example. It seems to work fine. Jim From rodrigohaasbrasil at yahoo.com.br Fri Dec 16 00:51:35 2005 From: rodrigohaasbrasil at yahoo.com.br (Rodrigo) Date: Thu, 15 Dec 2005 20:51:35 -0300 Subject: [C++-sig] pyterralib Message-ID: <43A20187.9010507@yahoo.com.br> Ol?! Vi uma resposta sua em um forum quando procurava por "pyterralib". Gostaria de saber se existe? Obrigado! Rodrigo _______________________________________________________ Yahoo! doce lar. Fa?a do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html From roman.yakovenko at gmail.com Sun Dec 18 11:47:16 2005 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 18 Dec 2005 12:47:16 +0200 Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject In-Reply-To: <20051215170408.63262.qmail@web2305.mail.yahoo.co.jp> References: <20051215170408.63262.qmail@web2305.mail.yahoo.co.jp> Message-ID: <7465b6170512180247l72ab33f8n7156ebb603a63197@mail.gmail.com> On 12/15/05, Shin-ichi MORITA wrote: > Hi David and Roman, > > I'm confused! > You say "If you override __init__(), you must call > module1.Derived.__init__()", don't you? > > But I do NOT override __init__() here. > > Again... everything is ok except for module1. > Please check out "test_owner.tar.bz2" which I sent before. I checked your test case on windows (vc 7.1) and it works as expected. It seems, that I can not help you. Sorry. > Anyway, my concern is "boost::python::detail::wrapper_base > should be polymorphic? (or should have virtual > destructor?)". > > Thanks. > > David Abrahams wrote: > > > I think that __init__() is implicitly called > > because > > > __init__() is not overriden. > > > > It is not. Listen to Roman. > > > > -------------------------------------- > STOP HIV/AIDS. > Yahoo! JAPAN Redribbon Campaign 2005 > http://pr.mail.yahoo.co.jp/redribbon/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From shin1_morita at yahoo.co.jp Sun Dec 18 15:40:56 2005 From: shin1_morita at yahoo.co.jp (Shin-ichi MORITA) Date: Sun, 18 Dec 2005 23:40:56 +0900 (JST) Subject: [C++-sig] returning a wrapper instance exposed in the other module is not converted to its owner PyObject In-Reply-To: <7465b6170512180247l72ab33f8n7156ebb603a63197@mail.gmail.com> Message-ID: <20051218144056.7354.qmail@web2306.mail.yahoo.co.jp> Hi, Thank you for your comment. Maybe this is gcc issue. I think that there is something wrong in vague linkage of type_info without vtable. http://www.gnu.org/software/gcc/faq.html#dso --- Roman Yakovenko wrote: > I checked your test case on windows (vc 7.1) and it > works as expected. > It seems, that I can not help you. > > Sorry. -------------------------------------- STOP HIV/AIDS. Yahoo! JAPAN Redribbon Campaign 2005 http://pr.mail.yahoo.co.jp/redribbon/ From patrick.hartling at gmail.com Mon Dec 19 04:15:21 2005 From: patrick.hartling at gmail.com (Patrick Hartling) Date: Sun, 18 Dec 2005 21:15:21 -0600 Subject: [C++-sig] Thread safety In-Reply-To: <43A31742.3020608@everestkc.net> References: <43A31742.3020608@everestkc.net> Message-ID: <944f7d8e0512181915m1548f88w38d667dd680b3af6@mail.gmail.com> On 12/16/05, dueymk wrote: > Hi, > I'm wrapping a multi-threaded C++ dll with Boost.Python. A thread is created when a wrapped structure is subclassed and instantiated in Python. This thread spends most of it's time in C++ but calls a virtual function which may be overridden by the Python subclass. I've done the following: > > class Original > { > int counter; > > virtual bool Process(int *count) > { > *count++; > return true; > } > } > > struct PythonOriginal : Original, wrapper > { > bool Process(int *count) > { > if (override Process = this->get_override("Process")) > { > PyGILState_STATE gstate; > gstate = PyGILState_Ensure(); > > bool answer = call(Process.ptr(), boost::ref(count)); > > PyGILState_Release(gstate); > return answer; > } > else > return Original::Process(count); > } > > bool default_Process(int *count) > { > return this->PleoraCamera::ProcessFrame(count); > } > > } > > BOOST_PYTHON_MODULE(PythonOriginal) > { > class_("Original") > .def("Process", &Original::Process, &PythonOriginal::default_Process) > ; > } > > Then in Python: > > class PyOrig(Original): > def Process(self, count): > count = count + 10 > return True > > orig = PyOrig() > > > The only thing I did for thread safety was to add the PyGILState calls to the virtual function wrapper around the call<>. After all that, my question is, is that sufficient? Also, are there any obvious problems with this example. It seems to work fine. I have a very similar case with my use of Boost.Python. With my code, a Python object will be instantiated and then handed off to the multi-threaded C++ library. The Python interpreter runs in the primordial thread, but the method invocations on the Python object are made from a different thread. My locking of the GIL has thus far been done before the call to boost::python::get_override() or any other Boost.Python functions. I changed my code so that the GIL is locked after the call to boost::python::get_override() as you have done above. I found that my code crashed at the first attempt of the C++ library's attempt to invoke a method of the Python object from a spawned thread. The crash occurred as a result of the call to boost::python::get_override() since it calls into the Python interpreter without the GIL being locked. I can provide a stack trace (from GDB) if you would like to see it. -Patrick -- Patrick L. Hartling http://www.137.org/patrick/ From s_sourceforge at nedprod.com Mon Dec 19 18:28:28 2005 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Mon, 19 Dec 2005 17:28:28 -0000 Subject: [C++-sig] Thread safety In-Reply-To: <944f7d8e0512181915m1548f88w38d667dd680b3af6@mail.gmail.com> References: <43A31742.3020608@everestkc.net> Message-ID: <43A6EDBC.24594.112BDCBB@s_sourceforge.nedprod.com> On 18 Dec 2005 at 21:15, Patrick Hartling wrote: > The only thing I did for thread safety was to add the PyGILState calls to the virtual function wrapper around the call<>. After all that, my question is, is that suffi> > I have a very similar case with my use of Boost.Python. With my code, > a Python object will be instantiated and then handed off to the > multi-threaded C++ library. The Python interpreter runs in the > primordial thread, but the method invocations on the Python object are > made from a different thread. > > My locking of the GIL has thus far been done before the call to > boost::python::get_override() or any other Boost.Python functions. I > changed my code so that the GIL is locked after the call to > boost::python::get_override() as you have done above. I found that my > code crashed at the first attempt of the C++ library's attempt to > invoke a method of the Python object from a spawned thread. The crash > occurred as a result of the call to boost::python::get_override() > since it calls into the Python interpreter without the GIL being > locked. I can provide a stack trace (from GDB) if you would like to > see it. You will find this very tricky to get right, as BPL dives into Python at weird points such as the container indexing suite iterators. Far better to patch BPL to lock and unlock the python GIL around entrances into C++ code. The mechanics of this are not easy. Best download BoostPatches.zip from http://svn.berlios.de/viewcvs/tnfox/trunk/Python/ and see the changes for yourself. Note that these do not support the modern get_override() interface yet (as pyste still uses the old one). Cheers, Niall From amohr at pixar.com Mon Dec 19 20:56:11 2005 From: amohr at pixar.com (Alex Mohr) Date: Mon, 19 Dec 2005 11:56:11 -0800 Subject: [C++-sig] Can't call injected method taking SmartPtr with derived object... Message-ID: <43A7105B.6050906@pixar.com> I'm having a bit of trouble with inheritance and injected methods. Here's a small example. In this example, SmartPtr is a custom smart pointer much like boost::shared_ptr. -------------------------------------------------------- class Base { public: virtual ~Base() {} }; class Derived : public Base { public: virtual ~Derived() {} static SmartPtr GetAsBase(SmartPtr const &p) { return SmartPtr(p); } string derivedMethod() { return "Derived Method"; } }; static SmartPtr newDerived() { ...makes a new derived... } static string injectedMethod(SmartPtr const &self) { return "Injected Method"; } BOOST_PYTHON_MODULE(foo) { class_ >("Base", no_init); class_, bases > ("Derived", no_init) .def("__init__", make_constructor(newDerived)) .def("derivedMethod", &Derived::derivedMethod) .def("injectedMethod", injectedMethod) .def("GetAsBase", &Derived::GetAsBase).staticmethod("GetAsBase") ; } >>> d = Derived() >>> d.derivedMethod() 'Derived Method' >>> d.injectedMethod() 'Injected Method' >>> b = Derived.GetAsBase(d) >>> type(b) >>> b.derivedMethod() 'Derived Method' >>> b.injectedMethod() Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in Derived.injectedMethod(Derived) did not match C++ signature: injectedMethod(SmartPtr) -------------------------------------------------------- Here are some observations. 1) This actually works right if I make the C++ injectedMethod take 'Derived const &' rather than 'SmartPtr const &'. 2) The whole example works fine *as-is* if I use boost::shared_ptr rather than my own custom smart pointer. Any help is greatly appreciated. Thanks, Alex From dueymk at everestkc.net Mon Dec 19 23:58:05 2005 From: dueymk at everestkc.net (dueymk) Date: Mon, 19 Dec 2005 16:58:05 -0600 Subject: [C++-sig] Thread safety In-Reply-To: <944f7d8e0512181915m1548f88w38d667dd680b3af6@mail.gmail.com> References: <43A31742.3020608@everestkc.net> <944f7d8e0512181915m1548f88w38d667dd680b3af6@mail.gmail.com> Message-ID: <43A73AFD.8030302@everestkc.net> It turns out that using the PyGILState* functions was sufficient. I also had to add: #ifdef WITH_THREAD Py_Initialize(); PyEval_InitThreads(); #endif to my module initialization code. After that, it seems to work fine. Jim Patrick Hartling wrote: > On 12/16/05, dueymk wrote: > > > I have a very similar case with my use of Boost.Python. With my code, > a Python object will be instantiated and then handed off to the > multi-threaded C++ library. The Python interpreter runs in the > primordial thread, but the method invocations on the Python object are > made from a different thread. > > My locking of the GIL has thus far been done before the call to > boost::python::get_override() or any other Boost.Python functions. I > changed my code so that the GIL is locked after the call to > boost::python::get_override() as you have done above. I found that my > code crashed at the first attempt of the C++ library's attempt to > invoke a method of the Python object from a spawned thread. The crash > occurred as a result of the call to boost::python::get_override() > since it calls into the Python interpreter without the GIL being > locked. I can provide a stack trace (from GDB) if you would like to > see it. > > -Patrick > > > -- > Patrick L. Hartling > http://www.137.org/patrick/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From amohr at pixar.com Tue Dec 20 01:15:29 2005 From: amohr at pixar.com (Alex Mohr) Date: Mon, 19 Dec 2005 16:15:29 -0800 Subject: [C++-sig] Calling func that takes intrusive_ptr with intrusive_ptr... Message-ID: <43A74D21.3000903@pixar.com> Hmm.. I was expecting this to work. Any ideas as to why it doesn't? Thanks, Alex #include #include #include using namespace boost::python; using boost::intrusive_ptr; using std::string; class Base { public: virtual ~Base() {} }; class Derived : public Base { public: virtual ~Derived() {} }; void intrusive_ptr_add_ref(Base *base) {} void intrusive_ptr_add_ref(Base *base) {} intrusive_ptr makeDerived() { return intrusive_ptr(new Derived()); } string takesBasePtr(intrusive_ptr const &base) { return "takesBasePtr"; } BOOST_PYTHON_MODULE(foo) { class_ >("Base", no_init); class_, bases > ("Derived", no_init) .def("__init__", make_constructor(makeDerived)) .def("takesBasePtr", takesBasePtr) ; } ================================================== >>> from foo import * >>> d = Derived() >>> d.takesBasePtr() Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in Derived.takesBasePtr(Derived) did not match C++ signature: takesBasePtr(boost::intrusive_ptr) From amohr at pixar.com Tue Dec 20 19:48:19 2005 From: amohr at pixar.com (Alex Mohr) Date: Tue, 20 Dec 2005 10:48:19 -0800 Subject: [C++-sig] Custom smart pointer progress (I think?) Message-ID: <43A851F3.9000107@pixar.com> I have come up with what seems to be an initial solution to the problems I posted yesterday regarding smart pointers that are not shared_ptr. Digging into boost python, I found converter/shared_ptr_from_python.hpp. I followed its lead and did something like the code below. If I instantiate one of these SmartPtrFromPython for each T that has SmartPtr as the held type, then the broken examples I posted yesterday seem to work as I would expect, just like in the shared_ptr case. Of course this seems a bit questionable. I think I'm dealing with private API, and I don't really know if registering these converters is potentially dangerous. Is this a reasonable approach? Thanks, Alex using namespace boost::python; template struct SmartPtrFromPython { SmartPtrFromPython() { converter::registry::insert(&convertible, &construct, type_id >()); } private: static void *convertible(PyObject *p) { if (p == Py_None) return p; return converter::get_lvalue_from_python(p, converter::registered::converters); } static void construct(PyObject *source, converter:: rvalue_from_python_stage1_data *data) { void *const storage = ((converter:: rvalue_from_python_storage >*)data)-> storage.bytes; // None case: if (data->convertible == source) new (storage) SmartPtr(); else new (storage) SmartPtr (static_cast(data->convertible)); data->convertible = storage; } } From bob at glumol.com Mon Dec 19 23:01:04 2005 From: bob at glumol.com (bob at glumol.com) Date: Mon, 19 Dec 2005 23:01:04 +0100 (CET) Subject: [C++-sig] Cycles won't be deleted Message-ID: <1464.192.168.0.2.1135029664.squirrel@www.glumol.com> Hello, I'm sorry if this question has already been asked but I didn't find an answer on the archives. With the Python code : class C: pass c1 = C() c2 = C() c1.child = c2 c2.parent = c1 del c1 del c2 import gc gc.collect() gc.collect() will return 2. Now if C is not a pure Python class but a BPL one, gc.collect() will return 0 and the 2 objects seem to never be deleted. I can define 'child' and 'parent' as members of the C++ class (using a shared_ptr and a weak_ptr, that works) but if an other cycle is defined in Python, the objects won't be deleted. Could someone explain me why such a behavior ? (I'm using Windows, Boost 1.33.1 and Visual Studio Express 2005) Thanks by advance Sylvain B. From driedel at printingforsystems.com Thu Dec 22 16:25:34 2005 From: driedel at printingforsystems.com (David P. Riedel) Date: Thu, 22 Dec 2005 10:25:34 -0500 Subject: [C++-sig] Patches for pyste In-Reply-To: <432F2B51.1050908@esss.com.br> References: <432F17EC.8000401@vrsource.org> <432F2B51.1050908@esss.com.br> Message-ID: Nicodemus wrote: > Hi Allen. > > Allen Bierbaum wrote: > > >>I have a patch that makes a couple of small changes to pyste. >> [snip] > > > Patch applied. Thanks Allen! > > Regards, > Bruno. I am wondering about the future of pyste. Pyste uses gccxml and the last version of that I have been able to find is for gcc 3.x but gcc is now up to 4.0.2. Will pyste still be usable as gcc advances to new versions without corresponding updates to gccxml? Thanks Dave Riedel From markus at relix.de Thu Dec 22 17:17:33 2005 From: markus at relix.de (Markus Heller) Date: Thu, 22 Dec 2005 17:17:33 +0100 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ Message-ID: <200512221717.33520.markus@relix.de> Dear List, I intend to execute a Python script from within a C++ program. I have already managed to embed Python and execute a simple program line. Though, I have a complex data object in C++, which I don't want to serialize, write out to a file in order to read it in again. I would preferably like to define a Python object from within C++ and hand over this data structure directly. Unfortunately the Python/C API Reference Manual doesn't offer any precise help. It is more like a manual for experts, not a guide to beginners like me... So do you have any hint for me? Where can I get some more information? As said, I want to create a Python object in C++ and use it in Python afterwards. Thanks in advance, Markus From seefeld at sympatico.ca Thu Dec 22 18:04:37 2005 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 22 Dec 2005 12:04:37 -0500 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <200512221717.33520.markus@relix.de> References: <200512221717.33520.markus@relix.de> Message-ID: <43AADCA5.6020603@sympatico.ca> Markus Heller wrote: > So do you have any hint for me? Where can I get some more information? As > said, I want to create a Python object in C++ and use it in Python > afterwards. If it is a pure python object, and if you want to use it in python (only ?), why do you want to create it in C++ ? What type will your object have ? A built-in python type or a type defined in your own python script ? What do you want to do with that object from within your C++ program before handing control back to python ? The boost.python tutorial (http://boost.org/libs/python/doc/tutorial/doc/html/index.html) as well as the reference manual (http://boost.org/libs/python/doc/v2/reference.html) should get you started. You may also look into example code in boost/libs/python/test, in particular boost/libs/python/test/exec.cpp. HTH, Stefan From markus at relix.de Fri Dec 23 03:32:39 2005 From: markus at relix.de (Markus Heller) Date: Fri, 23 Dec 2005 03:32:39 +0100 Subject: [C++-sig] =?iso-8859-1?q?embedded_Python=3A_Access_an_object_defi?= =?iso-8859-1?q?ned_previously_in=09C++?= In-Reply-To: <43AADCA5.6020603@sympatico.ca> References: <200512221717.33520.markus@relix.de> <43AADCA5.6020603@sympatico.ca> Message-ID: <200512230332.39706.markus@relix.de> Hi Stefan, > > So do you have any hint for me? Where can I get some more information? As > > said, I want to create a Python object in C++ and use it in Python > > afterwards. > > If it is a pure python object, and if you want to use it in python (only > ?), why do you want to create it in C++ ? > What type will your object have ? A built-in python type or a type defined > in your own python script ? What do you want to do with that object from > within your C++ program before handing control back to python ? > > The boost.python tutorial > (http://boost.org/libs/python/doc/tutorial/doc/html/index.html) as well as > the reference manual (http://boost.org/libs/python/doc/v2/reference.html) > should get you started. You may also look into example code in > boost/libs/python/test, in particular boost/libs/python/test/exec.cpp. You see, I have a rather big struct in my C++ memory and I want to retain a certain flexibility and give the users of my application the chance to do some customized data processing. To me the ideal way is to offer them access to the data through python. Best wishes, Markus From seefeld at sympatico.ca Fri Dec 23 04:00:01 2005 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 22 Dec 2005 22:00:01 -0500 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <200512230332.39706.markus@relix.de> References: <200512221717.33520.markus@relix.de> <43AADCA5.6020603@sympatico.ca> <200512230332.39706.markus@relix.de> Message-ID: <43AB6831.3070007@sympatico.ca> Markus Heller wrote: > Hi Stefan, > > >>>So do you have any hint for me? Where can I get some more information? As >>>said, I want to create a Python object in C++ and use it in Python >>>afterwards. >> >>If it is a pure python object, and if you want to use it in python (only >>?), why do you want to create it in C++ ? >>What type will your object have ? A built-in python type or a type defined >>in your own python script ? What do you want to do with that object from >>within your C++ program before handing control back to python ? >> >>The boost.python tutorial >>(http://boost.org/libs/python/doc/tutorial/doc/html/index.html) as well as >>the reference manual (http://boost.org/libs/python/doc/v2/reference.html) >>should get you started. You may also look into example code in >>boost/libs/python/test, in particular boost/libs/python/test/exec.cpp. > > > You see, I have a rather big struct in my C++ memory and I want to retain a > certain flexibility and give the users of my application the chance to do > some customized data processing. To me the ideal way is to offer them access > to the data through python. Ok, I was misled by your phrasing then, sorry. It seems you really want to reflect your C++ type(s) into python, using boost.python's class_ mechanism. That is described rather well in the above docs, I think. May be you could ask more specific questions once you run into difficulties, sending code snippets, error messages, and the like ? Or, a *concrete* example of what you want to do, i.e. how the C++ type looks like, and how you want it to look like in python, etc. Regards, Stefan From markus at relix.de Fri Dec 23 05:05:57 2005 From: markus at relix.de (Markus Heller) Date: Fri, 23 Dec 2005 05:05:57 +0100 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <43AB6831.3070007@sympatico.ca> References: <200512221717.33520.markus@relix.de> <200512230332.39706.markus@relix.de> <43AB6831.3070007@sympatico.ca> Message-ID: <200512230505.58280.markus@relix.de> Dear Stefan, > > You see, I have a rather big struct in my C++ memory and I want to retain > > a certain flexibility and give the users of my application the chance to > > do some customized data processing. To me the ideal way is to offer them > > access to the data through python. > > Ok, I was misled by your phrasing then, sorry. It seems you really want > to reflect your C++ type(s) into python, using boost.python's class_ > mechanism. > That is described rather well in the above docs, I think. May be you > could ask more specific questions once you run into difficulties, sending > code snippets, error messages, and the like ? > Or, a *concrete* example of what you want to do, i.e. how the C++ type > looks like, and how you want it to look like in python, etc. I restructured my code for performance issues, and now I have a smaller and simpler struct, containing two individual strings (STL strings) and a vector of strings. The individual strings should not be a problem, I assume, and the vector of strings is actually a tuple. But the problem is more that I am not so proficient in python at all. I think, I will consider your hints in depth and come back once I can send you more qualified utterances on this wonderful scripting language :-) Thanks a lot!! Markus From girtsk at latnet.lv Fri Dec 23 10:40:52 2005 From: girtsk at latnet.lv (Girts Kalnins) Date: Fri, 23 Dec 2005 11:40:52 +0200 Subject: [C++-sig] How to compile latest Boost.Python on Mac OS X? Message-ID: <1135330852.43abc624a8161@clients.latnet.lv> I use Mac OS X 10.4.3, then installed ActivePython-2.4.2-248-macosx-powerpc.dmg. When I tried to compile boost.python from version 1.33.1, it fails to link. GCC version: i686-apple-darwin8-gcc-4.0.0; I also use prebuilt bjam. The script I use: ************************************************* #!/bin/sh PYTHON_ROOT="/Library/Frameworks/Python.framework/Versions/2.4" ; export PYTHON_ROOT PYTHON_VERSION=2.4 ; export PYTHON_VERSION PYTHON_LIB_PATH=2.4 ; export PYTHON_LIB_PATH ./bjam -sBUILD=release ************************************************* Output: administrators-computer:~/Sandbox/boost_1_33_1/libs/python/build testmaster$ ./boom ...found 930 targets... ...updating 2 targets... darwin-Link-DyLib-action ../../../bin/boost/libs/python/build/libboost_python.dylib/darwin/release/shared-linkable-true/libboost_python.dylib ld: Undefined symbols: _PyBool_FromLong _PyCallable_Check _PyErr_Clear [..snipped..] _PyNumber_Subtract _PyNumber_Xor _PyDict_GetItemString _PyMethod_Type /usr/bin/libtool: internal link edit command failed ************ >From error above looks like it can not find python library. On windows these files are in PYTHON_ROOT\Libs; python.lib and such. I also failed to build python from sources. the linker could not find __Py_Mac. Do you have any ideas? G'irts From tkirke at pacbell.net Fri Dec 23 23:56:11 2005 From: tkirke at pacbell.net (Tony Kirke) Date: Fri, 23 Dec 2005 14:56:11 -0800 (PST) Subject: [C++-sig] Patches for pyste In-Reply-To: Message-ID: <20051223225611.39783.qmail@web81509.mail.mud.yahoo.com> gccxml compiles fine for gcc 4.0.2. Use the CVS version of gccxml "David P. Riedel" wrote: Nicodemus wrote: > Hi Allen. > > Allen Bierbaum wrote: > > >>I have a patch that makes a couple of small changes to pyste. >> [snip] > > > Patch applied. Thanks Allen! > > Regards, > Bruno. I am wondering about the future of pyste. Pyste uses gccxml and the last version of that I have been able to find is for gcc 3.x but gcc is now up to 4.0.2. Will pyste still be usable as gcc advances to new versions without corresponding updates to gccxml? Thanks Dave Riedel _______________________________________________ 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 driedel at printingforsystems.com Tue Dec 27 15:33:10 2005 From: driedel at printingforsystems.com (David P. Riedel) Date: Tue, 27 Dec 2005 09:33:10 -0500 Subject: [C++-sig] Patches for pyste In-Reply-To: <20051223225611.39783.qmail@web81509.mail.mud.yahoo.com> References: <20051223225611.39783.qmail@web81509.mail.mud.yahoo.com> Message-ID: Tony Kirke wrote: > gccxml compiles fine for gcc 4.0.2. > Use the CVS version of gccxml > Tony, I will check this out. Thanks. Dave Riedel From markus at relix.de Wed Dec 28 08:08:21 2005 From: markus at relix.de (Markus Heller) Date: Wed, 28 Dec 2005 08:08:21 +0100 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <43AB6831.3070007@sympatico.ca> References: <200512221717.33520.markus@relix.de> <200512230332.39706.markus@relix.de> <43AB6831.3070007@sympatico.ca> Message-ID: <200512280808.22845.markus@relix.de> Hi Stefan, > Ok, I was misled by your phrasing then, sorry. It seems you really want > to reflect your C++ type(s) into python, using boost.python's class_ > mechanism. > That is described rather well in the above docs, I think. May be you > could ask more specific questions once you run into difficulties, sending > code snippets, error messages, and the like ? > Or, a *concrete* example of what you want to do, i.e. how the C++ type > looks like, and how you want it to look like in python, etc. well, I experimented a little with the boost libs, but I see that you can only expose entire classes with the class_ method. What I want, though, is just to expose a data object to the python program I would like to call through the Py/C-API. The definition of the data is as follows: >>>>> typedef std::vector multiline; struct XTuple { multiline XMLPath; std::string Content; }; struct IDoc { std::string DocURL; std::vector TupleSet; }; <<<<< I would like to expose an IDoc to Python, have all the processing of the TupleSet done out there and collect the results. Off course, the IDoc contents will be changing during runtime, so I cannot generate a shared object and be happy... I need to do this from within a so-called pipeline class. How can I expose the IDoc? Thanks in advance, Markus From markus at relix.de Wed Dec 28 09:28:49 2005 From: markus at relix.de (Markus Heller) Date: Wed, 28 Dec 2005 09:28:49 +0100 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <200512280808.22845.markus@relix.de> References: <200512221717.33520.markus@relix.de> <43AB6831.3070007@sympatico.ca> <200512280808.22845.markus@relix.de> Message-ID: <200512280928.50191.markus@relix.de> Hi Stefan, > well, I experimented a little with the boost libs, but I see that you can > only expose entire classes with the class_ method. What I want, though, is > just to expose a data object to the python program I would like to call > through the Py/C-API. I experimented a little with def and with the BOOST_PYTHON_MODULE macro. Then I created a little function which just returns "hahaha". I'm glad to say that it compiles well. But my question now is the following: Is it sufficient that the BOOST_PYTHON_MODULE block stands just below all the other functions in the according cpp file? I want to call a Python script from within one of the functions of this class. This Python script will need to import the pipeline module. What are the necessare preconditions to allow the script to load my exported function? Do I need to reset the PYTHONPATH variable? Does this variable need to point to where the binary is? Notabene, it is not a shared object... Thanks ahead for your answers! Markus From seefeld at sympatico.ca Wed Dec 28 16:51:37 2005 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 28 Dec 2005 10:51:37 -0500 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <200512280928.50191.markus@relix.de> References: <200512221717.33520.markus@relix.de> <43AB6831.3070007@sympatico.ca> <200512280808.22845.markus@relix.de> <200512280928.50191.markus@relix.de> Message-ID: <43B2B489.4040402@sympatico.ca> Markus Heller wrote: > Is it sufficient that the BOOST_PYTHON_MODULE block stands just below all the > other functions in the according cpp file? I don't understand the question. What do you mean by 'all the other functions' ? The BOOST_PYTHON_MODULE block is used to export specific C++ types / functions to python, and tells the python module loader how to find them. > I want to call a Python script from within one of the functions of this class. > This Python script will need to import the pipeline module. What are the > necessare preconditions to allow the script to load my exported function? > > Do I need to reset the PYTHONPATH variable? Does this variable need to point > to where the binary is? Notabene, it is not a shared object... That depends. When you want to load it as an ordinary python module, it has to be a shared object, and it must be in your PYTHONPATH. However: * you may adjust your PYTHONPATH programmatically just before loading the module * you may be able to register the python module programmatically such that the loader isn't involved at all, i.e. the module doesn't need to be in a DSO. I have never done that myself, though, so I can't give any specific advice. Some experimentation may be necessary. HTH, Stefan From markus at relix.de Thu Dec 29 08:52:46 2005 From: markus at relix.de (Markus Heller) Date: Thu, 29 Dec 2005 08:52:46 +0100 Subject: [C++-sig] embedded Python: Access an object defined previously in C++ In-Reply-To: <43B2B489.4040402@sympatico.ca> References: <200512221717.33520.markus@relix.de> <200512280928.50191.markus@relix.de> <43B2B489.4040402@sympatico.ca> Message-ID: <200512290852.47229.markus@relix.de> Dear Stefan, > * you may be able to register the python module programmatically such that > the loader isn't involved at all, i.e. the module doesn't need to be in > a DSO. I have never done that myself, though, so I can't give any > specific advice. Some experimentation may be necessary. Thanks a lot four your ideas and hints. I resolved most of my issues, mostly by studying this page: http://docs.python.org/ext/pure-embedding.html Best wishes! Markus From gxe13 at wowway.com Fri Dec 30 16:49:01 2005 From: gxe13 at wowway.com (Gregory Echols) Date: Fri, 30 Dec 2005 09:49:01 -0600 Subject: [C++-sig] looking for help... Message-ID: with C++ missionaries & cannibal program. Know of anyone I can ask?