vscode-python: "Run Selection" does not handle decorators properly.

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper


@my_decorator
def say_whee():
    print("Whee!")


say_whee()

shift+enter or ‘run’ button in vscode

>>> def my_decorator(func):
...     def wrapper():
...         print("Something is happening before the function is called.")
...         func()
...         print("Something is happening after the function is called.")
...     return wrapper
... @my_decorator
  File "<stdin>", line 7
    @my_decorator
    ^
SyntaxError: invalid syntax
>>>
>>> def say_whee():
...     print("Whee!")
...
>>> say_whee()
Whee!
>>>

python extension v2021.1.442908725-dev

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 24 (7 by maintainers)

Most upvoted comments

Verification steps:

  • Download the latest Insiders version of the Python extension
  • Copy the code from the original message:
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper


@my_decorator
def say_whee():
    print("Whee!")


say_whee()
  • Select it all and press shift + enter or run the Run Selection/Line in Terminal command
  • Make sure that the code is passed to the terminal and executed without any errors

What appears to be happening is the following:

  • the decorator gets executed as a single line in isolation, which produces a syntax error.
  • the undecorated/plain python statement beneath the decorator gets executed in isolation.

Ways of executing code with decorators that do seem to be working normally are:

  • Copying an pasting code into the REPL
  • Executing the file from the command line using python [script-path]
  • Using “Python: Run Selection/Line in Python Terminal” (shift + enter) if the decorator is indented as part of some scope (e.g. within an if statement or within a class definition)

Hence it is only the top level decorators that don’t work with “Python: Run Selection/Line in Python Terminal” (shift + enter) and it seems to be because the lines get evaluated / executed in isolation if they are not part of some indented block or pasted in as a whole. If “Python: Run Selection/Line in Python Terminal” (shift + enter) could be made to work like pasting from the clipboard works, then the problem would be solved.