Commit 3a8071a2 authored by Martin v. Löwis's avatar Martin v. Löwis

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.
........
parent 19fec8b5
...@@ -11,9 +11,10 @@ from tempfile import TemporaryFile ...@@ -11,9 +11,10 @@ from tempfile import TemporaryFile
from random import randint, random from random import randint, random
import test.test_support as support 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" TESTFN2 = TESTFN + "2"
TESTFNDIR = TESTFN + "d"
FIXEDTEST_SIZE = 1000 FIXEDTEST_SIZE = 1000
SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'), SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'),
...@@ -982,6 +983,28 @@ class TestsWithMultipleOpens(unittest.TestCase): ...@@ -982,6 +983,28 @@ class TestsWithMultipleOpens(unittest.TestCase):
def tearDown(self): def tearDown(self):
os.remove(TESTFN2) 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): class UniversalNewlineTests(unittest.TestCase):
def setUp(self): def setUp(self):
...@@ -1090,6 +1113,7 @@ class UniversalNewlineTests(unittest.TestCase): ...@@ -1090,6 +1113,7 @@ class UniversalNewlineTests(unittest.TestCase):
def test_main(): def test_main():
run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests, run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
PyZipFileTests, DecryptionTests, TestsWithMultipleOpens, PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
TestWithDirectory,
UniversalNewlineTests, TestsWithRandomBinaryFiles) UniversalNewlineTests, TestsWithRandomBinaryFiles)
if __name__ == "__main__": if __name__ == "__main__":
......
This diff was suppressed by a .gitattributes entry.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Read and write ZIP files. Read and write ZIP files.
""" """
import struct, os, time, sys, shutil import struct, os, time, sys, shutil
import binascii, cStringIO import binascii, cStringIO, stat
try: try:
import zlib # We may need its compression method import zlib # We may need its compression method
...@@ -940,11 +940,11 @@ class ZipFile: ...@@ -940,11 +940,11 @@ class ZipFile:
""" """
# build the destination pathname, replacing # build the destination pathname, replacing
# forward slashes to platform specific separators. # forward slashes to platform specific separators.
if targetpath[-1:] == "/": if targetpath[-1:] in (os.path.sep, os.path.altsep):
targetpath = targetpath[:-1] targetpath = targetpath[:-1]
# don't include leading "/" from file name if present # 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:]) targetpath = os.path.join(targetpath, member.filename[1:])
else: else:
targetpath = os.path.join(targetpath, member.filename) targetpath = os.path.join(targetpath, member.filename)
...@@ -956,6 +956,10 @@ class ZipFile: ...@@ -956,6 +956,10 @@ class ZipFile:
if upperdirs and not os.path.exists(upperdirs): if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs) os.makedirs(upperdirs)
if member.filename[-1] == '/':
os.mkdir(targetpath)
return targetpath
source = self.open(member, pwd=pwd) source = self.open(member, pwd=pwd)
target = file(targetpath, "wb") target = file(targetpath, "wb")
shutil.copyfileobj(source, target) shutil.copyfileobj(source, target)
...@@ -995,6 +999,7 @@ class ZipFile: ...@@ -995,6 +999,7 @@ class ZipFile:
"Attempt to write to ZIP archive that was already closed") "Attempt to write to ZIP archive that was already closed")
st = os.stat(filename) st = os.stat(filename)
isdir = stat.S_ISDIR(st.st_mode)
mtime = time.localtime(st.st_mtime) mtime = time.localtime(st.st_mtime)
date_time = mtime[0:6] date_time = mtime[0:6]
# Create ZipInfo instance to store file information # Create ZipInfo instance to store file information
...@@ -1003,6 +1008,8 @@ class ZipFile: ...@@ -1003,6 +1008,8 @@ class ZipFile:
arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
while arcname[0] in (os.sep, os.altsep): while arcname[0] in (os.sep, os.altsep):
arcname = arcname[1:] arcname = arcname[1:]
if isdir:
arcname += '/'
zinfo = ZipInfo(arcname, date_time) zinfo = ZipInfo(arcname, date_time)
zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes
if compress_type is None: if compress_type is None:
...@@ -1016,6 +1023,16 @@ class ZipFile: ...@@ -1016,6 +1023,16 @@ class ZipFile:
self._writecheck(zinfo) self._writecheck(zinfo)
self._didModify = True 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") fp = open(filename, "rb")
# Must overwrite CRC and sizes with correct data later # Must overwrite CRC and sizes with correct data later
zinfo.CRC = CRC = 0 zinfo.CRC = CRC = 0
......
...@@ -76,6 +76,9 @@ Core and Builtins ...@@ -76,6 +76,9 @@ Core and Builtins
Library 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, - 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 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 file size rather than 0). This is consistent with the behaviour of the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment