1 # We can test part of the module without zlib.
7 import zipfile
, os
, unittest
, sys
, shutil
, struct
9 from StringIO
import StringIO
10 from tempfile
import TemporaryFile
11 from random
import randint
, random
13 import test
.test_support
as support
14 from test
.test_support
import TESTFN
, run_unittest
16 TESTFN2
= TESTFN
+ "2"
19 SMALL_TEST_DATA
= [('_ziptest1', '1q2w3e4r5t'),
20 ('ziptest2dir/_ziptest2', 'qawsedrftg'),
21 ('/ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'),
22 ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')]
24 class TestsWithSourceFile(unittest
.TestCase
):
26 self
.line_gen
= ["Zipfile test line %d. random float: %f" % (i
, random())
27 for i
in xrange(FIXEDTEST_SIZE
)]
28 self
.data
= '\n'.join(self
.line_gen
) + '\n'
30 # Make a source file with some lines
31 fp
= open(TESTFN
, "wb")
35 def makeTestArchive(self
, f
, compression
):
36 # Create the ZIP archive
37 zipfp
= zipfile
.ZipFile(f
, "w", compression
)
38 zipfp
.write(TESTFN
, "another"+os
.extsep
+"name")
39 zipfp
.write(TESTFN
, TESTFN
)
40 zipfp
.writestr("strfile", self
.data
)
43 def zipTest(self
, f
, compression
):
44 self
.makeTestArchive(f
, compression
)
46 # Read the ZIP archive
47 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
48 self
.assertEqual(zipfp
.read(TESTFN
), self
.data
)
49 self
.assertEqual(zipfp
.read("another"+os
.extsep
+"name"), self
.data
)
50 self
.assertEqual(zipfp
.read("strfile"), self
.data
)
52 # Print the ZIP directory
62 directory
= fp
.getvalue()
63 lines
= directory
.splitlines()
64 self
.assertEquals(len(lines
), 4) # Number of files + header
66 self
.assert_('File Name' in lines
[0])
67 self
.assert_('Modified' in lines
[0])
68 self
.assert_('Size' in lines
[0])
70 fn
, date
, time
, size
= lines
[1].split()
71 self
.assertEquals(fn
, 'another.name')
72 # XXX: timestamp is not tested
73 self
.assertEquals(size
, str(len(self
.data
)))
76 names
= zipfp
.namelist()
77 self
.assertEquals(len(names
), 3)
78 self
.assert_(TESTFN
in names
)
79 self
.assert_("another"+os
.extsep
+"name" in names
)
80 self
.assert_("strfile" in names
)
83 infos
= zipfp
.infolist()
84 names
= [ i
.filename
for i
in infos
]
85 self
.assertEquals(len(names
), 3)
86 self
.assert_(TESTFN
in names
)
87 self
.assert_("another"+os
.extsep
+"name" in names
)
88 self
.assert_("strfile" in names
)
90 self
.assertEquals(i
.file_size
, len(self
.data
))
93 for nm
in (TESTFN
, "another"+os
.extsep
+"name", "strfile"):
94 info
= zipfp
.getinfo(nm
)
95 self
.assertEquals(info
.filename
, nm
)
96 self
.assertEquals(info
.file_size
, len(self
.data
))
98 # Check that testzip doesn't raise an exception
102 def testStored(self
):
103 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
104 self
.zipTest(f
, zipfile
.ZIP_STORED
)
106 def zipOpenTest(self
, f
, compression
):
107 self
.makeTestArchive(f
, compression
)
109 # Read the ZIP archive
110 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
112 zipopen1
= zipfp
.open(TESTFN
)
114 read_data
= zipopen1
.read(256)
117 zipdata1
.append(read_data
)
120 zipopen2
= zipfp
.open("another"+os
.extsep
+"name")
122 read_data
= zipopen2
.read(256)
125 zipdata2
.append(read_data
)
127 self
.assertEqual(''.join(zipdata1
), self
.data
)
128 self
.assertEqual(''.join(zipdata2
), self
.data
)
131 def testOpenStored(self
):
132 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
133 self
.zipOpenTest(f
, zipfile
.ZIP_STORED
)
135 def zipRandomOpenTest(self
, f
, compression
):
136 self
.makeTestArchive(f
, compression
)
138 # Read the ZIP archive
139 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
141 zipopen1
= zipfp
.open(TESTFN
)
143 read_data
= zipopen1
.read(randint(1, 1024))
146 zipdata1
.append(read_data
)
148 self
.assertEqual(''.join(zipdata1
), self
.data
)
151 def testRandomOpenStored(self
):
152 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
153 self
.zipRandomOpenTest(f
, zipfile
.ZIP_STORED
)
155 def zipReadlineTest(self
, f
, compression
):
156 self
.makeTestArchive(f
, compression
)
158 # Read the ZIP archive
159 zipfp
= zipfile
.ZipFile(f
, "r")
160 zipopen
= zipfp
.open(TESTFN
)
161 for line
in self
.line_gen
:
162 linedata
= zipopen
.readline()
163 self
.assertEqual(linedata
, line
+ '\n')
167 def zipReadlinesTest(self
, f
, compression
):
168 self
.makeTestArchive(f
, compression
)
170 # Read the ZIP archive
171 zipfp
= zipfile
.ZipFile(f
, "r")
172 ziplines
= zipfp
.open(TESTFN
).readlines()
173 for line
, zipline
in zip(self
.line_gen
, ziplines
):
174 self
.assertEqual(zipline
, line
+ '\n')
178 def zipIterlinesTest(self
, f
, compression
):
179 self
.makeTestArchive(f
, compression
)
181 # Read the ZIP archive
182 zipfp
= zipfile
.ZipFile(f
, "r")
183 for line
, zipline
in zip(self
.line_gen
, zipfp
.open(TESTFN
)):
184 self
.assertEqual(zipline
, line
+ '\n')
188 def testReadlineStored(self
):
189 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
190 self
.zipReadlineTest(f
, zipfile
.ZIP_STORED
)
192 def testReadlinesStored(self
):
193 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
194 self
.zipReadlinesTest(f
, zipfile
.ZIP_STORED
)
196 def testIterlinesStored(self
):
197 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
198 self
.zipIterlinesTest(f
, zipfile
.ZIP_STORED
)
201 def testDeflated(self
):
202 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
203 self
.zipTest(f
, zipfile
.ZIP_DEFLATED
)
205 def testOpenDeflated(self
):
206 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
207 self
.zipOpenTest(f
, zipfile
.ZIP_DEFLATED
)
209 def testRandomOpenDeflated(self
):
210 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
211 self
.zipRandomOpenTest(f
, zipfile
.ZIP_DEFLATED
)
213 def testReadlineDeflated(self
):
214 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
215 self
.zipReadlineTest(f
, zipfile
.ZIP_DEFLATED
)
217 def testReadlinesDeflated(self
):
218 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
219 self
.zipReadlinesTest(f
, zipfile
.ZIP_DEFLATED
)
221 def testIterlinesDeflated(self
):
222 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
223 self
.zipIterlinesTest(f
, zipfile
.ZIP_DEFLATED
)
225 def testLowCompression(self
):
226 # Checks for cases where compressed data is larger than original
227 # Create the ZIP archive
228 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_DEFLATED
)
229 zipfp
.writestr("strfile", '12')
232 # Get an open object for strfile
233 zipfp
= zipfile
.ZipFile(TESTFN2
, "r", zipfile
.ZIP_DEFLATED
)
234 openobj
= zipfp
.open("strfile")
235 self
.assertEqual(openobj
.read(1), '1')
236 self
.assertEqual(openobj
.read(1), '2')
238 def testAbsoluteArcnames(self
):
239 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_STORED
)
240 zipfp
.write(TESTFN
, "/absolute")
243 zipfp
= zipfile
.ZipFile(TESTFN2
, "r", zipfile
.ZIP_STORED
)
244 self
.assertEqual(zipfp
.namelist(), ["absolute"])
247 def testAppendToZipFile(self
):
248 # Test appending to an existing zipfile
249 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_STORED
)
250 zipfp
.write(TESTFN
, TESTFN
)
252 zipfp
= zipfile
.ZipFile(TESTFN2
, "a", zipfile
.ZIP_STORED
)
253 zipfp
.writestr("strfile", self
.data
)
254 self
.assertEqual(zipfp
.namelist(), [TESTFN
, "strfile"])
257 def testAppendToNonZipFile(self
):
258 # Test appending to an existing file that is not a zipfile
259 # NOTE: this test fails if len(d) < 22 because of the first
260 # line "fpin.seek(-22, 2)" in _EndRecData
261 d
= 'I am not a ZipFile!'*10
262 f
= file(TESTFN2
, 'wb')
265 zipfp
= zipfile
.ZipFile(TESTFN2
, "a", zipfile
.ZIP_STORED
)
266 zipfp
.write(TESTFN
, TESTFN
)
269 f
= file(TESTFN2
, 'rb')
271 zipfp
= zipfile
.ZipFile(f
, "r")
272 self
.assertEqual(zipfp
.namelist(), [TESTFN
])
276 def test_WriteDefaultName(self
):
277 # Check that calling ZipFile.write without arcname specified produces the expected result
278 zipfp
= zipfile
.ZipFile(TESTFN2
, "w")
280 self
.assertEqual(zipfp
.read(TESTFN
), file(TESTFN
).read())
283 def test_PerFileCompression(self
):
284 # Check that files within a Zip archive can have different compression options
285 zipfp
= zipfile
.ZipFile(TESTFN2
, "w")
286 zipfp
.write(TESTFN
, 'storeme', zipfile
.ZIP_STORED
)
287 zipfp
.write(TESTFN
, 'deflateme', zipfile
.ZIP_DEFLATED
)
288 sinfo
= zipfp
.getinfo('storeme')
289 dinfo
= zipfp
.getinfo('deflateme')
290 self
.assertEqual(sinfo
.compress_type
, zipfile
.ZIP_STORED
)
291 self
.assertEqual(dinfo
.compress_type
, zipfile
.ZIP_DEFLATED
)
294 def test_WriteToReadonly(self
):
295 # Check that trying to call write() on a readonly ZipFile object
296 # raises a RuntimeError
297 zipf
= zipfile
.ZipFile(TESTFN2
, mode
="w")
298 zipf
.writestr("somefile.txt", "bogus")
300 zipf
= zipfile
.ZipFile(TESTFN2
, mode
="r")
301 self
.assertRaises(RuntimeError, zipf
.write
, TESTFN
)
304 def testExtract(self
):
305 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_STORED
)
306 for fpath
, fdata
in SMALL_TEST_DATA
:
307 zipfp
.writestr(fpath
, fdata
)
310 zipfp
= zipfile
.ZipFile(TESTFN2
, "r")
311 for fpath
, fdata
in SMALL_TEST_DATA
:
312 writtenfile
= zipfp
.extract(fpath
)
314 # make sure it was written to the right place
315 if os
.path
.isabs(fpath
):
316 correctfile
= os
.path
.join(os
.getcwd(), fpath
[1:])
318 correctfile
= os
.path
.join(os
.getcwd(), fpath
)
319 correctfile
= os
.path
.normpath(correctfile
)
321 self
.assertEqual(writtenfile
, correctfile
)
323 # make sure correct data is in correct file
324 self
.assertEqual(fdata
, file(writtenfile
, "rb").read())
326 os
.remove(writtenfile
)
330 # remove the test file subdirectories
331 shutil
.rmtree(os
.path
.join(os
.getcwd(), 'ziptest2dir'))
333 def testExtractAll(self
):
334 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_STORED
)
335 for fpath
, fdata
in SMALL_TEST_DATA
:
336 zipfp
.writestr(fpath
, fdata
)
339 zipfp
= zipfile
.ZipFile(TESTFN2
, "r")
341 for fpath
, fdata
in SMALL_TEST_DATA
:
342 if os
.path
.isabs(fpath
):
343 outfile
= os
.path
.join(os
.getcwd(), fpath
[1:])
345 outfile
= os
.path
.join(os
.getcwd(), fpath
)
347 self
.assertEqual(fdata
, file(outfile
, "rb").read())
353 # remove the test file subdirectories
354 shutil
.rmtree(os
.path
.join(os
.getcwd(), 'ziptest2dir'))
360 class TestZip64InSmallFiles(unittest
.TestCase
):
361 # These tests test the ZIP64 functionality without using large files,
362 # see test_zipfile64 for proper tests.
365 self
._limit
= zipfile
.ZIP64_LIMIT
366 zipfile
.ZIP64_LIMIT
= 5
368 line_gen
= ("Test of zipfile line %d." % i
for i
in range(0, FIXEDTEST_SIZE
))
369 self
.data
= '\n'.join(line_gen
)
371 # Make a source file with some lines
372 fp
= open(TESTFN
, "wb")
376 def largeFileExceptionTest(self
, f
, compression
):
377 zipfp
= zipfile
.ZipFile(f
, "w", compression
)
378 self
.assertRaises(zipfile
.LargeZipFile
,
379 zipfp
.write
, TESTFN
, "another"+os
.extsep
+"name")
382 def largeFileExceptionTest2(self
, f
, compression
):
383 zipfp
= zipfile
.ZipFile(f
, "w", compression
)
384 self
.assertRaises(zipfile
.LargeZipFile
,
385 zipfp
.writestr
, "another"+os
.extsep
+"name", self
.data
)
388 def testLargeFileException(self
):
389 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
390 self
.largeFileExceptionTest(f
, zipfile
.ZIP_STORED
)
391 self
.largeFileExceptionTest2(f
, zipfile
.ZIP_STORED
)
393 def zipTest(self
, f
, compression
):
394 # Create the ZIP archive
395 zipfp
= zipfile
.ZipFile(f
, "w", compression
, allowZip64
=True)
396 zipfp
.write(TESTFN
, "another"+os
.extsep
+"name")
397 zipfp
.write(TESTFN
, TESTFN
)
398 zipfp
.writestr("strfile", self
.data
)
401 # Read the ZIP archive
402 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
403 self
.assertEqual(zipfp
.read(TESTFN
), self
.data
)
404 self
.assertEqual(zipfp
.read("another"+os
.extsep
+"name"), self
.data
)
405 self
.assertEqual(zipfp
.read("strfile"), self
.data
)
407 # Print the ZIP directory
417 directory
= fp
.getvalue()
418 lines
= directory
.splitlines()
419 self
.assertEquals(len(lines
), 4) # Number of files + header
421 self
.assert_('File Name' in lines
[0])
422 self
.assert_('Modified' in lines
[0])
423 self
.assert_('Size' in lines
[0])
425 fn
, date
, time
, size
= lines
[1].split()
426 self
.assertEquals(fn
, 'another.name')
427 # XXX: timestamp is not tested
428 self
.assertEquals(size
, str(len(self
.data
)))
431 names
= zipfp
.namelist()
432 self
.assertEquals(len(names
), 3)
433 self
.assert_(TESTFN
in names
)
434 self
.assert_("another"+os
.extsep
+"name" in names
)
435 self
.assert_("strfile" in names
)
438 infos
= zipfp
.infolist()
439 names
= [ i
.filename
for i
in infos
]
440 self
.assertEquals(len(names
), 3)
441 self
.assert_(TESTFN
in names
)
442 self
.assert_("another"+os
.extsep
+"name" in names
)
443 self
.assert_("strfile" in names
)
445 self
.assertEquals(i
.file_size
, len(self
.data
))
448 for nm
in (TESTFN
, "another"+os
.extsep
+"name", "strfile"):
449 info
= zipfp
.getinfo(nm
)
450 self
.assertEquals(info
.filename
, nm
)
451 self
.assertEquals(info
.file_size
, len(self
.data
))
453 # Check that testzip doesn't raise an exception
459 def testStored(self
):
460 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
461 self
.zipTest(f
, zipfile
.ZIP_STORED
)
465 def testDeflated(self
):
466 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
467 self
.zipTest(f
, zipfile
.ZIP_DEFLATED
)
469 def testAbsoluteArcnames(self
):
470 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_STORED
, allowZip64
=True)
471 zipfp
.write(TESTFN
, "/absolute")
474 zipfp
= zipfile
.ZipFile(TESTFN2
, "r", zipfile
.ZIP_STORED
)
475 self
.assertEqual(zipfp
.namelist(), ["absolute"])
479 zipfile
.ZIP64_LIMIT
= self
._limit
483 class PyZipFileTests(unittest
.TestCase
):
484 def testWritePyfile(self
):
485 zipfp
= zipfile
.PyZipFile(TemporaryFile(), "w")
487 if fn
.endswith('.pyc') or fn
.endswith('.pyo'):
492 bn
= os
.path
.basename(fn
)
493 self
.assert_(bn
not in zipfp
.namelist())
494 self
.assert_(bn
+ 'o' in zipfp
.namelist() or bn
+ 'c' in zipfp
.namelist())
498 zipfp
= zipfile
.PyZipFile(TemporaryFile(), "w")
500 if fn
.endswith('.pyc') or fn
.endswith('.pyo'):
503 zipfp
.writepy(fn
, "testpackage")
505 bn
= "%s/%s"%("testpackage", os
.path
.basename(fn
))
506 self
.assert_(bn
not in zipfp
.namelist())
507 self
.assert_(bn
+ 'o' in zipfp
.namelist() or bn
+ 'c' in zipfp
.namelist())
510 def testWritePythonPackage(self
):
512 packagedir
= os
.path
.dirname(email
.__file
__)
514 zipfp
= zipfile
.PyZipFile(TemporaryFile(), "w")
515 zipfp
.writepy(packagedir
)
517 # Check for a couple of modules at different levels of the hieararchy
518 names
= zipfp
.namelist()
519 self
.assert_('email/__init__.pyo' in names
or 'email/__init__.pyc' in names
)
520 self
.assert_('email/mime/text.pyo' in names
or 'email/mime/text.pyc' in names
)
522 def testWritePythonDirectory(self
):
525 fp
= open(os
.path
.join(TESTFN2
, "mod1.py"), "w")
526 fp
.write("print 42\n")
529 fp
= open(os
.path
.join(TESTFN2
, "mod2.py"), "w")
530 fp
.write("print 42 * 42\n")
533 fp
= open(os
.path
.join(TESTFN2
, "mod2.txt"), "w")
534 fp
.write("bla bla bla\n")
537 zipfp
= zipfile
.PyZipFile(TemporaryFile(), "w")
538 zipfp
.writepy(TESTFN2
)
540 names
= zipfp
.namelist()
541 self
.assert_('mod1.pyc' in names
or 'mod1.pyo' in names
)
542 self
.assert_('mod2.pyc' in names
or 'mod2.pyo' in names
)
543 self
.assert_('mod2.txt' not in names
)
546 shutil
.rmtree(TESTFN2
)
548 def testWriteNonPyfile(self
):
549 zipfp
= zipfile
.PyZipFile(TemporaryFile(), "w")
550 file(TESTFN
, 'w').write('most definitely not a python file')
551 self
.assertRaises(RuntimeError, zipfp
.writepy
, TESTFN
)
555 class OtherTests(unittest
.TestCase
):
556 def testUnicodeFilenames(self
):
557 zf
= zipfile
.ZipFile(TESTFN
, "w")
558 zf
.writestr(u
"foo.txt", "Test for unicode filename")
559 zf
.writestr(u
"\xf6.txt", "Test for unicode filename")
560 self
.assertTrue(isinstance(zf
.infolist()[0].filename
, unicode))
562 zf
= zipfile
.ZipFile(TESTFN
, "r")
563 self
.assertEqual(zf
.filelist
[0].filename
, "foo.txt")
564 self
.assertEqual(zf
.filelist
[1].filename
, u
"\xf6.txt")
567 def testCreateNonExistentFileForAppend(self
):
568 if os
.path
.exists(TESTFN
):
571 filename
= 'testfile.txt'
572 content
= 'hello, world. this is some content.'
575 zf
= zipfile
.ZipFile(TESTFN
, 'a')
576 zf
.writestr(filename
, content
)
578 except IOError, (errno
, errmsg
):
579 self
.fail('Could not append data to a non-existent zip file.')
581 self
.assert_(os
.path
.exists(TESTFN
))
583 zf
= zipfile
.ZipFile(TESTFN
, 'r')
584 self
.assertEqual(zf
.read(filename
), content
)
587 def testCloseErroneousFile(self
):
588 # This test checks that the ZipFile constructor closes the file object
589 # it opens if there's an error in the file. If it doesn't, the traceback
590 # holds a reference to the ZipFile object and, indirectly, the file object.
591 # On Windows, this causes the os.unlink() call to fail because the
592 # underlying file is still open. This is SF bug #412214.
594 fp
= open(TESTFN
, "w")
595 fp
.write("this is not a legal zip file\n")
598 zf
= zipfile
.ZipFile(TESTFN
)
599 except zipfile
.BadZipfile
:
602 def testIsZipErroneousFile(self
):
603 # This test checks that the is_zipfile function correctly identifies
604 # a file that is not a zip file
605 fp
= open(TESTFN
, "w")
606 fp
.write("this is not a legal zip file\n")
608 chk
= zipfile
.is_zipfile(TESTFN
)
609 self
.assert_(chk
is False)
611 def testIsZipValidFile(self
):
612 # This test checks that the is_zipfile function correctly identifies
613 # a file that is a zip file
614 zipf
= zipfile
.ZipFile(TESTFN
, mode
="w")
615 zipf
.writestr("foo.txt", "O, for a Muse of Fire!")
617 chk
= zipfile
.is_zipfile(TESTFN
)
618 self
.assert_(chk
is True)
620 def testNonExistentFileRaisesIOError(self
):
621 # make sure we don't raise an AttributeError when a partially-constructed
622 # ZipFile instance is finalized; this tests for regression on SF tracker
625 # The bug we're testing for caused an AttributeError to be raised
626 # when a ZipFile instance was created for a file that did not
627 # exist; the .fp member was not initialized but was needed by the
628 # __del__() method. Since the AttributeError is in the __del__(),
629 # it is ignored, but the user should be sufficiently annoyed by
630 # the message on the output that regression will be noticed
632 self
.assertRaises(IOError, zipfile
.ZipFile
, TESTFN
)
634 def testClosedZipRaisesRuntimeError(self
):
635 # Verify that testzip() doesn't swallow inappropriate exceptions.
637 zipf
= zipfile
.ZipFile(data
, mode
="w")
638 zipf
.writestr("foo.txt", "O, for a Muse of Fire!")
641 # This is correct; calling .read on a closed ZipFile should throw
642 # a RuntimeError, and so should calling .testzip. An earlier
643 # version of .testzip would swallow this exception (and any other)
644 # and report that the first file in the archive was corrupt.
645 self
.assertRaises(RuntimeError, zipf
.read
, "foo.txt")
646 self
.assertRaises(RuntimeError, zipf
.open, "foo.txt")
647 self
.assertRaises(RuntimeError, zipf
.testzip
)
648 self
.assertRaises(RuntimeError, zipf
.writestr
, "bogus.txt", "bogus")
649 file(TESTFN
, 'w').write('zipfile test data')
650 self
.assertRaises(RuntimeError, zipf
.write
, TESTFN
)
652 def test_BadConstructorMode(self
):
653 # Check that bad modes passed to ZipFile constructor are caught
654 self
.assertRaises(RuntimeError, zipfile
.ZipFile
, TESTFN
, "q")
656 def test_BadOpenMode(self
):
657 # Check that bad modes passed to ZipFile.open are caught
658 zipf
= zipfile
.ZipFile(TESTFN
, mode
="w")
659 zipf
.writestr("foo.txt", "O, for a Muse of Fire!")
661 zipf
= zipfile
.ZipFile(TESTFN
, mode
="r")
662 # read the data to make sure the file is there
664 self
.assertRaises(RuntimeError, zipf
.open, "foo.txt", "q")
667 def test_Read0(self
):
668 # Check that calling read(0) on a ZipExtFile object returns an empty
669 # string and doesn't advance file pointer
670 zipf
= zipfile
.ZipFile(TESTFN
, mode
="w")
671 zipf
.writestr("foo.txt", "O, for a Muse of Fire!")
672 # read the data to make sure the file is there
673 f
= zipf
.open("foo.txt")
674 for i
in xrange(FIXEDTEST_SIZE
):
675 self
.assertEqual(f
.read(0), '')
677 self
.assertEqual(f
.read(), "O, for a Muse of Fire!")
680 def test_OpenNonexistentItem(self
):
681 # Check that attempting to call open() for an item that doesn't
682 # exist in the archive raises a RuntimeError
683 zipf
= zipfile
.ZipFile(TESTFN
, mode
="w")
684 self
.assertRaises(KeyError, zipf
.open, "foo.txt", "r")
686 def test_BadCompressionMode(self
):
687 # Check that bad compression methods passed to ZipFile.open are caught
688 self
.assertRaises(RuntimeError, zipfile
.ZipFile
, TESTFN
, "w", -1)
690 def test_NullByteInFilename(self
):
691 # Check that a filename containing a null byte is properly terminated
692 zipf
= zipfile
.ZipFile(TESTFN
, mode
="w")
693 zipf
.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!")
694 self
.assertEqual(zipf
.namelist(), ['foo.txt'])
697 support
.unlink(TESTFN
)
698 support
.unlink(TESTFN2
)
700 class DecryptionTests(unittest
.TestCase
):
701 # This test checks that ZIP decryption works. Since the library does not
702 # support encryption at the moment, we use a pre-generated encrypted
706 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
707 '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
708 '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
709 'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
710 '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
711 '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
712 '\x00\x00L\x00\x00\x00\x00\x00' )
714 'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02'
715 '\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04'
716 '\x00\xe8\x03\xe8\x03\xc7<M\xb5a\xceX\xa3Y&\x8b{oE\xd7\x9d\x8c\x98\x02\xc0'
717 'PK\x07\x08xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00PK\x01\x02\x17\x03'
718 '\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00'
719 '\x04\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00ze'
720 'roUT\x05\x00\x03\xd6\x8b\x92GUx\x00\x00PK\x05\x06\x00\x00\x00\x00\x01'
721 '\x00\x01\x00?\x00\x00\x00[\x00\x00\x00\x00\x00' )
723 plain
= 'zipfile.py encryption test'
727 fp
= open(TESTFN
, "wb")
730 self
.zip = zipfile
.ZipFile(TESTFN
, "r")
731 fp
= open(TESTFN2
, "wb")
734 self
.zip2
= zipfile
.ZipFile(TESTFN2
, "r")
742 def testNoPassword(self
):
743 # Reading the encrypted file without password
744 # must generate a RunTime exception
745 self
.assertRaises(RuntimeError, self
.zip.read
, "test.txt")
746 self
.assertRaises(RuntimeError, self
.zip2
.read
, "zero")
748 def testBadPassword(self
):
749 self
.zip.setpassword("perl")
750 self
.assertRaises(RuntimeError, self
.zip.read
, "test.txt")
751 self
.zip2
.setpassword("perl")
752 self
.assertRaises(RuntimeError, self
.zip2
.read
, "zero")
754 def testGoodPassword(self
):
755 self
.zip.setpassword("python")
756 self
.assertEquals(self
.zip.read("test.txt"), self
.plain
)
757 self
.zip2
.setpassword("12345")
758 self
.assertEquals(self
.zip2
.read("zero"), self
.plain2
)
761 class TestsWithRandomBinaryFiles(unittest
.TestCase
):
763 datacount
= randint(16, 64)*1024 + randint(1, 1024)
764 self
.data
= ''.join((struct
.pack('<f', random()*randint(-1000, 1000)) for i
in xrange(datacount
)))
766 # Make a source file with some lines
767 fp
= open(TESTFN
, "wb")
772 support
.unlink(TESTFN
)
773 support
.unlink(TESTFN2
)
775 def makeTestArchive(self
, f
, compression
):
776 # Create the ZIP archive
777 zipfp
= zipfile
.ZipFile(f
, "w", compression
)
778 zipfp
.write(TESTFN
, "another"+os
.extsep
+"name")
779 zipfp
.write(TESTFN
, TESTFN
)
782 def zipTest(self
, f
, compression
):
783 self
.makeTestArchive(f
, compression
)
785 # Read the ZIP archive
786 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
787 testdata
= zipfp
.read(TESTFN
)
788 self
.assertEqual(len(testdata
), len(self
.data
))
789 self
.assertEqual(testdata
, self
.data
)
790 self
.assertEqual(zipfp
.read("another"+os
.extsep
+"name"), self
.data
)
793 def testStored(self
):
794 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
795 self
.zipTest(f
, zipfile
.ZIP_STORED
)
797 def zipOpenTest(self
, f
, compression
):
798 self
.makeTestArchive(f
, compression
)
800 # Read the ZIP archive
801 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
803 zipopen1
= zipfp
.open(TESTFN
)
805 read_data
= zipopen1
.read(256)
808 zipdata1
.append(read_data
)
811 zipopen2
= zipfp
.open("another"+os
.extsep
+"name")
813 read_data
= zipopen2
.read(256)
816 zipdata2
.append(read_data
)
818 testdata1
= ''.join(zipdata1
)
819 self
.assertEqual(len(testdata1
), len(self
.data
))
820 self
.assertEqual(testdata1
, self
.data
)
822 testdata2
= ''.join(zipdata2
)
823 self
.assertEqual(len(testdata1
), len(self
.data
))
824 self
.assertEqual(testdata1
, self
.data
)
827 def testOpenStored(self
):
828 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
829 self
.zipOpenTest(f
, zipfile
.ZIP_STORED
)
831 def zipRandomOpenTest(self
, f
, compression
):
832 self
.makeTestArchive(f
, compression
)
834 # Read the ZIP archive
835 zipfp
= zipfile
.ZipFile(f
, "r", compression
)
837 zipopen1
= zipfp
.open(TESTFN
)
839 read_data
= zipopen1
.read(randint(1, 1024))
842 zipdata1
.append(read_data
)
844 testdata
= ''.join(zipdata1
)
845 self
.assertEqual(len(testdata
), len(self
.data
))
846 self
.assertEqual(testdata
, self
.data
)
849 def testRandomOpenStored(self
):
850 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
851 self
.zipRandomOpenTest(f
, zipfile
.ZIP_STORED
)
853 class TestsWithMultipleOpens(unittest
.TestCase
):
855 # Create the ZIP archive
856 zipfp
= zipfile
.ZipFile(TESTFN2
, "w", zipfile
.ZIP_DEFLATED
)
857 zipfp
.writestr('ones', '1'*FIXEDTEST_SIZE
)
858 zipfp
.writestr('twos', '2'*FIXEDTEST_SIZE
)
861 def testSameFile(self
):
862 # Verify that (when the ZipFile is in control of creating file objects)
863 # multiple open() calls can be made without interfering with each other.
864 zipf
= zipfile
.ZipFile(TESTFN2
, mode
="r")
865 zopen1
= zipf
.open('ones')
866 zopen2
= zipf
.open('ones')
867 data1
= zopen1
.read(500)
868 data2
= zopen2
.read(500)
869 data1
+= zopen1
.read(500)
870 data2
+= zopen2
.read(500)
871 self
.assertEqual(data1
, data2
)
874 def testDifferentFile(self
):
875 # Verify that (when the ZipFile is in control of creating file objects)
876 # multiple open() calls can be made without interfering with each other.
877 zipf
= zipfile
.ZipFile(TESTFN2
, mode
="r")
878 zopen1
= zipf
.open('ones')
879 zopen2
= zipf
.open('twos')
880 data1
= zopen1
.read(500)
881 data2
= zopen2
.read(500)
882 data1
+= zopen1
.read(500)
883 data2
+= zopen2
.read(500)
884 self
.assertEqual(data1
, '1'*FIXEDTEST_SIZE
)
885 self
.assertEqual(data2
, '2'*FIXEDTEST_SIZE
)
888 def testInterleaved(self
):
889 # Verify that (when the ZipFile is in control of creating file objects)
890 # multiple open() calls can be made without interfering with each other.
891 zipf
= zipfile
.ZipFile(TESTFN2
, mode
="r")
892 zopen1
= zipf
.open('ones')
893 data1
= zopen1
.read(500)
894 zopen2
= zipf
.open('twos')
895 data2
= zopen2
.read(500)
896 data1
+= zopen1
.read(500)
897 data2
+= zopen2
.read(500)
898 self
.assertEqual(data1
, '1'*FIXEDTEST_SIZE
)
899 self
.assertEqual(data2
, '2'*FIXEDTEST_SIZE
)
906 class UniversalNewlineTests(unittest
.TestCase
):
908 self
.line_gen
= ["Test of zipfile line %d." % i
for i
in xrange(FIXEDTEST_SIZE
)]
909 self
.seps
= ('\r', '\r\n', '\n')
910 self
.arcdata
, self
.arcfiles
= {}, {}
911 for n
, s
in enumerate(self
.seps
):
912 self
.arcdata
[s
] = s
.join(self
.line_gen
) + s
913 self
.arcfiles
[s
] = '%s-%d' % (TESTFN
, n
)
914 open(self
.arcfiles
[s
], "wb").write(self
.arcdata
[s
])
916 def makeTestArchive(self
, f
, compression
):
917 # Create the ZIP archive
918 zipfp
= zipfile
.ZipFile(f
, "w", compression
)
919 for fn
in self
.arcfiles
.values():
923 def readTest(self
, f
, compression
):
924 self
.makeTestArchive(f
, compression
)
926 # Read the ZIP archive
927 zipfp
= zipfile
.ZipFile(f
, "r")
928 for sep
, fn
in self
.arcfiles
.items():
929 zipdata
= zipfp
.open(fn
, "rU").read()
930 self
.assertEqual(self
.arcdata
[sep
], zipdata
)
934 def readlineTest(self
, f
, compression
):
935 self
.makeTestArchive(f
, compression
)
937 # Read the ZIP archive
938 zipfp
= zipfile
.ZipFile(f
, "r")
939 for sep
, fn
in self
.arcfiles
.items():
940 zipopen
= zipfp
.open(fn
, "rU")
941 for line
in self
.line_gen
:
942 linedata
= zipopen
.readline()
943 self
.assertEqual(linedata
, line
+ '\n')
947 def readlinesTest(self
, f
, compression
):
948 self
.makeTestArchive(f
, compression
)
950 # Read the ZIP archive
951 zipfp
= zipfile
.ZipFile(f
, "r")
952 for sep
, fn
in self
.arcfiles
.items():
953 ziplines
= zipfp
.open(fn
, "rU").readlines()
954 for line
, zipline
in zip(self
.line_gen
, ziplines
):
955 self
.assertEqual(zipline
, line
+ '\n')
959 def iterlinesTest(self
, f
, compression
):
960 self
.makeTestArchive(f
, compression
)
962 # Read the ZIP archive
963 zipfp
= zipfile
.ZipFile(f
, "r")
964 for sep
, fn
in self
.arcfiles
.items():
965 for line
, zipline
in zip(self
.line_gen
, zipfp
.open(fn
, "rU")):
966 self
.assertEqual(zipline
, line
+ '\n')
970 def testReadStored(self
):
971 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
972 self
.readTest(f
, zipfile
.ZIP_STORED
)
974 def testReadlineStored(self
):
975 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
976 self
.readlineTest(f
, zipfile
.ZIP_STORED
)
978 def testReadlinesStored(self
):
979 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
980 self
.readlinesTest(f
, zipfile
.ZIP_STORED
)
982 def testIterlinesStored(self
):
983 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
984 self
.iterlinesTest(f
, zipfile
.ZIP_STORED
)
987 def testReadDeflated(self
):
988 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
989 self
.readTest(f
, zipfile
.ZIP_DEFLATED
)
991 def testReadlineDeflated(self
):
992 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
993 self
.readlineTest(f
, zipfile
.ZIP_DEFLATED
)
995 def testReadlinesDeflated(self
):
996 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
997 self
.readlinesTest(f
, zipfile
.ZIP_DEFLATED
)
999 def testIterlinesDeflated(self
):
1000 for f
in (TESTFN2
, TemporaryFile(), StringIO()):
1001 self
.iterlinesTest(f
, zipfile
.ZIP_DEFLATED
)
1004 for sep
, fn
in self
.arcfiles
.items():
1006 support
.unlink(TESTFN
)
1007 support
.unlink(TESTFN2
)
1011 run_unittest(TestsWithSourceFile
, TestZip64InSmallFiles
, OtherTests
,
1012 PyZipFileTests
, DecryptionTests
, TestsWithMultipleOpens
,
1013 UniversalNewlineTests
, TestsWithRandomBinaryFiles
)
1015 if __name__
== "__main__":