[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