Skip to content

Commit ba0e4a4

Browse files
jaracoclaude
andauthored
[3.14] gh-100609: Render an unnamed zipfile as ":zipfile:" in zipfile.Path (GH-160103) (#160124)
Synchronizes the fix from zipp 3.23.1. `str()` of a `zipfile.Path` whose zipfile has no filename previously raised `TypeError`. (cherry picked from commit ba96fab) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent fdd97fb commit ba0e4a4

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

‎Lib/test/test_zipfile/_path/test_path.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@ class Subclass(zipfile.Path):
351351
root = Subclass(alpharep)
352352
assert isinstance(root / 'b', Subclass)
353353

354+
def test_at(self):
355+
zip_file = self.fixtures.enter_context(zipfile.ZipFile(io.BytesIO(), 'w'))
356+
root = zipfile.Path(zip_file)
357+
assert root.at == ''
358+
assert (root / 'foo' / 'bar').at == 'foo/bar'
359+
360+
def test_str(self):
361+
"""
362+
An unnamed zip file is indicated by ":zipfile:"
363+
"""
364+
zip_file = self.fixtures.enter_context(zipfile.ZipFile(io.BytesIO(), 'w'))
365+
root = zipfile.Path(zip_file)
366+
assert str(root) == ':zipfile:'
367+
assert str(root / 'foo' / 'bar') == ':zipfile:/foo/bar'
368+
354369
@pass_alpharep
355370
def test_filename(self, alpharep):
356371
root = zipfile.Path(alpharep)

‎Lib/zipfile/_path/__init__.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class Path:
273273
resolve to the zipfile.
274274
275275
>>> str(path)
276-
'mem/abcde.zip/'
276+
'mem/abcde.zip'
277277
>>> path.name
278278
'abcde.zip'
279279
>>> path.filename == pathlib.Path('mem/abcde.zip')
@@ -431,7 +431,10 @@ def relative_to(self, other, *extra):
431431
return posixpath.relpath(str(self), str(other.joinpath(*extra)))
432432

433433
def __str__(self):
434-
return posixpath.join(self.root.filename, self.at)
434+
root = self.root.filename
435+
if root is None:
436+
root = ':zipfile:'
437+
return posixpath.join(root, self.at) if self.at else root
435438

436439
def __repr__(self):
437440
return self.__repr.format(self=self)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``str()`` of a :class:`zipfile.Path` whose underlying zipfile has no
2+
filename, such as one constructed from an :class:`io.BytesIO`, now renders
3+
that filename as ``:zipfile:`` instead of raising :exc:`TypeError`. The root
4+
of a zipfile is also no longer rendered with a trailing slash. Synchronized
5+
with :pypi:`zipp` 3.23.1.

0 commit comments

Comments
 (0)