From 503ce8e49110f45515d625776f2c83ca5d8bf57e Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Sun, 4 Oct 2026 17:48:34 +0000 Subject: [PATCH] Fix FileStorage on Windows: open fd with O_BINARY, UTF-8 release logs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit os.open() on Windows defaults to O_TEXT, so the CRT translated \r\n in binary ciphertext: writes grew, offsets shifted, reads came up short and the RAF callbacks failed with EIO (probe/read/write depending on where a 0x0A byte landed). Pass O_BINARY where it exists. Also reconfigure stdout/stderr to UTF-8 in tools/release.py so the ✓/✗/⚠ summary lines don't crash on cp1252 Windows consoles. --- src/aeg/raf.py | 3 +++ tools/release.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/aeg/raf.py b/src/aeg/raf.py index d18ac49..679cb1b 100644 --- a/src/aeg/raf.py +++ b/src/aeg/raf.py @@ -104,6 +104,9 @@ class FileStorage: flags = os.O_RDWR | os.O_CREAT | os.O_EXCL else: raise ValueError(f"Unsupported mode: {mode}") + # O_BINARY (Windows only): keep the CRT from translating \r\n in + # binary data, which corrupts ciphertext and shifts offsets + flags |= getattr(os, "O_BINARY", 0) self._fd = os.open(path, flags, 0o644) self._closed = False self._lock = threading.Lock() diff --git a/tools/release.py b/tools/release.py index a6de867..438e8be 100755 --- a/tools/release.py +++ b/tools/release.py @@ -305,6 +305,11 @@ def run_benchmark(wheel: Path, py_version: str) -> bool: def main(): """Build wheels for all supported Python versions.""" + # Windows CI consoles default to cp1252; emit ✓/✗/⚠ as UTF-8 + for stream in (sys.stdout, sys.stderr): + if hasattr(stream, "reconfigure"): + stream.reconfigure(encoding="utf-8", errors="replace") + # CI matrix jobs build per-platform wheels but never upload; a separate # publish job uploads everything once all platforms have succeeded. no_upload = "--no-upload" in sys.argv