[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] Conflict between setuptools & requirements in official PyQt5 docs
From:       "Jones, Bryan" <bjones () ece ! msstate ! edu>
Date:       2016-02-12 18:00:31
Message-ID: CAHhYbD_iNsxUgitPxQ6V1iFOzJsvL0SJE6tQax8+X0SaDa6Bvg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Phil,

I'm always impressed with you quick turnaround. Thanks for the fix!

Bryan

On Wed, Feb 10, 2016 at 4:38 PM, Phil Thompson <phil@riverbankcomputing.com>
wrote:

>
> > On 10 Feb 2016, at 8:57 pm, Jones, Bryan <bjones@ece.msstate.edu> wrote:
> >
> > 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)
>
> Attached is a patch (also in tonight's PyQt5 snapshot but you'll need a
> SIP snapshot as well) that will stop this particular crash.
>
> Note that as soon as you start using __del__ the behaviour of the garbage
> collector changes.
>
> Phil
>
>


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

[Attachment #5 (text/html)]

<div dir="ltr">Phil,<div><br></div><div>I&#39;m always impressed with you quick \
turnaround. Thanks for the fix!</div><div><br></div><div>Bryan</div></div><div \
class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 10, 2016 at 4:38 PM, \
Phil Thompson <span dir="ltr">&lt;<a href="mailto:phil@riverbankcomputing.com" \
target="_blank">phil@riverbankcomputing.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br> &gt; On 10 Feb 2016, \
at 8:57 pm, Jones, Bryan &lt;<a \
href="mailto:bjones@ece.msstate.edu">bjones@ece.msstate.edu</a>&gt; wrote:<br> \
&gt;<br> &gt; 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 (&quot;QApplication destroyed; terminating \
application&quot;) with a backtrace.<br> &gt;<br>
&gt; The third case is more interesting -- the cause is more subtle and more likely \
(IMHO) to occur in &quot;real&quot; code. Here&#39;s a second pass at it, with a bit \
of cleanup. It looks like I&#39;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&#39;s __del__) or destroyed (the C++ destructor). Any thoughts?<br> &gt;<br>
&gt; import sys<br>
&gt; import os<br>
&gt; import platform<br>
&gt; import gc<br>
&gt; import sip<br>
&gt; from PyQt5.QtWidgets import QApplication, QWidget<br>
&gt; from PyQt5.QtCore import QT_VERSION_STR<br>
&gt; from PyQt5.Qt import PYQT_VERSION_STR<br>
&gt;<br>
&gt; app = None<br>
&gt;<br>
&gt; DEBUG = False<br>
&gt;<br>
&gt; if DEBUG:<br>
&gt;        def printDestroyed(qObject):<br>
&gt;              qObjectStr = str(qObject)<br>
&gt;              def destroyed():<br>
&gt;                    print(&#39;destroyed {}&#39;.format(qObjectStr))<br>
&gt;              qObject.destroyed.connect(destroyed)<br>
&gt;<br>
&gt;        class QApplicationF(QApplication):<br>
&gt;              def __del__(self):<br>
&gt;                    print(&#39;finalized {}&#39;.format(self))<br>
&gt;<br>
&gt;        class QWidgetF(QWidget):<br>
&gt;              def __del__(self):<br>
&gt;                    print(&#39;finalized {}&#39;.format(self))<br>
&gt;<br>
&gt;        def checkLeaks():<br>
&gt;              for o in gc.get_objects():<br>
&gt;                    try:<br>
&gt;                          if not sip.isdeleted(o):<br>
&gt;                                sip.dump(o)<br>
&gt;                    except TypeError:<br>
&gt;                          pass<br>
&gt;<br>
&gt; else:<br>
&gt;        def printDestroyed(_): pass<br>
&gt;        QApplicationF = QApplication<br>
&gt;        QWidgetF = QWidget<br>
&gt;        def checkLeaks(): pass<br>
&gt;<br>
&gt; def foo(x):<br>
&gt;        return lambda: x<br>
&gt;<br>
&gt; def qtMain(doCrash):<br>
&gt;        global app<br>
&gt;        app = QApplicationF(sys.argv)<br>
&gt;        printDestroyed(app)<br>
&gt;<br>
&gt;        w = QWidgetF()<br>
&gt;        printDestroyed(w)<br>
&gt;<br>
&gt;        param = w if doCrash else 1<br>
&gt;        w.destroyed.connect(foo(param))<br>
&gt;<br>
&gt; def gcCrash(createCycle, doCollect):<br>
&gt;        qtMain(createCycle)<br>
&gt;        checkLeaks()<br>
&gt;        gc.collect(doCollect)<br>
&gt;<br>
&gt; if __name__ == &#39;__main__&#39;:<br>
&gt;        # Both must be True for a crash.<br>
&gt;        gcCrash(True, True)<br>
<br>
</div></div>Attached is a patch (also in tonight&#39;s PyQt5 snapshot but you&#39;ll \
need a SIP snapshot as well) that will stop this particular crash.<br> <br>
Note that as soon as you start using __del__ the behaviour of the garbage collector \
changes.<br> <span class="HOEnZb"><font color="#888888"><br>
Phil<br>
<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div \
class="gmail_signature">Bryan A. Jones, Ph.D.<br>Associate Professor<br>Department of \
Electrical and Computer Engineering<br>231 Simrall / PO Box 9571<br>Mississippi State \
University<br>Mississippi state, MS 39762<br><a \
href="http://www.ece.msstate.edu/~bjones" \
target="_blank">http://www.ece.msstate.edu/~bjones</a><br>bjones AT ece DOT msstate \
DOT edu<br>voice 662-325-3149<br>fax 662-325-2298<br><br>Our Master, Jesus Christ, is \
on his way. He&#39;ll show up right on<br>time, his arrival guaranteed by the Blessed \
and Undisputed Ruler,<br>High King, High God.<br>- 1 Tim. 6:14b-15 (The \
Message)<br></div> </div>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic