Skip to content

Commit f578f66

Browse files
committed
To avoid passthrough parameters, use _for_archive to mutate a constructed ZipInfo.
1 parent a8f6a9f commit f578f66

File tree

5 files changed

+17
-21
lines changed

5 files changed

+17
-21
lines changed

Doc/library/zipfile.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,12 @@ The module defines the following items:
8585
continues to work as a property for backwards compatibility.
8686

8787

88-
.. classmethod:: for_name(filename, archive, *, date_time=None)
88+
.. method:: _for_archive(archive)
8989

90-
Construct an appropriate :class:`ZipInfo` from a *filename*,
91-
a :class:`ZipFile` archive and an optional *date_time*.
90+
Resolve the date_time, compression attributes, and external attributes
91+
to suitable defaults as used by :method:`ZipFile.writestr`.
9292

93-
If *date_time* is not specified, the current local time is used
94-
instead, namely ``date_time = time.localtime(time.time())[:6]``.
93+
Returns self for chaining.
9594

9695
.. versionadded:: 3.14
9796

Lib/test/test_zipfile/_path/test_path.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ def test_backslash_not_separator(self):
634634
"""
635635
data = io.BytesIO()
636636
zf = zipfile.ZipFile(data, "w")
637-
zf.writestr(DirtyZipInfo.for_name("foo\\bar", zf), b"content")
637+
zf.writestr(DirtyZipInfo("foo\\bar")._for_archive(zf), b"content")
638638
zf.filename = ''
639639
root = zipfile.Path(zf)
640640
(first,) = root.iterdir()

Lib/test/test_zipfile/test_core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,13 +2212,13 @@ def test_create_empty_zipinfo_repr(self):
22122212
zi = zipfile.ZipInfo(filename="empty")
22132213
self.assertEqual(repr(zi), "<ZipInfo filename='empty' file_size=0>")
22142214

2215-
def test_create_zipinfo_for_name(self):
2215+
def test_for_archive(self):
22162216
base_filename = TESTFN2.rstrip('/')
22172217

22182218
with zipfile.ZipFile(TESTFN, mode="w", compresslevel=1,
22192219
compression=zipfile.ZIP_STORED) as zf:
22202220
# no trailing forward slash
2221-
zi = zipfile.ZipInfo.for_name(base_filename, zf)
2221+
zi = zipfile.ZipInfo(base_filename)._for_archive(zf)
22222222
self.assertEqual(zi.compress_level, 1)
22232223
self.assertEqual(zi.compress_type, zipfile.ZIP_STORED)
22242224
# ?rw- --- ---
@@ -2230,7 +2230,7 @@ def test_create_zipinfo_for_name(self):
22302230
with zipfile.ZipFile(TESTFN, mode="w", compresslevel=1,
22312231
compression=zipfile.ZIP_STORED) as zf:
22322232
# with a trailing slash
2233-
zi = zipfile.ZipInfo.for_name(f'{base_filename}/', zf)
2233+
zi = zipfile.ZipInfo(f'{base_filename}/')._for_archive(zf)
22342234
self.assertEqual(zi.compress_level, 1)
22352235
self.assertEqual(zi.compress_type, zipfile.ZIP_STORED)
22362236
# d rwx rwx r-x

Lib/zipfile/__init__.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import sys
1414
import threading
1515
import time
16+
from typing import Self
1617

1718
try:
1819
import zlib # We may need its compression method
@@ -605,17 +606,15 @@ def from_file(cls, filename, arcname=None, *, strict_timestamps=True):
605606

606607
return zinfo
607608

608-
@classmethod
609-
def for_name(cls, filename, archive, *, date_time=None):
610-
"""Construct an appropriate ZipInfo from a filename and a ZipFile.
609+
def _for_archive(self, archive: ZipFile) -> Self:
610+
"""Resolve suitable defaults from the archive.
611611
612-
The *filename* is expected to be the name of a file in the archive.
612+
Resolve the date_time, compression attributes, and external attributes
613+
to suitable defaults as used by :method:`ZipFile.writestr`.
613614
614-
If *date_time* is not specified, the current local time is used.
615+
Return self.
615616
"""
616-
if date_time is None:
617-
date_time = time.localtime(time.time())[:6]
618-
self = cls(filename=filename, date_time=date_time)
617+
self.date_time = time.localtime(time.time())[:6]
619618
self.compress_type = archive.compression
620619
self.compress_level = archive.compresslevel
621620
if self.filename.endswith('/'): # pragma: no cover
@@ -1931,7 +1930,7 @@ def writestr(self, zinfo_or_arcname, data,
19311930
if isinstance(zinfo_or_arcname, ZipInfo):
19321931
zinfo = zinfo_or_arcname
19331932
else:
1934-
zinfo = ZipInfo.for_name(zinfo_or_arcname, self)
1933+
zinfo = ZipInfo(zinfo_or_arcname)._for_archive(self)
19351934

19361935
if not self.fp:
19371936
raise ValueError(
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
Add :meth:`zipfile.ZipInfo.for_name` factory for constructing
2-
:class:`~zipfile.ZipInfo` objects from a filename and an archive. Patch by
3-
Bénédikt Tran.
1+
Add :meth:`zipfile.ZipInfo._for_archive` setting default properties on :class:`~zipfile.ZipInfo` objects. Patch by Bénédikt Tran and Jason R. Coombs.

0 commit comments

Comments
 (0)