You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I encountered an edge-case while using zipfile.Path with in-memory data buffers. It seems like the filename of the root is set to None, which breaks anything that tries to join the zip-filename and its internal path (including str(), ``.
I have two suggested fixes:
Update the initialization of the zipfile.FastLookup-class and set self.filename to ":memory:" if it is None, matching what you would write in e.g. sqlite to get an in-memory database.
Update all places where the code attempts do Path-operations on self.root.filename to notice if the filename is None and use ":memory:" instead.
The first is definitely the easiest fix, but the second would maybe be more backwards compatible in case someone uses Path.root.filename to notice that the zipfile.Path-object points to an in-memory zipfile. Though, I'm not sure how big of a problem that is.
I don't have any strong opinions of which to choose, and I would be happy to implement the fix.
Minimal reproducible example
importioimportzipfile# Create a dummy Zip filedata=io.BytesIO()
withzipfile.ZipFile(data, mode="w") aszf:
zf.writestr("hello.txt", "python\n")
# Try to iterate over its contentdata.seek(0)
p=zipfile.Path(data)
print(str(p))
print(list(p.iterdir()))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[92], line 13
11 p = zipfile.Path(data)
---> 12 print(str(p))
File /usr/lib/python3.12/zipfile/_path/__init__.py:391, in Path.__str__(self)
390 def __str__(self):
--> 391 return posixpath.join(self.root.filename, self.at)
File <frozen posixpath>:76, in join(a, *p)
TypeError: expected str, bytes or os.PathLike object, not NoneType
Demonstration of fix
importioimportzipfile# Create a dummy Zip filedata=io.BytesIO()
withzipfile.ZipFile(data, mode="w") aszf:
zf.writestr("hello.txt", "python\n")
# Try to iterate over its contentdata.seek(0)
p=zipfile.Path(data)
p.root.filename=":memory:"print(str(p))
print(list(p.iterdir()))
:memory:/
[Path(':memory:', 'hello.txt')]
CPython versions tested on:
3.12, 3.14
Operating systems tested on:
Ubuntu 24.04 (WSL), Fedora (via the Python devcontainer on GitHub codespaces)
I just realised that option 2. might be preferable, because we should probably overload the parent method to prevent it from resolving to "." when the path is ":memory:" anyways?
I've started working on this now. I had one idea though: How about setting the name to \0 if it represents an in-memory byte string? That way it's clear that it isn't a local path with the name ":memory:".
Update: Looking at the tests, it seems like it's supposed to fail. So I'll only update the code so __str__ doesn't fail
Bug description:
I encountered an edge-case while using
zipfile.Path
with in-memory data buffers. It seems like the filename of the root is set toNone
, which breaks anything that tries to join the zip-filename and its internal path (includingstr()
, ``.I have two suggested fixes:
zipfile.FastLookup
-class and setself.filename
to":memory:"
if it is None, matching what you would write in e.g. sqlite to get an in-memory database.self.root.filename
to notice if the filename is None and use ":memory:
" instead.The first is definitely the easiest fix, but the second would maybe be more backwards compatible in case someone uses
Path.root.filename
to notice that thezipfile.Path
-object points to an in-memory zipfile. Though, I'm not sure how big of a problem that is.I don't have any strong opinions of which to choose, and I would be happy to implement the fix.
Minimal reproducible example
Demonstration of fix
CPython versions tested on:
3.12, 3.14
Operating systems tested on:
Ubuntu 24.04 (WSL), Fedora (via the Python devcontainer on GitHub codespaces)
Linked PRs
str(zipfile.Path)
from raising exception onio.BytesIO
-input #130381The text was updated successfully, but these errors were encountered: