Index: Lib/zipfile.py =================================================================== --- Lib/zipfile.py (version 67911) +++ Lib/zipfile.py (working copy) @@ -945,9 +945,14 @@ """ # build the destination pathname, replacing # forward slashes to platform specific separators. - if targetpath[-1:] == "/": + if targetpath[-1:] == os.sep: targetpath = targetpath[:-1] + isdir = False + + if member.filename[-1:] == os.sep: + isdir = True + # don't include leading "/" from file name if present if os.path.isabs(member.filename): targetpath = os.path.join(targetpath, member.filename[1:]) @@ -958,9 +963,13 @@ # Create all upper directories if necessary. upperdirs = os.path.dirname(targetpath) - if upperdirs and not os.path.exists(upperdirs): + if upperdirs and not os.path.isdir(upperdirs): os.makedirs(upperdirs) + if isdir: + os.mkdir(targetpath) + return targetpath + source = self.open(member, pwd=pwd) target = file(targetpath, "wb") shutil.copyfileobj(source, target) @@ -999,15 +1008,26 @@ raise RuntimeError( "Attempt to write to ZIP archive that was already closed") + isdir = False + + if os.path.isdir(filename): + isdir = True + st = os.stat(filename) mtime = time.localtime(st.st_mtime) date_time = mtime[0:6] + # Create ZipInfo instance to store file information if arcname is None: arcname = filename + arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) while arcname[0] in (os.sep, os.altsep): arcname = arcname[1:] + + if isdir: + arcname += os.sep + zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes if compress_type is None: @@ -1019,6 +1039,14 @@ zinfo.flag_bits = 0x00 zinfo.header_offset = self.fp.tell() # Start of header bytes + if isdir: + zinfo.file_size = 0 + zinfo.compress_size = 0 + zinfo.CRC = 0 + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + return + self._writecheck(zinfo) self._didModify = True fp = open(filename, "rb")