From 3a2884f1f056922758bf9fe790dfd05a3843055d Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Wed, 28 Oct 2026 10:37:19 +0100 Subject: Report .dbz write failures as Error Co-Authored-By: Claude Haiku 5.5 --- generat3d/dbz.py | 14 ++++++++++---- tests/test_dbz.py | 6 ++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/generat3d/dbz.py b/generat3d/dbz.py index a71fbd5..2a56230 100644 --- a/generat3d/dbz.py +++ b/generat3d/dbz.py @@ -15,6 +15,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import contextlib import gzip import json import math @@ -22,7 +23,7 @@ import os import tempfile from pathlib import Path -from . import __version__ +from . import Error, __version__ from .evaluate import evaluate @@ -70,11 +71,16 @@ def build(scene, roots): def write(doc, out): """Write doc as gzipped JSON. A temp file plus rename: no partial file on failure.""" out = Path(out) - fd, tmp = tempfile.mkstemp(dir=out.parent, prefix=out.name, suffix=".tmp") + tmp = None try: + fd, tmp = tempfile.mkstemp(dir=out.parent, prefix=out.name, suffix=".tmp") with os.fdopen(fd, "wb") as f: f.write(gzip.compress(json.dumps(doc).encode())) os.replace(tmp, out) - except BaseException: - os.unlink(tmp) + except BaseException as e: + if tmp is not None: + with contextlib.suppress(OSError): + os.unlink(tmp) + if isinstance(e, OSError): + raise Error(f"cannot write {out}: {e.strerror or e}") from None raise diff --git a/tests/test_dbz.py b/tests/test_dbz.py index 7bcf69a..35c7699 100644 --- a/tests/test_dbz.py +++ b/tests/test_dbz.py @@ -24,6 +24,7 @@ import tempfile import unittest from pathlib import Path +from generat3d import Error from generat3d.dbz import build, orientation_quat, write from generat3d.library import Library from generat3d.scene import load @@ -77,3 +78,8 @@ class DbzTest(unittest.TestCase): with self.assertRaises(TypeError): write({"bad": object()}, out) self.assertEqual(list(Path(d).iterdir()), []) + + def test_os_error_becomes_error(self): + with tempfile.TemporaryDirectory() as d: + with self.assertRaisesRegex(Error, "cannot write"): + write(self.doc, Path(d) / "missing" / "s.dbz") -- cgit v1.2.3