rope icon indicating copy to clipboard operation
rope copied to clipboard

Rope exception when f-string has a # before a variable when using extract method

Open rlbr opened this issue 1 year ago • 1 comments

Describe the bug Rope throws an exception when an f-string has a # before a {variable} when using extract method

For example, this is a valid f-string in python:

f"#{h}"

However, selecting this block in an editor and attempting to use code action extract would result in an error being thrown.

To Reproduce Steps to reproduce the behavior:

  1. Code before refactoring:
def main():
    h = 1
    g = f"#{h}"
  1. Describe the refactoring you want to do

Extract the f-string to a function

  1. Expected code after refactoring:
def main():
    h = 1
    g = extracted_method(h)

def extracted_method(h):
    return f"#{h}"
  1. Describe the error or unexpected result that you are getting
[stderr] 2024-11-27 14:36:45,788 CST - ERROR - pylsp_rope.plugin - Exception when doing workspace/executeCommand: f-string: invalid syntax (<string>, line 2)
[stderr] Traceback (most recent call last):
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/pylsp_rope/plugin.py", line 158, in pylsp_execute_command
[stderr]     return commands[command](workspace, **arguments[0])(
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/pylsp_rope/refactoring.py", line 44, in __call__
[stderr]     rope_changeset = self.get_changes()
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/pylsp_rope/refactoring.py", line 112, in get_changes
[stderr]     rope_changeset = refactoring.get_changes(
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/extract.py", line 82, in get_changes
[stderr]     new_contents = _ExtractPerformer(info).extract()
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/extract.py", line 287, in extract
[stderr]     extract_info = self._collect_info()
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/extract.py", line 314, in _collect_info
[stderr]     self._find_matches(extract_collector)
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/extract.py", line 328, in _find_matches
[stderr]     for region_match in region_matches:
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/similarfinder.py", line 108, in get_matches
[stderr]     for match in self._get_matched_asts(code):
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/similarfinder.py", line 117, in _get_matched_asts
[stderr]     wanted = self._create_pattern(code)
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/refactor/similarfinder.py", line 124, in _create_pattern
[stderr]     node = ast.parse(expression)
[stderr]   File "/home/raphael/.venv/testware/lib/python3.9/site-packages/rope/base/ast.py", line 33, in parse
[stderr]     return ast.parse(source, filename=filename, *args, **kwargs)
[stderr]   File "/home/raphael/.pyenv/versions/3.9.18/lib/python3.9/ast.py", line 50, in parse
[stderr]     return compile(source, filename, mode, flags,
[stderr]   File "<string>", line 2
[stderr]     (${h})
[stderr]      ^
[stderr] SyntaxError: f-string: invalid syntax

Editor information (please complete the following information):

  • Project Python version: 3.9.18
  • Rope Python version: 3.9.18 (same venv)
  • Rope version: 1.13.0
  • Text editor/IDE and version: emacs 29.3 (via eglot)
  • python-lsp-server version: 1.12.0
  • pylsp-rope version: 0.1.16

rlbr avatar Nov 27 '24 20:11 rlbr

The source of this behavior appears to lie in RawSimilarFinder._replace_wildcards.

In [4]: RawSimilarFinder._replace_wildcards(None, '${g} = f"#{${h}}"')
Out[4]: '__rope__variable_normal_g = f"#{${h}}"'

The return should be '__rope__variable_normal_g = f"#{__rope__variable_normal_h}"'

rlbr avatar Dec 02 '24 22:12 rlbr