From 78195ee848dc846a6415ecb6d6e5329081eb3983 Mon Sep 17 00:00:00 2001 From: Caleb Date: Tue, 22 Sep 2026 19:45:41 +0800 Subject: [PATCH] fix(chat): increment temp file suffix correctly --- core/chat/message_elements.py | 2 +- tests/test_message_elements.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/core/chat/message_elements.py b/core/chat/message_elements.py index 2abfb32e..9b1146f1 100644 --- a/core/chat/message_elements.py +++ b/core/chat/message_elements.py @@ -70,13 +70,13 @@ def _move_no_clobber(source: str, candidate: str) -> Optional[str]: numbered candidate. Returns the final path, or None when the move was not possible (e.g. filesystems without hard link support). """ + root, ext = os.path.splitext(candidate) counter = 1 while True: try: os.link(source, candidate) break except FileExistsError: - root, ext = os.path.splitext(candidate) candidate = f"{root}_{counter}{ext}" counter += 1 except OSError: diff --git a/tests/test_message_elements.py b/tests/test_message_elements.py index c8ce47c5..ca7dac1c 100644 --- a/tests/test_message_elements.py +++ b/tests/test_message_elements.py @@ -7,6 +7,7 @@ from core.chat.message_elements import ( _build_temp_file_path, _infer_mime_from_bytes, + _move_no_clobber, check_base64, ElementType, Text, @@ -25,6 +26,24 @@ ) +# ── _move_no_clobber ───────────────────────────────────────────── + +def test_move_no_clobber_increments_from_original_candidate(tmp_path): + source = tmp_path / "source" + source.write_bytes(b"new") + candidate = tmp_path / "download.png" + candidate.write_bytes(b"original") + (tmp_path / "download_1.png").write_bytes(b"first duplicate") + + result = _move_no_clobber(str(source), str(candidate)) + + assert result == str(tmp_path / "download_2.png") + assert not source.exists() + assert candidate.read_bytes() == b"original" + assert (tmp_path / "download_1.png").read_bytes() == b"first duplicate" + assert (tmp_path / "download_2.png").read_bytes() == b"new" + + # ── _infer_mime_from_bytes ────────────────────────────────────────── def test_infer_png():