[PyQt] Slot type validation: int/qint64

VA dev+pyqt at indigo.re
Sat Apr 30 15:18:37 BST 2016


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?
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?

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?

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?

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.


More information about the PyQt mailing list