Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add ZipFile.for_name helper
  • Loading branch information
picnixz committed Aug 28, 2024
commit b95ccebaf046675e0aa4f5a7b2f92634806a6a28
17 changes: 0 additions & 17 deletions Lib/test/test_zipfile/_path/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,20 +657,3 @@ class DirtyZipInfo(zipfile.ZipInfo):
def __init__(self, filename, *args, **kwargs):
super().__init__(filename, *args, **kwargs)
self.filename = filename

@classmethod
def for_name(cls, name, archive):
"""
Construct the same way that ZipFile.writestr does.

TODO: extract this functionality and re-use
"""
self = cls(filename=name, date_time=time.localtime(time.time())[:6])
self.compress_type = archive.compression
self.compress_level = archive.compresslevel
if self.filename.endswith('/'): # pragma: no cover
self.external_attr = 0o40775 << 16 # drwxrwxr-x
self.external_attr |= 0x10 # MS-DOS directory flag
else:
self.external_attr = 0o600 << 16 # ?rw-------
return self
34 changes: 23 additions & 11 deletions Lib/zipfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,26 @@ def from_file(cls, filename, arcname=None, *, strict_timestamps=True):

return zinfo

@classmethod
def for_name(cls, filename, archive, *, date_time=None):
Comment thread
jaraco marked this conversation as resolved.
Outdated
"""Construct an appropriate ZipInfo from a filename and a ZipFile.

The *filename* is expected to be the name of a file in the archive.

If *date_time* is not specified, the current local time is used.
Comment thread
jaraco marked this conversation as resolved.
Outdated
"""
if date_time is None:
date_time = time.localtime(time.time())[:6]
self = cls(filename=filename, date_time=date_time)
self.compress_type = archive.compression
self.compress_level = archive.compresslevel
if self.filename.endswith('/'): # pragma: no cover
self.external_attr = 0o40775 << 16 # drwxrwxr-x
self.external_attr |= 0x10 # MS-DOS directory flag
else:
self.external_attr = 0o600 << 16 # ?rw-------
return self

def is_dir(self):
"""Return True if this archive member is a directory."""
if self.filename.endswith('/'):
Expand Down Expand Up @@ -1903,18 +1923,10 @@ def writestr(self, zinfo_or_arcname, data,
the name of the file in the archive."""
if isinstance(data, str):
data = data.encode("utf-8")
if not isinstance(zinfo_or_arcname, ZipInfo):
zinfo = ZipInfo(filename=zinfo_or_arcname,
date_time=time.localtime(time.time())[:6])
zinfo.compress_type = self.compression
zinfo.compress_level = self.compresslevel
if zinfo.filename.endswith('/'):
zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x
zinfo.external_attr |= 0x10 # MS-DOS directory flag
else:
zinfo.external_attr = 0o600 << 16 # ?rw-------
else:
if isinstance(zinfo_or_arcname, ZipInfo):
zinfo = zinfo_or_arcname
else:
zinfo = ZipInfo.for_name(zinfo_or_arcname, self)

if not self.fp:
raise ValueError(
Expand Down