[PyQt] Segfault with 5.9 snapshot when connecting to destroyed signal

Phil Thompson phil at riverbankcomputing.com
Tue Jun 6 16:28:56 BST 2017


On 6 Jun 2017, at 4:20 pm, Florian Bruhin <me at the-compiler.org> wrote:
> 
> On Tue, Jun 06, 2017 at 03:34:12PM +0100, Phil Thompson wrote:
>> On 5 Jun 2017, at 10:42 pm, Florian Bruhin <me at the-compiler.org> wrote:
>>> 
>>> Hi,
>>> 
>>> the attached script works fine with PyQt 5.8, but segfaults with the
>>> current 5.9 snapshot. This is a simplified version of pytest-qt's
>>> SignalBlocker: http://pytest-qt.readthedocs.io/en/latest/signals.html
>>> 
>>> The "self.args = args" saves a reference to the to-be-destroyed object,
>>> which probably triggers this in some way - saving the arguments is done
>>> as a general thing here though. It's probably a bit unorthodox, but
>>> still shouldn't segfault I guess?
>> 
>> Should be fixed in tonight's PyQt snapshot.
>> 
>> Current snapshots have additional code to detect when certain objects
>> get destroyed. This is deceptively difficult to get right (as you have
>> found). I'd appreciate any testing you can do with the snapshots
>> before the v5.9 release.
> 
> Thanks! Another thing I've noticed is with code like this:
> 
>    class NetworkManager(QNetworkAccessManager):
> 
>        def __init__(self, parent=None):
>            super().__init__(parent)
>            self._replies = []
> 
>        def createRequest(self, *args):
>            reply = super().createRequest(*args)
>            self._replies.append(reply)
>            reply.destroyed.connect(self._requests.remove)
>            return reply
> 
> I suddenly got "ValueError: list.remove(x): x not in list" with the
> snapshot which I didn't with 5.8.
> 
> I ended up just removing[1] that reply tracking because I didn't need it
> anymore, but now I wonder whether that's expected. I'm guessing the
> argument of the destroyed signal doesn't compare equal to what I
> stored earlier anymore?
> 
> Let me know if you need a minimal example and I'll see if I can write one.

Try it again with tonight's snapshot.

As far as PyQt is concerned the destroyed() signal is evil. This would be a lot easier if you ask a QObject if it was being destroyed.

Phil


More information about the PyQt mailing list