[C++-sig] Docstrings question
Hi all I'm fairly new to Boost.Python and currently I'm looking for a convenient way of adding docstrings to overloaded operators, e.g: class A; class B A operator+(A const&, A const&); B operator+(B const&, B const&); BOOST_PYTHON_MODULE(foo) { bp::class_("A") .def(self + self) //< How to add docstring here? } I know I could also use: A (*A_add_op)(A const&, A const&) = operator+; bp::class_("A") .def("__add__", A_add_op, "Add two A objects") or a direct cast, but honestly, I don't look forward to all that typing, and it is so much harder to read than the first option. Thanks for the help Michael PGP.sig Description: This is a digitally signed message part ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Boost.Python property definition question
Hi all I can't seem to figure out how to wrap this in Boost.Python without the need for auxiliary functions: #include #include using std::string; using namespace boost::python; class A { string m_s; public: A(string const& s) : m_s(s) {} // read-only access ( string const& s() const { return m_s; } // read-write access string& s() { return m_s; } }; BOOST_PYTHON_MODULE(A) { class_ ("A", init()) .add_property("s", // this getter works fine make_function( (string const&(A::*)()const)&A::s, return_value_policy()), // this setter fails make_function( (string&(A::*)())&A::s, return_internal_reference<>())) ; } When I try to run the following: import A a = A.A("Hello") a.s = "World!" I get below error message: ArgumentError: Python argument types in None.None(A, str) did not match C++ signature: None(A {lvalue}) How do I solve this problem? Thanks for any advice Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Boost.Python property definition question
On 01/30/2012 04:58 PM, Jim Bosch wrote: > On 01/30/2012 09:32 AM, Michael Wild wrote: >> Hi all >> >> I can't seem to figure out how to wrap this in Boost.Python without the >> need for auxiliary functions: >> > > > >>string& s() { return m_s; } > > The second argument to add_property should be an actual setter, not a > non-const-reference getter. In this case, you can write another free > function that delegates to the non-const-getter, then wrap that: > > void set_s(A & a, std::string const & s) { a.s() = s; } > > ... > > .add_property("s", > make_function( >(string const&(A::*)()const)&A::s, >return_value_policy()), > make_function(&set_set) > ) > > > > HTH > > Jim Bosch That's what I've been referring to as "auxiliary" functions. If possible, I'd like to avoid them because I don't fancy writing hundreds of those... I could live with calling a template. However, so far I haven't been able to come up with one that is sufficiently easy to use... So far I came up with the this: template void set_helper(T& self, ArgType& arg) { (self.*method)() = arg; } But it is a bit cumbersome to use, as it doesn't deduce its first two template arguments on its own. Is there any way to achieve that feat? Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Boost.Python property definition question
On 01/30/2012 07:28 PM, Jim Bosch wrote: > On 01/30/2012 12:11 PM, Michael Wild wrote: >> That's what I've been referring to as "auxiliary" functions. If >> possible, I'd like to avoid them because I don't fancy writing hundreds >> of those... I could live with calling a template. However, so far I >> haven't been able to come up with one that is sufficiently easy to use... >> >> So far I came up with the this: >> >> template >> void set_helper(T& self, ArgType& arg) >> { >>(self.*method)() = arg; >> } >> >> But it is a bit cumbersome to use, as it doesn't deduce its first two >> template arguments on its own. Is there any way to achieve that feat? >> > > If you're up for playing with Boost.FunctionTypes, you should be able to > write a wrapper for make_function that deduces those types for you: > > namespace bp = boost::python; > > template > void set_helper(T & self, A const & arg) { > (self.*method)() = arg; > } > > template > bp::object make_set_helper(F f) { > // F is the member function type; use Boost.FunctionTypes to > // figure out A and T, then... > return bp::make_function(&set_helper); > } > > > I'll leave it to you to fill in the details. I haven't tried it myself, > but I think it would work. > > > Jim Thanks for that hint, I'll certainly take a look. The only think that would bother me with this solution is that I would need to disambiguate between the non-const and const functions with the casting operator again. Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Boost.Python property definition question
On 01/31/2012 05:56 PM, Jim Bosch wrote: > On 01/31/2012 12:41 AM, Michael Wild wrote: >> On 01/30/2012 07:28 PM, Jim Bosch wrote: >>> On 01/30/2012 12:11 PM, Michael Wild wrote: >>>> That's what I've been referring to as "auxiliary" functions. If >>>> possible, I'd like to avoid them because I don't fancy writing hundreds >>>> of those... I could live with calling a template. However, so far I >>>> haven't been able to come up with one that is sufficiently easy to >>>> use... >>>> >>>> So far I came up with the this: >>>> >>>> template >>>> void set_helper(T& self, ArgType& arg) >>>> { >>>> (self.*method)() = arg; >>>> } >>>> >>>> But it is a bit cumbersome to use, as it doesn't deduce its first two >>>> template arguments on its own. Is there any way to achieve that feat? >>>> >>> >>> If you're up for playing with Boost.FunctionTypes, you should be able to >>> write a wrapper for make_function that deduces those types for you: >>> >>> namespace bp = boost::python; >>> >>> template >>> void set_helper(T& self, A const& arg) { >>> (self.*method)() = arg; >>> } >>> >>> template >>> bp::object make_set_helper(F f) { >>> // F is the member function type; use Boost.FunctionTypes to >>> // figure out A and T, then... >>> return bp::make_function(&set_helper); >>> } >>> >>> >>> I'll leave it to you to fill in the details. I haven't tried it myself, >>> but I think it would work. >>> >>> >>> Jim >> >> Thanks for that hint, I'll certainly take a look. The only think that >> would bother me with this solution is that I would need to disambiguate >> between the non-const and const functions with the casting operator >> again. >> > > You might be able to address that by having two make_helper functions, > using enable_if/disable_if to select one when the return type is const > and the other when it isn't. The one invoked for const returns would > just call make_function directly to make a getter, while the non-const > one would be like make_set_helper above. > > > Jim Sorry, I think you'll have to expand a bit on that. Do you mean that I can use enable_if/disable_if to select between the two implementations? Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Wrapping a non-copyiable static instance in bp::object
Dear all I struggle to find a way in which I can wrap a static instance in a bp::object without copying it. The goal is to have object identity for this static instance: struct A { /*...*/ static A static_a; }; a A::a; bp::object static_instance() { static bp::object* result = new bp::object(A::static_a); // [1] return *result; } Wrapping A and static_instance with Boost.Python is no problem, and everything works as expected, however the A::static_a that is being passed to bp::object() at [1] is being copied, which defeats the whole purpose. Anybody has an idea how achieve this? Thanks! Cheers Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Wrapping a non-copyiable static instance in bp::object
I knew (hoped, really) there would be a simple solution! Thanks, it works beautifully. Michael PS: Sorry, I posted earlier, but didn't notice that I got rejected because I used the wrong sender address... On 01/16/2013 10:29 PM, Wojciech Mamrak wrote: > Hi, > > bp::object static_instance() > { > static bp::object* result = new bp::object(boost::ref(A::static_a)); > return *result; > } > > Instead of exposing a function static_instance in your module, you can > alternatively add a variable to your module's scope: > > scope sc; > sc.attr("static_a") = boost::ref(A::static_a); //no copy here > > regards > > > 2013/1/16 Michael Wild : >> Dear all >> >> I struggle to find a way in which I can wrap a static instance in a >> bp::object without copying it. The goal is to have object identity for >> this static instance: >> >> struct A { >> /*...*/ >> static A static_a; >> }; >> >> a A::a; >> >> bp::object static_instance() >> { >> static bp::object* result = new bp::object(A::static_a); // [1] >> return *result; >> } >> >> Wrapping A and static_instance with Boost.Python is no problem, and >> everything works as expected, however the A::static_a that is being >> passed to bp::object() at [1] is being copied, which defeats the whole >> purpose. >> >> Anybody has an idea how achieve this? Thanks! >> >> Cheers >> >> Michael > ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] to_python converter and make_getter
Dear all I have defined a to_python converter following http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters. Everything is fine and dandy, however what bugs me is having to specify a return_value_policy() for every make_getter call. Looking through the sources it seems that I should be able to tell make_getter what the default policy should be by somehow specializing default_member_getter_policy and default_datum_getter_policy. However, is this the right way to go, or should I attack the problem at a lower level, e.g. by specializing default_getter_by_ref? Or should I directly specialize make_getter? Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] to_python converter and make_getter
On 01/22/2013 11:27 PM, Jim Bosch wrote: > On 01/22/2013 04:18 PM, Michael Wild wrote: >> Dear all >> >> I have defined a to_python converter following >> http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters. >> >> Everything is fine and dandy, however what bugs me is having to specify >> a return_value_policy() for every make_getter call. >> Looking through the sources it seems that I should be able to tell >> make_getter what the default policy should be by somehow specializing >> default_member_getter_policy and default_datum_getter_policy. However, >> is this the right way to go, or should I attack the problem at a lower >> level, e.g. by specializing default_getter_by_ref? Or should I directly >> specialize make_getter? >> > > Could you provide a little more information about what you're trying to > do and what the error is? I'm surprised that you're having to specify a > call-policy manually for return-by-value; I've used by-value to_python > converters plenty of times without ever having to do that. > > Jim > I don't have to do it for functions that return by value, only for static members that I want to wrap in a static property. I put the example here: https://gist.github.com/4602341 Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Failed to import pyd File When python embed into C++
On Wed, Jan 23, 2013 at 8:19 AM, salinea wrote: > > I create a pyd File named "testPyd" with boostPython,and then I import the > testPyd module into "test.py", it works perfect! > But when I embeded the python interpreter into my C++ project and run the > "test.py", it comes out a "ImportErr: no module named testPyd". > It has confused me for two days and I googled for long time,but I can't > find > the answer! > Anybody here can help me ? > Thank you! > > Here is my test examples: > The C++ codes to build the *pyd File* is: > Excute.h > > #ifndef EXCUTE_H_ > #define EXCUTE_H_ > #include > > class Excute > { > public: > Excute(){} > int getIoReuslt(std::string ioStr); > int getSignal(); > }; > #endif > > Excute.cpp: > #include "Excute.h" > #include "Explanation.h" > #include > > int Excute::getIoReuslt(std::string ioStr) > { > return 1; > } > > int Excute::getSignal() > { > int i = rand()%2; > return i; > } > > BOOST_PYTHON_MODULE(pythonDll) > { > using namespace boost::python; > class_("Excute", init<>()) > .def("getIoResult", &Excute::getIoReuslt) > .def("getSignal", &Excute::getSignal) > ; > } > Then a pyd File Named pythonDll is created(pythonDll.pyd), > Here are the codes in my test.py: > test.py: > > from pythonDll import* > h=Excurte() > print h.getIoResult("a") > print h.getSignal() > > And this script works perfect in IDLE. > > And then I embed python into my C++ project,Here are the test codes: > #include > #include > > int main(int argc, char* argv[]) > { > Py_Initialize(); > FILE * fp = fopen("$PATH/test.py", "r"); > if (fp == NULL) > { > return 1; > } > PyRun_SimpleString("execfile($PATH/test.py')"); > Py_Finalize(); > > system("Pause"); > > return 0; > } > > The result is: > Traceback (most recent call last): > File "", line 1, in > File "$PATH/test.py", line 1, in > from pythonDll import* > ImportError: No module named pythonDll > [19228 refs] > > Just to help you debug the issue: have you tried putting something like this into your test.py? import sys sys.stderr.write("PYTHONPATH = %s\n"%(":".join(sys.path))) Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] to_python converter and make_getter
On 01/23/2013 05:44 PM, Jim Bosch wrote: > On 01/23/2013 12:34 AM, Michael Wild wrote: >> On 01/22/2013 11:27 PM, Jim Bosch wrote: >>> On 01/22/2013 04:18 PM, Michael Wild wrote: >>>> Dear all >>>> >>>> I have defined a to_python converter following >>>> http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters. >>>> >>>> >>>> Everything is fine and dandy, however what bugs me is having to specify >>>> a return_value_policy() for every make_getter call. >>>> Looking through the sources it seems that I should be able to tell >>>> make_getter what the default policy should be by somehow specializing >>>> default_member_getter_policy and default_datum_getter_policy. However, >>>> is this the right way to go, or should I attack the problem at a lower >>>> level, e.g. by specializing default_getter_by_ref? Or should I directly >>>> specialize make_getter? >>>> >>> >>> Could you provide a little more information about what you're trying to >>> do and what the error is? I'm surprised that you're having to specify a >>> call-policy manually for return-by-value; I've used by-value to_python >>> converters plenty of times without ever having to do that. >>> >>> Jim >>> >> >> I don't have to do it for functions that return by value, only for >> static members that I want to wrap in a static property. >> >> I put the example here: https://gist.github.com/4602341 >> > > Ah, that makes sense. Well, if Giuseppe's idea of just converting the > object once doesn't work for you, I'd recommend not specializing any > boost::python internals, and just writing a convenience that calls > make_getter the way you want: > > template > bp::object my_make_getter(D const & d) { > return bp::make_getter( > d, > bp::return_value_policy() > ); > } > > HTH! > > Jim > Yes, I thought of that too. While this "solves" this case (it certainly is not very discoverable for future maintainers), it does not help in the case of container support. Say I wanted to expose std::vector (or std::vector from the Boost.Python FAQ, for that matter) using the boost::python::vector_indexing_suite. I am perfectly able to create such a list, I can append items, the only thing I can't do is *retrieving* them. It's like a black hole for data ;-) Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] to_python converter and make_getter
On 01/23/2013 07:03 PM, Jim Bosch wrote: > On 01/23/2013 12:56 PM, Michael Wild wrote: > > > >> >> Yes, I thought of that too. While this "solves" this case (it certainly >> is not very discoverable for future maintainers), it does not help in >> the case of container support. Say I wanted to expose >> std::vector (or std::vector from the Boost.Python >> FAQ, for that matter) using the boost::python::vector_indexing_suite. I >> am perfectly able to create such a list, I can append items, the only >> thing I can't do is *retrieving* them. It's like a black hole for data >> ;-) >> > > I'm afraid the vector_indexing_suite is some black magic I'm not > terribly familiar with. But I do know that in some contexts it returns > proxy objects in order to allow setting and safer lifetime management, > and I suspect that's what is not playing nicely with your custom > converters. Or have you investigated that further and determined that > it's calling make_getter, and that's why you're focused on that? Not at all, I just stumbled across this problem a little later than the one with the make_getter. Somehow I suspect that if I can teach bp to properly return by value, both cases would be resolved automagically. After all, things work smoothly for std::string. Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] to_python converter and make_getter
[re-post with the correct from-address, the original got rejected] On 01/23/2013 07:08 PM, Michael Wild wrote: > On 01/23/2013 07:03 PM, Jim Bosch wrote: >> On 01/23/2013 12:56 PM, Michael Wild wrote: >> >> >> >>> >>> Yes, I thought of that too. While this "solves" this case (it certainly >>> is not very discoverable for future maintainers), it does not help in >>> the case of container support. Say I wanted to expose >>> std::vector (or std::vector from the Boost.Python >>> FAQ, for that matter) using the boost::python::vector_indexing_suite. I >>> am perfectly able to create such a list, I can append items, the only >>> thing I can't do is *retrieving* them. It's like a black hole for data >>> ;-) >>> >> >> I'm afraid the vector_indexing_suite is some black magic I'm not >> terribly familiar with. But I do know that in some contexts it returns >> proxy objects in order to allow setting and safer lifetime management, >> and I suspect that's what is not playing nicely with your custom >> converters. Or have you investigated that further and determined that >> it's calling make_getter, and that's why you're focused on that? > > Not at all, I just stumbled across this problem a little later than the > one with the make_getter. Somehow I suspect that if I can teach bp to > properly return by value, both cases would be resolved automagically. > After all, things work smoothly for std::string. > > Michael > About the indexing_suite: By setting the NoProxy template argument to true, the custom string is being converted correctly, leaving me only with make_getter to be dealt with. For now I think I'll go with explicitly specializing make_getter. AFAIK this does no harm and automagically fixes class_::add_property() and friends. Thanks for all the input. Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] CallPolicy for operators
Hi all Is there a way to apply a CallPolicy to operator definitions? In particular, I'm interested in the inplace operators (+=, -=, *=, /= and friends). To give a bit more context: The library I'm trying to wrap exposes some static const objects. So far, I have been able to wrap modifying function by having a registration facility for these static const objects and a custom CallPolicy that raises an AttributError when one tries to modify one of the registered objects. One option I see is to directly define __iadd__ etc. instead of using the built-in convenience operators. However, I'm not sure whether that has unintended side-effects. I haven't completely understood the operators implementation in bp, but it looks fairly involved. Thanks Michael ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] CallPolicy for operators
On Fri, Mar 15, 2013 at 12:54 PM, Neal Becker wrote: > Jim Bosch wrote: > > > On 01/27/2013 05:02 AM, Michael Wild wrote: > >> Hi all > >> > >> Is there a way to apply a CallPolicy to operator definitions? In > >> particular, I'm interested in the inplace operators (+=, -=, *=, /= and > >> friends). > >> > >> To give a bit more context: The library I'm trying to wrap exposes some > >> static const objects. So far, I have been able to wrap modifying > >> function by having a registration facility for these static const > >> objects and a custom CallPolicy that raises an AttributError when one > >> tries to modify one of the registered objects. > >> > >> One option I see is to directly define __iadd__ etc. instead of using > >> the built-in convenience operators. However, I'm not sure whether that > >> has unintended side-effects. I haven't completely understood the > >> operators implementation in bp, but it looks fairly involved. > >> > > > > I think directly implementing __iadd__ is probably your best bet. I > don't > > think there are any side-effects you need to worry about, but it would > > probably be a lot of boilerplate. Do make sure you read up on how those > > methods are supposed to be implemented in pure-Python as regards to > handling > > unexpected types, however, and make sure you follow the same rules in > your C++ > > implementation. > > > > Jim > > I've always used e.g. __iadd__ rather than the convenience stuff. No > problems. > > Yeah, that's what I've been doing now. ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig