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

Don't do eval/exec inside of except clause #812

Closed
thegunslingers opened this issue Dec 22, 2021 · 3 comments
Closed

Don't do eval/exec inside of except clause #812

thegunslingers opened this issue Dec 22, 2021 · 3 comments

Comments

@thegunslingers
Copy link

Environment data

  • debugpy version: 1.5.1
  • OS and version: Win 10
  • Python version (& distribution if applicable, e.g. Anaconda): Python 3.9 via Anaconda
  • Using VS Code or Visual Studio: VS Code

Actual behavior

In the debug console of VS Code there is a syntax error when using an f string in an assert statement. The same line does not produce a syntax error without a debuger or in VS Code when using run and debug.

Expected behavior

For the example script below there should be no syntax error when trying to run a line similar to below in the debug console.

assert testval >200, f"Test Value was not greater than 200, the value was {testval:d}"

Steps to reproduce:

  1. Create an example script like below and set a breakpoint on the assert line
  2. Start a debugging session in VS Code
  3. Open the debug console and run the assert line. (Observe the syntax error that is raised before being caught by the assert error
  4. In the debugging session run the next line (the same assert line and observe no syntax error before the assert error is raised).

Example Script:

testval = 100
assert testval >200, f"Test Value was not greater than 200, the value was {testval:d}"
@int19h
Copy link
Contributor

int19h commented Jan 6, 2022

The reason why this happens is that we try to evaluate the code as an expression first (so that we can print out the result if there is one), and only if that fails, try treating it as a statement. Basically something like:

try:
    code = compile(src, "<string>", "eval")
except Exception:
    code = compile(src, "<string>", "exec")

Since assert is a statement, the first compile() fails, and we fall back onto the second one. But then when we actually try to eval it, the assertion itself fails. Since the eval is also in the except-block, it is treated as a chained exception, and when Python prints out the traceback, it prints the original exception (i.e. SyntaxError in this case) first, followed by AssertError.

The same issue appears if you try to run e.g. raise Exception, or if True: 1/0 - basically, any statement that is not a valid expression, and that raises an exception.

To avoid this, we shouldn't be doing eval() while handling the exception. Note, however, that this will not preclude the SyntaxError from actually happening - it's by design - but only from being reported alongside the actual error.

@thegunslingers
Copy link
Author

Thanks for the explanation!

@fabioz fabioz changed the title Using an f string with formatting in an assert statment results in a syntax error in the debug console Don't do eval/exec inside of except clause Jan 20, 2022
@rftw
Copy link

rftw commented Jan 23, 2022

I too came across a similar issue and wondered why the debug console is complaining about a syntax error.
A simple fix could be to suppress the exception chaining like:

try:
    code = compile(src, "<string>", "eval")
except Exception:
    try:
        exec(compile(src, "<string>", "exec"))
    except Exception as e:
        raise e from None

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