Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.
This commit is contained in:
parent
187b063005
commit
bf28d2dcad
@ -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):
|
|||||||
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
|
|||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user