Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breakpointing with python unittest #550

Closed
rijobro opened this issue Feb 22, 2021 · 10 comments
Closed

Breakpointing with python unittest #550

rijobro opened this issue Feb 22, 2021 · 10 comments
Assignees

Comments

@rijobro
Copy link

rijobro commented Feb 22, 2021

Environment data

  • VS Code version: 1.53.2
  • Extension version (available under the Extensions sidebar): v2021.2.582707922
  • OS and version: MacOS 11.2.1 (Big Sur)
  • Python version (& distribution if applicable, e.g. Anaconda): 3.8.5 (Conda)
  • Type of virtual environment used (N/A | venv | virtualenv | conda | ...): N/A
  • Value of the python.languageServer setting: Pylance

Expected behaviour

I am running some tests using python's unittest. When an exception is raised, I'd like VS Code to breakpoint at the point the error is thrown. I have "Uncaught Exceptions" enabled and "Raised Exceptions" disabled, and I see the desired behaviour when running the code normally (not with unittest). In the minimum working example below, I'd like the code to breakpoint at line 4 when the exception is raised.

Actual behaviour

Instead of the desried/expected behaviour, the breakpoint is on the final line with an empty stack call and no way of getting back to line 4 or the variables present at that time. This makes debugging useless. I imagine this occurs because unittest catches all uncaught exceptions, so I'd like a way for VSCode to breakpoint if the except was not written by the user (as is the case with unittest). I've seen a suggested solution here (microsoft/vscode-python#14056 (comment)) and also thought that setting justMyCode might help, too, but neither did.

Caveat 1: I know I could enable "Raised Exceptions" but the code I'm working on has lots of intentional raises which are caught. So enabling "Raised Exceptions" would take too long to sift through all the intentional raises.

Caveat 2: I know there is the "Test" tab. When I click to debug the test it says "No Tests Ran". This is strange because I simply run the test from inside the "Test" tab, it successfully runs (it still raises the error, and there is no breakpointing, but it runs at least).

Steps to reproduce:

In the example below, I'd like the breakpoint at line 4 (raise RuntimeError()), but I'm getting it instead at line 11 (unittest.main()), which has an empty stack call and no way to get back to line 4 or any of the variables that were present at that time.

import unittest

def something():
    raise RuntimeError()

class TestClass(unittest.TestCase):
    def test_method(self):
        something()

if __name__ == "__main__":
    unittest.main()
@int19h int19h transferred this issue from microsoft/vscode-python Feb 22, 2021
@int19h
Copy link
Contributor

int19h commented Feb 22, 2021

To clarify - did you try locally patching your debugpy to enable user-unhandled exceptions, but it still didn't work as expected when you enabled the corresponding filter in UI?

@rijobro
Copy link
Author

rijobro commented Feb 22, 2021

Sorry that wasn't clear. I followed the advice given in the linked comment, but found that my settings already matched the suggested changes:

{"filter": "userUnhandled", "label": "User Uncaught Exceptions", "default": True},

@int19h
Copy link
Contributor

int19h commented Feb 22, 2021

The code in question was changed slightly since that comment was written: it's now conditional on environment variable DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED, which must be set to 1.

If you have enabled it successfully, the exception filter should show up "User Uncaught" in addition to "Uncaught" and "Raised". Are you seeing it?

@rijobro
Copy link
Author

rijobro commented Feb 23, 2021

As in, in my .bashrc I put:

export DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED=1

and then restart VSCode?

@int19h
Copy link
Contributor

int19h commented Feb 23, 2021

That should work, although I'd check it manually in the terminal first (i.e. export in some shell, then launch VSCode from that same shell).

@rijobro
Copy link
Author

rijobro commented Feb 25, 2021

I've tried a few combinations including:

  • export DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED=1 && /Applications/Visual\ Studio\ Code.app/Contents/MacOS/Electron
  • export DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED=1 && code
  • add export DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED=1 to ~/.zprofile and then launch from icon

Unfortunately none give me the extra breakpoint button. Any further ideas?

@rijobro
Copy link
Author

rijobro commented Feb 25, 2021

I even hardcoded clients.py to be:

        exception_breakpoint_filters = [
            {"filter": "raised", "label": "Raised Exceptions", "default": False},
            {"filter": "uncaught", "label": "Uncaught Exceptions", "default": True},
        ]
        exception_breakpoint_filters += [
            {
                "filter": "userUnhandled",
                "label": "User Uncaught Exceptions",
                "default": True,
            },
        ]
        # if int(os.getenv("DEBUGPY_EXCEPTION_FILTER_USER_UNHANDLED", "0")) != 0:

But this still didn't add the button.

@fabioz
Copy link
Collaborator

fabioz commented Feb 25, 2021

It seemed to work for me (maybe you're editing a clients.py but also have debugpy installed elsewhere and it is picking a different version?)...

As a note, after changing the environment variable, you need to run it once for the button to appear (as the VSCode UI will be updated based on what the debugger gives at runtime).

i.e.: it should show:

image

After that, you need to enable it.

If you still can't get it to work, please provide the logging (maybe it can give some hint on what's not correct).

i.e.:

  • Open VS Code
  • Select the command Extensions: Open Extensions Folder
  • Locate the Python extension directory, typically of the form ms-python.python-2020..***
  • In that directory ensure you do not have any debug*.log files, if you do, please delete them
  • Go back into VS Code and modify your launch.json to add the setting "logToFile": true, see below:
{
    "name": "Python: Current File (Integrated Terminal)",
    "type": "python",
    "request": "launch",
    "program": "${file}",
    "console": "integratedTerminal",
    "logToFile": true
}
  • Start debugging
  • When done, go back into the extension directory and upload the debug*.log files into this GitHub issue.

@rijobro
Copy link
Author

rijobro commented Feb 25, 2021

The trick I was missing was to run it once to get it to refresh! Thanks!

@fabioz
Copy link
Collaborator

fabioz commented Feb 25, 2021

Great that it's working now ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants