From e2928c2a68dbc0ab78a81a4e291ba0c888b9d616 Mon Sep 17 00:00:00 2001 From: Susan5140s <167346857+sushan5140@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:11:45 +0530 Subject: [PATCH] fix: expand empty multi-node placeholders without crashing (#365) --- src/renaissance/syntax_tree/ast_rewriter.py | 4 ++-- test/syntax_tree/test_ast_rewriter.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/renaissance/syntax_tree/ast_rewriter.py b/src/renaissance/syntax_tree/ast_rewriter.py index 18b16f4d..6b6b031e 100644 --- a/src/renaissance/syntax_tree/ast_rewriter.py +++ b/src/renaissance/syntax_tree/ast_rewriter.py @@ -526,11 +526,11 @@ def __get_texts(self, nodes: Sequence[Rewritable], transform: Callable[[str], st The text between the nodes is kept. A node with rewrites queued inside it is replaced by its rewritten text, and transform, if given, is applied to the text of each node. """ + if not nodes: + return "" if len(nodes) == 1: text = self.__get_text(nodes[0]) return transform(text) if transform else text - # TODO(FrancescoPezzella): an empty `$$x` raises IndexError here, e.g. `f($$args)` -> `g($$args)` on `f()`. - # https://github.com/TNO/Renaissance.Py/issues/329 start = self.cor_offset(nodes[0].offset) end = self.cor_offset(nodes[-1].extended_end_offset) rewriter = Rewriter(self.content[start:end]) diff --git a/test/syntax_tree/test_ast_rewriter.py b/test/syntax_tree/test_ast_rewriter.py index cda37e1a..55ba91d5 100644 --- a/test/syntax_tree/test_ast_rewriter.py +++ b/test/syntax_tree/test_ast_rewriter.py @@ -1040,10 +1040,11 @@ def test_python_placeholder_replacement(self, source: str, expected: str) -> Non "from a import X # café\nimport b\n", ), ("f(1, 2)\n", "f($$args)", "g($$args)", "g(1, 2)\n"), + ("f()\n", "f($$args)", "g($$args)", "g()\n"), ], ) def test_python_multi_node_placeholder(self, source: str, find: str, replacement: str, expected: str) -> None: - """Verify a `$$` placeholder bound to several nodes expands to all of them, keeping their text and layout.""" + """Verify a `$$` placeholder expands zero or more nodes, preserving text and layout.""" root = PythonRstNode.load_from_text(source, "test.py") pattern = PythonPatternFactory(PythonFactory(PythonRstNode)).create_statements(find) rewriter = ASTRewriter(root)