From bf62d88af8a4c0bfe9e7fceb81d33815b69c45eb Mon Sep 17 00:00:00 2001 From: oyeong011 Date: Tue, 8 Sep 2026 10:07:49 +0900 Subject: [PATCH] Restore original files when in-place edits are interrupted Constraint: Preserve rollback behavior for all exceptions leaving the context. Confidence: high Scope-risk: narrow Tested: Full pytest suite and a real SIGINT during an in-place rewrite. Not-tested: Windows runtime; existing lint findings remain unchanged. --- path/__init__.py | 2 +- tests/test_path.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/path/__init__.py b/path/__init__.py index 33dd979..fb8394c 100644 --- a/path/__init__.py +++ b/path/__init__.py @@ -1787,7 +1787,7 @@ def in_place( try: yield readable, writable - except Exception: + except BaseException: # move backup back readable.close() writable.close() diff --git a/tests/test_path.py b/tests/test_path.py index b424bb6..8c202ff 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1229,6 +1229,17 @@ def test_exception_in_context(self, tmpdir): assert 'Lorem' not in data assert 'lazy dog' in data + @pytest.mark.parametrize('error', [KeyboardInterrupt, SystemExit, GeneratorExit]) + def test_base_exception_restores_original(self, tmpdir, error): + doc = self.create_reference(tmpdir) + with pytest.raises(error), doc.in_place(encoding='utf-8') as (reader, writer): + writer.write(self.alternate_content) + raise error() + assert doc.read_text(encoding='utf-8') == self.reference_content + assert reader.closed + assert writer.closed + assert not (doc + '.bak').exists() + def test_write_mode_invalid(self, tmpdir): with pytest.raises(ValueError): with (Path(tmpdir) / 'document').in_place(mode='w'):