From 5436457ac09ae545a2f7bf95adb8eaac4a7a951e Mon Sep 17 00:00:00 2001 From: worldmozara Date: Sat, 15 Aug 2026 17:41:06 +0800 Subject: [PATCH] core/tools: allow edit_lineno append to an empty file Appending via edit_lineno required the last line to be read, which made writing to an empty file impossible (line 0 does not exist). An empty file has nothing to clobber, so the append needs no prior read. --- src/plyngent/tools/file/edit_lineno.py | 5 +++-- tests/test_tools/test_edit_lineno.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plyngent/tools/file/edit_lineno.py b/src/plyngent/tools/file/edit_lineno.py index f366316..bf98352 100644 --- a/src/plyngent/tools/file/edit_lineno.py +++ b/src/plyngent/tools/file/edit_lineno.py @@ -60,10 +60,11 @@ def _unread_lines_in_range( """Lines in ``start_line..end_line`` that were not read with line numbers. Appending (``start_line == n + 1``) requires the last line to be read, so - line numbers stay truthful; the append point itself is not a line. + line numbers stay truthful; the append point itself is not a line. An empty + file (``n == 0``) has nothing to clobber, so appending needs no read. """ if start_line == n + 1: - return [] if n in read_lines else [n] + return [] if n == 0 or n in read_lines else [n] return sorted(set(range(start_line, end_line + 1)) - read_lines) diff --git a/tests/test_tools/test_edit_lineno.py b/tests/test_tools/test_edit_lineno.py index 0c55c22..6bd95e3 100644 --- a/tests/test_tools/test_edit_lineno.py +++ b/tests/test_tools/test_edit_lineno.py @@ -66,6 +66,16 @@ def test_edit_lineno_requires_all_lines_read(workspace: object) -> None: assert "replaced lines 2-3" in out +def test_edit_lineno_append_to_empty_file(workspace: object) -> None: + """An empty file has nothing to clobber, so appending needs no read.""" + del workspace + _ = call_sync(write_file, "empty.txt", "") + _ = reset_lineno_tracker() + out = call_sync(edit_lineno, "empty.txt", 1, 1, "first\n") + assert "appended" in out + assert call_sync(read_file, "empty.txt") == "L1-1\nfirst\n" + + def test_edit_lineno_append_requires_last_line_read(workspace: object) -> None: del workspace _ = call_sync(write_file, "ap.txt", "a\nb\nc\n")