rope
rope copied to clipboard
Rope exception when f-string has a # before a variable when using extract method
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:
- Code before refactoring:
def main():
h = 1
g = f"#{h}"
- Describe the refactoring you want to do
Extract the f-string to a function
- Expected code after refactoring:
def main():
h = 1
g = extracted_method(h)
def extracted_method(h):
return f"#{h}"
- 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
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}"'