diff options
Diffstat (limited to 'Lib/test/test_zipfile.py')
-rw-r--r-- | Lib/test/test_zipfile.py | 262 |
1 files changed, 94 insertions, 168 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index d278e06a453..ef3c3d8d676 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,8 +1,8 @@ import contextlib import io import os -import sys import importlib.util +import posixpath import time import struct import zipfile @@ -38,10 +38,6 @@ def get_files(test): yield f test.assertFalse(f.closed) -def openU(zipfp, fn): - with check_warnings(('', DeprecationWarning)): - return zipfp.open(fn, 'rU') - class AbstractTestsWithSourceFile: @classmethod def setUpClass(cls): @@ -61,6 +57,9 @@ class AbstractTestsWithSourceFile: zipfp.write(TESTFN, "another.name") zipfp.write(TESTFN, TESTFN) zipfp.writestr("strfile", self.data) + with zipfp.open('written-open-w', mode='w') as f: + for line in self.line_gen: + f.write(line) def zip_test(self, f, compression): self.make_test_archive(f, compression) @@ -76,7 +75,7 @@ class AbstractTestsWithSourceFile: zipfp.printdir(file=fp) directory = fp.getvalue() lines = directory.splitlines() - self.assertEqual(len(lines), 4) # Number of files + header + self.assertEqual(len(lines), 5) # Number of files + header self.assertIn('File Name', lines[0]) self.assertIn('Modified', lines[0]) @@ -90,23 +89,25 @@ class AbstractTestsWithSourceFile: # Check the namelist names = zipfp.namelist() - self.assertEqual(len(names), 3) + self.assertEqual(len(names), 4) self.assertIn(TESTFN, names) self.assertIn("another.name", names) self.assertIn("strfile", names) + self.assertIn("written-open-w", names) # Check infolist infos = zipfp.infolist() names = [i.filename for i in infos] - self.assertEqual(len(names), 3) + self.assertEqual(len(names), 4) self.assertIn(TESTFN, names) self.assertIn("another.name", names) self.assertIn("strfile", names) + self.assertIn("written-open-w", names) for i in infos: self.assertEqual(i.file_size, len(self.data)) # check getinfo - for nm in (TESTFN, "another.name", "strfile"): + for nm in (TESTFN, "another.name", "strfile", "written-open-w"): info = zipfp.getinfo(nm) self.assertEqual(info.filename, nm) self.assertEqual(info.file_size, len(self.data)) @@ -372,14 +373,18 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile, test_low_compression = None def zip_test_writestr_permissions(self, f, compression): - # Make sure that writestr creates files with mode 0600, - # when it is passed a name rather than a ZipInfo instance. + # Make sure that writestr and open(... mode='w') create files with + # mode 0600, when they are passed a name rather than a ZipInfo + # instance. self.make_test_archive(f, compression) with zipfile.ZipFile(f, "r") as zipfp: zinfo = zipfp.getinfo('strfile') self.assertEqual(zinfo.external_attr, 0o600 << 16) + zinfo2 = zipfp.getinfo('written-open-w') + self.assertEqual(zinfo2.external_attr, 0o600 << 16) + def test_writestr_permissions(self): for f in get_files(self): self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED) @@ -451,6 +456,10 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile, with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: self.assertRaises(RuntimeError, zipfp.write, TESTFN) + with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: + with self.assertRaises(RuntimeError): + zipfp.open(TESTFN, mode='w') + def test_add_file_before_1980(self): # Set atime and mtime to 1970-01-01 os.utime(TESTFN, (0, 0)) @@ -1022,32 +1031,6 @@ class OtherTests(unittest.TestCase): data += zipfp.read(info) self.assertIn(data, {b"foobar", b"barfoo"}) - def test_universal_deprecation(self): - f = io.BytesIO() - with zipfile.ZipFile(f, "w") as zipfp: - zipfp.writestr('spam.txt', b'ababagalamaga') - - with zipfile.ZipFile(f, "r") as zipfp: - for mode in 'U', 'rU': - with self.assertWarns(DeprecationWarning): - zipopen = zipfp.open('spam.txt', mode) - zipopen.close() - - def test_universal_readaheads(self): - f = io.BytesIO() - - data = b'a\r\n' * 16 * 1024 - with zipfile.ZipFile(f, 'w', zipfile.ZIP_STORED) as zipfp: - zipfp.writestr(TESTFN, data) - - data2 = b'' - with zipfile.ZipFile(f, 'r') as zipfp, \ - openU(zipfp, TESTFN) as zipopen: - for line in zipopen: - data2 += line - - self.assertEqual(data, data2.replace(b'\n', b'\r\n')) - def test_writestr_extended_local_header_issue1202(self): with zipfile.ZipFile(TESTFN2, 'w') as orig_zip: for data in 'abcdefghijklmnop': @@ -1255,9 +1238,12 @@ class OtherTests(unittest.TestCase): zipf.writestr("foo.txt", "O, for a Muse of Fire!") with zipfile.ZipFile(TESTFN, mode="r") as zipf: - # read the data to make sure the file is there + # read the data to make sure the file is there zipf.read("foo.txt") self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") + # universal newlines support is removed + self.assertRaises(RuntimeError, zipf.open, "foo.txt", "U") + self.assertRaises(RuntimeError, zipf.open, "foo.txt", "rU") def test_read0(self): """Check that calling read(0) on a ZipExtFile object returns an empty @@ -1428,6 +1414,35 @@ class OtherTests(unittest.TestCase): # testzip returns the name of the first corrupt file, or None self.assertIsNone(zipf.testzip()) + def test_open_conflicting_handles(self): + # It's only possible to open one writable file handle at a time + msg1 = b"It's fun to charter an accountant!" + msg2 = b"And sail the wide accountant sea" + msg3 = b"To find, explore the funds offshore" + with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_STORED) as zipf: + with zipf.open('foo', mode='w') as w2: + w2.write(msg1) + with zipf.open('bar', mode='w') as w1: + with self.assertRaises(RuntimeError): + zipf.open('handle', mode='w') + with self.assertRaises(RuntimeError): + zipf.open('foo', mode='r') + with self.assertRaises(RuntimeError): + zipf.writestr('str', 'abcde') + with self.assertRaises(RuntimeError): + zipf.write(__file__, 'file') + with self.assertRaises(RuntimeError): + zipf.close() + w1.write(msg2) + with zipf.open('baz', mode='w') as w2: + w2.write(msg3) + + with zipfile.ZipFile(TESTFN2, 'r') as zipf: + self.assertEqual(zipf.read('foo'), msg1) + self.assertEqual(zipf.read('bar'), msg2) + self.assertEqual(zipf.read('baz'), msg3) + self.assertEqual(zipf.namelist(), ['foo', 'bar', 'baz']) + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -1761,6 +1776,22 @@ class UnseekableTests(unittest.TestCase): with zipf.open('twos') as zopen: self.assertEqual(zopen.read(), b'222') + def test_open_write(self): + for wrapper in (lambda f: f), Tellable, Unseekable: + with self.subTest(wrapper=wrapper): + f = io.BytesIO() + f.write(b'abc') + bf = io.BufferedWriter(f) + with zipfile.ZipFile(wrapper(bf), 'w', zipfile.ZIP_STORED) as zipf: + with zipf.open('ones', 'w') as zopen: + zopen.write(b'111') + with zipf.open('twos', 'w') as zopen: + zopen.write(b'222') + self.assertEqual(f.getvalue()[:5], b'abcPK') + with zipfile.ZipFile(f) as zipf: + self.assertEqual(zipf.read('ones'), b'111') + self.assertEqual(zipf.read('twos'), b'222') + @requires_zlib class TestsWithMultipleOpens(unittest.TestCase): @@ -1871,6 +1902,19 @@ class TestsWithMultipleOpens(unittest.TestCase): with open(os.devnull) as f: self.assertLess(f.fileno(), 100) + def test_write_while_reading(self): + with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_DEFLATED) as zipf: + zipf.writestr('ones', self.data1) + with zipfile.ZipFile(TESTFN2, 'a', zipfile.ZIP_DEFLATED) as zipf: + with zipf.open('ones', 'r') as r1: + data1 = r1.read(500) + with zipf.open('twos', 'w') as w1: + w1.write(self.data2) + data1 += r1.read() + self.assertEqual(data1, self.data1) + with zipfile.ZipFile(TESTFN2) as zipf: + self.assertEqual(zipf.read('twos'), self.data2) + def tearDown(self): unlink(TESTFN2) @@ -1940,137 +1984,19 @@ class TestWithDirectory(unittest.TestCase): unlink(TESTFN) -class AbstractUniversalNewlineTests: - @classmethod - def setUpClass(cls): - cls.line_gen = [bytes("Test of zipfile line %d." % i, "ascii") - for i in range(FIXEDTEST_SIZE)] - cls.seps = (b'\r', b'\r\n', b'\n') - cls.arcdata = {} - for n, s in enumerate(cls.seps): - cls.arcdata[s] = s.join(cls.line_gen) + s - - def setUp(self): - self.arcfiles = {} - for n, s in enumerate(self.seps): - self.arcfiles[s] = '%s-%d' % (TESTFN, n) - with open(self.arcfiles[s], "wb") as f: - f.write(self.arcdata[s]) - - def make_test_archive(self, f, compression): - # Create the ZIP archive - with zipfile.ZipFile(f, "w", compression) as zipfp: - for fn in self.arcfiles.values(): - zipfp.write(fn, fn) - - def read_test(self, f, compression): - self.make_test_archive(f, compression) - - # Read the ZIP archive - with zipfile.ZipFile(f, "r") as zipfp: - for sep, fn in self.arcfiles.items(): - with openU(zipfp, fn) as fp: - zipdata = fp.read() - self.assertEqual(self.arcdata[sep], zipdata) - - def test_read(self): - for f in get_files(self): - self.read_test(f, self.compression) - - def readline_read_test(self, f, compression): - self.make_test_archive(f, compression) - - # Read the ZIP archive - with zipfile.ZipFile(f, "r") as zipfp: - for sep, fn in self.arcfiles.items(): - with openU(zipfp, fn) as zipopen: - data = b'' - while True: - read = zipopen.readline() - if not read: - break - data += read - - read = zipopen.read(5) - if not read: - break - data += read - - self.assertEqual(data, self.arcdata[b'\n']) - - def test_readline_read(self): - for f in get_files(self): - self.readline_read_test(f, self.compression) - - def readline_test(self, f, compression): - self.make_test_archive(f, compression) - - # Read the ZIP archive - with zipfile.ZipFile(f, "r") as zipfp: - for sep, fn in self.arcfiles.items(): - with openU(zipfp, fn) as zipopen: - for line in self.line_gen: - linedata = zipopen.readline() - self.assertEqual(linedata, line + b'\n') - - def test_readline(self): - for f in get_files(self): - self.readline_test(f, self.compression) - - def readlines_test(self, f, compression): - self.make_test_archive(f, compression) - - # Read the ZIP archive - with zipfile.ZipFile(f, "r") as zipfp: - for sep, fn in self.arcfiles.items(): - with openU(zipfp, fn) as fp: - ziplines = fp.readlines() - for line, zipline in zip(self.line_gen, ziplines): - self.assertEqual(zipline, line + b'\n') - - def test_readlines(self): - for f in get_files(self): - self.readlines_test(f, self.compression) - - def iterlines_test(self, f, compression): - self.make_test_archive(f, compression) +class ZipInfoTests(unittest.TestCase): + def test_from_file(self): + zi = zipfile.ZipInfo.from_file(__file__) + self.assertEqual(posixpath.basename(zi.filename), 'test_zipfile.py') + self.assertFalse(zi.is_dir()) - # Read the ZIP archive - with zipfile.ZipFile(f, "r") as zipfp: - for sep, fn in self.arcfiles.items(): - with openU(zipfp, fn) as fp: - for line, zipline in zip(self.line_gen, fp): - self.assertEqual(zipline, line + b'\n') - - def test_iterlines(self): - for f in get_files(self): - self.iterlines_test(f, self.compression) - - def tearDown(self): - for sep, fn in self.arcfiles.items(): - unlink(fn) - unlink(TESTFN) - unlink(TESTFN2) - - -class StoredUniversalNewlineTests(AbstractUniversalNewlineTests, - unittest.TestCase): - compression = zipfile.ZIP_STORED - -@requires_zlib -class DeflateUniversalNewlineTests(AbstractUniversalNewlineTests, - unittest.TestCase): - compression = zipfile.ZIP_DEFLATED - -@requires_bz2 -class Bzip2UniversalNewlineTests(AbstractUniversalNewlineTests, - unittest.TestCase): - compression = zipfile.ZIP_BZIP2 - -@requires_lzma -class LzmaUniversalNewlineTests(AbstractUniversalNewlineTests, - unittest.TestCase): - compression = zipfile.ZIP_LZMA + def test_from_dir(self): + dirpath = os.path.dirname(os.path.abspath(__file__)) + zi = zipfile.ZipInfo.from_file(dirpath, 'stdlib_tests') + self.assertEqual(zi.filename, 'stdlib_tests/') + self.assertTrue(zi.is_dir()) + self.assertEqual(zi.compress_type, zipfile.ZIP_STORED) + self.assertEqual(zi.file_size, 0) if __name__ == "__main__": unittest.main() |