Merged revisions 68885 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r68885 | martin.v.loewis | 2009-01-24 15:00:33 +0100 (Sa, 24 Jan 2009) | 3 lines

  Issue #4710: Extract directories properly in the zipfile module;
  allow adding directories to a zipfile.
........
This commit is contained in:
Martin v. Löwis 2009-01-24 14:04:33 +00:00
parent 19fec8b58f
commit 3a8071a26f
4 changed files with 48 additions and 4 deletions

View File

@ -11,9 +11,10 @@ from tempfile import TemporaryFile
from random import randint, random
import test.test_support as support
from test.test_support import TESTFN, run_unittest
from test.test_support import TESTFN, run_unittest, findfile
TESTFN2 = TESTFN + "2"
TESTFNDIR = TESTFN + "d"
FIXEDTEST_SIZE = 1000
SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'),
@ -982,6 +983,28 @@ class TestsWithMultipleOpens(unittest.TestCase):
def tearDown(self):
os.remove(TESTFN2)
class TestWithDirectory(unittest.TestCase):
def setUp(self):
os.mkdir(TESTFN2)
def testExtractDir(self):
zipf = zipfile.ZipFile(findfile("zipdir.zip"))
zipf.extractall(TESTFN2)
self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a")))
self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b")))
self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c")))
def testStoreDir(self):
os.mkdir(os.path.join(TESTFN2, "x"))
zipf = zipfile.ZipFile(TESTFN, "w")
zipf.write(os.path.join(TESTFN2, "x"), "x")
self.assertTrue(zipf.filelist[0].filename.endswith("x/"))
def tearDown(self):
shutil.rmtree(TESTFN2)
if os.path.exists(TESTFN):
os.remove(TESTFN)
class UniversalNewlineTests(unittest.TestCase):
def setUp(self):
@ -1090,6 +1113,7 @@ class UniversalNewlineTests(unittest.TestCase):
def test_main():
run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
TestWithDirectory,
UniversalNewlineTests, TestsWithRandomBinaryFiles)
if __name__ == "__main__":

BIN
Lib/test/zipdir.zip Normal file

Binary file not shown.

View File

@ -2,7 +2,7 @@
Read and write ZIP files.
"""
import struct, os, time, sys, shutil
import binascii, cStringIO
import binascii, cStringIO, stat
try:
import zlib # We may need its compression method
@ -940,11 +940,11 @@ class ZipFile:
"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
if targetpath[-1:] == "/":
if targetpath[-1:] in (os.path.sep, os.path.altsep):
targetpath = targetpath[:-1]
# don't include leading "/" from file name if present
if os.path.isabs(member.filename):
if member.filename[0] == '/':
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
@ -956,6 +956,10 @@ class ZipFile:
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.filename[-1] == '/':
os.mkdir(targetpath)
return targetpath
source = self.open(member, pwd=pwd)
target = file(targetpath, "wb")
shutil.copyfileobj(source, target)
@ -995,6 +999,7 @@ class ZipFile:
"Attempt to write to ZIP archive that was already closed")
st = os.stat(filename)
isdir = stat.S_ISDIR(st.st_mode)
mtime = time.localtime(st.st_mtime)
date_time = mtime[0:6]
# Create ZipInfo instance to store file information
@ -1003,6 +1008,8 @@ class ZipFile:
arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
while arcname[0] in (os.sep, os.altsep):
arcname = arcname[1:]
if isdir:
arcname += '/'
zinfo = ZipInfo(arcname, date_time)
zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes
if compress_type is None:
@ -1016,6 +1023,16 @@ class ZipFile:
self._writecheck(zinfo)
self._didModify = True
if isdir:
zinfo.file_size = 0
zinfo.compress_size = 0
zinfo.CRC = 0
self.filelist.append(zinfo)
self.NameToInfo[zinfo.filename] = zinfo
self.fp.write(zinfo.FileHeader())
return
fp = open(filename, "rb")
# Must overwrite CRC and sizes with correct data later
zinfo.CRC = CRC = 0

View File

@ -76,6 +76,9 @@ Core and Builtins
Library
-------
- Issue #4710: Extract directories properly in the zipfile module;
allow adding directories to a zipfile.
- Issue #5008: When a file is opened in append mode with the new IO library,
do an explicit seek to the end of file (so that e.g. tell() returns the
file size rather than 0). This is consistent with the behaviour of the