[Py++] Does pyplusplus respect explicit constructors?

View: New views
4 Messages — Rating Filter:   Alert me  

[Py++] Does pyplusplus respect explicit constructors?

by Christopher Bruns :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Single-argument C++ constructors in pyplusplus seem to generate a
boost::python::implicitly_convertible tag, even when the constructor
is declared "explicit" in C++.  That doesn't sound right to me.
Shouldn't a pair of types that are not implicitly convertible in C++,
also not be implicitly convertible in python?

I suspect I can manually adjust the implicitly_convertible tag
generation using the "allow_implicit_conversion" flag in pyplusplus.
Is there a way to tell pyplusplus to avoid generating an
implicitly_convertible tag for all explicit constructors?


########## test.h input source ############

class Foo {
public:
    Foo() {}
};

class Bar {
public:
    // explicit constructor means don't implicitly convert Foo to Bar in C++
    explicit Bar(Foo&) {}
};

###############################

########## wrap.py wrapping code ####

from pyplusplus import module_builder

mb = module_builder.module_builder_t(["test.h"]
    , gccxml_path = "C:\\Program Files\\gccxml_sherm\\bin\\gccxml.exe")
mb.build_code_creator( module_name='test' )
mb.write_module( 'test_explicit.cpp' )

##################################

##### generated test_explicit.cpp ######

// This file has been generated by Py++.

#include "boost/python.hpp"

#include "test.h"

namespace bp = boost::python;

BOOST_PYTHON_MODULE(test){
    { //::Bar
        typedef bp::class_< Bar > Bar_exposer_t;
        Bar_exposer_t Bar_exposer = Bar_exposer_t( "Bar", bp::init<
Foo & >(( bp::arg("arg0") )) );
        bp::scope Bar_scope( Bar_exposer );
        bp::implicitly_convertible< Foo &, Bar >(); // <-- *** I'm
surprised by this ***
    }

    bp::class_< Foo >( "Foo", bp::init< >() );
}

##################################
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@...
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [Py++] Does pyplusplus respect explicit constructors?

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 30, 2009 at 6:18 PM, Christopher Bruns <cmbruns@...> wrote:
> Single-argument C++ constructors in pyplusplus seem to generate a
> boost::python::implicitly_convertible tag, even when the constructor
> is declared "explicit" in C++.  That doesn't sound right to me.

I don't completely agree with you.

> Shouldn't a pair of types that are not implicitly convertible in C++,
> also not be implicitly convertible in python?

It depends on your use cases.

> I suspect I can manually adjust the implicitly_convertible tag
> generation using the "allow_implicit_conversion" flag in pyplusplus.
> Is there a way to tell pyplusplus to avoid generating an
> implicitly_convertible tag for all explicit constructors?

I don't think so. I attached gccxml generated file for your code. As
you can see both constructors ( Foo and Bar )  have "explitic=1". So
Py++ has no way to find out whether a constructor explicit or not.

If such functionality would present, I think that the default would be
the opposite.

HTH

--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@...
http://mail.python.org/mailman/listinfo/cplusplus-sig

1.tar.bz (6K) Download Attachment

Parent Message unknown Re: [Py++] Does pyplusplus respect explicit constructors?

by Christopher Bruns :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Roman Yakovenko wrote:
> On Wed, Sep 30, 2009 at 6:18 PM, Christopher Bruns <cmbruns at stanford.edu> wrote:
> > I suspect I can manually adjust the implicitly_convertible tag
> > generation using the "allow_implicit_conversion" flag in pyplusplus.
> > Is there a way to tell pyplusplus to avoid generating an
> > implicitly_convertible tag for all explicit constructors?
>
> I don't think so. I attached gccxml generated file for your code. As
> you can see both constructors ( Foo and Bar )  have "explitic=1". So
> Py++ has no way to find out whether a constructor explicit or not.

I disagree.  Py++ does have a way to find out.  The only time
"explicit" matters is when a constructor takes exactly one argument.
gccxml sets "explicit=1" in all cases when the number of arguments is
other than 1.  That is why you saw "explicit=1" in all of the
constructors in the previous example.  However, in the case where
there is exactly one argument, gccxml does the right thing.  Consider
the following case:

### test.h ####
struct Foo1 {};
struct Foo2 {};

struct Bar {
    explicit Bar(Foo1&); // no implicit conversion
    Bar(Foo2&); // allows implicit conversion
};
#############


### fragment of resulting xml file from gccxml ###
  <Constructor id="_10" name="Bar" explicit="1" context="_3"
access="public" mangled="_ZN3BarC1ER4Foo1 *INTERNAL* "
demangled="Bar::Bar(Foo1&)" location="f0:5" file="f0" line="5"
extern="1">
    <Argument type="_22" location="f0:5" file="f0" line="5"/>
  </Constructor>
  <Constructor id="_11" name="Bar" context="_3" access="public"
mangled="_ZN3BarC1ER4Foo2 *INTERNAL* " demangled="Bar::Bar(Foo2&)"
location="f0:6" file="f0" line="6" extern="1">
    <Argument type="_23" location="f0:6" file="f0" line="6"/>
  </Constructor>
#######################

Notice that gccxml sets "explicit=1" for the first Bar constructor,
but not for the second.

However, Py++ sets "allow_implicit_conversion" to True for both
constructors.  I think gccxml is doing the right thing here.  But I am
not so sure about Py++ behavior.  I would have assumed that the first
Bar constructor would have "allow_implicit_conversion" set to False.
I was wrong about being able to use "allow_implicit_conversion" for
this task.  Is there another way to get at the "explicit" xml tag from
the module_builder object?  Or do I need to parse the xml file or
source code separately to discover this information?

Thank you Roman for your diligent feedback.  I sincerely appreciate
the quick and thoughtful feedback you provide to everyone on this
mailing list.

Chris Bruns
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@...
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [Py++] Does pyplusplus respect explicit constructors?

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 1, 2009 at 5:46 PM, Christopher Bruns <cmbruns@...> wrote:

> I disagree.  Py++ does have a way to find out.  The only time
> "explicit" matters is when a constructor takes exactly one argument.
> gccxml sets "explicit=1" in all cases when the number of arguments is
> other than 1.  That is why you saw "explicit=1" in all of the
> constructors in the previous example.  However, in the case where
> there is exactly one argument, gccxml does the right thing.  Consider
> the following case:
>
> ### test.h ####
> struct Foo1 {};
> struct Foo2 {};
>
> struct Bar {
>    explicit Bar(Foo1&); // no implicit conversion
>    Bar(Foo2&); // allows implicit conversion
> };
> #############
>
>
> ### fragment of resulting xml file from gccxml ###
>  <Constructor id="_10" name="Bar" explicit="1" context="_3"
> access="public" mangled="_ZN3BarC1ER4Foo1 *INTERNAL* "
> demangled="Bar::Bar(Foo1&)" location="f0:5" file="f0" line="5"
> extern="1">
>    <Argument type="_22" location="f0:5" file="f0" line="5"/>
>  </Constructor>
>  <Constructor id="_11" name="Bar" context="_3" access="public"
> mangled="_ZN3BarC1ER4Foo2 *INTERNAL* " demangled="Bar::Bar(Foo2&)"
> location="f0:6" file="f0" line="6" extern="1">
>    <Argument type="_23" location="f0:6" file="f0" line="6"/>
>  </Constructor>
> #######################
>
> Notice that gccxml sets "explicit=1" for the first Bar constructor,
> but not for the second.

I didn't know that, so pygccxml didn't provided access to the information.

> However, Py++ sets "allow_implicit_conversion" to True for both
> constructors.  I think gccxml is doing the right thing here.  But I am
> not so sure about Py++ behavior.

Well, these days I would implement "allow_implicit_conversion" to be a
mix of the user desire and "explicit" attribute. But, this change will
introduce backward compatibility problem, which I would like to avoid.

> I would have assumed that the first
> Bar constructor would have "allow_implicit_conversion" set to False.
> I was wrong about being able to use "allow_implicit_conversion" for
> this task.  Is there another way to get at the "explicit" xml tag from
> the module_builder object?  Or do I need to parse the xml file or
> source code separately to discover this information?

No. I updated pygccxml package
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1761&view=rev

All you need is to write the following code:

mb = module_builder_t(...)
mb.constructors( lambda c: c.explicit == True
).allow_implicit_conversion = False

That's all

> Thank you Roman for your diligent feedback.  I sincerely appreciate
> the quick and thoughtful feedback you provide to everyone on this
> mailing list.

Wow :-). Thank you for such words!

--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@...
http://mail.python.org/mailman/listinfo/cplusplus-sig