mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
No more allow mode 'w'/'x'
- File is not truncated in mode 'w'/'x', which results non-shrinked file. - This cannot be simply resolved by adding truncation for mode 'w'/'x', which may be used on an unseekable file buffer and truncation is not allowed.
This commit is contained in:
parent
602b909b5a
commit
bb90f48f60
3 changed files with 24 additions and 19 deletions
|
|
@ -523,7 +523,7 @@ ZipFile Objects
|
||||||
Removes a member from the archive. *zinfo_or_arcname* is either the full
|
Removes a member from the archive. *zinfo_or_arcname* is either the full
|
||||||
path of the member, or a :class:`ZipInfo` instance.
|
path of the member, or a :class:`ZipInfo` instance.
|
||||||
|
|
||||||
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'``.
|
The archive must be opened with mode ``'a'``.
|
||||||
|
|
||||||
Calling :meth:`remove` on a closed ZipFile will raise a :exc:`ValueError`.
|
Calling :meth:`remove` on a closed ZipFile will raise a :exc:`ValueError`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1503,6 +1503,23 @@ def test_verify(self):
|
||||||
zh.remove(file)
|
zh.remove(file)
|
||||||
mock_fn.assert_not_called()
|
mock_fn.assert_not_called()
|
||||||
|
|
||||||
|
# mode 'w': error and do nothing
|
||||||
|
with zipfile.ZipFile(TESTFN, 'w', self.compression) as zh:
|
||||||
|
zh.writestr(file, data)
|
||||||
|
with mock.patch('zipfile.ZipFile._remove_members') as mock_fn:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
zh.remove(file)
|
||||||
|
mock_fn.assert_not_called()
|
||||||
|
|
||||||
|
# mode 'x': error and do nothing
|
||||||
|
os.remove(TESTFN)
|
||||||
|
with zipfile.ZipFile(TESTFN, 'x', self.compression) as zh:
|
||||||
|
zh.writestr(file, data)
|
||||||
|
with mock.patch('zipfile.ZipFile._remove_members') as mock_fn:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
zh.remove(file)
|
||||||
|
mock_fn.assert_not_called()
|
||||||
|
|
||||||
# mode 'a': the most general use case
|
# mode 'a': the most general use case
|
||||||
with zipfile.ZipFile(TESTFN, 'w', self.compression) as zh:
|
with zipfile.ZipFile(TESTFN, 'w', self.compression) as zh:
|
||||||
zh.writestr(file, data)
|
zh.writestr(file, data)
|
||||||
|
|
@ -1531,21 +1548,6 @@ def test_verify(self):
|
||||||
zh.remove(zinfo)
|
zh.remove(zinfo)
|
||||||
mock_fn.assert_not_called()
|
mock_fn.assert_not_called()
|
||||||
|
|
||||||
# mode 'w': like 'a'; allows removing a just written member
|
|
||||||
with zipfile.ZipFile(TESTFN, 'w', self.compression) as zh:
|
|
||||||
zh.writestr(file, data)
|
|
||||||
with mock.patch('zipfile.ZipFile._remove_members') as mock_fn:
|
|
||||||
zh.remove(file)
|
|
||||||
mock_fn.assert_called_once_with({zh.getinfo(file)})
|
|
||||||
|
|
||||||
# mode 'x': like 'w'
|
|
||||||
os.remove(TESTFN)
|
|
||||||
with zipfile.ZipFile(TESTFN, 'x', self.compression) as zh:
|
|
||||||
zh.writestr(file, data)
|
|
||||||
with mock.patch('zipfile.ZipFile._remove_members') as mock_fn:
|
|
||||||
zh.remove(file)
|
|
||||||
mock_fn.assert_called_once_with({zh.getinfo(file)})
|
|
||||||
|
|
||||||
def test_zip64(self):
|
def test_zip64(self):
|
||||||
"""Test if members use zip64."""
|
"""Test if members use zip64."""
|
||||||
file = 'datafile.txt'
|
file = 'datafile.txt'
|
||||||
|
|
|
||||||
|
|
@ -1867,10 +1867,13 @@ def extractall(self, path=None, members=None, pwd=None):
|
||||||
self._extract_member(zipinfo, path, pwd)
|
self._extract_member(zipinfo, path, pwd)
|
||||||
|
|
||||||
def remove(self, zinfo_or_arcname):
|
def remove(self, zinfo_or_arcname):
|
||||||
"""Remove a member from the archive."""
|
"""Remove a member from the archive.
|
||||||
|
|
||||||
if self.mode not in ('w', 'x', 'a'):
|
The archive must be open with mode 'a', since mode 'w'/'x' may be used
|
||||||
raise ValueError("remove() requires mode 'w', 'x', or 'a'")
|
on an unseekable file buffer, which disallows truncation."""
|
||||||
|
|
||||||
|
if self.mode != 'a':
|
||||||
|
raise ValueError("remove() requires mode 'a'")
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Attempt to write to ZIP archive that was already closed")
|
"Attempt to write to ZIP archive that was already closed")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue