test_zipfile.py revision c0fac96c29a3842d9370e4c954ae1f4d57f849d0
1import zlib # implied prerequisite
2import zipfile, os, StringIO, tempfile
3from test.test_support import TestFailed
4
5srcname = "junk9630"+os.extsep+"tmp"
6zipname = "junk9708"+os.extsep+"tmp"
7
8
9def zipTest(f, compression, srccontents):
10    zip = zipfile.ZipFile(f, "w", compression)   # Create the ZIP archive
11    zip.write(srcname, "another"+os.extsep+"name")
12    zip.write(srcname, srcname)
13    zip.close()
14
15    zip = zipfile.ZipFile(f, "r", compression)   # Read the ZIP archive
16    readData2 = zip.read(srcname)
17    readData1 = zip.read("another"+os.extsep+"name")
18    zip.close()
19
20    if readData1 != srccontents or readData2 != srccontents:
21        raise TestFailed, "Written data doesn't equal read data."
22
23
24try:
25    fp = open(srcname, "wb")               # Make a source file with some lines
26    for i in range(0, 1000):
27        fp.write("Test of zipfile line %d.\n" % i)
28    fp.close()
29
30    fp = open(srcname, "rb")
31    writtenData = fp.read()
32    fp.close()
33
34    for file in (zipname, tempfile.TemporaryFile(), StringIO.StringIO()):
35        zipTest(file, zipfile.ZIP_STORED, writtenData)
36
37    for file in (zipname, tempfile.TemporaryFile(), StringIO.StringIO()):
38        zipTest(file, zipfile.ZIP_DEFLATED, writtenData)
39
40finally:
41    if os.path.isfile(srcname):           # Remove temporary files
42        os.unlink(srcname)
43    if os.path.isfile(zipname):
44        os.unlink(zipname)
45
46
47# This test checks that the ZipFile constructor closes the file object
48# it opens if there's an error in the file.  If it doesn't, the traceback
49# holds a reference to the ZipFile object and, indirectly, the file object.
50# On Windows, this causes the os.unlink() call to fail because the
51# underlying file is still open.  This is SF bug #412214.
52#
53fp = open(srcname, "w")
54fp.write("this is not a legal zip file\n")
55fp.close()
56try:
57    zf = zipfile.ZipFile(srcname)
58except zipfile.BadZipfile:
59    os.unlink(srcname)
60
61
62# make sure we don't raise an AttributeError when a partially-constructed
63# ZipFile instance is finalized; this tests for regression on SF tracker
64# bug #403871.
65try:
66    zipfile.ZipFile(srcname)
67except IOError:
68    # The bug we're testing for caused an AttributeError to be raised
69    # when a ZipFile instance was created for a file that did not
70    # exist; the .fp member was not initialized but was needed by the
71    # __del__() method.  Since the AttributeError is in the __del__(),
72    # it is ignored, but the user should be sufficiently annoyed by
73    # the message on the output that regression will be noticed
74    # quickly.
75    pass
76else:
77    raise TestFailed("expected creation of readable ZipFile without\n"
78                     "  a file to raise an IOError.")
79
80
81# Verify that testzip() doesn't swallow inappropriate exceptions.
82data = StringIO.StringIO()
83zipf = zipfile.ZipFile(data, mode="w")
84zipf.writestr("foo.txt", "O, for a Muse of Fire!")
85zipf.close()
86zipf = zipfile.ZipFile(data, mode="r")
87zipf.close()
88try:
89    zipf.testzip()
90except RuntimeError:
91    # This is correct; calling .read on a closed ZipFile should throw
92    # a RuntimeError, and so should calling .testzip.  An earlier
93    # version of .testzip would swallow this exception (and any other)
94    # and report that the first file in the archive was corrupt.
95    pass
96else:
97    raise TestFailed("expected calling .testzip on a closed ZipFile"
98                     " to raise a RuntimeError")
99del data, zipf
100