[Ns-developers] Status of Python bindings

Mathieu Lacage mathieu.lacage at sophia.inria.fr
Tue May 6 10:30:35 PDT 2008


On Tue, 2008-05-06 at 00:56 +0100, Gustavo Carneiro wrote:

>         > 2. Once in a while, a developer does something like ./waf
>         --scan-bindings,
>         > which calls pybindgen in gccxml mode, and outputs a
>         ns3module_generated.py
>         > file (or several files, one per module, if the generated
>         file ends up being
>         > large)
>         
>         
>         +1 to the latter option (one file per ns3 module)
> 
> It is non-trivial work, but I can do it.

+1 beer !


>         I would be fine with re-running --scan-bindings (2) regularly
>         to attempt
>         to generate the bindings for our codebase provided we can
>         agree that if
>         it fails and if you cannot fix it (because you are dead or
>         just away for
>         an extended period of time :), we can just use its output as a
>         starting
>         point and then, write the missing python code by hand. To
>         summarize, if
>         2) works sufficiently well that the generated code is readable
>         and
>         editable and that we almost never have to hack its output, I
>         am all for
>         it because I know that, at worst, I can hack it without
>         relying on you
>         being alive.
> 
> But of course the code will be perfectly readable and hackable.

+2 beer !

> 
> Only the customizations for supporting the core module, as well as
> simulador schedule, will be hard to read, but that can't be helped.
> If you want a nice Python API you need custom code for certain low
> level stuff.  That would be true for _any_ python binding technology
> you decided to use.

yes.

> 
> As for me disappearing, Python bindings for NS-3 would be in no worse
> shape than NS-3 core module would be if you disappeared and took all
> that C++ template black magic with you... :-) 

yep.


>         Which clearly outlines the underlying C++ function and its
>         python
>         equivalent.
> 
> If the python function name is different from the C++ one you are
> probably doing something wrong.  Different <whatever> names in Python

There are some cases where you want to do that to wrap some non-trivial
C++ APIs to python: For example, the Simulator::Schedule methods cannot
be easily wrapped and I see, as expected, that you are using renaming
tricks to wrap them.

>  and C++ will only cause confusion for NS-3 programmers, who often
> need to switch back and forth between Python and C++ and do not want
> to learn two similar but subtly different APIs.  So I really don't
> agree making the python name mandatory will be helpful. 

ok.

> 
> 
>         
>         Now, I do understand why you took the simpler path of avoiding
>         the
>         redundant information everywhere because the number of cases
>         where
>         CppFunctionName will be different from PyFunctionName will be
>         very small
>         but, that shortcut really does muddy the conceptual model of
>         how things
>         work.
>         
>         So, I can see a couple of ways to deal with this 'muddying':
>          a) become pedantic as suggested above at the cost of extra
>         verbosity
>         and pain
>          b) structure in the API in a different way which moves all
>         the
>         assumptions about the C++ -> python names to a single clear
>         location.
>         
>         I think that a) is really too painful so, what could b) look
>         like ?
> 
> Bah.. you are just using the old trick of offering a worse alternative
> as option so that the one you prefer does not seem so bad by
> comparison... :P

My boss gave me hands-on courses in rhetoric :)

> But I am willing to give it a fair chance..

thank you :)

> .
>  
>         Here
>         is a proposal:
>         
>         # describe the C++ code we want to wrap
>         header = CppHeader ('a.h')
>         header.add_function ('CppFunctionName', return_type, args)
>         A = header.add_class ('CppClassName, ...)
>         A.add_method (...)
>         ns3 = header.add_namespace ('ns3')
>         ns3.add_function (...)
>         ns3.add_class (...)
> 
> Since I really want PyBindGen to be applicable to pure C code as well
> as C++, this would have to be just class Header, not CppHeader. 

I thought that we could have a CHeader class to mirror CppHeader for
that case.

> 
> 
>         
>         # describe how to wrap the above C++ code.
>         mod = PyModule ('a')
>         mod.wrap_header (header)
>         mod.generate_output (out_file)
> 
> Personally, I don't grok this model very well.  Types and functions
> belong to namespaces, not headers.  When you are programming in C++
> you don't think in terms of which header file each type lives in, you
> think about namespaces.  Or at least I do.

I suspect that my main concern is that I have not yet been able to
really understand the model implemented by your API which is why I have
tried to come up with a model which made sense to me. So, I wrote a
couple more examples attached to this email to try to get a better
handle on the way your API is structured: feel free to add them to your
examples directory.

Thinking some more about your API, I wrote the following summary: would
you mind point out what I misunderstood ?

The Module python class represents a set of python bindings to generate
within a top-level python module. If you write:
mod = Module ('a')
mod.add_ (...)
you effectively create a python module 'a' which contains:
  - a set of python functions to wrap c++ functions
  - a set of python classes to wrap c++ classes
  - a set of python modules to wrap c++ namespaces
  - a set of python inner classes to wrap c++ inner classes

Is the above paragraph correct ?

Part of my confusion with this API might simply be that this 'Module'
python class does not necessarily represent a single python module: it
_can_ represent one but it can also represent a python package. So,
maybe the simple solution to my complaints would be to find a better
name for that class such as 'Binding' and use it as follows:

binding = Binding ('TopLevelModuleName')
binding.add_ (...)

Now, while writing the attached examples, it occured to me that a small
set of minor syntactical changes would also improve the API:
  - add_include ('"a.h"') -> add_include ('a.h')
  - C = CppClass (...), add_class (C) -> C = add_cpp_class (...)
  - add_method (CppMethod (...)) -> add_cpp_method (...)
  - Function (return_type, name, args) -> Function (name, return_type,
args). The same would hold for add_cpp_method, of course.

[snip]

Mathieu
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ex.tar.gz
Type: application/x-compressed-tar
Size: 1703 bytes
Desc: not available
Url : http://mailman.isi.edu/pipermail/ns-developers/attachments/20080506/8aab360c/ex.tar.bin


More information about the Ns-developers mailing list