Skip to content

SIGINT is ignored by MacOSX backend #3991

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

Closed
Equidamoid opened this issue Jan 10, 2015 · 15 comments · Fixed by #25966
Closed

SIGINT is ignored by MacOSX backend #3991

Equidamoid opened this issue Jan 10, 2015 · 15 comments · Fixed by #25966

Comments

@Equidamoid
Copy link

Here is an example:

import matplotlib
#matplotlib.use('Qt4Agg')
from matplotlib import pyplot as plt
plt.plot(1, 1)
plt.show()

Run this script from terminal, wait for the window to appear and press Ctrl-C (in terminal). The script will not die.
Then uncomment the matplotlib.use line an Ctrl-C will work as intended.

UPD:
If I press Ctrl-C and then move mouse over the plot window the following exception appears in the log:

Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backend_bases.py", line 1850, in enter_notify_event
    def enter_notify_event(self, guiEvent=None, xy=None):
KeyboardInterrupt

The same is for callback set using signal.signal(signal.SIGTERM, cb), callback is not called until window receives any event (focus change, mouse move, etc).

@Equidamoid
Copy link
Author

I've found a workaround to make script exit on sigint. Backend's event loop seems to block (sigmask or sigsuspend?) signals while waiting for a new event so we need to introduce an event that will fire without any interation with the window -- a timer. Next, all interrupts are catched somewhere inside matplotlib code so we need to make own SIGINT handler that will end the current process.
Here is the example code:

from matplotlib import pyplot as plt
import signal
import os

def sig(a, b):
    print("got sigint, exitting!")
    os._exit(0)

def timercb(e):
    print("timer")
signal.signal(signal.SIGINT, sig)

plt.plot(1)
fig, ax = plt.subplots()
timer = fig.canvas.new_timer(interval=5000)
timer.add_callback(timercb, ax)
timer.start()
plt.show()

I set the timer interval to 5 sec to make it sensible that signal arrives only after timer event happens.

@tacaswell tacaswell added this to the v1.5.x milestone Jan 10, 2015
@tacaswell
Copy link
Member

attn @mdehoon

@WeatherGod
Copy link
Member

This is an interesting idea. I wonder if this approach (the timer, that is)
might be a suitable trick to deal with the other issues we are having with
the macosx backend and its eventloop?

On Sat, Jan 10, 2015 at 9:41 AM, Thomas A Caswell notifications@github.com
wrote:

attn @mdehoon https://github.com/mdehoon


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

@mdehoon
Copy link
Contributor

mdehoon commented Jan 13, 2015

@WeatherGod Which other issues are there with the macosx backend and its event loop?

@tacaswell
Copy link
Member

I assume @WeatherGod is referring to bilt not working.

@mdehoon
Copy link
Contributor

mdehoon commented Jan 13, 2015

@WeatherGod

This is an interesting idea. I wonder if this approach (the timer, that is)
might be a suitable trick to deal with the other issues we are having with
the macosx backend and its eventloop?

When working on event loops, one has to resist the urge to use tricks to solve issues. Tricks may solve a particular symptom but you will end up with a bunch of hacks that will be very difficult to disentangle.

@mdehoon
Copy link
Contributor

mdehoon commented Jan 13, 2015

@tacaswell The bug in that case is not caused by the MacOSX backend, but by the upstream code trying to draw stuff outside of the event loop.

@WeatherGod
Copy link
Member

@mdehoon, Fair enough. and I can see a bunch of problems with the idea for
blitting anyway. In any case, what do you think of this PR?

On Mon, Jan 12, 2015 at 9:28 PM, mdehoon notifications@github.com wrote:

@tacaswell https://github.com/tacaswell The bug in that case is not
caused by the MacOSX backend, but by the upstream code trying to draw stuff
outside of the event loop.


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

@mdehoon
Copy link
Contributor

mdehoon commented Jan 14, 2015

@WeatherGod The suggested bug fix should not be applied, as this is not a bug in the MacOSX backend, but in Python itself. See issue 3180 on the Python website:
http://bugs.python.org/issue3180
Note that the bug also appears with other backends (e.g. Tkinter, see the example on the Python bug report).
It could help if you guys poke the Python developers on this issue if it stalls.
Depending on how issue 3180 is fixed by the Python developers, some changes to the MacOSX backend may be needed at that time. Let's keep this issue open until then.

@mdehoon
Copy link
Contributor

mdehoon commented Jan 17, 2015

This pull request #4006 allows the delivery of interrupts once Python is fixed.

@petehuang
Copy link
Contributor

Can someone on OSX try to reproduce using the snippet in OP?

@efiring
Copy link
Member

efiring commented Jan 8, 2017

I can still reproduce the original problem (Ctl-C does not close the window) with master and python 3.5.2 from Anaconda.

@tacaswell
Copy link
Member

https://bugs.python.org/issue23237 <- @mdehoon 's upstream patch is still not merged, closing as there is nothing we can do about this.

@tacaswell
Copy link
Member

@efiring does this problem also persist with mpl 2.0.0rc2 + IPython?

@efiring
Copy link
Member

efiring commented Jan 8, 2017

I can't run it from ipython on my system; I am using Anaconda, which is running ipython with a non-framework build of python. I can only test it as a standalone script using pythonw.

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

Successfully merging a pull request may close this issue.

6 participants