Commit bf28d2dc authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.

parent 187b0630
...@@ -538,13 +538,16 @@ conflict. ...@@ -538,13 +538,16 @@ conflict.
.. envvar:: PYTHONIOENCODING .. envvar:: PYTHONIOENCODING
If this is set before running the interpreter, it overrides the encoding used If this is set before running the interpreter, it overrides the encoding used
for stdin/stdout/stderr, in the syntax ``encodingname:errorhandler``. The for stdin/stdout/stderr, in the syntax ``encodingname:errorhandler``. Both
``:errorhandler`` part is optional and has the same meaning as in the ``encodingname`` and the ``:errorhandler`` parts are optional and have
:func:`str.encode`. the same meaning as in :func:`str.encode`.
For stderr, the ``:errorhandler`` part is ignored; the handler will always be For stderr, the ``:errorhandler`` part is ignored; the handler will always be
``'backslashreplace'``. ``'backslashreplace'``.
.. versionchanged:: 3.4
The ``encodingname`` part is now optional.
.. envvar:: PYTHONNOUSERSITE .. envvar:: PYTHONNOUSERSITE
......
...@@ -544,6 +544,42 @@ class SysModuleTest(unittest.TestCase): ...@@ -544,6 +544,42 @@ class SysModuleTest(unittest.TestCase):
out = p.communicate()[0].strip() out = p.communicate()[0].strip()
self.assertEqual(out, b'?') self.assertEqual(out, b'?')
env["PYTHONIOENCODING"] = "ascii"
p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=env)
out, err = p.communicate()
self.assertEqual(out, b'')
self.assertIn(b'UnicodeEncodeError:', err)
self.assertIn(rb"'\xa2'", err)
env["PYTHONIOENCODING"] = "ascii:"
p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=env)
out, err = p.communicate()
self.assertEqual(out, b'')
self.assertIn(b'UnicodeEncodeError:', err)
self.assertIn(rb"'\xa2'", err)
env["PYTHONIOENCODING"] = ":surrogateescape"
p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xdcbd))'],
stdout=subprocess.PIPE, env=env)
out = p.communicate()[0].strip()
self.assertEqual(out, b'\xbd')
@unittest.skipUnless(test.support.FS_NONASCII,
'requires OS support of non-ASCII encodings')
def test_ioencoding_nonascii(self):
env = dict(os.environ)
env["PYTHONIOENCODING"] = ""
p = subprocess.Popen([sys.executable, "-c",
'print(%a)' % test.support.FS_NONASCII],
stdout=subprocess.PIPE, env=env)
out = p.communicate()[0].strip()
self.assertEqual(out, os.fsencode(test.support.FS_NONASCII))
@unittest.skipIf(sys.base_prefix != sys.prefix, @unittest.skipIf(sys.base_prefix != sys.prefix,
'Test is not venv-compatible') 'Test is not venv-compatible')
def test_executable(self): def test_executable(self):
......
...@@ -7,6 +7,8 @@ Projected Release date: 2013-09-29 ...@@ -7,6 +7,8 @@ Projected Release date: 2013-09-29
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.
Library Library
------- -------
......
...@@ -1056,7 +1056,7 @@ initstdio(void) ...@@ -1056,7 +1056,7 @@ initstdio(void)
PyObject *std = NULL; PyObject *std = NULL;
int status = 0, fd; int status = 0, fd;
PyObject * encoding_attr; PyObject * encoding_attr;
char *encoding = NULL, *errors; char *pythonioencoding = NULL, *encoding, *errors;
/* Hack to avoid a nasty recursion issue when Python is invoked /* Hack to avoid a nasty recursion issue when Python is invoked
in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
...@@ -1088,19 +1088,23 @@ initstdio(void) ...@@ -1088,19 +1088,23 @@ initstdio(void)
} }
Py_DECREF(wrapper); Py_DECREF(wrapper);
encoding = Py_GETENV("PYTHONIOENCODING"); pythonioencoding = Py_GETENV("PYTHONIOENCODING");
errors = NULL; encoding = errors = NULL;
if (encoding) { if (pythonioencoding) {
encoding = _PyMem_Strdup(encoding); pythonioencoding = _PyMem_Strdup(pythonioencoding);
if (encoding == NULL) { if (pythonioencoding == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
goto error; goto error;
} }
errors = strchr(encoding, ':'); errors = strchr(pythonioencoding, ':');
if (errors) { if (errors) {
*errors = '\0'; *errors = '\0';
errors++; errors++;
if (!*errors)
errors = NULL;
} }
if (*pythonioencoding)
encoding = pythonioencoding;
} }
/* Set sys.stdin */ /* Set sys.stdin */
...@@ -1180,7 +1184,7 @@ initstdio(void) ...@@ -1180,7 +1184,7 @@ initstdio(void)
status = -1; status = -1;
} }
PyMem_Free(encoding); PyMem_Free(pythonioencoding);
Py_XDECREF(bimod); Py_XDECREF(bimod);
Py_XDECREF(iomod); Py_XDECREF(iomod);
return status; return status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment