Python Support


Detailed Description

As of v0.86, the python bindings moved from a pyste based generator to a pyplusplus based generator. This has meant a significant improvement in bindings quality as pyste required substantial patching to get it to generate suitable output for TnFOX, but also that pyplusplus generates better quality output anyway. Nevertheless, it took till v0.87 to get both the bindings and pyplusplus itself up to a reasonable state - my thanks to Roman Yakovenko for the tireless work he has put into pyplusplus, most especially that he has spent so much time on getting the TnFOX bindings up to scratch.

One of the big advantages of pyplusplus over pyste is that you can programmatically set call policies and patch in code. The many days of manually writing policies that pyste required were effectively wasted time when viewed from this context - however, it also means that the pyplusplus bindings are far more maintainable than pyste ones. And the pyste ones were already far more maintainable than any SWIG based solution.

Current issues with the python bindings which will hopefully get fixed soon:

How to build the bindings

TnFOX's Python bindings are almost entirely automatically generated and you can find the necessary files in the Python directory. You will also need Python v2.4 or later and the Boost library v1.34 or later (or else patch in my void * support patch into an earlier version).

You'll also need a modern compiler such as MSVC7.1 or later or GCC v3.22 or later (GCC v3.4 or later is far faster, so you should use that instead. GCC v4.0 or later comes with my symbol visibility patch which very substantially improves load times)

You'll also need a fast computer. Anything using this much compile-time introspection takes an age but you can rest easy knowing that for every two years hence compilation speed should double. In only a few years, it'll take no more than five minutes or so. Until then, distributed compilation is very useful as are multi-processor machines - and you can tell scons to use as many processors as you have using the -j switch. You should always run one more build than there are processors in your system eg; two for a uniprocessor system, three for a dual core system etc.

You also need a minimum of 1Gb RAM. This is for linking the bindings, which takes a huge amount of RAM. Anything less swaps to hell and takes forever.

Place Boost into a directory called "boost" next to the TnFOX directory. Overwrite the files in Boost.Python with the contents of BoostPatches.zip. Get a bjam from somewhere (see boost docs). Run bjam "-sBUILD=release" in boost/libs/python/build (use debug if you're building a debug version). This should build a TnFOX customised boost.python library - no compile errors should occur, but it should refuse to link (this is deliberate).

Install gccxml, pygccxml and pyplusplus.

Open a command window and go into the TnFOX/Python directory. If you have changed the header files of TnFOX (eg; through upgrading the version), make VERY sure you delete the fx.xml file first - this is the cache of parsing the TnFOX headers - and also delete the generated directory as pyplusplus uses the existing output to speed up its operation.

Run 'python create_tnfox.py'. After a few minutes it should return. If there is a file called patch.diff in the Python directory then apply this using:

cd generated
patch -p1 < ../patch.diff
As pyplusplus improves, the requirement to do this patch will disappear.

Run scons. This part takes between an hour and six hours depending on how fast your machine is.

Note:
If using GCC, you really want to use a -fvisibility enabled version (>=v4.x) of GCC if possible as it will reduce the size of the TnFOX shared object by around 20Mb and you will reduce load times for anything linked against TnFOX.so from six minutes to four seconds :). You will also need v1.3.2 or later of Boost.
Afterwards, it's as simple as
from TnFOX import *
... to begin writing powerful portable GUI based apps from Python!

Features:

In fact it's easier to list what doesn't work rather than what does which is the overriding quantity - but off the top of my head: Furthermore I've implemented a number of automatic conversions where TnFOX classes transparently become Python ones and vice versa: If you look inside the Python directory, there is a "FXPy examples" directory containing some of the same examples that come with FXPy except altered to use TnFOX. The changes in most cases were trivial, but you should note that these python bindings are automatically generated rather than by hand, so useful behaviour like FXPy had is not possible:

Caveats:

Not everything can be supported. Python and C++ are two very different languages which is why they complement each other so well. Things that are not supported and never will be supported: And then also there's a long list of things which will be added or fixed with time: Finally, there is the issue of lifetime management. Boost.Python allows you to tie the lifetime of things together to prevent dangling references eg; you get the address() from a QBlkSocket and delete the QBlkSocket - now the address is clearly no longer valid unless you made a copy of it which is exactly what has been enforced.

As it happens, actually in this case as a QHostAddress is copyable, a copy is made silently for you. But the point remains valid - wherever I have had a choice, I erred on the side of caution and chose anything returned (all reference and pointer types - values are copied as are const references when the object has a copy constructor) to live only as long as the thing you got it from. Hence things like FXApp::getWindowAt() where the window returned would almost certainly outlive the reference you temporarily got from FXApp::instance() will in fact become invalid when your FXApp reference is killed. If you think I was being over-zealous, please post to the newsgroup below stating why with a good example of why alternative behaviour would be better and still safe!

If you want support for these bindings, please join the tnfox-discussion
at
lists.sourceforge.net mailing list and ask there.


Classes

class  FXPythonException
 An exception originally thrown within Python. More...
class  FX::FXPython
 Miscellaneous Python facilities. More...
class  FX::FXPythonInterp
 An instance of the python interpreter. More...
class  FX::FXPython_CtxHold
 Wraps context sets in an exception-proof fashion. More...
class  FX::FXCodeToPythonCode< vector, length >
 Allows you to convert calls to C++ code to calls to Python code. More...


(C) 2002-2008 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Jun 13 21:55:19 2008 for TnFOX by doxygen v1.5.6