Wednesday, June 22, 2011

PyQt API #1, PyQt API #2 and PySide compatibility

One year after its creation, the new Python library for Qt named PySide has reached version 1.0 for a while now. Even if Python developers are still hesitating to use intensively this new library despite its permissive license (LGPL), the fact is that PySide has brought a constructive competition in a field which was exclusively dominated by PyQt, the historical Python-Qt library which is still distributed under non-permissive licensing terms (GPL or commercial license). So, a lot of projects have already chosen to make the necessary changes to be able to migrate from PyQt to PySide when it's time, i.e. when PySide is mature enough (version 1.0 is still moving fast: very nasty bugs have been fixed between v1.0.0 and the latest v1.0.3 release). For example, in scientific Python ecosystem, IPython (with its new Qt frontend which will be integrated in a future Spyder version), Matplotlib and Enthought Tool Suite have made the choice to move forward.

PySide is intended to be compatible with PyQt's API #2 which was introduced with PyQt v4.6 (this is the default API for Python 3). So the first step to migrate from PyQt to PySide is to switch from API #1 to API #2, which means no more QString, QStringList or QVariant objects (replaced by Python objects):

For Spyder, I chose to deal with this transition period with the following solution. The idea is to be able to test alternatively (and without changing too much code) the three cases (PyQt API #1, PyQt API #2 and PySide) by implementing a transitional package that your code will import instead of importing directly PyQt or PySide. See for example the Spyder's Qt transitional package :
(in the rest of the code, all import PyQt4.QtGui statements are for example replaced by import spyderlib.qt.QtGui)

At first, I thought that the best solution was to migrate directly to PyQt API #2, hence breaking the compatibility with PyQt API #1 (it's hard to resist to the temptation of getting rid of QString and QVariant objects!). But then I realized that other projects using the Spyder's widgets (source code editor, array editor or dictionnary editor widgets) like guidata would be forced to perform this migration at the same time: this was not acceptable and would lead to maintain two different versions of Spyder, one compatible with API #1 (Spyder v2.1) and the other with API #2 (Spyder v2.2). So I'm now convinced that the best solution is to change the code to make it compatible with both APIs and this is quite easy to do (it's now done in v2.1): QString objects can be used implicitely and QVariant objects and methods may be replaced by simple conversion functions (see 'from_qvariant' and 'to_qvariant' in spyderlib's code):

Here is the example of the NumPy arrays editor widget which is compatible with PyQt API #1, API #2 and PySide:

Another difference between PyQt and PySide is the way the QFileDialog static methods are wrapped. In PyQt, getOpenFileName returns only the filename. With PySide, the same function returns a tuple containing the filename and the selected filter. So we have to deal with it and the best way is to write wrappers that ensure full compatibility with PyQt (API #1 and #2) and PySide. This is done here:

There are still a lot of bug to fix for Spyder to be fully compatible with PySide (only Spyder's light mode is running with PySide, with very minor bugs) but that's a great start!

Wednesday, June 15, 2011

Welcome to Spyder's blog

This is the Spyder's official blog.

Of course this is the right place to keep you informed about the new features, the philosophy and the future directions of the project. But Spyder is more than a development environment: it's a realistic and very efficient replacement for MATLAB or IDL. In other words, Spyder is intimately related to the scientific Python ecosystem (the Python language and all the Python packages available out there): this is a global solution for your scientific development projects as well as for your data analysis/visualization work, the perfect companion for all your numerical computing needs. So from this perspective, this is also the right place for presenting our subjective thoughts on this scientific Python world.

Note that there are a lot of interesting online resources on scientific Python but the best starting point would probably be the SciPy website: home page of the SciPy conference and the SciPy Python library (see the mailing lists, the blogs, the cookbook and the brand new "Ask SciPy" Q&A forum).