use CFRunLoop directly in `ipython kernel --pylab osx` #809

Merged
merged 2 commits into from Oct 8, 2011

Conversation

Projects
None yet
2 participants
@minrk
Member

minrk commented Sep 20, 2011

CFRunLoop integration is now made via matplotlib.backend_macosx.TimerMac, rather than assuming Tk is native.

It will still fallback on Tk if matplotlib is < 1.1.0, which introduces the necessary Timer. This means that it still won't work on current EPD, which has X11-linked libtk and matplotlib 1.0.1, but at least it will display a warning explaining why.

Also removes caveat in docs that qtconsole doesn't work with native MacOSX, since it does on any normal (non-EPD) install.

So this will work in more places, but still not in the most common failure case (stock EPD) described in #640.

Yet another approach is to use PyObjC to hook into the eventloop directly, but that still doesn't solve the EPD problem, which doesn't ship with PyObjC (it probably should).

use CFRunLoop directly in `ipython kernel --pylab osx`
via matplotlib.backend_macosx.TimerMac, rather than Tk

Fallback on Tk if matplotlib is < 1.1.0, which introduces the necessary Timer. This means that it still won't work on current EPD, which has X11-linked libtk and matplotlib 1.0.1,
but at least it will display a warning explaining why.

also remove caveat in docs that qtconsole doesn't work with native MacOSX, since it does on normal (non-EPD) installs.

So this will work in more places, but still not in most common failure case (stock EPD) described in #640.
IPython/zmq/ipkernel.py
+ self.do_one_iteration()
+ # and back:
+ sys.excepthook = handle_int
+ t = TimerMac(poll_interval)

This comment has been minimized.

@fperez

fperez Sep 30, 2011

Member

I'd add a blank line after the end of the func definition for readability

@fperez

fperez Sep 30, 2011

Member

I'd add a blank line after the end of the func definition for readability

This comment has been minimized.

@minrk

minrk Oct 1, 2011

Member

done.

@minrk

minrk Oct 1, 2011

Member

done.

+ # don't let interrupts during mainloop invoke crash_handler:
+ sys.excepthook = handle_int
+ show.mainloop()
+ sys.excepthook = real_excepthook

This comment has been minimized.

@fperez

fperez Sep 30, 2011

Member

What happens if there's an exception in the mainloop call? sys.excepthook won't get properly restored...

@fperez

fperez Sep 30, 2011

Member

What happens if there's an exception in the mainloop call? sys.excepthook won't get properly restored...

This comment has been minimized.

@minrk

minrk Oct 1, 2011

Member

I'll stick the restore-excepthook in a finally clause, to make sure it is restored. Note that the special excepthook is identical to the original, save for handing keyboard interrupts, so there really isn't any difference. Either the error is a KeyboardInterrupt, and the loop is entered again, with no change, or it is anything else, which generates a crash report as usual, and exits.

Here's a question, though - should an exception in mainloop cause an IPython crash report? There is zero IPython code run in there, it's all matplotlib. Should a matplotlib bug be presented to the user as an IPython crash?

I worry that our crash reports are sometimes overzealous, often presenting far too much information, and ultimately being less instructive than a regular traceback.

@minrk

minrk Oct 1, 2011

Member

I'll stick the restore-excepthook in a finally clause, to make sure it is restored. Note that the special excepthook is identical to the original, save for handing keyboard interrupts, so there really isn't any difference. Either the error is a KeyboardInterrupt, and the loop is entered again, with no change, or it is anything else, which generates a crash report as usual, and exits.

Here's a question, though - should an exception in mainloop cause an IPython crash report? There is zero IPython code run in there, it's all matplotlib. Should a matplotlib bug be presented to the user as an IPython crash?

I worry that our crash reports are sometimes overzealous, often presenting far too much information, and ultimately being less instructive than a regular traceback.

This comment has been minimized.

@fperez

fperez Oct 1, 2011

Member

Valid concern, and it seems we're producing more of them lately. They were originally so aggressive because they really were a way for us to debug an actual crash in the user's code. So they should only happen when IPython totally died.

But whenever we catch a normal exception (possibly from mpl or another tool), showtraceback() should be used instead. I'm not sure why we've ended up over time with our crash handler showing up so often.

@fperez

fperez Oct 1, 2011

Member

Valid concern, and it seems we're producing more of them lately. They were originally so aggressive because they really were a way for us to debug an actual crash in the user's code. So they should only happen when IPython totally died.

But whenever we catch a normal exception (possibly from mpl or another tool), showtraceback() should be used instead. I'm not sure why we've ended up over time with our crash handler showing up so often.

This comment has been minimized.

@minrk

minrk Oct 1, 2011

Member

Actually, I was wrong - mainloop includes calls to IPython's doi() via a timer, so all IPython code does end up within that call once a single plot window exists. And the KernelApp does not register a full crashhandler, it just registers FormattedTB, so you do just get a regular traceback instead of a crash. But if the crash_handler catches an error, it goes to the terminal, instead of being posted via PUB to frontends. This is true for all Kernels.

@minrk

minrk Oct 1, 2011

Member

Actually, I was wrong - mainloop includes calls to IPython's doi() via a timer, so all IPython code does end up within that call once a single plot window exists. And the KernelApp does not register a full crashhandler, it just registers FormattedTB, so you do just get a regular traceback instead of a crash. But if the crash_handler catches an error, it goes to the terminal, instead of being posted via PUB to frontends. This is true for all Kernels.

ensure excepthook is restored in OSXKernel mainloop
also add some friendly whitespace per @fperez review

minrk added a commit that referenced this pull request Oct 8, 2011

Merge pull request #809 from minrk/osxkernel
use CFRunLoop directly in `ipython kernel --pylab osx`

@minrk minrk merged commit 321d643 into ipython:master Oct 8, 2011

mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this pull request Nov 3, 2014

Merge pull request #809 from minrk/osxkernel
use CFRunLoop directly in `ipython kernel --pylab osx`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment