[C++-sig] pyplusplus tutorials & GUI wizard

Roman Yakovenko roman.yakovenko at gmail.com
Sun Feb 5 08:37:22 CET 2006


On 2/2/06, Matthias Baas <baas at ira.uka.de> wrote:
> > I did not test my changes with GCC. I will test them. As a temporal solution
> > you can remove the wrapper code creator. Try to use finalize method on
> > class code creator.
>
> Uhm, I didn't see any finalize() method anywhere...?
> By "class code creator" you probably don't mean the object I create with
> module_creator.creator_t(), right? Then how do I obtain the class code
> creator that corresponds to my particular class?

Take a look on this UML diagram. It is incomplete but will give you some
understanding of existent code creators:

http://www.language-binding.net/pyplusplus/code_creators.png

module_creator.creator_t() function returns instance of class module_t.
This class contains module_body_t code creator( accessible via body property ).
As you can see from the UML diagram they both derive from compound_t code
creator. This means that they contain other code creators. You can get access
to them via "creators" property. There are few functions that will
help you to find
particular code creator. You can find them in code_creators\algorithm.py module.
Take a look on py_easybmp example. You can also take a look on unit test:

http://tinyurl.com/ckux9
( see creator_finder_tester_t tester )


> >> Basically, it works, but there is still a problem. Whenever I add a new
> >> class there's a new header file that gets included into *all* files
> >> automatically which wouldn't be necessary. So the files still change and
> >> get recompiled. [...]
> >
> > The problem is that I ( pyplusplus ) can not build set of required files.
> > Consider next case:
> > file a.h
> >   class A{};
> >
> > file b.h
> >   #include "a.h"
> >
> >   class B{};
> >
> > You want to export A and B. pyplusplus will generate include to a.h
> > and b.h.
>
> Why don't you just include the header that actually defines the
> corresponding class (i.e. "a.h" when wrapping A and "b.h" when wrapping
> B)?

This is exactly what I do. May be I did not explain my self well.

> >> (Just out of curiosity, how do you determine whether a file has to be
> >> written or not, do you really compare the contents of the existing file
> >> with the data you're about to write?)
> >
> > Yes, this is the only way, that I know, that does it reliably.
> > Don't warry about performance. It takes only 90 - 100 second to create\generate
> > Boost.Python bindings for TnFOX, 625 files.
>
> Do you generate the bindings on a local drive or on a network drive?
> Maybe performance could become an issue once the data has to be
> transferred over a network...?
> By the way, an alternative to comparing the entire file could be storing
> a checksum (such as CRC32, see zlib.crc32()) somewhere at the top of the
> file and comparing only that value.
> But so far, this is really a minor issue. If I get the above header
> thing sorted out, the current performance is good enough for me (and I
> am already on a network drive).

I test it on local drive only. Also on my laptop the drive speed is
5400. So the
performance are really important. Right now I am quite satisfied with
performance.
I see from your posting that you too. If it will become an issue, I am
sure we can find some way to solve it.

> >> def filter(decl):
> >>      return decl.name in [...<a list of class names>...]
> >>
> >> But now that I come to think about it, I don't understand why this works
> >> at all. I noticed that the filter function is also applied to class
> >> methods in which case the function returns False. But why are the
> >> methods then exposed? (I thought this would be a way to filter out the
> >> protected methods, but obviously this is not how it's supposed to work...)
> >
> > You found a bug. Thanks. I will fix it.
>
> Does that mean my above filter won't work anymore (as it would produce
> 'empty' classes) and I will have to return True when called on the
> actual class methods? (and if so, how would the updated filter look like?)

First of all you are right. Now small explanation how filtering works.
pygccxml defines make_flatten function. This function takes declaration
and returns list of all declarations found\located\defined in that declaration,
including it self. Filter functions use this function to create list
that contains
all declarations and after this then call "match" function on every declaration.
This approach has advantage ( fine control ) and disadvantage(
a little bit complex "match" function ).

Now how do you write filter function:

def should_stay(decl):
    if isinstance( decl.parent, pygccxml.declarations.class_t ):
        return True #This will leave all declarations defined under classes
   if ....

if you need even grater control on exported declarations you can use
next filter:

   if isinstance( decl, pygccxml.declarations.member_calldef_t):
      if decl.access_type != pygccxml.declaration.ACCESS_TYPES.PUBLIC:
           return False

Be sure to take a look on py_qtxml example: http://tinyurl.com/9uhv4
This examples reuse Qt XML class naming convention. It leaves only classes
that their name start with 'QDom' or 'QXml'. Also it removes
constructor, that as input
takes a pointer to implementation details class instance.

An other example is py_date_time: http://tinyurl.com/e44kh. This example
defines pretty complex "should_stay_ function. This is also should help you.

I hope this was helpful. Also I fixed bug you reported in previous
post. Thanks for
reporting them. As always fixes in CVS.

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

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



More information about the Cplusplus-sig mailing list