Skip to content

Commit 3c39579

Browse files
committed
gh-152845: No more forbid metadata_encoding in mode 'a'
Allow `metadata_encoding` parameter in all modes, allowing proper decoding with a customized codec in 'a' mode. Ignore this parameter for 'w'/'x' modes.
1 parent 4b27192 commit 3c39579

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

Lib/test/test_zipfile/test_core.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5735,20 +5735,26 @@ def test_read_with_metadata_encoding(self):
57355735
# Read the ZIP archive with correct metadata_encoding
57365736
with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp:
57375737
self._test_read(zipfp, self.file_names, self.file_content)
5738+
with zipfile.ZipFile(TESTFN, "a", metadata_encoding='shift_jis') as zipfp:
5739+
self._test_read(zipfp, self.file_names, self.file_content)
57385740

57395741
def test_read_without_metadata_encoding(self):
57405742
# Read the ZIP archive without metadata_encoding
57415743
expected_names = [name.encode('shift_jis').decode('cp437')
57425744
for name in self.file_names[:2]] + self.file_names[2:]
57435745
with zipfile.ZipFile(TESTFN, "r") as zipfp:
57445746
self._test_read(zipfp, expected_names, self.file_content)
5747+
with zipfile.ZipFile(TESTFN, "a") as zipfp:
5748+
self._test_read(zipfp, expected_names, self.file_content)
57455749

57465750
def test_read_with_incorrect_metadata_encoding(self):
57475751
# Read the ZIP archive with incorrect metadata_encoding
57485752
expected_names = [name.encode('shift_jis').decode('koi8-u')
57495753
for name in self.file_names[:2]] + self.file_names[2:]
57505754
with zipfile.ZipFile(TESTFN, "r", metadata_encoding='koi8-u') as zipfp:
57515755
self._test_read(zipfp, expected_names, self.file_content)
5756+
with zipfile.ZipFile(TESTFN, "a", metadata_encoding='koi8-u') as zipfp:
5757+
self._test_read(zipfp, expected_names, self.file_content)
57525758

57535759
def test_read_with_unsuitable_metadata_encoding(self):
57545760
# Read the ZIP archive with metadata_encoding unsuitable for
@@ -5757,6 +5763,10 @@ def test_read_with_unsuitable_metadata_encoding(self):
57575763
zipfile.ZipFile(TESTFN, "r", metadata_encoding='ascii')
57585764
with self.assertRaises(UnicodeDecodeError):
57595765
zipfile.ZipFile(TESTFN, "r", metadata_encoding='utf-8')
5766+
with self.assertRaises(UnicodeDecodeError):
5767+
zipfile.ZipFile(TESTFN, "a", metadata_encoding='ascii')
5768+
with self.assertRaises(UnicodeDecodeError):
5769+
zipfile.ZipFile(TESTFN, "a", metadata_encoding='utf-8')
57605770

57615771
def test_read_after_append(self):
57625772
newname = '\u56db' # Han 'four'
@@ -5774,9 +5784,13 @@ def test_read_after_append(self):
57745784

57755785
with zipfile.ZipFile(TESTFN, "r") as zipfp:
57765786
self._test_read(zipfp, mojibake_expected_names, expected_content)
5787+
with zipfile.ZipFile(TESTFN, "a") as zipfp:
5788+
self._test_read(zipfp, mojibake_expected_names, expected_content)
57775789

57785790
with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp:
57795791
self._test_read(zipfp, expected_names, expected_content)
5792+
with zipfile.ZipFile(TESTFN, "a", metadata_encoding='shift_jis') as zipfp:
5793+
self._test_read(zipfp, expected_names, expected_content)
57805794

57815795
def test_append_keep_efs_flag(self):
57825796
"""Files loaded from an archive should keep original EFS flags when
@@ -5824,11 +5838,18 @@ def test_write_enforce_efs_flag(self):
58245838
self._test_read(zipfp, names, contents, comments, efs_flags)
58255839

58265840
def test_write_with_metadata_encoding(self):
5827-
ZF = zipfile.ZipFile
5841+
"""metadata_encoding should not affect the encoding of new files."""
5842+
names = ['\u4e00', 'file2']
5843+
contents = ['\u4e00'.encode('utf-8'), '\u4e8c'.encode('utf-8')]
5844+
efs_flags = [True, False]
5845+
58285846
for mode in ("w", "x", "a"):
5829-
with self.assertRaisesRegex(ValueError,
5830-
"^metadata_encoding is only"):
5831-
ZF("nonesuch.zip", mode, metadata_encoding="shift_jis")
5847+
unlink(TESTFN)
5848+
with zipfile.ZipFile(TESTFN, mode, metadata_encoding='shift_jis') as zipfp:
5849+
for i, name in enumerate(names):
5850+
zipfp.writestr(name, contents[i])
5851+
with zipfile.ZipFile(TESTFN, 'r') as zipfp:
5852+
self._test_read(zipfp, names, contents, None, efs_flags)
58325853

58335854
def test_add_comment(self):
58345855
with zipfile.ZipFile(TESTFN, "r") as zipfp:

Lib/zipfile/__init__.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,11 +1926,6 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
19261926
self._strict_timestamps = strict_timestamps
19271927
self.metadata_encoding = metadata_encoding
19281928

1929-
# Check that we don't try to write with nonconforming codecs
1930-
if self.metadata_encoding and mode != 'r':
1931-
raise ValueError(
1932-
"metadata_encoding is only supported for reading files")
1933-
19341929
# Check if we were passed a file-like object
19351930
if isinstance(file, os.PathLike):
19361931
file = os.fspath(file)

0 commit comments

Comments
 (0)