1
README FOR PLPLOT-GNOME 2 PYTHON BINDING
2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
-- describes the strategy used to create the PLplot-Gnome2 python
5
binding for the GCW driver and PlplotCanvas APIs
8
Thomas J. Duck <tom.duck@dal.ca>
14
The GCW driver API is autmoatically generated using PyGtk's h2def
15
and codegen utilities.
17
First, the h2def program is used to create the gcw.defs file from
18
gcw.h. The defs files contain the API in an easy to parse format,
19
and will likely prove helpful in automating the construction of
20
bindings for other languages.
22
Next, codegen uses the defs file to create gcw.c, which contains
23
the function wrappers. In the process, the gcw.override file is
24
consulted to fine tune the binding by overriding or ignoring the
25
wrappers for specified functions.
27
The gcwmodule.c file does the module initialization, and imports
28
the wrapped functions into python.
33
The PlplotCanvas API is also automatically generated, and in a
34
similar way to the GCW driver API. There are a few important
37
A key criterion in wrapping PlplotCanvas is that it should
38
interoperate with the PyGtk binding.
40
To understand how the binding works, it is important to
41
understand the PlplotCanvas construction. PlplotCanvas is a
42
GTK/Gnome widget that is derived from GnomeCanvas. It defines
43
methods to control various aspects of the object and its
44
presentation. PlplotCanvas also wraps the entire PLplot API so
45
that the PLplot functions can be called in an object-oriented
48
Now, on to the binding description and construction:
50
The top level class is plplotcanvas.Canvas, and it is defined
51
in plplotcanvas.py. plplotcanvas.Canvas inherits from
52
cplplotcanvas.Canvas, which is automatically generated as
55
plplotcanvas.Canvas is a small piece of code that contains only
56
a few special methods. When a method is called on
57
plplotcanvas.Canvas, it first checks to see if it inherited that
58
method from cplplotcanvas.Canvas. If not, then it uses __getattr__
59
to check for the method in the standard PLplot python API. Failing
60
that, an exception is thrown.
62
cplplotcanvas.Canvas wraps the C PlplotCanvas code, and is
63
automatically generated using PyGtk's h2def and codegen utilities,
64
as described above for the GCW driver API. Codegen automatically
65
handles PlplotCanvas methods with constant arguments. In some
66
special cases where something different needs to be done
67
(e.g., plplot_canvas_new constructor needs to set the "aa" property
68
to TRUE), or speed is important, cplplotcanvas.override defines the
69
binding code explicitly.
71
Methods using pointers or anything else that codegen doesn't
72
understand are put into the ignore-glob of cplplotcanvas.override
73
so that codegen doesn't try to wrap them. Because those methods
74
aren't wrapped and therefore aren't inherited by plplotcanvas.Canvas,
75
they are the ones that default to the standard PLplot python API via
76
__getattr__, as described above.
78
So, this is not a true binding per se: Where it is inconvenient
79
to do a wrapping, the binding simply replaces the functionality.
81
That's all there is to it.
83
Why not just let the standard python API handle all method calls by
84
by defining all PLplot functions in the ignore-glob? First, codegen
85
is *required* to make a binding for the PlplotCanvas class that is
86
compatible with PyGtk. The codegen wrappers will be much faster than
87
the python calls, and so there doesn't seem to be any good reason not
88
to let codegen wrap what it can.
90
As the PLplot API grows, most functions will be automatically added
91
as methods to cplplotcanvas.Canvas. Occasionally a new function will
92
cause a compile error or warning, and these are the functions that
93
need to be specified in the ignore-glob so that they are handled
94
via the __getattr__ method of plplotcanvas.Canvas.