如何通过 `jupyter-console --existing` 调用基于 `InteractiveShellEmbed` 的自定义异常钩子

0 投票
0 回答
9 浏览
提问于 2025-04-12 09:18

主要问题:我该如何在Jupyter笔记本的IPython内核中,运行一个完整功能的嵌入式IPython命令行(simple_prompt=False),并且在发生异常的框架命名空间中进行调试?

解释:

我有一个使用场景(几乎解决了,但还有一个主要缺陷):

在Jupyter笔记本中(使用Python内核),我运行一个嵌套的函数调用failing_function()。在调用的深层次中发生了异常。我想在命令行中使用我的自定义异常处理钩子(ipydex.ips_excepthook)来调试这个情况;它会在异常发生的框架中打开一个嵌入式IPython命令行,并提供向上和向下移动调用栈的可能性,我觉得这比传统的IPython调试器更有用。

我可以通过以下步骤实现这一点:在一个普通的Python脚本中:

import sys
from jupyter_console.app import ZMQTerminalIPythonApp

# mimic jupyter-console --existing: attach shell to running kernel
sys.argv = [sys.argv[0], "--existing"]
app = ZMQTerminalIPythonApp.instance()
app.initialize(None)
super(ZMQTerminalIPythonApp, app).start()

code = """
import ipydex
import traceback
try:
    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 kernel
app.shell.run_cell(code)

问题:

这个方法可以实现,但有一个缺陷:它只提供了嵌入式IPython命令行的simple_prompt模式。背景是:我的自定义异常处理钩子内部创建了一个from IPython.terminal.embed.InteractiveShellEmbed的实例,并调用它的主循环(这是预期的)。这个主循环有两种不同的提示模式:默认模式和简单模式。默认模式有很多我想要的功能(比如彩色输出、TAB补全等),而简单模式则没有。这种模式是由这一行代码决定的:IPython/terminal/interactiveshell.py#L134

我尝试强制将类变量InteractiveShellEmbed.simple_prompt设置为False,但结果却出现了RuntimeError: This event loop is already running(这就太简单了)。

我看到有三种可能的方法可以实现我想要的效果:

  • a) 让InteractiveShellEmbed在正在运行的ZMQTerminalIPythonApp中以默认模式(即非简单模式)运行。
  • b) 直接在发生异常的框架命名空间中运行ZMQTerminalIPythonApp.shell.mainloop()(并提供向上和向下移动调用栈的可能性)。
  • c) 暂时用我的自定义ipydex.ips_excepthook覆盖sys.excepthook,并直接执行failing_function()而不使用try ... except

对于a):整个自定义异常处理钩子的故事只是我的动机。问题归结为让app.shell.run_cell('IPython.embed(colors="neutral")')在默认模式下运行(而不是简单模式)。对于b):我不知道这是否可行,因为InteractiveShellEmbed.mainloop接受关键字参数local_nsmodule(全局命名空间),而ZMQTerminalIPythonApp.shell.mainloop则不接受。对于c):这在普通脚本中完美可行,但在“注入”代码到正在运行的Jupyter内核时却不行,因为覆盖sys.excepthook似乎没有效果。

衍生问题:

  1. 哪种方法(a、b、c)最有希望?
  2. 下一步该怎么做比较好?
  3. 我还有哪些其他可能性?

0 个回答

暂无回答

撰写回答