[C++-sig] Base class defined in other header file not included in bp::bases<>

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

[C++-sig] Base class defined in other header file not included in bp::bases<>

by Haridev, Meghana :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi Folks,

 

I’m having some trouble generating boost-python wrapper code using pyplusplus for a derived class which has one of its base classes defined in another file.

 

Simple scenario:

 

mydir/

            other.hpp:

            class baseB{ };

 

            hierarchy.hpp:

 

#include "other.hpp"

class baseA{ };

class derivedC: public baseA, public baseB{ };

 

            generate_code.py:

            import os

from pyplusplus import module_builder

 

mb = module_builder.module_builder_t( files=['hierarchy.hpp'] )

mb.build_code_creator( module_name='inherit' )

mb.code_creator.user_defined_directories.append( os.path.abspath('.') )

mb.write_module('boost_hierarchy.cpp')

 

-------------------------------------------------------------------------------------------------------------------------

Generated code (boost_hierarchy.cpp) looks like this:

 

// This file has been generated by pyplusplus.

#include "boost/python.hpp"

#include "hierarchy.hpp"

 

namespace bp = boost::python;

 

BOOST_PYTHON_MODULE(inherit){

    bp::class_< baseA >( "baseA" );

 

    bp::class_< derivedC, bp::bases< baseA > >( "derivedC" );

}

 

How can I get pyplusplus to add ‘baseB’ to bp::bases<> for ‘derivedC’ class when ‘baseB’ class is defined in another file (present in the same directory or different directory)?

 

When I move the definition of ‘baseB’ class to hierarchy.hpp, boost wrapper for ‘derivedC’ is correctly generated as: bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

 

Thanks,

-Meghana.

 


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

Re: [C++-sig] Base class defined in other header file not included in bp::bases<>

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 7/13/06, Haridev, Meghana <mharidev@...> wrote:
> Hi Folks,
> I'm having some trouble generating boost-python wrapper code using
> pyplusplus for a derived class which has one of its base classes defined in
> another file.

> How can I get pyplusplus to add 'baseB' to bp::bases<> for 'derivedC' class
> when 'baseB' class is defined in another file (present in the same directory

If "other.hpp" presents in the same directory it will just work.

> or different directory)?

In this case baseB class will be excluded. The idea behind such
behaviour is next:
there is one directory that contains library interface and many
directories that contain
implementation details. So, by default pyplusplus excludes from generation all
declarations defined in other directories. You can find more information here:
http://language-binding.net/pyplusplus/tutorials/module_builder/module_builder.html

Next few lines of code will include baseB:

mb = module_builder_t( ... )
mb.class_( 'baseB' ).include()
#or if you want to include all declarations from directory Y:
mb.decls( header_dir=Y ).include()

I hope, this will help you.

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

Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>

by Haridev, Meghana :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi Roman,

Thanks for your help!

 

Another question:

 

Say that I have already written manually boost-python wrappers for baseB class (present in different directory) and have a shared library for it.

 

Now I want to use pyplusplus to generate the boost-python wrappers for derivedC class.

 

Like you suggested, if I add: mb.class_( 'baseB' ).include()

It will give me the following generated code:

 

    bp::class_< baseB >( "baseB" );

    bp::class_< baseA >( "baseA" );

    bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

 

But what if I don't want pyplusplus to expose baseB again (I am going to link baseB’s shared library with derivedC’s boost wrapper) but I still want it to appear in bp::bases - is it possible to do that using pyplusplus?

 

In other words, I want the generated code to look like this:

 

    /* bp::class_< baseB >( "baseB" );  - Do not want to generate */

    bp::class_< baseA >( "baseA" );

    bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

 

Thanks,

-Meghana.

 

-----Original Message-----
From: c++-sig-bounces@... [mailto:c++-sig-bounces@...] On Behalf Of Roman Yakovenko
Sent: Wednesday, July 12, 2006 10:19 PM
To: Development of Python/C++ integration
Subject: Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>

 

On 7/13/06, Haridev, Meghana <mharidev@...> wrote:

> Hi Folks,

> I'm having some trouble generating boost-python wrapper code using

> pyplusplus for a derived class which has one of its base classes defined in

> another file.

 

> How can I get pyplusplus to add 'baseB' to bp::bases<> for 'derivedC' class

> when 'baseB' class is defined in another file (present in the same directory

 

If "other.hpp" presents in the same directory it will just work.

 

> or different directory)?

 

In this case baseB class will be excluded. The idea behind such

behaviour is next:

there is one directory that contains library interface and many

directories that contain

implementation details. So, by default pyplusplus excludes from generation all

declarations defined in other directories. You can find more information here:

http://language-binding.net/pyplusplus/tutorials/module_builder/module_builder.html

 

Next few lines of code will include baseB:

 

mb = module_builder_t( ... )

mb.class_( 'baseB' ).include()

#or if you want to include all declarations from directory Y:

mb.decls( header_dir=Y ).include()

 

I hope, this will help you.

 

--

Roman Yakovenko

C++ Python language binding

http://www.language-binding.net/

_______________________________________________

C++-sig mailing list

C++-sig@...

http://mail.python.org/mailman/listinfo/c++-sig


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

Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 7/13/06, Haridev, Meghana <mharidev@...> wrote:
> In other words, I want the generated code to look like this:
>     /* bp::class_< baseB >( "baseB" );  - Do not want to generate */
>
>     bp::class_< baseA >( "baseA" );
>
>     bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

It is possible, but you will have to understand a little how code
creators works.
There are few ways to solve the problem.

1. Exclude baseB from being generated, and add it manually to derivedC.
    Take a look on pyplusplus/code_creators/class_declaration.py -
class "class_t",
    method - _generate_bases. You will have to redefine this method, something
    like this:

    def my_generate_bases( self, base_creators ):
        if self.declaration.Name != 'derivedC':
            run current code
        else:
            your logic is going her

   pyplusplus.code_creators.class_t._generate_bases = my_generate_bases

2. You can include baseB to be generated, but instead of generating code it
    will generate empty string:

    mb = module_builder_t( ... )
    mb.build_code_creators( ... )

    from pyplusplus import code_creators

    baseB = mb.class_( 'baseB' )

    baseB_creators \
        = code_creators.creator_finder.find_by_declaration(
                     lambda decl: decl is baseB #what to look
                     , mb.code_creator ) #where
    #now, we have to leave only class_t and class_wrapper_t code creators
     relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t )
     baseB_creators = filters( lambda c: isinstance( c, relevant_clss ) )
     for c in baseB_creators:
         c.create = lambda self: ''

Second approach is better, because in this case pyplusplus will take
into account
all data available from baseB, but will not generate code.


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

Re: [C++-sig] Base class defined in other header file notincludedin bp::bases<>

by Haridev, Meghana :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi Roman,

 

I tried your second approach since it goes better with our environment. I made some changes (highlighted in bold below) to get it to run. It works fine till I come to the point where I need to write the module to multiple files (or even just a single file).

 

mb = module_builder_t( ... )

mb.class_('baseB').include() #because baseB defined in header file in diff directory

mb.build_code_creators( ... )

 

from pyplusplus import code_creators

 

baseB = mb.class_( 'baseB' )

baseB_creators \

        = code_creators.creator_finder.find_by_declaration(

                     lambda decl: decl is baseB #what to look

                     , mb.code_creator ) #where

 

#now, we have to leave only class_t and class_wrapper_t code creators

relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t )

 

baseB_creators = filter( lambda c: isinstance( c, relevant_clss ), baseB_creators )

 

for c in baseB_creators:

         c.create = lambda self: ''

 

mb.split_module( os.path.abspath('.') )

 

 

I get this error:

 

  File "generate_code.py", line 80, in export

    mb.split_module( os.path.abspath('.') )

  File "…pyplusplus/module_builder/builder.py", line 224, in split_module

    file_writers.write_multiple_files( self.code_creator, dir_name )

  File "…pyplusplus/file_writers/__init__.py", line 32, in write_multiple_files

    mfs.write()

  File "…pyplusplus/file_writers/multiple_files.py", line 253, in write

    map( self.split_class, class_creators )

  File "…pyplusplus/file_writers/multiple_files.py", line 171, in split_class

    self.__split_class_impl( class_creator )

  File "…pyplusplus/file_writers/multiple_files.py", line 148, in __split_class_impl

    , [class_creator] ))

  File "…pyplusplus/file_writers/multiple_files.py", line 126, in create_source

    answer.append( creator.wrapper.create() )

TypeError: <lambda>() takes exactly 1 argument (0 given)

 

 

Seems like it doesn’t like the empty string we give to create…

 

I also tried just writing the module to a single file:

mb.write_module( os.path.join( os.path.abspath('.'), settings.module_name + '.cpp' ) )

 

  File “…pyplusplus/module_builder/builder.py", line 215, in write_module

    file_writers.write_file( self.code_creator, file_name )

  File "…pyplusplus/file_writers/__init__.py", line 28, in write_file

    sf.write()

  File "…pyplusplus/file_writers/single_file.py", line 24, in write

    self.write_file( self.file_name, self.extmodule.create() )

  File "…pyplusplus/code_creators/code_creator.py", line 93, in create

    code = self._create_impl()

  File "…pyplusplus/code_creators/module.py", line 195, in _create_impl

    code = compound.compound_t.create_internal_code( self.creators[index:] )

  File "…pyplusplus/code_creators/compound.py", line 56, in create_internal_code

    internals = map( lambda expr: expr.create(), creators )

  File "…pyplusplus/code_creators/compound.py", line 56, in <lambda>

    internals = map( lambda expr: expr.create(), creators )

TypeError: <lambda>() takes exactly 1 argument (0 given)

 

Any suggestions?

 

Thanks,

-Meghana.

 

 

-----Original Message-----
From: c++-sig-bounces+mharidev=qualcomm.com@... [mailto:c++-sig-bounces+mharidev=qualcomm.com@...] On Behalf Of Roman Yakovenko
Sent: Friday, July 14, 2006 1:35 AM
To: Development of Python/C++ integration
Subject: Re: [C++-sig] Base class defined in other header file notincludedin bp::bases<>

 

On 7/13/06, Haridev, Meghana <mharidev@...> wrote:

> In other words, I want the generated code to look like this:

>     /* bp::class_< baseB >( "baseB" );  - Do not want to generate */

>     bp::class_< baseA >( "baseA" );

>     bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

 

It is possible, but you will have to understand a little how code

creators works.

There are few ways to solve the problem.

 

1. Exclude baseB from being generated, and add it manually to derivedC.

    Take a look on pyplusplus/code_creators/class_declaration.py -

class "class_t",

    method - _generate_bases. You will have to redefine this method, something

    like this:

 

    def my_generate_bases( self, base_creators ):

        if self.declaration.Name != 'derivedC':

            run current code

        else:

            your logic is going her

 

   pyplusplus.code_creators.class_t._generate_bases = my_generate_bases

 

2. You can include baseB to be generated, but instead of generating code it

    will generate empty string:

 

    mb = module_builder_t( ... )

    mb.build_code_creators( ... )

 

    from pyplusplus import code_creators

 

    baseB = mb.class_( 'baseB' )

 

    baseB_creators \

        = code_creators.creator_finder.find_by_declaration(

                     lambda decl: decl is baseB #what to look

                     , mb.code_creator ) #where

    #now, we have to leave only class_t and class_wrapper_t code creators

     relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t )

     baseB_creators = filters( lambda c: isinstance( c, relevant_clss ) )

     for c in baseB_creators:

         c.create = lambda self: ''

 

Second approach is better, because in this case pyplusplus will take

into account

all data available from baseB, but will not generate code.

 

 

--

Roman Yakovenko

C++ Python language binding

http://www.language-binding.net/

_______________________________________________

C++-sig mailing list

C++-sig@...

http://mail.python.org/mailman/listinfo/c++-sig


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

Re: [C++-sig] Base class defined in other header file notincludedin bp::bases<>

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 7/26/06, Haridev, Meghana <mharidev@...> wrote:
> for c in baseB_creators:
>
>          c.create = lambda self: ''
^^^^^^^^^^^^^^^^^^^^^
c.create = lambda: ''

Please try this, it should work.

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

Re: [C++-sig] Base class defined in other header file notincludedinbp::bases<>

by Haridev, Meghana :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Great - that works :-)
Thanks for your help!

-----Original Message-----
From: c++-sig-bounces@... [mailto:c++-sig-bounces@...] On
Behalf Of Roman Yakovenko
Sent: Wednesday, July 26, 2006 12:07 PM
To: Development of Python/C++ integration
Subject: Re: [C++-sig] Base class defined in other header file
notincludedinbp::bases<>

On 7/26/06, Haridev, Meghana <mharidev@...> wrote:
> for c in baseB_creators:
>
>          c.create = lambda self: ''
^^^^^^^^^^^^^^^^^^^^^
c.create = lambda: ''

Please try this, it should work.

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

Re: [C++-sig] Base class defined in other header file notincludedinbp::bases<>

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 7/26/06, Haridev, Meghana <mharidev@...> wrote:
> Great - that works :-)
> Thanks for your help!

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

Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>

by Rocketman@JSC :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have a few questions about this thread.  Basically I have the same problem, my bases for a binding are not getting picked up cause they are in a separate library.

I've tried solution #2 and here's a snippet from the Py++ generator file:

<<Start Snippet=================================================================

mb.build_code_creator( module_name='SmpSim' )

# This is an attempt at getting the bases included for Vehicle

baseModel = mb.class_('Model')

print type(mb.code_creator)

baseModel_creators = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseModel, mb.code_creator, False )

vehicle = mb.class_('Vehicle') # This is the class I need to add the bases to
vehicle = ( code_creators.class_t, code_creators.class_wrapper_t )

baseModel_creators = filter( lambda c: isinstance(c, vehicle), baseModel_creators)

for c in baseModel_creators:
    c.create = lambda: ''
<<End Snippet=================================================================

and I get the following error:

Traceback (most recent call last):
  File "/data/home/scott/eclipse/Smp_lib/generate_code.py", line 157, in <module>
    baseModel_creators = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseModel, mb.code_creator, False )
  File "/data/apps/oss/lib/python/pyplusplus/code_creators/algorithm.py", line 87, in find_by_declaration
    , search_area )
TypeError: 'module_t' object is not iterable

I'm sure this is something I'm doing wrong, but I looked at the API's and could not figure it out.  Does anyone have an idea what I'm doing wrong here?

Thanks in advance for any help.

Scott

Roman Yakovenko wrote:
On 7/13/06, Haridev, Meghana <mharidev@qualcomm.com> wrote:
> In other words, I want the generated code to look like this:
>     /* bp::class_< baseB >( "baseB" );  - Do not want to generate */
>
>     bp::class_< baseA >( "baseA" );
>
>     bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

It is possible, but you will have to understand a little how code
creators works.
There are few ways to solve the problem.

1. Exclude baseB from being generated, and add it manually to derivedC.
    Take a look on pyplusplus/code_creators/class_declaration.py -
class "class_t",
    method - _generate_bases. You will have to redefine this method, something
    like this:

    def my_generate_bases( self, base_creators ):
        if self.declaration.Name != 'derivedC':
            run current code
        else:
            your logic is going her

   pyplusplus.code_creators.class_t._generate_bases = my_generate_bases

2. You can include baseB to be generated, but instead of generating code it
    will generate empty string:

    mb = module_builder_t( ... )
    mb.build_code_creators( ... )

    from pyplusplus import code_creators

    baseB = mb.class_( 'baseB' )

    baseB_creators \
        = code_creators.creator_finder.find_by_declaration(
                     lambda decl: decl is baseB #what to look
                     , mb.code_creator ) #where
    #now, we have to leave only class_t and class_wrapper_t code creators
     relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t )
     baseB_creators = filters( lambda c: isinstance( c, relevant_clss ) )
     for c in baseB_creators:
         c.create = lambda self: ''

Second approach is better, because in this case pyplusplus will take
into account
all data available from baseB, but will not generate code.


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

Re: Base class defined in other header file not includedin bp::bases<>

by Roman Yakovenko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Sep 7, 2008 at 12:48 AM, Rocketman@JSC <snemeth@...> wrote:
> Roman Yakovenko wrote:
>>
>> On 7/13/06, Haridev, Meghana <mharidev@...> wrote:
>>> In other words, I want the generated code to look like this:
>>>     /* bp::class_< baseB >( "baseB" );  - Do not want to generate */
>>>
>>>     bp::class_< baseA >( "baseA" );
>>>
>>>     bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );

Did you read the following document
http://language-binding.net/pyplusplus/documentation/multi_module_development.html
?

I think, it will give you easy and clear way to achieve what you want.

HTH

--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
_______________________________________________
C++-sig mailing list
C++-sig@...
http://mail.python.org/mailman/listinfo/c++-sig
LightInTheBox - Buy quality products at wholesale price!