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

Question:

I am trying to debug my Python Pytest tests in VS Code, using the Testing Activity on the left bar. I am able to run my tests as expected, with some passing and some failing. I would like to debug the failing tests to more accurately determine what is causing the failures.

When I run an individual test in debug mode VS Code is properly hitting a breakpoint and stopping, and the Run and Debug pane shows the local variables. I can observe the status of local variables either in the Variables > Local pane or through the REPL, by typing the name of the variable.

When I try to print out any statement, such as using > print("here") I do not get any output to the Debug Console. When I reference a variable, or put the string directly using > "here" I do see the output to the Debug Console.

It seems to me that the stdout of my REPL is not displaying to the Debug Console. A number of answers online have been suggesting to add options like "redirectOutput": true or "console": "integratedTerminal", but neither of those seem to have worked. My full launch.json is below:

{
    // 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"
        }
    ]
}

Is there another setting I’m missing to enable this output? Have I got the wrong console type?

Asked By: WarSame

||

Answers:

One possible workaround I saw online is to print the DF in Spark to a string, then paste it into Notepad++ and convert the n values into newlines.

I was able to print the DF to a string using some code I found on another Stack Overflow answer:

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))

This can then be called using getShowString(df)

This does not solve the actual issue of getting terminal output directed to the debug window, but can help in this particular case.

Answered By: WarSame

So After a lot of frustrating "debugging" I found a solution that worked for me (if you are using pytest as me):

tldr

Two solutions:

  1. downgrade your vscode python extension to v2022.2.1924087327 that will do the trick (or any version that had the debugpy<=1.5.1).
    enter image description here

  2. Or, Launch the debbuger from the debug tab not the testing tab. And use a configuration like the following one

    {
        "name": "Python: Current File (Integrated Terminal)",
        "type": "python",
        "request": "launch",
        "program": "${file}",
        "console": "integratedTerminal",
        "purpose": ["debug-test"], 
        "redirectOutput": true,
        "env": {"PYTHONPATH": "${workspaceRoot}"}
    }
    
  3. Bonus. If you are using pytest you can temporarily disable the 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 of why the prints are not longer working.

    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')
    

the long explanation

so the problem apparently is that the debugpy (which is the library used by vscode python debugger) in is last version v1.6.0 fixed this "bug (827)". In a nutshell, this "bug" was that vscode "duplicated" all the stdout when debugging because it captures the pytest stdout and replicate it in the debugger console.
This is because, by default, pytest captures all the stdout and store it (so when running all test in parallel it doesn’t create a mess).

After "fixing" this issue, now, when you launch the test via the testing tab, by default, pytest is capturing all the stdout and the "new" (>=v1.6.1) debugpy ignores it. Therefore, all the print statements are not shown anymore on the debug console, even when you call print() in a breakpoint, because are captured by pytest (IDK where the pytest captured stdout is showing/stored if it is anywhere). which, in my case is a PITA.

You can disable the pytest capture option using the flag -s or --capture=no when launching pytest in a console or even from the debug tab as a custom configuration. but the problem is that there is no way (apparently) to add these parameters in vscode for the testing tab so pytest is executed using that option.

Therefore the solution that I found was to downgrade the python extension to a version that uses an older version of debugpy v1.5.1, you can see in the python extension changelog that from the version 2022.4.0 they update the debugpy version, so going before that did the trick for me, you will have the double stdout "bug" in the console, but the print statement will work.

ref: The issue that lead me to the solution


You may make your voice heard here in the vscode-python issues

Answered By: Pablo