bpo-43651: Fix EncodingWarning in zipfile (GH-25650)

This commit is contained in:
Inada Naoki 2021-04-27 15:45:31 +09:00 committed by GitHub
parent 5987b8c463
commit caae717c29
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 28 deletions

View file

@ -548,7 +548,7 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
def test_ignores_newline_at_end(self): def test_ignores_newline_at_end(self):
with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
zipfp.write(TESTFN, TESTFN) zipfp.write(TESTFN, TESTFN)
with open(TESTFN2, 'a') as f: with open(TESTFN2, 'a', encoding='utf-8') as f:
f.write("\r\n\00\00\00") f.write("\r\n\00\00\00")
with zipfile.ZipFile(TESTFN2, "r") as zipfp: with zipfile.ZipFile(TESTFN2, "r") as zipfp:
self.assertIsInstance(zipfp, zipfile.ZipFile) self.assertIsInstance(zipfp, zipfile.ZipFile)
@ -557,7 +557,7 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
zipfp.comment = b"this is a comment" zipfp.comment = b"this is a comment"
zipfp.write(TESTFN, TESTFN) zipfp.write(TESTFN, TESTFN)
with open(TESTFN2, 'a') as f: with open(TESTFN2, 'a', encoding='utf-8') as f:
f.write("abcdef\r\n") f.write("abcdef\r\n")
with zipfile.ZipFile(TESTFN2, "r") as zipfp: with zipfile.ZipFile(TESTFN2, "r") as zipfp:
self.assertIsInstance(zipfp, zipfile.ZipFile) self.assertIsInstance(zipfp, zipfile.ZipFile)
@ -1245,13 +1245,13 @@ class PyZipFileTests(unittest.TestCase):
def test_write_python_directory(self): def test_write_python_directory(self):
os.mkdir(TESTFN2) os.mkdir(TESTFN2)
try: try:
with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod1.py"), "w", encoding='utf-8') as fp:
fp.write("print(42)\n") fp.write("print(42)\n")
with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod2.py"), "w", encoding='utf-8') as fp:
fp.write("print(42 * 42)\n") fp.write("print(42 * 42)\n")
with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp: with open(os.path.join(TESTFN2, "mod2.txt"), "w", encoding='utf-8') as fp:
fp.write("bla bla bla\n") fp.write("bla bla bla\n")
with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
@ -1268,10 +1268,10 @@ class PyZipFileTests(unittest.TestCase):
def test_write_python_directory_filtered(self): def test_write_python_directory_filtered(self):
os.mkdir(TESTFN2) os.mkdir(TESTFN2)
try: try:
with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod1.py"), "w", encoding='utf-8') as fp:
fp.write("print(42)\n") fp.write("print(42)\n")
with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod2.py"), "w", encoding='utf-8') as fp:
fp.write("print(42 * 42)\n") fp.write("print(42 * 42)\n")
with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
@ -1287,7 +1287,7 @@ class PyZipFileTests(unittest.TestCase):
def test_write_non_pyfile(self): def test_write_non_pyfile(self):
with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
with open(TESTFN, 'w') as f: with open(TESTFN, 'w', encoding='utf-8') as f:
f.write('most definitely not a python file') f.write('most definitely not a python file')
self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) self.assertRaises(RuntimeError, zipfp.writepy, TESTFN)
unlink(TESTFN) unlink(TESTFN)
@ -1295,7 +1295,7 @@ class PyZipFileTests(unittest.TestCase):
def test_write_pyfile_bad_syntax(self): def test_write_pyfile_bad_syntax(self):
os.mkdir(TESTFN2) os.mkdir(TESTFN2)
try: try:
with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod1.py"), "w", encoding='utf-8') as fp:
fp.write("Bad syntax in python file\n") fp.write("Bad syntax in python file\n")
with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
@ -1317,7 +1317,7 @@ class PyZipFileTests(unittest.TestCase):
def test_write_pathlike(self): def test_write_pathlike(self):
os.mkdir(TESTFN2) os.mkdir(TESTFN2)
try: try:
with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: with open(os.path.join(TESTFN2, "mod1.py"), "w", encoding='utf-8') as fp:
fp.write("print(42)\n") fp.write("print(42)\n")
with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
@ -1646,7 +1646,7 @@ class OtherTests(unittest.TestCase):
# On Windows, this causes the os.unlink() call to fail because the # On Windows, this causes the os.unlink() call to fail because the
# underlying file is still open. This is SF bug #412214. # underlying file is still open. This is SF bug #412214.
# #
with open(TESTFN, "w") as fp: with open(TESTFN, "w", encoding="utf-8") as fp:
fp.write("this is not a legal zip file\n") fp.write("this is not a legal zip file\n")
try: try:
zf = zipfile.ZipFile(TESTFN) zf = zipfile.ZipFile(TESTFN)
@ -1656,7 +1656,7 @@ class OtherTests(unittest.TestCase):
def test_is_zip_erroneous_file(self): def test_is_zip_erroneous_file(self):
"""Check that is_zipfile() correctly identifies non-zip files.""" """Check that is_zipfile() correctly identifies non-zip files."""
# - passing a filename # - passing a filename
with open(TESTFN, "w") as fp: with open(TESTFN, "w", encoding='utf-8') as fp:
fp.write("this is not a legal zip file\n") fp.write("this is not a legal zip file\n")
self.assertFalse(zipfile.is_zipfile(TESTFN)) self.assertFalse(zipfile.is_zipfile(TESTFN))
# - passing a path-like object # - passing a path-like object
@ -1719,11 +1719,11 @@ class OtherTests(unittest.TestCase):
self.assertRaises(OSError, zipfile.ZipFile, TESTFN) self.assertRaises(OSError, zipfile.ZipFile, TESTFN)
def test_empty_file_raises_BadZipFile(self): def test_empty_file_raises_BadZipFile(self):
f = open(TESTFN, 'w') f = open(TESTFN, 'w', encoding='utf-8')
f.close() f.close()
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN) self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
with open(TESTFN, 'w') as fp: with open(TESTFN, 'w', encoding='utf-8') as fp:
fp.write("short file") fp.write("short file")
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN) self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
@ -1741,7 +1741,7 @@ class OtherTests(unittest.TestCase):
self.assertRaises(ValueError, zipf.open, "foo.txt") self.assertRaises(ValueError, zipf.open, "foo.txt")
self.assertRaises(ValueError, zipf.testzip) self.assertRaises(ValueError, zipf.testzip)
self.assertRaises(ValueError, zipf.writestr, "bogus.txt", "bogus") self.assertRaises(ValueError, zipf.writestr, "bogus.txt", "bogus")
with open(TESTFN, 'w') as f: with open(TESTFN, 'w', encoding='utf-8') as f:
f.write('zipfile test data') f.write('zipfile test data')
self.assertRaises(ValueError, zipf.write, TESTFN) self.assertRaises(ValueError, zipf.write, TESTFN)
@ -1911,7 +1911,7 @@ class OtherTests(unittest.TestCase):
# Issue 1710703: Check that opening a file with less than 22 bytes # Issue 1710703: Check that opening a file with less than 22 bytes
# raises a BadZipFile exception (rather than the previously unhelpful # raises a BadZipFile exception (rather than the previously unhelpful
# OSError) # OSError)
f = open(TESTFN, 'w') f = open(TESTFN, 'w', encoding='utf-8')
f.close() f.close()
self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN, 'r') self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN, 'r')
@ -2532,7 +2532,7 @@ class TestsWithMultipleOpens(unittest.TestCase):
zipf.read('ones') zipf.read('ones')
with zipf.open('ones') as zopen1: with zipf.open('ones') as zopen1:
pass pass
with open(os.devnull) as f: with open(os.devnull, "rb") as f:
self.assertLess(f.fileno(), 100) self.assertLess(f.fileno(), 100)
def test_write_while_reading(self): def test_write_while_reading(self):
@ -2695,11 +2695,11 @@ class CommandLineTest(unittest.TestCase):
@requires_zlib() @requires_zlib()
def test_create_command(self): def test_create_command(self):
self.addCleanup(unlink, TESTFN) self.addCleanup(unlink, TESTFN)
with open(TESTFN, 'w') as f: with open(TESTFN, 'w', encoding='utf-8') as f:
f.write('test 1') f.write('test 1')
os.mkdir(TESTFNDIR) os.mkdir(TESTFNDIR)
self.addCleanup(rmtree, TESTFNDIR) self.addCleanup(rmtree, TESTFNDIR)
with open(os.path.join(TESTFNDIR, 'file.txt'), 'w') as f: with open(os.path.join(TESTFNDIR, 'file.txt'), 'w', encoding='utf-8') as f:
f.write('test 2') f.write('test 2')
files = [TESTFN, TESTFNDIR] files = [TESTFN, TESTFNDIR]
namelist = [TESTFN, TESTFNDIR + '/', TESTFNDIR + '/file.txt'] namelist = [TESTFN, TESTFNDIR + '/', TESTFNDIR + '/file.txt']
@ -2911,7 +2911,7 @@ class TestPath(unittest.TestCase):
def test_open(self, alpharep): def test_open(self, alpharep):
root = zipfile.Path(alpharep) root = zipfile.Path(alpharep)
a, b, g = root.iterdir() a, b, g = root.iterdir()
with a.open() as strm: with a.open(encoding="utf-8") as strm:
data = strm.read() data = strm.read()
assert data == "content of a" assert data == "content of a"
@ -2923,7 +2923,7 @@ class TestPath(unittest.TestCase):
zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w')) zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w'))
with zf.joinpath('file.bin').open('wb') as strm: with zf.joinpath('file.bin').open('wb') as strm:
strm.write(b'binary contents') strm.write(b'binary contents')
with zf.joinpath('file.txt').open('w') as strm: with zf.joinpath('file.txt').open('w', encoding="utf-8") as strm:
strm.write('text file') strm.write('text file')
def test_open_extant_directory(self): def test_open_extant_directory(self):
@ -2954,7 +2954,7 @@ class TestPath(unittest.TestCase):
def test_read(self, alpharep): def test_read(self, alpharep):
root = zipfile.Path(alpharep) root = zipfile.Path(alpharep)
a, b, g = root.iterdir() a, b, g = root.iterdir()
assert a.read_text() == "content of a" assert a.read_text(encoding="utf-8") == "content of a"
assert a.read_bytes() == b"content of a" assert a.read_bytes() == b"content of a"
@pass_alpharep @pass_alpharep
@ -2963,13 +2963,13 @@ class TestPath(unittest.TestCase):
a = root.joinpath("a.txt") a = root.joinpath("a.txt")
assert a.is_file() assert a.is_file()
e = root.joinpath("b").joinpath("d").joinpath("e.txt") e = root.joinpath("b").joinpath("d").joinpath("e.txt")
assert e.read_text() == "content of e" assert e.read_text(encoding="utf-8") == "content of e"
@pass_alpharep @pass_alpharep
def test_joinpath_multiple(self, alpharep): def test_joinpath_multiple(self, alpharep):
root = zipfile.Path(alpharep) root = zipfile.Path(alpharep)
e = root.joinpath("b", "d", "e.txt") e = root.joinpath("b", "d", "e.txt")
assert e.read_text() == "content of e" assert e.read_text(encoding="utf-8") == "content of e"
@pass_alpharep @pass_alpharep
def test_traverse_truediv(self, alpharep): def test_traverse_truediv(self, alpharep):
@ -2977,7 +2977,7 @@ class TestPath(unittest.TestCase):
a = root / "a.txt" a = root / "a.txt"
assert a.is_file() assert a.is_file()
e = root / "b" / "d" / "e.txt" e = root / "b" / "d" / "e.txt"
assert e.read_text() == "content of e" assert e.read_text(encoding="utf-8") == "content of e"
@pass_alpharep @pass_alpharep
def test_traverse_simplediv(self, alpharep): def test_traverse_simplediv(self, alpharep):
@ -3034,9 +3034,9 @@ class TestPath(unittest.TestCase):
alpharep.writestr('foo.txt', 'foo') alpharep.writestr('foo.txt', 'foo')
alpharep.writestr('bar/baz.txt', 'baz') alpharep.writestr('bar/baz.txt', 'baz')
assert any(child.name == 'foo.txt' for child in root.iterdir()) assert any(child.name == 'foo.txt' for child in root.iterdir())
assert (root / 'foo.txt').read_text() == 'foo' assert (root / 'foo.txt').read_text(encoding="utf-8") == 'foo'
(baz,) = (root / 'bar').iterdir() (baz,) = (root / 'bar').iterdir()
assert baz.read_text() == 'baz' assert baz.read_text(encoding="utf-8") == 'baz'
HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13 HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13
@ -3070,7 +3070,7 @@ class TestPath(unittest.TestCase):
alpharep = self.zipfile_ondisk(alpharep) alpharep = self.zipfile_ondisk(alpharep)
with zipfile.ZipFile(alpharep) as file: with zipfile.ZipFile(alpharep) as file:
for rep in range(2): for rep in range(2):
zipfile.Path(file, 'a.txt').read_text() zipfile.Path(file, 'a.txt').read_text(encoding="utf-8")
@pass_alpharep @pass_alpharep
def test_subclass(self, alpharep): def test_subclass(self, alpharep):

View file

@ -2334,6 +2334,8 @@ class Path:
if args or kwargs: if args or kwargs:
raise ValueError("encoding args invalid for binary operation") raise ValueError("encoding args invalid for binary operation")
return stream return stream
else:
kwargs["encoding"] = io.text_encoding(kwargs.get("encoding"))
return io.TextIOWrapper(stream, *args, **kwargs) return io.TextIOWrapper(stream, *args, **kwargs)
@property @property
@ -2345,6 +2347,7 @@ class Path:
return pathlib.Path(self.root.filename).joinpath(self.at) return pathlib.Path(self.root.filename).joinpath(self.at)
def read_text(self, *args, **kwargs): def read_text(self, *args, **kwargs):
kwargs["encoding"] = io.text_encoding(kwargs.get("encoding"))
with self.open('r', *args, **kwargs) as strm: with self.open('r', *args, **kwargs) as strm:
return strm.read() return strm.read()