[PyQt] Missing QIODevice::read overloads

Florian Bruhin me at the-compiler.org
Sun May 31 17:03:59 BST 2015


* Phil Thompson <phil at riverbankcomputing.com> [2015-05-31 16:18:30 +0100]:
> On 25/05/2015 9:40 pm, Florian Bruhin wrote:
> >Hi,
> >
> >I noticed the following QIODevice overloads are missing in PyQt:
> >
> >    qint64 QIODevice::read(char * data, qint64 maxSize)
> >    qint64 QIODevice::readLine(char * data, qint64 maxSize)
> >
> >only the following are available:
> >
> >    QByteArray QIODevice::read(qint64 maxSize)
> >    QByteArray QIODevice::readLine(qint64 maxSize = 0)
> >
> >The issue with those is that it's impossible to check for errors:
> >
> >    This function has no way of reporting errors; returning an empty
> >    QByteArray can mean either that no data was currently available
> >    for reading, or that an error occurred.
> >
> >The best workaround I found so far is to check if
> >QIODevice::errorString is "Unknown error", but that's a hack...
> >
> >Maybe PyQt should provide the two other forms as well, when passing a
> >mutable byte object (QByteArray/bytearray?) as first parameter?
> 
> I'm not sure what the best solution is. The reason the overloads are missing
> is that, following the normal PyQt conventions, they would return a str
> (Py2) or a bytes (Py3) but the signature would then be indistinguishable
> from the overloads that return a QByteArray. Possible solutions...
> 
> 1. Give the overloads a different Python name.
> 
> 2. Change the existing methods to raise an exception (maybe initially a
> warning) on error.

toothrot from the #pyqt IRC channel (who seems to read this ML)
actually told me PyQt seems to return None rather than an empty string
when there's an error.

From sip/QtCore/qiodevice.sip:

        virtual SIP_PYOBJECT readData(qint64 maxlen) = 0 /DocType="Py_v3:bytes;str",ReleaseGIL/ [qint64 (char *data, qint64 maxlen)];
    %MethodCode
            // Return the data read or None if there was an error.
            if (a0 < 0)
            {
                PyErr_SetString(PyExc_ValueError, "maximum length of data to be read cannot be negative");
                sipIsErr = 1;
            }
            else
            {
                char *s = new char[a0];
                qint64 len;
            
                Py_BEGIN_ALLOW_THREADS
            #if defined(SIP_PROTECTED_IS_PUBLIC)
                len = sipCpp->readData(s, a0);
            #else
                len = sipCpp->sipProtect_readData(s, a0);
            #endif
                Py_END_ALLOW_THREADS
            
                if (len < 0)
                {
                    Py_INCREF(Py_None);
                    sipRes = Py_None;
                }
                else
                {
                    sipRes = SIPBytes_FromStringAndSize(s, len);
            
                    if (!sipRes)
                        sipIsErr = 1;
                }
            
                delete[] s;
            }
    %End


I'm actually fine with that solution, it means there *is* a way to
differentiate "no data" and "there was an error" from Python.

What's more problematic in my opinion is that we had to read the .sip
files to find out - [1] only links to the C++ documentation.

"There's almost no documentation for the classes" is actually
something I hear about PyQt and I tell them to stop worrying and just
read the C++ documentation - I see duplicating that makes no sense.

But at least for the cases where PyQt's signature/behaviour is
different from the Qt one, I think this should be documented
somewhere.

[1] http://pyqt.sourceforge.net/Docs/PyQt5/api/qiodevice.html

Florian

-- 
http://www.the-compiler.org | me at the-compiler.org (Mail/XMPP)
   GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc
         I love long mails! | http://email.is-not-s.ms/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20150531/bc91a926/attachment.sig>


More information about the PyQt mailing list