Patch #1775025: allow opening zipfile members via ZipInfo instances.
Patch by Graham Horler.
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index c83622a..4bc2104 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -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)
 
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 33fcfb1..b812a82 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -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()