Index: Lib/zipfile.py =================================================================== --- Lib/zipfile.py (revision 86668) +++ Lib/zipfile.py (working copy) @@ -473,9 +473,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(br'^(?P[^\r\n]+)|(?P\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 @@ 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 @@ # 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 @@ 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,