On 2010-04-22, Matti Airas wrote:
> On 21.04.2010 17:13, ext Mark Summerfield wrote:
> > Looks fine to me.
> >
> > But since only QtDBus needed this and you're going to use dbus-python,
> > couldn't we just defer this unless/until it is needed? Then we get a
> > nice clean no-QVariant API:-)
> 
> OK, this time the modifications are slightly bigger (including
> reordering of paragraphs) so I cut and pasted the whole section below. I
> cut a few corners and left the decision of retaining QVariant to the
> implementation phase. I admit it's not the cleanest approach in the
> world but if you're OK with this, it could save us some time and effort
> juggling with the PSEPs in the future.

I've updated the PSEP making use of your text (but slightly modified).

If you want two or more people to be able to edit it I think it is
easiest to do your changes and then supply the complete file with those
changes. Then anyone can diff (or use vim -d) to see exactly what the
changes are & vice versa. (But I don't suppose it matters much since
presumably this'll soon be set in stone;-)

----------------------------------------------------------------------
PSEP: 101
Title: Adopt PyQt's API 2 for PySide
Version: $Revision$
Last-Modified: $Date$
Author: Mark Summerfield <[email protected]>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 14-Apr-2010
Post-History: 14-Apr-2010, 15-Apr-2010, 16-Apr-2010, 20-Apr-2010, 22-
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 PySide.


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.

One key purpose of API 2 is to avoid the need for Python programmers to
have to worry or even know about QString or QVariant. For Python
programmers str is the string they are used to so translation to/from
QString should be transparent and automatic. Similarly, why should
Python programmers have to know about QVariant when that is a C++
workaround for C++'s lack of support for duck typing etc.? Again,
translation to/from QVariant should be transparent and automatic. API 2
achieves this and eliminates QString and (to some extent) QVariant.


API 1 vs. API 2
===============


No QString and almost no QVariant
---------------------------------

The key difference between the APIs is that API 2 does not make QString
or (to some extent) QVariant available to programmers.

This means using Python's native string types for strings (e.g., unicode
for Python 2 and str for Python 3).

PyQt's approach to dealing with QVariants will be mimicked: Python
objects are automatically converted to and from QVariants wherever
QVariants must be passed as arguments and when QVariants are returned.

By supporting automatic conversion to and from QVariants, any Python
object (including dicts, lists, and tuples) can be used wherever a
QVariant is expected, so most programmers most of the time won't have to
know or care about QVariant at all.

If the need arises during the implementation phase, the QVariant class
may be added to the API so that programmers can pass a QVariant
explicitly if they need to. If this is done, to support the creation of
QVariants, a set of static functions named after the types in
QVariant.Type will need to be implemented, e.g.::

     QVariant.fromUInt(pythonObject) -> QVariant
     QVariant.fromInt(pythonObject) -> 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 (or
unicode on Python 2). In particular, API 2 also automatically converts
QChar and QStringRef to and from strs (or unicodes on Python 2). It also
converts QStringList to and from a Python list of strs (list of unicodes
on Python 2). (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 represents 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.


Compatibility
=============

The proposed API 2 is incompatible with API 1, but since PySide is not
yet widely used and hasn't reached version 1.0.0, it seems reasonable to
break compatibility for the sake of getting PySide "right". Furthermore,
if API 2 is adopted it means that PySide programs will have the same API
whether Python 2 or Python 3 is used which will make it much easier for
those who start out with PySide and Python 2 and later on port to Python
3---something that isn't so easy with PyQt.


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.

Richard Dale and Lauro Moura gave suggestions regarding QVariant.

The section of Exceptions was dropped as a result of feedback from Matti
Airas; Matti also added to the discussion in numerous ways.

Detlev Offenbach also contributed to the discussion on Compatibility.


Copyright
=========

This document has been placed in the public domain.

----------------------------------------------------------------------

-- 
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
    C++, Python, Qt, PyQt - training and consultancy
        "Programming in Python 3 (Second Edition)" - ISBN 0321680561
_______________________________________________
PySide mailing list
[email protected]
http://lists.openbossa.org/listinfo/pyside

Reply via email to