Commit 84f6de9d authored by Martin v. Löwis's avatar Martin v. Löwis

Patch #1517891: Make 'a' create the file if it doesn't exist.

Fixes #1514451.
parent c6d626ed
...@@ -101,6 +101,8 @@ cat myzip.zip >> python.exe ...@@ -101,6 +101,8 @@ cat myzip.zip >> python.exe
\end{verbatim} \end{verbatim}
also works, and at least \program{WinZip} can read such files. also works, and at least \program{WinZip} can read such files.
If \var{mode} is \code{a} and the file does not exist at all,
it is created.
\var{compression} is the ZIP compression method to use when writing \var{compression} is the ZIP compression method to use when writing
the archive, and should be \constant{ZIP_STORED} or the archive, and should be \constant{ZIP_STORED} or
\constant{ZIP_DEFLATED}; unrecognized values will cause \constant{ZIP_DEFLATED}; unrecognized values will cause
...@@ -114,6 +116,9 @@ cat myzip.zip >> python.exe ...@@ -114,6 +116,9 @@ cat myzip.zip >> python.exe
ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by
default because the default \program{zip} and \program{unzip} commands on default because the default \program{zip} and \program{unzip} commands on
\UNIX{} (the InfoZIP utilities) don't support these extensions. \UNIX{} (the InfoZIP utilities) don't support these extensions.
\versionchanged[If the file does not exist, it is created if the
mode is 'a']{2.6}
\end{classdesc} \end{classdesc}
\begin{methoddesc}{close}{} \begin{methoddesc}{close}{}
......
...@@ -307,6 +307,28 @@ class PyZipFileTests(unittest.TestCase): ...@@ -307,6 +307,28 @@ class PyZipFileTests(unittest.TestCase):
class OtherTests(unittest.TestCase): class OtherTests(unittest.TestCase):
def testCreateNonExistentFileForAppend(self):
if os.path.exists(TESTFN):
os.unlink(TESTFN)
filename = 'testfile.txt'
content = 'hello, world. this is some content.'
try:
zf = zipfile.ZipFile(TESTFN, 'a')
zf.writestr(filename, content)
zf.close()
except IOError, (errno, errmsg):
self.fail('Could not append data to a non-existent zip file.')
self.assert_(os.path.exists(TESTFN))
zf = zipfile.ZipFile(TESTFN, 'r')
self.assertEqual(zf.read(filename), content)
zf.close()
os.unlink(TESTFN)
def testCloseErroneousFile(self): def testCloseErroneousFile(self):
# This test checks that the ZipFile constructor closes the file object # This test checks that the ZipFile constructor closes the file object
# it opens if there's an error in the file. If it doesn't, the traceback # it opens if there's an error in the file. If it doesn't, the traceback
......
...@@ -396,7 +396,14 @@ class ZipFile: ...@@ -396,7 +396,14 @@ class ZipFile:
self._filePassed = 0 self._filePassed = 0
self.filename = file self.filename = file
modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
try:
self.fp = open(file, modeDict[mode])
except IOError:
if mode == 'a':
mode = key = 'w'
self.fp = open(file, modeDict[mode]) self.fp = open(file, modeDict[mode])
else:
raise
else: else:
self._filePassed = 1 self._filePassed = 1
self.fp = file self.fp = file
......
...@@ -128,6 +128,9 @@ Core and builtins ...@@ -128,6 +128,9 @@ Core and builtins
Library Library
------- -------
- Patch #1517891: Mode 'a' for ZipFile now creates the file if it
doesn't exist.
- Patch #698833: Support file decryption in zipfile. - Patch #698833: Support file decryption in zipfile.
- Patch #685268: Consider a package's __path__ in imputil. - Patch #685268: Consider a package's __path__ in imputil.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment