[PyQt] Conflict between setuptools & requirements in official PyQt5 docs

Jones, Bryan bjones at ece.msstate.edu
Wed Feb 10 20:57:09 GMT 2016


Thanks for the feedback. The first two crashes (quickCrash and slowCrash)
were, as you say, fairly obvious programmer errors. It would be nice if
this would emit some sort of error ("QApplication destroyed; terminating
application") with a backtrace.

The third case is more interesting -- the cause is more subtle and more
likely (IMHO) to occur in "real" code. Here's a second pass at it, with a
bit of cleanup. It looks like I've created a cycle between the QWidget
(whose destroyed signal refers to foo) and the function foo (which retains
a reference to the QWidget). When Python breaks the cycle during its
garbage collection, it finalizes the QWidget, which invokes foo, which
causes a crash. The QApplication instance, however, is still valid and has
not been either finalized (that is, Python's __del__) or destroyed (the C++
destructor). Any thoughts?

import sys
import os
import platform
import gc
import sip
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QT_VERSION_STR
from PyQt5.Qt import PYQT_VERSION_STR

app = None

DEBUG = False

if DEBUG:
    def printDestroyed(qObject):
        qObjectStr = str(qObject)
        def destroyed():
            print('destroyed {}'.format(qObjectStr))
        qObject.destroyed.connect(destroyed)

    class QApplicationF(QApplication):
        def __del__(self):
            print('finalized {}'.format(self))

    class QWidgetF(QWidget):
        def __del__(self):
            print('finalized {}'.format(self))

    def checkLeaks():
        for o in gc.get_objects():
            try:
                if not sip.isdeleted(o):
                    sip.dump(o)
            except TypeError:
                pass

else:
    def printDestroyed(_): pass
    QApplicationF = QApplication
    QWidgetF = QWidget
    def checkLeaks(): pass

def foo(x):
    return lambda: x

def qtMain(doCrash):
    global app
    app = QApplicationF(sys.argv)
    printDestroyed(app)

    w = QWidgetF()
    printDestroyed(w)

    param = w if doCrash else 1
    w.destroyed.connect(foo(param))

def gcCrash(createCycle, doCollect):
    qtMain(createCycle)
    checkLeaks()
    gc.collect(doCollect)

if __name__ == '__main__':
    # Both must be True for a crash.
    gcCrash(True, True)


On Wed, Feb 10, 2016 at 2:26 PM, Baz Walter <bazwal at ftml.net> wrote:

> On 10/02/16 18:44, Phil Thompson wrote:
> > On 10 Feb 2016, at 6:08 pm, Baz Walter <bazwal at ftml.net> wrote:
> >>
> >> On 10/02/16 17:24, Phil Thompson wrote:
> >>
> >> Which works okay, but still dumps core on exit, which I don't
> >> understand. Any ideas why that is?
> >
> > With your changes it works fine for me (on OSX), no crash on exit.
> >
> > Phil
> >
>
> I'm testing on Linux, but can't get any useful back-trace. The only clue
> is that it seems to be another one of those crashes that occurs in the
> QXcbEventReader thread (i.e. like the QtWebEngine crashes on exit). If I
> don't show() the widget, there's no crash.
>
> --
> Regards
> Baz Walter
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>



-- 
Bryan A. Jones, Ph.D.
Associate Professor
Department of Electrical and Computer Engineering
231 Simrall / PO Box 9571
Mississippi State University
Mississippi state, MS 39762
http://www.ece.msstate.edu/~bjones
bjones AT ece DOT msstate DOT edu
voice 662-325-3149
fax 662-325-2298

Our Master, Jesus Christ, is on his way. He'll show up right on
time, his arrival guaranteed by the Blessed and Undisputed Ruler,
High King, High God.
- 1 Tim. 6:14b-15 (The Message)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20160210/c75d2e94/attachment-0001.html>


More information about the PyQt mailing list