"Extract method" produces syntax error with multiline except clause
Environment data
- Language Server version: 2021.12.0
- OS and version: linux x64
- Python version (and distribution if applicable, e.g. Anaconda): Originally observed with CPython 3.8 in a virtual environment and reproduced using the CPython 3.10 system install
- python.analysis.indexing: undefined
- python.analysis.typeCheckingMode: off
Scenario
(see below for full code snippets)
Assume we have a try/except clause like the following somewhere in the function we want to refactor:
try:
raise ValueError("This is a test")
except (
KeyError,
ValueError,
) as e:
print(e)
We highlight a range of lines that contains the above lines, hit the :bulb: and select "Extract method".
Expected behaviour
Assuming the code did not have any syntax errors before, the resulting code should also be free of syntax errors.
Actual behaviour
A line break is added between ( and as e: in the second-to-last line of the above example, causing a syntax error.
try:
raise ValueError("This is a test")
except (
KeyError,
ValueError,
)
as e:
print(e)
Logs
Python Language Server Log
[Info - 9:50:42 PM] Pylance language server 2021.12.0 (pyright acfc919d) starting
[Info - 9:50:42 PM] Server root directory: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist
[Info - 9:50:42 PM] No configuration file found.
[Info - 9:50:42 PM] No pyproject.toml file found.
[Info - 9:50:42 PM] Setting pythonPath for service "vscode_python_extract_broken": "/bin/python"
[Warn - 9:50:42 PM] stubPath /home/jhoeke/git/vscode_python_extract_broken/typings is not a valid directory.
[Info - 9:50:42 PM] Assuming Python version 3.10
[Info - 9:50:42 PM] Assuming Python platform Linux
Search paths for /home/jhoeke/git/vscode_python_extract_broken
/home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib
/home/jhoeke/git/vscode_python_extract_broken
/home/jhoeke/git/vscode_python_extract_broken/typings
/home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stubs/...
/home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/bundled/stubs
/usr/lib64/python3.10
/usr/lib64/python3.10/lib-dynload
/home/jhoeke/.local/lib/python3.10/site-packages
/usr/lib64/python3.10/site-packages
/usr/lib/python3.10/site-packages
[Warn - 9:50:43 PM] Exception received when installing file system watcher: TypeError [ERR_FEATURE_UNAVAILABLE_ON_PLATFORM]: The feature watch recursively is unavailable on the current platform, which is being used to run Node.js
[Warn - 9:50:43 PM] Exception received when installing file system watcher: TypeError [ERR_FEATURE_UNAVAILABLE_ON_PLATFORM]: The feature watch recursively is unavailable on the current platform, which is being used to run Node.js
[Warn - 9:50:43 PM] Exception received when installing file system watcher: TypeError [ERR_FEATURE_UNAVAILABLE_ON_PLATFORM]: The feature watch recursively is unavailable on the current platform, which is being used to run Node.js
[Warn - 9:50:43 PM] Exception received when installing file system watcher: TypeError [ERR_FEATURE_UNAVAILABLE_ON_PLATFORM]: The feature watch recursively is unavailable on the current platform, which is being used to run Node.js
[Warn - 9:50:43 PM] Exception received when installing file system watcher: TypeError [ERR_FEATURE_UNAVAILABLE_ON_PLATFORM]: The feature watch recursively is unavailable on the current platform, which is being used to run Node.js
[Info - 9:50:43 PM] Searching for source files
[Info - 9:50:43 PM] Found 1 source file
[Info - 9:50:43 PM] Background analysis(1) root directory: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist
[Info - 9:50:43 PM] Background analysis(1) started
Background analysis message: setConfigOptions
Background analysis message: setImportResolver
Background analysis message: ensurePartialStubPackages
Background analysis message: setTrackedFiles
Background analysis message: markAllFilesDirty
Background analysis message: setFileOpened
[FG] parsing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (16ms)
[FG] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/builtins.pyi [fs read 1ms] (61ms)
[FG] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/builtins.pyi (29ms)
[FG] binding: /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
Background analysis message: getSemanticTokens full
[BG(1)] getSemanticTokens full at /home/jhoeke/git/vscode_python_extract_broken/demo.py ...
[BG(1)] parsing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (17ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/builtins.pyi [fs read 2ms] (56ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/builtins.pyi (23ms)
[BG(1)] binding: /home/jhoeke/git/vscode_python_extract_broken/demo.py (0ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/typing.pyi [fs read 1ms] (18ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/typing.pyi (7ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/_typeshed/__init__.pyi [fs read 0ms] (6ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/_typeshed/__init__.pyi (1ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/types.pyi [fs read 0ms] (7ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/types.pyi (3ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/typing_extensions.pyi [fs read 0ms] (4ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/typing_extensions.pyi (2ms)
[BG(1)] parsing: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/abc.pyi [fs read 0ms] (0ms)
[BG(1)] binding: /home/jhoeke/.vscode/extensions/ms-python.vscode-pylance-2021.12.0/dist/typeshed-fallback/stdlib/abc.pyi (1ms)
[BG(1)] getSemanticTokens full at /home/jhoeke/git/vscode_python_extract_broken/demo.py (166ms)
Background analysis message: getSemanticTokens range
[BG(1)] getSemanticTokens range 0:0 - 16:0 at /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
Background analysis message: analyze
[BG(1)] analyzing: /home/jhoeke/git/vscode_python_extract_broken/demo.py ...
[BG(1)] checking: /home/jhoeke/git/vscode_python_extract_broken/demo.py (6ms)
[BG(1)] analyzing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (6ms)
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: setFileOpened
Background analysis message: markFilesDirty
Background analysis message: analyze
[BG(1)] analyzing: /home/jhoeke/git/vscode_python_extract_broken/demo.py ...
[BG(1)] parsing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
[BG(1)] binding: /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
[BG(1)] checking: /home/jhoeke/git/vscode_python_extract_broken/demo.py (14ms)
[BG(1)] analyzing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (16ms)
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
[FG] parsing: /home/jhoeke/git/vscode_python_extract_broken/demo.py (5ms)
[FG] binding: /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
Background analysis message: getSemanticTokens delta
[BG(1)] getSemanticTokens delta previousResultId:1638910243387 at /home/jhoeke/git/vscode_python_extract_broken/demo.py (1ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: markFilesDirty
Background analysis message: analyze
Code Snippet / Additional information
Example Code
def main():
"""Demo of the bug"""
print("Select from here")
try:
raise ValueError("This is a test")
except (
KeyError,
ValueError,
) as e:
print(e)
print('...to here and select "Extract method" in the 💡 menu.')
return 0
Result
def main():
"""Demo of the bug"""
new_func()
return 0
def new_func():
print("Select from here")
try:
raise ValueError("This is a test")
except (
KeyError,
ValueError,
)
as e:
print(e)
print('...to here and select "Extract method" in the 💡 menu.')

This is a very useful project! Thanks for the great work :heart:
I noticed this bug today and although it wasn't really a big problem, i figured i'd file a report anyways since i didn't find one. Please let me know if you need any further information.
I can add that it's not limited to except clause, multiline with statement also results in incorrect syntax:
with open(
"filepath",
) as f:
pass
becomes
def new_func():
with open(
"filepath",
)
as f:
pass
Even a multiline function call becomes weirdly indented (but still valid syntax):
print(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
becomes
def new_func():
print(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
Thank you for reporting this issue.