Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
authorŁukasz Langa <lukasz@langa.pl>
Mon, 22 Nov 2010 23:31:26 +0000 (23:31 +0000)
committerŁukasz Langa <lukasz@langa.pl>
Mon, 22 Nov 2010 23:31:26 +0000 (23:31 +0000)
Lib/zipfile.py

index 184f4d290ddbf1ea90855c3d882cc2ba9e764489..eec8eceaeda92be36c9eece800b4299d3915f685 100644 (file)
@@ -473,9 +473,11 @@ class ZipExtFile(io.BufferedIOBase):
     # Search for universal newlines or line chunks.
     PATTERN = re.compile(br'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)')
 
-    def __init__(self, fileobj, mode, zipinfo, decrypter=None):
+    def __init__(self, fileobj, mode, zipinfo, decrypter=None,
+                 close_fileobj=False):
         self._fileobj = fileobj
         self._decrypter = decrypter
+        self._close_fileobj = close_fileobj
 
         self._compress_type = zipinfo.compress_type
         self._compress_size = zipinfo.compress_size
@@ -647,6 +649,12 @@ class ZipExtFile(io.BufferedIOBase):
         self._offset += len(data)
         return data
 
+    def close(self):
+        try:
+            if self._close_fileobj:
+                self._fileobj.close()
+        finally:
+            super().close()
 
 
 class ZipFile:
@@ -889,8 +897,10 @@ class ZipFile:
         # given a file object in the constructor
         if self._filePassed:
             zef_file = self.fp
+            should_close = False
         else:
             zef_file = io.open(self.filename, 'rb')
+            should_close = True
 
         # Make sure we have an info object
         if isinstance(name, ZipInfo):
@@ -944,7 +954,7 @@ class ZipFile:
             if h[11] != check_byte:
                 raise RuntimeError("Bad password for file", name)
 
-        return  ZipExtFile(zef_file, mode, zinfo, zd)
+        return  ZipExtFile(zef_file, mode, zinfo, zd, close_fileobj=should_close)
 
     def extract(self, member, path=None, pwd=None):
         """Extract a member from the archive to the current working directory,