import os import stat import tempfile import unittest from atomic_write import atomic_write, atomic_write_text, atomic_write_bytes class TestAtomicWrite(unittest.TestCase): def setUp(self): self.d = tempfile.mkdtemp() self.p = os.path.join(self.d, "out.txt") def test_basic_text(self): with atomic_write(self.p) as f: f.write("hello world") with open(self.p) as f: self.assertEqual(f.read(), "hello world") def test_bytes(self): atomic_write_bytes(self.p, b"\x00\x01\x02") with open(self.p, "rb") as f: self.assertEqual(f.read(), b"\x00\x01\x02") def test_text_helper(self): atomic_write_text(self.p, "abc") with open(self.p) as f: self.assertEqual(f.read(), "abc") def test_no_partial_on_exception(self): # pre-existing content must survive a failed write with open(self.p, "w") as f: f.write("ORIGINAL") try: with atomic_write(self.p) as f: f.write("PARTIAL") raise RuntimeError("boom") except RuntimeError: pass with open(self.p) as f: self.assertEqual(f.read(), "ORIGINAL") def test_no_temp_leftover_on_exception(self): try: with atomic_write(self.p) as f: f.write("x") raise ValueError("x") except ValueError: pass leftovers = [n for n in os.listdir(self.d) if n.startswith(".atomic_")] self.assertEqual(leftovers, []) def test_preserves_mode(self): with open(self.p, "w") as f: f.write("x") os.chmod(self.p, 0o600) with atomic_write(self.p) as f: f.write("y") self.assertEqual(stat.S_IMODE(os.stat(self.p).st_mode), 0o600) def test_overwrite_replaces(self): atomic_write_text(self.p, "first") atomic_write_text(self.p, "second") with open(self.p) as f: self.assertEqual(f.read(), "second") def test_creates_parent_dir(self): p = os.path.join(self.d, "sub", "deep", "f.txt") atomic_write_text(p, "nested") with open(p) as f: self.assertEqual(f.read(), "nested") def test_rejects_bad_mode(self): with self.assertRaises(ValueError): with atomic_write(self.p, mode="a"): pass def test_empty_write(self): atomic_write_text(self.p, "") self.assertTrue(os.path.exists(self.p)) with open(self.p) as f: self.assertEqual(f.read(), "") if __name__ == "__main__": unittest.main(verbosity=2)