On Mittwoch, 14. April 2010, Mark Summerfield wrote: > Hi, > > Here is a rough draft of a PSEP for a more Pythonic API for Python > 3/PySide that is compatible with PyQt4's API 2. > > > ---------------------------------------------------------------------- > 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 QByteArray, QString, or QVariant
QByteArray is still available. It was discussed (at least between Phil and myself) but the decision was to not break compatibility again, which I appreciated much. It saved me a lot of porting work for the eric5 development environment. > ----------------------------------- > > The key difference between the APIs is that API 2 does not make QByteArray, > QString, or QVariant available to programmers, instead using Python 3's > native bytes class for QByteArrays, (Unicode) 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 QByteArray and bytes or 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. > > 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/>`_. > > > Copyright > ========= > > This document has been placed in the public domain. > > ---------------------------------------------------------------------- > -- Detlev Offenbach [email protected] _______________________________________________ PySide mailing list [email protected] http://lists.openbossa.org/listinfo/pyside
