Repository navigation
ZipFile.Path print failed when built zip file is based on a bytes stream #109200
Description
Bug report
Bug description:
Hi,
The print() function of a zipfile.Path failed if the ZipFile is based on a bytes stream.
More generally, every try to display or build a path based on bytes stream ZipFile path seems to fail.
A zip file is needed for playing this use case.
The mine is composed like this :
folder_root
├── folder_depth1
│ ├── folder_depth2
│ │ ├── folder_depth3
│ │ │ └── Python-Logo.png
│ │ └── Python-Logo.png
│ └── Python-Logo.png
└── Python-Logo.png
and is named "my_package.zip"
To trigger the problem I type these commands :
from zipfile import ZipFile, Path as ZPath
from io import BytesIO
with open("my_package.zip", "rb") as f:
my_bytes=BytesIO(f.read())
my_zf_from_file=ZipFile("my_package.zip")
for i in ZPath(my_zf_from_file).iterdir():
print(i)
my_zf_from_bytes=ZipFile(my_bytes)
for i in ZPath(my_zf_from_bytes).iterdir():
print(i)Here is my output:
>>> from zipfile import ZipFile, Path as ZPath
>>> from io import BytesIO
>>> with open("my_package.zip", "rb") as f:
... my_bytes=BytesIO(f.read())
...
>>> my_zf_from_file=ZipFile("my_package.zip")
>>> for i in ZPath(my_zf_from_file).iterdir():
... print(i)
...
my_package.zip/folder_root/
>>> my_zf_from_bytes=ZipFile(my_bytes)
>>> for i in ZPath(my_zf_from_bytes).iterdir():
... print(i)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/lib/python3.9/zipfile.py", line 2347, in __str__
return posixpath.join(self.root.filename, self.at)
File "/usr/lib/python3.9/posixpath.py", line 76, in join
a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not NoneTypeTo have more information I wrote this function
def mywalk(top):
dirs=[]
files=[]
for item in top.iterdir():
if item.is_file():
files.append(item)
elif item.is_dir():
dirs.append(item)
yield top.name, dirs, files
for d in dirs:
for w in mywalk(d):
yield wand then, launch it, like this
for w in mywalk(ZPath(my_zf_from_bytes)):
print(w)
for w in mywalk(ZPath(my_zf_from_file)):
print(w)Here is my output:
>>> for w in mywalk(ZPath(my_zf_from_bytes)):
... print(w)
...
...
('', [Path(None, 'folder_root/')], [])
('folder_root', [Path(None, 'folder_root/folder_depth1/')], [Path(None, 'folder_root/Python-Logo.png')])
('folder_depth1', [Path(None, 'folder_root/folder_depth1/folder_depth2/')], [Path(None, 'folder_root/folder_depth1/Python-Logo.png')])
('folder_depth2', [Path(None, 'folder_root/folder_depth1/folder_depth2/folder_depth3/')], [Path(None, 'folder_root/folder_depth1/folder_depth2/Python-Logo.png')])
('folder_depth3', [], [Path(None, 'folder_root/folder_depth1/folder_depth2/folder_depth3/Python-Logo.png')])
>>>
>>> for w in mywalk(ZPath(my_zf_from_file)):
... print(w)
...
('', [Path('my_package.zip', 'folder_root/')], [])
('folder_root', [Path('my_package.zip', 'folder_root/folder_depth1/')], [Path('my_package.zip', 'folder_root/Python-Logo.png')])
('folder_depth1', [Path('my_package.zip', 'folder_root/folder_depth1/folder_depth2/')], [Path('my_package.zip', 'folder_root/folder_depth1/Python-Logo.png')])
('folder_depth2', [Path('my_package.zip', 'folder_root/folder_depth1/folder_depth2/folder_depth3/')], [Path('my_package.zip', 'folder_root/folder_depth1/folder_depth2/Python-Logo.png')])
('folder_depth3', [], [Path('my_package.zip', 'folder_root/folder_depth1/folder_depth2/folder_depth3/Python-Logo.png')])
In the first case (zipfile path based on a bytes stream), the Path-like objects have 'None' as root when the root is the name of the package in the second case (zipfile path made based on the file).
My though is that a path is not intended to bring a NoneType element and so a path.join failed when a transformation into a string is needed.
What about change this "None" by an empty string ?
CPython versions tested on:
3.8, 3.9
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Activity
barneygale commentedon May 5, 2025
I think this is a duplicate of #100609, so I'll close this issue. Thanks for reporting all the same!