[PyQt] Slot type validation: int/qint64
Phil Thompson
phil at riverbankcomputing.com
Mon May 2 15:55:01 BST 2016
On 30 Apr 2016, at 3:18 pm, VA <dev+pyqt at indigo.re> wrote:
>
> Le 30/04/2016 12:54, Phil Thompson a écrit :
>> On 29 Apr 2016, at 7:36 pm, Florian Bruhin <me at the-compiler.org> wrote:
>>>
>>> * Florian Bruhin <me at the-compiler.org> [2016-04-26 20:11:49 +0200]:
>>>> Hi!
>>>>
>>>> Thanks to the slot type validation of PyQt 5.6 I discovered a lot of cases
>>>> where my decorations where plain wrong...
>>>>
>>>> However in this case I'm unsure what's going on:
>>>>
>>>> Traceback (most recent call last):
>>>> File ".../qutebrowser/browser/webpage.py", line 327, in on_unsupported_content
>>>> suggested_filename=suggested_filename)
>>>> File ".../qutebrowser/browser/downloads.py", line 884, in fetch
>>>> download = DownloadItem(reply, self._win_id, self)
>>>> File ".../qutebrowser/browser/downloads.py", line 332, in __init__
>>>> self.init_reply(reply)
>>>> File ".../qutebrowser/browser/downloads.py", line 430, in init_reply
>>>> reply.downloadProgress.connect(self.stats.on_download_progress)
>>>> TypeError: decorated slot has no signature compatible with downloadProgress(qint64,qint64)
>>>>
>>>> [...]
>>>>
>>>> Using 'qint64', 'qint64' instead works.
>>>>
>>>> I've tried to create a minimal example:
>>>>
>>>> [...]
>>>>
>>>> But that seems to work fine for some reason...
>>>
>>> I can reproduce the issue with the attached example (thanks to ntome
>>> in the #pyqt IRC channel).
>>
>> The problem is that a Python int is mapped to a C++ int in the slot signature, even though a Python int is capable of storing much bigger values. Connecting a qint64 to a C++ int is invalid, hence the error.
>>
>> A fix for this would be map a Python int to the biggest C++ integer type. However I am uncomfortable making such a change without a lot more thought and experimentation (particularly when handling quint64).
>>
>> In the meantime the workaround (which should always work) is to use 'qint64' as you are doing.
>
> How come the mapping used to work, and now it doesn't anymore?
It never worked. Instead the code path for an undecorated method was followed.
> Was the validation done silently but not enforced, falling back to
> connecting the signal to a regular Python callable, rather than a
> promoting the callback to a full-fledged Qt slot? Was the fallback
> abandoned, to force removing the @Slot when the signature doesn't match?
The fallback wasn't intentional in the first place.
> I used to do @Slot(object) to perform a kind of "catch all" (for one
> argument) but this new decorator validation just prevents it.
> Is there a way to disable the validation?
Just remove the decorator - it was having no effect apart from defining a C++ slot that wasn't being used.
> I'm using Qscintilla. With PyQt 5.5, I could successfully connect:
> - SCN_MODIFIED (int, int, const char *, int, int, int, int, int, int,
> int) to @Slot(int, int, str, int, int, int, int, int, int, int)
> - SCN_MACRORECORD (unsigned int, unsigned long, void *) to @Slot(int,
> int, object)
> Now, not only slot validation prevents it from working, but if I repeat
> the C++ signature (quoting the type names), it may work but after a few
> signal emissions and the slot getting called a few times, Python segfaults.
> If I completely omit the @Slot decorator, the connection works too, but
> it still quickly segfaults after a few emissions.
> Even if I'm not doing anything with the slots arguments (the slot just
> containing "pass"), it still segfaults.
> What could cause those segfaults?
I can't reproduce any crashes when the decorator is removed.
The above is a good example of why this needed fixing as it hides at least two bugs. First, your signature for the SCN_MODIFIED slot is wrong - it should be a bytes not a str argument. Second, PyQt doesn't handle a bytes argument properly. I suspect it also doesn't handle void* properly either.
> In the meantime, it would be a good thing to update
> http://pyqt.sourceforge.net/Docs/PyQt5/incompatibilities.html and warn
> about the problems, and I hope there's a fix for those.
Phil
More information about the PyQt
mailing list