microsoft / pylance-release

Documentation and issues for Pylance
Creative Commons Attribution 4.0 International
1.7k stars 770 forks source link

"Extract method" produces syntax error with multiline except clause #2146

Open jh0ker opened 2 years ago

jh0ker commented 2 years ago

Environment data

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.')

image

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.

Molkree commented 1 year ago

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"
)
bschnurr commented 1 month ago

Thank you for reporting this issue.