[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