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
|
||||
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`.
|
||||
|
||||
|
|
|
|||
|
|
@ -1503,6 +1503,23 @@ def test_verify(self):
|
|||
zh.remove(file)
|
||||
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
|
||||
with zipfile.ZipFile(TESTFN, 'w', self.compression) as zh:
|
||||
zh.writestr(file, data)
|
||||
|
|
@ -1531,21 +1548,6 @@ def test_verify(self):
|
|||
zh.remove(zinfo)
|
||||
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):
|
||||
"""Test if members use zip64."""
|
||||
file = 'datafile.txt'
|
||||
|
|
|
|||
|
|
@ -1867,10 +1867,13 @@ def extractall(self, path=None, members=None, pwd=None):
|
|||
self._extract_member(zipinfo, path, pwd)
|
||||
|
||||
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'):
|
||||
raise ValueError("remove() requires mode 'w', 'x', or 'a'")
|
||||
The archive must be open with mode 'a', since mode 'w'/'x' may be used
|
||||
on an unseekable file buffer, which disallows truncation."""
|
||||
|
||||
if self.mode != 'a':
|
||||
raise ValueError("remove() requires mode 'a'")
|
||||
if not self.fp:
|
||||
raise ValueError(
|
||||
"Attempt to write to ZIP archive that was already closed")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue