From 60a149f97050a5f67b13c49fa9dc22f1c841c5c9 Mon Sep 17 00:00:00 2001 From: Greg Brandt Date: Sat, 14 Feb 2026 17:11:46 -0800 Subject: [PATCH 1/2] Check to see if the file exists first in append mode --- avrokit/url/google.py | 7 +++---- avrokit/url/s3.py | 7 +++---- pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/avrokit/url/google.py b/avrokit/url/google.py index ef317fd..2461dc0 100644 --- a/avrokit/url/google.py +++ b/avrokit/url/google.py @@ -120,12 +120,11 @@ def open(self) -> IO[Any]: self._current_local = tmpfile self._current_local_stream = self._current_local # Download to file if r/rb mode, or if append mode (to preserve existing content on failure) - if "r" in self.mode or "a" in self.mode: - # N.b. always writes in binary mode + if "r" in self.mode or ("a" in self.mode and blob.exists()): blob.download_to_file(tmpfile) tmpfile.seek(0) - if "a" in self.mode: - tmpfile.seek(0, 2) # Seek to end for append mode + if "a" in self.mode: + tmpfile.seek(0, 2) if "b" not in self.mode: # So if the user wants to read text, we need to decode it self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") diff --git a/avrokit/url/s3.py b/avrokit/url/s3.py index 2edeee4..40d0f57 100644 --- a/avrokit/url/s3.py +++ b/avrokit/url/s3.py @@ -95,12 +95,11 @@ def open(self) -> IO[Any]: self._current_local = tmpfile self._current_local_stream = self._current_local # Download to file if "r"/"rb" mode, or if append mode (to preserve existing content on failure) - if "r" in self.mode or "a" in self.mode: - # N.b. always writes in binary mode + if "r" in self.mode or ("a" in self.mode and self.exists()): client.download_fileobj(self.bucket, self.path, tmpfile) tmpfile.seek(0) - if "a" in self.mode: - tmpfile.seek(0, 2) # Seek to end for append mode + if "a" in self.mode: + tmpfile.seek(0, 2) if "b" not in self.mode: # So if the user wants to read text, we need to decode it self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") diff --git a/pyproject.toml b/pyproject.toml index 84ce178..f279b81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ [tool.poetry] name = "avrokit" -version = "0.0.3" +version = "0.0.4" description = "Python utilities for working with Avro data files" authors = ["Greg Brandt "] license = "Apache-2.0" From c1d15ef1d4e594c391d6531c39ff43f7b65a582b Mon Sep 17 00:00:00 2001 From: Greg Brandt Date: Sat, 14 Feb 2026 19:47:48 -0800 Subject: [PATCH 2/2] Fix TextIOWrapper issue --- avrokit/url/google.py | 6 +----- avrokit/url/s3.py | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/avrokit/url/google.py b/avrokit/url/google.py index 2461dc0..f85832c 100644 --- a/avrokit/url/google.py +++ b/avrokit/url/google.py @@ -125,11 +125,7 @@ def open(self) -> IO[Any]: tmpfile.seek(0) if "a" in self.mode: tmpfile.seek(0, 2) - if "b" not in self.mode: - # So if the user wants to read text, we need to decode it - self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") - elif ("w" in self.mode or "a" in self.mode) and "b" not in self.mode: - # Same thing when we're writing text + if "b" not in self.mode: self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") stream = cast(IO[Any], self._current_local_stream) return stream diff --git a/avrokit/url/s3.py b/avrokit/url/s3.py index 40d0f57..1408b1a 100644 --- a/avrokit/url/s3.py +++ b/avrokit/url/s3.py @@ -100,11 +100,7 @@ def open(self) -> IO[Any]: tmpfile.seek(0) if "a" in self.mode: tmpfile.seek(0, 2) - if "b" not in self.mode: - # So if the user wants to read text, we need to decode it - self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") - elif ("w" in self.mode or "a" in self.mode) and "b" not in self.mode: - # Same thing when we're writing text + if "b" not in self.mode: self._current_local_stream = io.TextIOWrapper(tmpfile, encoding="utf-8") stream = cast(IO[Any], self._current_local_stream) return stream