summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInada Naoki <songofacandy@gmail.com>2021-03-31 05:26:08 (GMT)
committerGitHub <noreply@github.com>2021-03-31 05:26:08 (GMT)
commitff3c9739bd69aa8b58007e63c9e40e6708b4761e (patch)
tree8f2b09f576e0f8ddb79d0a1e412363cff697ced7
parent1b4a9c7956d5dc64f8002f62bf0faae2d1892f90 (diff)
downloadcpython-ff3c9739bd69aa8b58007e63c9e40e6708b4761e.zip
cpython-ff3c9739bd69aa8b58007e63c9e40e6708b4761e.tar.gz
cpython-ff3c9739bd69aa8b58007e63c9e40e6708b4761e.tar.bz2
bpo-43510: PEP 597: Accept `encoding="locale"` in binary mode (GH-25103)
It make `encoding="locale"` usable everywhere `encoding=None` is allowed.
-rw-r--r--Lib/_pyio.py2
-rw-r--r--Lib/test/test_io.py11
-rw-r--r--Modules/_io/_iomodule.c3
3 files changed, 14 insertions, 2 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 0f182d4..ba0b0a2 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -221,7 +221,7 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
raise ValueError("can't have read/write/append mode at once")
if not (creating or reading or writing or appending):
raise ValueError("must have exactly one of read/write/append mode")
- if binary and encoding is not None:
+ if binary and encoding is not None and encoding != "locale":
raise ValueError("binary mode doesn't take an encoding argument")
if binary and errors is not None:
raise ValueError("binary mode doesn't take an errors argument")
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index c731302..6a9ce39 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -531,6 +531,17 @@ class IOTest(unittest.TestCase):
self.assertRaises(OSError, obj.truncate)
self.assertRaises(OSError, obj.truncate, 0)
+ def test_open_binmode_encoding(self):
+ """open() raises ValueError when encoding is specified in bin mode"""
+ self.assertRaises(ValueError, self.open, os_helper.TESTFN,
+ "wb", encoding="utf-8")
+
+ # encoding=None and encoding="locale" is allowed.
+ with self.open(os_helper.TESTFN, "wb", encoding=None):
+ pass
+ with self.open(os_helper.TESTFN, "wb", encoding="locale"):
+ pass
+
def test_open_handles_NUL_chars(self):
fn_with_NUL = 'foo\0bar'
self.assertRaises(ValueError, self.open, fn_with_NUL, 'w')
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 652c2ce..c627ca2 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -346,7 +346,8 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
goto error;
}
- if (binary && encoding != NULL) {
+ if (binary && encoding != NULL
+ && strcmp(encoding, "locale") != 0) {
PyErr_SetString(PyExc_ValueError,
"binary mode doesn't take an encoding argument");
goto error;