From 84f6de9d7e4a65089531699f1c6efc4e15d13dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Tue, 13 Feb 2007 10:10:39 +0000 Subject: Patch #1517891: Make 'a' create the file if it doesn't exist. Fixes #1514451. --- Doc/lib/libzipfile.tex | 5 +++++ Lib/test/test_zipfile.py | 22 ++++++++++++++++++++++ Lib/zipfile.py | 9 ++++++++- Misc/NEWS | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Doc/lib/libzipfile.tex b/Doc/lib/libzipfile.tex index d3fca64..06a236c 100644 --- a/Doc/lib/libzipfile.tex +++ b/Doc/lib/libzipfile.tex @@ -101,6 +101,8 @@ cat myzip.zip >> python.exe \end{verbatim} 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 the archive, and should be \constant{ZIP_STORED} or \constant{ZIP_DEFLATED}; unrecognized values will cause @@ -114,6 +116,9 @@ cat myzip.zip >> python.exe ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by default because the default \program{zip} and \program{unzip} commands on \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} \begin{methoddesc}{close}{} diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 2d206df..c17039f 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -307,6 +307,28 @@ class PyZipFileTests(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): # 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 diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 93a0b75..6e59242 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -396,7 +396,14 @@ class ZipFile: self._filePassed = 0 self.filename = file modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} - self.fp = open(file, modeDict[mode]) + try: + self.fp = open(file, modeDict[mode]) + except IOError: + if mode == 'a': + mode = key = 'w' + self.fp = open(file, modeDict[mode]) + else: + raise else: self._filePassed = 1 self.fp = file diff --git a/Misc/NEWS b/Misc/NEWS index 06ffc16..c6d3831 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -128,6 +128,9 @@ Core and builtins Library ------- +- Patch #1517891: Mode 'a' for ZipFile now creates the file if it + doesn't exist. + - Patch #698833: Support file decryption in zipfile. - Patch #685268: Consider a package's __path__ in imputil. -- cgit v0.12