Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Unexpected null receiver" when using python -c #4195

Closed
anntzer opened this issue Mar 6, 2015 · 11 comments
Closed

"Unexpected null receiver" when using python -c #4195

anntzer opened this issue Mar 6, 2015 · 11 comments
Labels
Milestone

Comments

@anntzer
Copy link
Contributor

anntzer commented Mar 6, 2015

Sometimes I use python -c ... to plot something quickly from the terminal. With the Qt5Agg backend, closing the window leads to a (rather benign) error being printed on the terminal:

$ python -c 'import matplotlib; matplotlib.use("Qt4Agg"); from pylab import *; plot([1, 2], [3, 4]); show()' # exits normally when closing the window
$ python -c 'import matplotlib; matplotlib.use("Qt5Agg"); from pylab import *; plot([1, 2], [3, 4]); show()' # message is printed when closing the window
QCoreApplication::postEvent: Unexpected null receiver
@tacaswell tacaswell added this to the next point release milestone Mar 6, 2015
@tacaswell
Copy link
Member

Please don't use pylab and please don't do bulk imports (particularly from pylab).

attn @mfitzp thoughts on the Qt issue?

@mfitzp
Copy link
Member

mfitzp commented Mar 6, 2015

Unfortunately I'm not able to reproduce the error to test (on PyQt5), but the error results from an attempt by Qt to post (send) an event to an object that has been deleted. Since it's happening at shutdown it's probably a an object delete ordering issue. I can't find any reference to manual deletion of objects, so it might be a Python garbage collection thing.

This block in backend_qt5.py for TimerQT caught my eye however. It is attempting to clean up the connected timers but by being on the __del__ block might be getting called once the Qt object has already started deleting.

def __del__(self):
    # Probably not necessary in practice, but is good behavior to
    # disconnect
    try:
        TimerBase.__del__(self)
        self._timer.timeout.disconnect(self._on_timer)
    except RuntimeError:
        # Timer C++ object already deleted
        pass

There is a signal on all QObjects that Qt uses to notify just before deletion. The following line in the object __init__ will trigger this:

self.destroyed.connect( lambda o: self._timer.timeout.disconnect(self._on_timer) )

e.g.

def __init__(self, *args, **kwargs):
    TimerBase.__init__(self, *args, **kwargs)

    # Create a new timer and connect the timeout() signal to the
    # _on_timer method.
    self._timer = QtCore.QTimer()
    self._timer.timeout.connect(self._on_timer)
    self._timer_set_interval()

    self.destroyed.connect( lambda o: self._timer.timeout.disconnect(self._on_timer) )

def _timer_set_single_shot(self):
    self._timer.setSingleShot(self._single)

@anntzer can you test the above and see if it solves the issue?

If it helps it I'll test vs. PyQt4 and PySide also.

@anntzer
Copy link
Contributor Author

anntzer commented Mar 6, 2015

This doesn't seem to help (i.e. I see the same issue).

re pylab: I know the issues wit pylab and actually use OO-style for most of my programs (especially as I usually write full GUIs) but I'd have thought that it's still OK for one-off programs (that are directly given at the command line and not even written to an actual file...).

@WeatherGod
Copy link
Member

For what you are doing, it is fine so long as you are aware of the caveats.
I wouldn't expect you to use the pyplot interface or the OO interface for
such things. Although, I have to admit, it doesn't seem very elegant as it
stands. I wonder if a bash alias could help hide away a lot of that?

pylab "plot([1, 2], [3, 4])"

and then tuck away everything before and the plt.show() into the alias?

On Fri, Mar 6, 2015 at 2:41 PM, Antony Lee notifications@github.com wrote:

This doesn't seem to help (i.e. I see the same issue).

re pylab: I know the issues wit pylab and actually use OO-style for most
of my programs (especially as I usually write full GUIs) but I'd have
thought that it's still OK for one-off programs (that are directly given at
the command line and not even written to an actual file...).


Reply to this email directly or view it on GitHub
#4195 (comment)
.

@anntzer
Copy link
Contributor Author

anntzer commented Mar 6, 2015

That's a good idea:

pylab () { python -c "from pylab import *; $1; show()" }
pltdoc () { pydoc pylab.$1 }

@WeatherGod
Copy link
Member

I have a feeling that the other developers are going to shun me at the next
conference... ;-)

On Fri, Mar 6, 2015 at 4:19 PM, Antony Lee notifications@github.com wrote:

That's a good idea:

pylab () { python -c "from pylab import *; $1; show()" }
pltdoc () { pydoc pylab.$1 }


Reply to this email directly or view it on GitHub
#4195 (comment)
.

@tacaswell
Copy link
Member

We should make pylab print out a giant ascii art banner and a short essay
on why it should not be used every time it is imported.

(Mostly joking)

On Fri, Mar 6, 2015, 16:37 Benjamin Root notifications@github.com wrote:

I have a feeling that the other developers are going to shun me at the next
conference... ;-)

On Fri, Mar 6, 2015 at 4:19 PM, Antony Lee notifications@github.com
wrote:

That's a good idea:

pylab () { python -c "from pylab import *; $1; show()" }
pltdoc () { pydoc pylab.$1 }


Reply to this email directly or view it on GitHub
<
#4195 (comment)

.


Reply to this email directly or view it on GitHub
#4195 (comment)
.

@anntzer
Copy link
Contributor Author

anntzer commented Mar 11, 2015

In fact, I see the same issue with IPython:

$ ipython
Python 3.4.3 (default, Feb 26 2015, 23:01:07) 
Type "copyright", "credits" or "license" for more information.

IPython 3.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: %pylab
Using matplotlib backend: Qt5Agg
Populating the interactive namespace from numpy and matplotlib

In [2]: <Ctrl-D>
Do you really want to exit ([y]/n)? 
QCoreApplication::postEvent: Unexpected null receiver

@mfitzp
Copy link
Member

mfitzp commented Mar 11, 2015

@anntzer As I can't reproduce it's difficult to work out a solution. Can you give me the your full system specification (Windows/Mac/Linux + version; version of matplotlib; version of PyQt5; version of Qt5)? I'll try to match your build and see where that gets me.

@anntzer
Copy link
Contributor Author

anntzer commented Mar 11, 2015

$ uname -a # Arch Linux
Linux antony1 3.18.6-1-ARCH #1 SMP PREEMPT Sat Feb 7 08:44:05 CET 2015 x86_64 GNU/Linux
$ python --version
Python 3.4.3
$ python -c 'import matplotlib, PyQt5.Qt; print("matplotlib", matplotlib.__version__, "Qt5", PyQt5.Qt.QT_VERSION_STR, "PyQt5", PyQt5.Qt.PYQT_VERSION_STR)'
matplotlib 1.4.3 Qt5 5.4.1 PyQt5 5.4.1

@anntzer
Copy link
Contributor Author

anntzer commented May 21, 2015

Can't reproduce this anymore even though I am still using the same versions of all packages on the same machine. Feel free to close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants