--- 2.7/zipfile.py 2011-10-08 20:17:46.360505737 +0200 +++ modified-2.7/zipfile.py 2011-10-09 12:06:47.017625833 +0200 @@ -473,9 +473,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?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(self.__class__,self).close() class ZipFile: @@ -864,10 +872,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - ifile = self.open(name, "r", pwd) - res = ifile.read() - ifile.close() - return res + with self.open(name, "r", pwd) as ifile: + return ifile.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -890,8 +896,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -905,6 +915,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -916,6 +928,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -934,9 +948,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -994,7 +1011,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close()