You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Main question: How can I run an embedded IPython shell with a full-featured prompt (simple_prompt=False) in the namespace of a frame where an exception occurred in the context of a running IPython kernel of a Jupyter notebook?
Explanation:
I have the following usecase (which is almost solved, up to one major flaw):
In Jupyter notebook (python kernel) I run some nested function call failing_function(). Deep down in the call stack an exception happens.
I want to debug the situation on the commandline with my custom excepthook (ipydex.ips_excepthook; it opens an emebedded IPython shell right in the frame where the exception occurs and offers the possibility to move up in the frame stack, which I find more useful than the classical IPython debugger).
I can achieve this with the following steps: Within an ordinary python script:
importsysfromjupyter_console.appimportZMQTerminalIPythonApp# mimic jupyter-console --existing: attach shell to running kernelsys.argv= [sys.argv[0], "--existing"]
app=ZMQTerminalIPythonApp.instance()
app.initialize(None)
super(ZMQTerminalIPythonApp, app).start()
code="""import ipydeximport tracebacktry: failing_function()except Exception as ex: value, tb = traceback._parse_value_tb(ex, traceback._sentinel, traceback._sentinel) ipydex.ips_excepthook(type(ex), ex, tb)"""# run this code in the context of the running kernelapp.shell.run_cell(code)
Problem:
This works, but with one flaw: It only offers the simple_prompt-mode of the embedded IPython shell. Background: My custom excepthook internally creates an instance of from IPython.terminal.embed.InteractiveShellEmbed and calls its mainloop (as intended). This mainloop has two different prompt-modes: default and simple. The default mode has many desired features (colored output, TAB-completion, ...), which I desire but the simple mode does not offer. The mode is determined by this line IPython/terminal/interactiveshell.py#L134.
I tried to force the class variable InteractiveShellEmbed.simple_prompt to False but then I get RuntimeError: This event loop is already running (would have been too easy).
I see three possible ways to achieve the desired behavior:
a) Let InteractiveShellEmbed run in default (i.e. not simple) mode inside the running ZMQTerminalIPythonApp.
b) Run ZMQTerminalIPythonApp.shell.mainloop() directly in the namespace of the frame where the exception occurs (and offer the possibility to go up and down again in the frame stack).
c) Temporarily overwrite sys.excepthook with my custom ipydex.ips_excepthook and just execute failing_function() without try ... except.
For a): The whole story with the custom excepthook is just my motivation. The problem boils down to achieving that app.shell.run_cell('IPython.embed(colors="neutral")') runs in default (not simple) prompt mode.
For b): I dont know whether that is possible because InteractiveShellEmbed.mainloop accepts key word args local_ns and module (global name space), whereas ZMQTerminalIPythonApp.shell.mainloop does not.
For c): This works perfectly for normal scripts but not when "injecting" code in a running jupyter kernel, because overwriting sys.excepthook does not seem to have an effect.
Derived questions:
Which of the directions (a, b, c) is the most promising?
What would be a good next step?
What other possibilities do I have?
The text was updated successfully, but these errors were encountered:
Main question: How can I run an embedded IPython shell with a full-featured prompt (
simple_prompt=False
) in the namespace of a frame where an exception occurred in the context of a running IPython kernel of a Jupyter notebook?Explanation:
I have the following usecase (which is almost solved, up to one major flaw):
In Jupyter notebook (python kernel) I run some nested function call
failing_function()
. Deep down in the call stack an exception happens.I want to debug the situation on the commandline with my custom excepthook (
ipydex.ips_excepthook
; it opens an emebedded IPython shell right in the frame where the exception occurs and offers the possibility to move up in the frame stack, which I find more useful than the classical IPython debugger).I can achieve this with the following steps: Within an ordinary python script:
Problem:
This works, but with one flaw: It only offers the
simple_prompt
-mode of the embedded IPython shell. Background: My custom excepthook internally creates an instance offrom IPython.terminal.embed.InteractiveShellEmbed
and calls its mainloop (as intended). This mainloop has two different prompt-modes: default and simple. The default mode has many desired features (colored output, TAB-completion, ...), which I desire but the simple mode does not offer. The mode is determined by this line IPython/terminal/interactiveshell.py#L134.I tried to force the class variable
InteractiveShellEmbed.simple_prompt
toFalse
but then I getRuntimeError: This event loop is already running
(would have been too easy).I see three possible ways to achieve the desired behavior:
InteractiveShellEmbed
run in default (i.e. not simple) mode inside the runningZMQTerminalIPythonApp
.ZMQTerminalIPythonApp.shell.mainloop()
directly in the namespace of the frame where the exception occurs (and offer the possibility to go up and down again in the frame stack).sys.excepthook
with my customipydex.ips_excepthook
and just executefailing_function()
withouttry ... except
.For a): The whole story with the custom excepthook is just my motivation. The problem boils down to achieving that
app.shell.run_cell('IPython.embed(colors="neutral")')
runs in default (not simple) prompt mode.For b): I dont know whether that is possible because
InteractiveShellEmbed.mainloop
accepts key word argslocal_ns
andmodule
(global name space), whereasZMQTerminalIPythonApp.shell.mainloop
does not.For c): This works perfectly for normal scripts but not when "injecting" code in a running jupyter kernel, because overwriting
sys.excepthook
does not seem to have an effect.Derived questions:
The text was updated successfully, but these errors were encountered: