diff options
author | Gregory P. Smith <greg@krypto.org> | 2023-01-20 07:04:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-20 07:04:30 (GMT) |
commit | 5927013e47a8c63b70e104152351f3447baa819c (patch) | |
tree | 277eabd54cc4d1755178ff3ba3a8ea779d25528a /Lib/test/test_zipfile | |
parent | 9e025d305f159aebf01775ad1dc2817679f01aa9 (diff) | |
download | cpython-5927013e47a8c63b70e104152351f3447baa819c.zip cpython-5927013e47a8c63b70e104152351f3447baa819c.tar.gz cpython-5927013e47a8c63b70e104152351f3447baa819c.tar.bz2 |
gh-101144: Allow open and read_text encoding to be positional. (#101145)
The zipfile.Path open() and read_text() encoding parameter can be supplied as a positional argument without causing a TypeError again. 3.10.0b1 included a regression that made it keyword only.
Documentation update included as users writing code to be compatible with a wide range of versions will need to consider this for some time.
Diffstat (limited to 'Lib/test/test_zipfile')
-rw-r--r-- | Lib/test/test_zipfile/test_path.py | 74 |
1 files changed, 69 insertions, 5 deletions
diff --git a/Lib/test/test_zipfile/test_path.py b/Lib/test/test_zipfile/test_path.py index 02253c5..3086fd2 100644 --- a/Lib/test/test_zipfile/test_path.py +++ b/Lib/test/test_zipfile/test_path.py @@ -1,11 +1,12 @@ import io -import zipfile +import itertools import contextlib import pathlib -import unittest -import string import pickle -import itertools +import string +from test.support.script_helper import assert_python_ok +import unittest +import zipfile from ._test_params import parameterize, Invoked from ._functools import compose @@ -145,7 +146,69 @@ class TestPath(unittest.TestCase): a, b, g = root.iterdir() with a.open(encoding="utf-8") as strm: data = strm.read() - assert data == "content of a" + self.assertEqual(data, "content of a") + with a.open('r', "utf-8") as strm: # not a kw, no gh-101144 TypeError + data = strm.read() + self.assertEqual(data, "content of a") + + def test_open_encoding_utf16(self): + in_memory_file = io.BytesIO() + zf = zipfile.ZipFile(in_memory_file, "w") + zf.writestr("path/16.txt", "This was utf-16".encode("utf-16")) + zf.filename = "test_open_utf16.zip" + root = zipfile.Path(zf) + (path,) = root.iterdir() + u16 = path.joinpath("16.txt") + with u16.open('r', "utf-16") as strm: + data = strm.read() + self.assertEqual(data, "This was utf-16") + with u16.open(encoding="utf-16") as strm: + data = strm.read() + self.assertEqual(data, "This was utf-16") + + def test_open_encoding_errors(self): + in_memory_file = io.BytesIO() + zf = zipfile.ZipFile(in_memory_file, "w") + zf.writestr("path/bad-utf8.bin", b"invalid utf-8: \xff\xff.") + zf.filename = "test_read_text_encoding_errors.zip" + root = zipfile.Path(zf) + (path,) = root.iterdir() + u16 = path.joinpath("bad-utf8.bin") + + # encoding= as a positional argument for gh-101144. + data = u16.read_text("utf-8", errors="ignore") + self.assertEqual(data, "invalid utf-8: .") + with u16.open("r", "utf-8", errors="surrogateescape") as f: + self.assertEqual(f.read(), "invalid utf-8: \udcff\udcff.") + + # encoding= both positional and keyword is an error; gh-101144. + with self.assertRaisesRegex(TypeError, "encoding"): + data = u16.read_text("utf-8", encoding="utf-8") + + # both keyword arguments work. + with u16.open("r", encoding="utf-8", errors="strict") as f: + # error during decoding with wrong codec. + with self.assertRaises(UnicodeDecodeError): + f.read() + + def test_encoding_warnings(self): + """EncodingWarning must blame the read_text and open calls.""" + code = '''\ +import io, zipfile +with zipfile.ZipFile(io.BytesIO(), "w") as zf: + zf.filename = '<test_encoding_warnings in memory zip file>' + zf.writestr("path/file.txt", b"Spanish Inquisition") + root = zipfile.Path(zf) + (path,) = root.iterdir() + file_path = path.joinpath("file.txt") + unused = file_path.read_text() # should warn + file_path.open("r").close() # should warn +''' + proc = assert_python_ok('-X', 'warn_default_encoding', '-c', code) + warnings = proc.err.splitlines() + self.assertEqual(len(warnings), 2, proc.err) + self.assertRegex(warnings[0], rb"^<string>:8: EncodingWarning:") + self.assertRegex(warnings[1], rb"^<string>:9: EncodingWarning:") def test_open_write(self): """ @@ -187,6 +250,7 @@ class TestPath(unittest.TestCase): root = zipfile.Path(alpharep) a, b, g = root.iterdir() assert a.read_text(encoding="utf-8") == "content of a" + a.read_text("utf-8") # No positional arg TypeError per gh-101144. assert a.read_bytes() == b"content of a" @pass_alpharep |