你如何让 VS Code 将调试标准输出写入调试控制台?

How do you get VS Code to write Debug stdout to the Debug Console?

我正在尝试使用左侧栏中的测试 Activity 在 VS Code 中调试我的 Python Pytest 测试。我能够 运行 我的测试如期进行,有的通过了,有的失败了。我想调试失败的测试以更准确地确定导致失败的原因。

当我 运行 调试模式下的单个测试 VS Code 正确地命中断点并停止时,运行 和调试窗格显示局部变量。我可以在“变量”>“本地”窗格中或通过 REPL 通过键入变量名称来观察局部变量的状态。

当我尝试打印任何语句时,例如使用 > print("here"),我没有得到任何输出到调试控制台。当我引用变量或直接使用 > "here" 放置字符串时,我确实看到了调试控制台的输出。

在我看来,我的 REPL 的标准输出没有显示到调试控制台。许多在线答案建议添加 "redirectOutput": true"console": "integratedTerminal" 之类的选项,但这些似乎都没有用。我的完整 launch.json 如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit"
            ],
            "console": "integratedTerminal",
            "stopOnEntry": false,
            "redirectOutput": true,
            "outputCapture": "std"
        }
    ]
}

我还缺少其他设置来启用此输出吗?我是不是弄错了控制台类型?

我在网上看到的一种可能的解决方法是将 Spark 中的 DF 打印为字符串,然后将其粘贴到 Notepad++ 并将 \n 值转换为换行符。

我能够使用在另一个 Stack Overflow 答案中找到的一些代码将 DF 打印为字符串:

def getShowString(df, n=20, truncate=True, vertical=False):
    if isinstance(truncate, bool) and truncate:
        return(df._jdf.showString(n, 20, vertical))
    else:
        return(df._jdf.showString(n, int(truncate), vertical))

然后可以使用 getShowString(df)

调用它

这并不能解决将终端输出定向到调试 window 的实际问题,但在这种特殊情况下会有所帮助。

所以在经历了很多令人沮丧的“调试”之后,我找到了一个适合我的解决方案(如果你像我一样使用 pytest):

tldr

两种解决方案:

  1. 将您的 vscode python 扩展程序降级为 v2022.2.1924087327 即可解决问题(或具有 debugpy<=1.5.1 的任何版本)。

  2. 或者,从 debug tab 而不是 testing tab 启动调试器。并使用如下配置

    {
        "name": "Python: Current File (Integrated Terminal)",
        "type": "python",
        "request": "launch",
        "program": "${file}",
        "console": "integratedTerminal",
        "purpose": ["debug-test"], 
        "redirectOutput": true,
        "env": {"PYTHONPATH": "${workspaceRoot}"}
    }
    
  3. 奖金。如果您正在使用 pytest,您可以暂时禁用打印不再有效的原因 capture of the stdout of pytest so your print statements, and the print function, *if you breakpoint inside the contextmanager, will work too. This is very cumbersome but points out the original problem

    def test_disabling_capturing(capsys):
        print('this output is captured')
        with capsys.disabled():
            print('output not captured, going directly to sys.stdout')
        print('this output is also captured')
    

长解释

所以问题显然是 debugpyvscode python 调试器使用的库)是最新版本 v1.6.0 fixed this "bug (827)"。简而言之,这个“错误”是 vscode 在调试时“复制”了所有标准输出,因为它捕获了 pytest stdout 并将其复制到调试器控制台中。 这是因为,默认情况下,pytest 捕获所有标准输出并存储它(因此当 运行 所有并行测试时,它不会造成混乱)。

“修复”此问题后,现在,当您通过 testing tab 启动测试时,默认情况下,pytest 会捕获所有 stdout 和“新”( >=v1.6.1) debugpy 忽略它。因此,调试控制台上不再显示所有打印语句,即使您在断点中调用 print(),因为它们被 pytest 捕获(IDK,其中 pytest 捕获的标准输出是 showing/stored如果它在任何地方)。其中,在我的例子中是 PITA。

在控制台中启动 pytest 时,您可以使用标志 -s--capture=no 禁用 pytest 捕获选项,甚至从调试选项卡作为自定义配置。但问题是 在 vscode 中为 testing tab 添加这些参数,因此使用该选项执行 pytest。

因此,我找到的解决方案是将 python 扩展降级为使用旧版本 debugpy v1.5.1 的版本,您可以在 python extension changelog 从版本 2022.4.0 他们更新了 debugpy 版本,所以在那之前对我有用,你将拥有双 stdout 控制台中的“错误”,但 print 语句将起作用。

ref:issue 引导我找到解决方案


您可以在 debugpy 问题中在这里发表您的意见,以鼓励修复它:https://github.com/microsoft/debugpy/issues/947