Skip to content

Commit

Permalink
Allow append mode for ZIP (#1453)
Browse files Browse the repository at this point in the history
  • Loading branch information
martindurant committed Dec 7, 2023
1 parent 7c3408a commit 51027de
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
3 changes: 3 additions & 0 deletions fsspec/implementations/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ def readlines(self, *args, **kwargs):
def close(self):
return self.f.close()

def truncate(self, size=None) -> int:
return self.f.truncate(size)

@property
def closed(self):
return self.f.closed
Expand Down
26 changes: 26 additions & 0 deletions fsspec/implementations/tests/test_zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,29 @@ def test_zip_glob_star(m):
fs, _ = fsspec.core.url_to_fs("zip::memory://out.zip")
outfiles = fs.glob("*")
assert len(outfiles) == 1


def test_append(m, tmpdir):
fs = fsspec.filesystem("zip", fo="memory://out.zip", mode="w")
with fs.open("afile", "wb") as f:
f.write(b"data")
fs.close()

fs = fsspec.filesystem("zip", fo="memory://out.zip", mode="a")
with fs.open("bfile", "wb") as f:
f.write(b"data")
fs.close()

assert len(fsspec.open_files("zip://*::memory://out.zip")) == 2

fs = fsspec.filesystem("zip", fo=f"{tmpdir}/out.zip", mode="w")
with fs.open("afile", "wb") as f:
f.write(b"data")
fs.close()

fs = fsspec.filesystem("zip", fo=f"{tmpdir}/out.zip", mode="a")
with fs.open("bfile", "wb") as f:
f.write(b"data")
fs.close()

assert len(fsspec.open_files("zip://*::memory://out.zip")) == 2
6 changes: 5 additions & 1 deletion fsspec/implementations/zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ def __init__(
raise ValueError(f"mode '{mode}' no understood")
self.mode = mode
if isinstance(fo, str):
if mode == "a":
m = "r+b"
else:
m = mode + "b"
fo = fsspec.open(
fo, mode=mode + "b", protocol=target_protocol, **(target_options or {})
fo, mode=m, protocol=target_protocol, **(target_options or {})
)
self.of = fo
self.fo = fo.__enter__() # the whole instance is a context
Expand Down

0 comments on commit 51027de

Please sign in to comment.