Hi, Here is an updated version. The update concerns QByteArray.
---------------------------------------------------------------------- PSEP: Title: More Pythonic API for Python 3/PySide Version: $Revision$ Last-Modified: $Date$ Author: Mark Summerfield <[email protected]> Status: Type: Content-Type: text/x-rst Created: 14-Apr-2010 Post-History: 14-Apr-2010 Abstract ======== PyQt4 provides two different (and incompatible) APIs. API 1 is the original API and the one supported by PySide. API 2 is a new Python 3-specific API that is much more Pythonic. This PSEP proposes that PySide adopt PyQt4's API 2 for when PySide is used with Python 3. Rationale ========= API 1 is useful for those using PySide to prototype C++/Qt programs since it is very close to the C++/Qt API. However, for those who want to create PySide programs in their own right, and especially for existing Python programmers, API 1 is cumbersome and un-Pythonic when it comes to handling QStrings and QVariants, both of which are used a lot. If PySide were to support API 2, it will make PySide much more attractive to Python 3 programmers. Also, supporting API 2 will mean that existing Python 3/PyQt4 programs that use API 2 by default will be able to switch to PySide. Python 3-Specific Differences ============================= No QString, or QVariant ----------------------- The key difference between the APIs is that API 2 does not make QString or QVariant available to programmers, instead using Python 3's native str type for strings, and any Python class for QVariant. The benefit of API 2 in this regard is that programmers never have to explicitly convert between QString and str, so programmers never get caught out accidentally trying to use a QString method on a str or vice versa. For the Qt APIs that accept or return QVariants, API 2 allows programmers to pass any Python object and when a QVariant is returned from Qt it is automatically converted to its original Python type (with an invalid QVariant mapped to None). For QString, API 2 goes beyond simply replacing QString with str. In particular, API 2 also automatically converts QChar and QStringRef to and from strs. It also converts QStringList to and from a Python list of strs. (PyQt4's API 2 does not implement QLatin1Char, QLatin1String, or QStringMatcher.) Native C++/Qt QStrings are mutable, so PyQt4's API 2 has changed the signatures of some of the affected functions to return a str (or a tuple including a str) when in the C++/Qt API a QString parameter would have been modified. In addition, API 2 has added two methods to QFontMetrics and QFontMetricsF, widthChar() and boundingRectChar(), which take a str of length one and call QFontMetrics::width() and QFontMetrics::boundingRect() with a QChar argument. These were added because the width of a single character may be different from that of a string that contains a single character, even if the characters are the same. Changes to Other Types ---------------------- API 2 also affects some other types, as follows. Where QByteArrays are expected, bytes objects can be used, but unlike QString, QByteArray has been retained to ease porting from API 1, so in API 2 byte sequences can be represented by QByteArray, bytes, and bytearray objects. QDate, QDateTime, QTime, and QUrl's __hash__() methods return a string representation so that identical dates (and identical date/times or times or URLs) will have identical hash values. QTextStream's bin(), hex(), and oct() functions have been renamed bin_(), hex_(), and oct_(), to avoid conflicting with Python's built-ins of the same names. Support for Keyword Arguments ============================= PyQt 4.7 adds support for keyword arguments which is very convenient and much more Pythonic. This change is not Python 3-specific, but it does represent an extension to the PyQt APIs that a compatible PySide ought to implement. One problem with this is that while changes to argument names don't affect C++/Qt, they would break the Python API. Furthermore, since changing argument names is harmless in C++/Qt, such changes do take place between Qt versions. This means that for PySide, sensible names much be used in the first place---and stuck to. Naturally, for PyQt compatibility, PySide ought to use the same names as PyQt. PyQt does not integrate Python and Qt's property systems, but it does allow Qt properties to be set when an object is constructed using keyword arguments (i.e., where the keyword is the name of a Qt property). Also, PyQt provides the pyqtConfigure() method for all objects that have Qt properties: this method can be called at any time and the object's Qt properties set by passing it keyword arguments. (This feature could be put in a separate PSEP since it is not Python 3-specific.) Exceptions Rather than Error Codes ================================== C++/Qt does not raise exceptions; it always returns error values or indicates errors in other ways. A more Pythonic way to indicate errors is to raise exceptions. PyQt4 supports the existing C++/Qt way. If PySide was willing to be incompatible with PyQt4, at least regarding Python 3/PySide programs, then PySide could raise exceptions when errors occur. (For example, for any class that has an errorString() method, PySide could raise an exception with the error string's text as an attribute.) Changing APIs ============= API 1 is the default for PyQt 4.x with Python 2.x, and for PyQt 4.0-4.5 with Python 3.x, and is the API used by PySide. API 2 is the default for PyQt 4.6+ with Python 3.x. PyQt provides a means of changing the API on a per-class basis. PySide could offer a similar mechanism, but this would mean that programmers might end up with Python 3/PySide programs that used the two different APIs, one in some modules, and the other in other modules. PySide should not offer such a mechanism, but should instead support API 1 for Python 2.x and API 2 for Python 3.x to avoid confusion. (If users demanded an API changing mechanism, it could be added later.) Compatibility ============= The proposed API 2 is incompatible with API 1, but since PySide is not available for Python 3 yet, the incompatibility will only affect those porting from Python 2 to Python 3. Such porting affects Python programs generally, and also PyQt programs, so does not add to (or reduce) the porting burden. References ========== `PyQt v4 Reference Manual: Potential Incompatibilities section, Selecting Incompatible APIs section, Support for Keyword Arguments section, and Support for Qt Properties section <http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html/>`_. Contributors ============ Richard Dale and Detlev Offenbach pointed out that QByteArray had been retained in API 2. Copyright ========= This document has been placed in the public domain. ---------------------------------------------------------------------- -- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Advanced Qt Programming" - ISBN 0321635906 _______________________________________________ PySide mailing list [email protected] http://lists.openbossa.org/listinfo/pyside
