如何更改 IPython %pdb 和 %debug 调试器?

2024-01-08

默认情况下,ipython 使用 ipdb 作为带有 %pdb 或 %debug 魔法的调试器。 但是,我更喜欢 pdb++...有没有办法更改用这些魔法调用的调试器? (我知道我可以简单地在 pdb++ 的异常情况下使用 pdb.xpm() ,但我想让它与 ipython magic 命令一起使用,这样我就不必每次都包装代码......)


因此,至少在有限的情况下,而且不是以我一定推荐的方式,这里的答案是肯定的。我不能保证下面的内容会在我所做的范围之外工作,但它可能会给你足够的洞察力来自己尝试。需要谨慎,因为它涉及更改未记录的属性ipython运行时的 shell 类。 TLDR:我找到了如何ipython调用调试器时%pdb魔法开启或当您致电%debug魔法,我更新了它以使用我想要的调试器。如果您只想使用对我有用的方法并且不关心搜索,请跳过接下来的两段。

长版:当你跑步时ipython它启动一个实例TerminalInteractiveShell https://github.com/ipython/ipython/blob/master/IPython/terminal/interactiveshell.py,其中有一个debugger_cls属性告诉你调试器ipython将启动。不幸的是,在这个水平上TerminalInteractiveShell, debugger_cls实际上是类的一个属性,并且没有允许您修改它的设置器。相反,它要么被设置为Pdb(实际上是一个更有特色的ipython Pdb比传统的pdb) or TerminalPdb(甚至更多功能)。

然而,如果你深入挖掘,你会发现debugger_cls被传递到InteractiveShell https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py#L1089初始化回溯的处理方式。在那里它似乎消失在初始化中InteractiveShell's InteractiveTB财产,但实际上最终只是作为debugger_cls的属性(InteractiveTB)类(通过设置继承属性TBTools https://github.com/ipython/ipython/blob/master/IPython/core/ultratb.py#L204)。最后,这个debugger_cls属性仅用于设置pdb属性(或多或少通过做TBToolsInstance.pdb = TBToolsInstance.debugger_cls())在几个地方之一。无论如何,事实证明these属性can被改变!如果你正确地改变它们,它们就会渗透到外壳本身!重要的是,这取决于以下事实:ipython利用特质 https://traitlets.readthedocs.io/en/stable/config.html包来创建一个Singletonshell 的对象,这允许您从终端本身访问该对象。下面详细介绍一下。

下面我展示了您可以在以下位置运行的代码ipythonshell 来达到你想要的结果。作为一个例子,我正在替换默认的调试器(TerminalPdb)使用我创建的修改版本可以更好地处理某些列表理解(LcTerminalPdb https://github.com/emiliosalazar/LcTerminalPdb)。该过程(您可以在ipythonshell)如下。

# import the TerminalInteractiveShell class
from IPython.terminal.interactiveshell import TerminalInteractiveShell
# grab the specific instance of the already initialized ipython
shl = TerminalInteractiveShell().instance()
# grab the InteractiveTB attribute (which is a class)
tbClass = shl.InteractiveTB
# load the debugger class you want to use; I assume it's accessible on your path
from LcTerminalPdb import LcTerminalPdb
# change tbClass's debugger_cls to the debugger you want (for consistency 
# with the next line)
tbClass.debugger_cls = LcTerminalPdb
# more importantly, set the pdb attribute to an instance of the class
tbClass.pdb = tbClass.debugger_cls()
# The above line is necessary if you already have the terminal running 
# (and have entered pdb at least once); otherwise, ipython will run it on 
# its own

就是这样!请注意,因为您调用instance()的方法TerminalInteractiveShell,您正在获取当前正在运行的 shell 的对象,这就是为什么修改将影响 shell 本身以及所有后续调试。作为奖励,您可以将这些代码行添加到您的ipython_config.py https://ipython.org/ipython-doc/3/config/intro.html文件,所以你想要的调试器(LcTerminalPdb这里)总是装载着ipython:

c.InteractiveShellApp.exec_lines = [
'%pdb on',
'from LcTerminalPdb import LcTerminalPdb',
'from IPython.terminal.interactiveshell import TerminalInteractiveShell',
'shl = TerminalInteractiveShell().instance().InteractiveTB',
'shl.debugger_cls = LcTerminalPdb',
]

注意上面我不需要写额外的shl.pdb = shl.debugger_cls()线,如ipython将在第一次进入调试点时处理它。但可以肯定的是,请随意。

NOTES:

  • 我只使用过测试过LcTerminalPdb,而且只是简短的,但它似乎工作正常
  • 我怀疑只要其他pdb调试器具有相同的 APIpdb(即如果它们可以被PYTHONBREAKPOINT https://peps.python.org/pep-0553/环境变量)然后它应该可以工作
  • 我真的不清楚改变如此深层的属性是否会产生意想不到的效果,所以不确定我在多大程度上推荐这种方法
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改 IPython %pdb 和 %debug 调试器? 的相关文章

随机推荐