[Python-checkins] r63499 - in python/trunk: Doc/library/zipfile.rst Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS

georg.brandl python-checkins at python.org
Tue May 20 10:25:48 CEST 2008


Author: georg.brandl
Date: Tue May 20 10:25:48 2008
New Revision: 63499

Log:
Patch #1775025: allow opening zipfile members via ZipInfo instances.
Patch by Graham Horler.


Modified:
   python/trunk/Doc/library/zipfile.rst
   python/trunk/Lib/test/test_zipfile.py
   python/trunk/Lib/zipfile.py
   python/trunk/Misc/NEWS

Modified: python/trunk/Doc/library/zipfile.rst
==============================================================================
--- python/trunk/Doc/library/zipfile.rst	(original)
+++ python/trunk/Doc/library/zipfile.rst	Tue May 20 10:25:48 2008
@@ -155,11 +155,11 @@
 .. method:: ZipFile.open(name[, mode[, pwd]])
 
    Extract a member from the archive as a file-like object (ZipExtFile). *name* is
-   the name of the file in the archive. The *mode* parameter, if included, must be
-   one of the following: ``'r'`` (the  default), ``'U'``, or ``'rU'``. Choosing
-   ``'U'`` or  ``'rU'`` will enable universal newline support in the read-only
-   object. *pwd* is the password used for encrypted files.  Calling  :meth:`open`
-   on a closed ZipFile will raise a  :exc:`RuntimeError`.
+   the name of the file in the archive, or a :class:`ZipInfo` object. The *mode*
+   parameter, if included, must be one of the following: ``'r'`` (the  default),
+   ``'U'``, or ``'rU'``. Choosing ``'U'`` or  ``'rU'`` will enable universal newline
+   support in the read-only object. *pwd* is the password used for encrypted files.
+   Calling  :meth:`open` on a closed ZipFile will raise a  :exc:`RuntimeError`.
 
    .. note::
 
@@ -178,16 +178,22 @@
       create a new file object that will be held by the ZipExtFile, allowing it to
       operate independently of the  ZipFile.
 
+   .. note::
+
+      The :meth:`open`, :meth:`read` and :meth:`extract` methods can take a filename
+      or a :class:`ZipInfo` object.  You will appreciate this when trying to read a
+      ZIP file that contains members with duplicate names.
+
    .. versionadded:: 2.6
 
 
 .. method:: ZipFile.extract(member[, path[, pwd]])
 
-   Extract a member from the archive to the current working directory, using its
-   full name.  Its file information is extracted as accurately as possible.
-   *path* specifies a different directory to extract to.   *member* can be a
-   filename or a :class:`ZipInfo` object.  *pwd* is the password used for
-   encrypted files.
+   Extract a member from the archive to the current working directory; *member*
+   must be its full name or a :class:`ZipInfo` object).  Its file information is
+   extracted as accurately as possible.  *path* specifies a different directory
+   to extract to.  *member* can be a filename or a :class:`ZipInfo` object.
+   *pwd* is the password used for encrypted files.
 
    .. versionadded:: 2.6
 
@@ -216,13 +222,14 @@
 
 .. method:: ZipFile.read(name[, pwd])
 
-   Return the bytes of the file in the archive.  The archive must be open for read
-   or append. *pwd* is the password used for encrypted  files and, if specified, it
-   will override the default password set with :meth:`setpassword`.  Calling
+   Return the bytes of the file *name* in the archive.  *name* is the name of the
+   file in the archive, or a :class:`ZipInfo` object.  The archive must be open for
+   read or append. *pwd* is the password used for encrypted  files and, if specified,
+   it will override the default password set with :meth:`setpassword`.  Calling
    :meth:`read` on a closed ZipFile  will raise a :exc:`RuntimeError`.
 
    .. versionchanged:: 2.6
-      *pwd* was added.
+      *pwd* was added, and *name* can now be a :class:`ZipInfo` object.
 
 
 .. method:: ZipFile.testzip()

Modified: python/trunk/Lib/test/test_zipfile.py
==============================================================================
--- python/trunk/Lib/test/test_zipfile.py	(original)
+++ python/trunk/Lib/test/test_zipfile.py	Tue May 20 10:25:48 2008
@@ -132,6 +132,25 @@
         for f in (TESTFN2, TemporaryFile(), StringIO()):
             self.zipOpenTest(f, zipfile.ZIP_STORED)
 
+    def testOpenViaZipInfo(self):
+        # Create the ZIP archive
+        zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
+        zipfp.writestr("name", "foo")
+        zipfp.writestr("name", "bar")
+        zipfp.close()
+
+        zipfp = zipfile.ZipFile(TESTFN2, "r")
+        infos = zipfp.infolist()
+        data = ""
+        for info in infos:
+            data += zipfp.open(info).read()
+        self.assert_(data == "foobar" or data == "barfoo")
+        data = ""
+        for info in infos:
+            data += zipfp.read(info)
+        self.assert_(data == "foobar" or data == "barfoo")
+        zipfp.close()
+
     def zipRandomOpenTest(self, f, compression):
         self.makeTestArchive(f, compression)
 

Modified: python/trunk/Lib/zipfile.py
==============================================================================
--- python/trunk/Lib/zipfile.py	(original)
+++ python/trunk/Lib/zipfile.py	Tue May 20 10:25:48 2008
@@ -776,10 +776,13 @@
         else:
             zef_file = open(self.filename, 'rb')
 
-        # Get info object for name
-        zinfo = self.getinfo(name)
-
-        filepos = zef_file.tell()
+        # Make sure we have an info object
+        if isinstance(name, ZipInfo):
+            # 'name' is already an info object
+            zinfo = name
+        else:
+            # Get info object for name
+            zinfo = self.getinfo(name)
 
         zef_file.seek(zinfo.header_offset, 0)
 
@@ -884,7 +887,7 @@
         if upperdirs and not os.path.exists(upperdirs):
             os.makedirs(upperdirs)
 
-        source = self.open(member.filename, pwd=pwd)
+        source = self.open(member, pwd=pwd)
         target = file(targetpath, "wb")
         shutil.copyfileobj(source, target)
         source.close()

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue May 20 10:25:48 2008
@@ -52,6 +52,10 @@
 Library
 -------
 
+- Issue #1775025: You can now specify zipfile members to open(),
+  read() or extract() via a ZipInfo instance.  This allows handling
+  duplicate filenames in zipfiles.
+
 - Issue #961805: Fix Text.edit_modified() in Tkinter.
 
 - Issue #1793: Function ctypes.util.find_msvcrt() added that returns


More information about the Python-checkins mailing list