[C++-sig] Docstrings question

2010-10-15 Thread Michael Wild
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

2012-01-30 Thread Michael Wild
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

2012-01-30 Thread Michael Wild
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

2012-01-30 Thread Michael Wild
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

2012-01-31 Thread Michael Wild
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

2013-01-16 Thread 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


Re: [C++-sig] Wrapping a non-copyiable static instance in bp::object

2013-01-20 Thread Michael Wild
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

2013-01-22 Thread Michael Wild
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

2013-01-22 Thread Michael Wild
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++

2013-01-23 Thread Michael Wild
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

2013-01-23 Thread Michael Wild
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

2013-01-23 Thread Michael Wild
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

2013-01-24 Thread Michael Wild
[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

2013-01-27 Thread Michael Wild
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

2013-03-15 Thread Michael Wild
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