Extract raises IndexError or ModuleSyntaxError instead of RefactoringError for an empty or whitespace-only region

未关闭 适合新手
#926 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 7 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python

调研方向

从 rope/refactor/extract.py 中的 _get_single_expression_body() 开始,其中 extracted.lstrip()[0] 在空字符串上会抛出 IndexError。使用 issue 中的脚本复现,该脚本覆盖 ExtractVariable 和 ExtractMethod 的空区域,以及 ExtractMethod 的纯空白区域。当三种情况都抛出带有清晰信息的 RefactoringError 时即完成,检查位置可以是 _ExceptionalConditionChecker.base_conditions(),或构造函数中 _fix_start() 和 _fix_end() 之后。

由索引模型根据 Issue 内容生成。

描述

ExtractMethod and ExtractVariable raise IndexError for an empty region, and ModuleSyntaxError about a generated wrapper for a region that contains only whitespace. Both are user mistakes, not internal errors, so they should be reported as RefactoringError, as the other bad-region cases are.

This matters for editor integrations. Neovim sends an empty range when the user requests code actions without a selection, so a language server calls extract with an empty region all the time. It has to tell "can't extract here" apart from a real crash it should log.

To Reproduce

import pathlib
import tempfile

from rope.base.project import Project
from rope.refactor import extract

source = "def f(a):\n    b = a + 1\n    return b\n"
root = pathlib.Path(tempfile.mkdtemp())
(root / "m.py").write_text(source)
project = Project(str(root), ropefolder=None)
resource = project.get_resource("m.py")

expr = source.index("a + 1")
indent = source.index("    b =")
for label, cls, start, end in [
    ("extract variable, empty region", extract.ExtractVariable, expr, expr),
    ("extract method, empty region", extract.ExtractMethod, expr, expr),
    ("extract method, whitespace only", extract.ExtractMethod, indent, indent + 4),
]:
    try:
        cls(project, resource, start, end).get_changes("new_name")
    except Exception as e:
        print(f"{label}: {type(e).__name__}: {e}")

Output on master (46ebf37), Python 3.13:

extract variable, empty region: IndexError: string index out of range
extract method, empty region: IndexError: string index out of range
extract method, whitespace only: ModuleSyntaxError: Syntax error in file <string> line <1>: expected an indented block after function definition on line 1

The IndexError comes from _get_single_expression_body(), which indexes extracted.lstrip()[0] on an empty string.

Expected behaviour

RefactoringError, with a message such as "Extracted piece should contain at least one expression or statement". Checking it in _ExceptionalConditionChecker.base_conditions(), or in the constructor after _fix_start() and _fix_end(), would cover both cases.

Editor information

主要语言
Python
星标
2.2k
派生
197
平均合并
2 天 13 小时
30 天内合并 PR
5

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

python-rope/rope 的其他 Issue

查看 python-rope/rope 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。