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

3

12

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?

Disguise answered 9/4, 2022 at 20:39 Comment(3)
hey! did you find a solution to this bug? I have the same problem, I already tried almost all configurations that I found around, still not able to print, I can in my other mac, for some reason I the other one it's just not workingCrippen
I did find one method on a StackOVerflow answer somewhere which pointed me in the right direction for my use case. I've put it as an answer down below, but it doesn't solve the underlying problem so I'm not going to accept it as an answer.Disguise
hey @Disguise maybe this issue will help you, it solved my problem. last comment I post the solution, apparently was a problem with pytestCrippen
C
15

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

Crippen answered 15/4, 2022 at 20:59 Comment(4)
Thank you for your detailed answer Pablo! It's frustrating to not have the debug option available in the testing tab. For my purposes debugging the test directly is working fine, so I'll keep in mind to do that directly, rather than from within the testing tab. Thanks for the great explanation!Disguise
Thank you. After weeks of troubleshooting, thanks to your solution I finally can use debugging within vs code testing again.Schopenhauerism
I was able to add the -s argument to the testing tab. I've done that by creating a pytest.ini file in the root of my project. Then I added the addopts = -s under [pytest]Ane
@ThiagoAlves Awesome, that worked! You should post this as an answer :)Spider
C
1

This is not a solution to the problem, but it may help when dealing with it. It will not send stdout to the console. However, it will allow you to inspect a string in its fully formatted form.

It appears that the debugger treats str specially, and it displays it in its compressed form (e.g "\n") instead of actually displaying it in human friendly layout.

So, if you wrap that string in another class, then you can inspect the string in its full glory.

Create this class as a helper:

@dataclass
class FakeString():
    string: str
    def __repr__(self) -> str:
        return self.string + "\nFake String #####"

Now when you are in the debugger, and you need to see a string printed correctly, you can just do this in repl:

> some_string = "hello world\nformatted correctly"

> some_string
'hello world\nformatted correctly'
> FakeString(some_string)
hello world
formatted correctly
Fake String #####

Obviously you don't need that "Fake String ####" suffix, that is just there to make this example more clear about what is happening.

Cory answered 2/7, 2024 at 14:41 Comment(0)
D
-1

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.

Disguise answered 14/4, 2022 at 16:45 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.