Commit fc435118 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #25339: PYTHONIOENCODING now has priority over locale in setting the

error handler for stdin and stdout.
parent 731b1b12
...@@ -691,8 +691,10 @@ class SysModuleTest(unittest.TestCase): ...@@ -691,8 +691,10 @@ class SysModuleTest(unittest.TestCase):
args = [sys.executable, "-c", code] args = [sys.executable, "-c", code]
if isolated: if isolated:
args.append("-I") args.append("-I")
elif encoding: if encoding is not None:
env['PYTHONIOENCODING'] = encoding env['PYTHONIOENCODING'] = encoding
else:
env.pop('PYTHONIOENCODING', None)
p = subprocess.Popen(args, p = subprocess.Popen(args,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
...@@ -709,14 +711,31 @@ class SysModuleTest(unittest.TestCase): ...@@ -709,14 +711,31 @@ class SysModuleTest(unittest.TestCase):
'stderr: backslashreplace\n') 'stderr: backslashreplace\n')
# replace the default error handler # replace the default error handler
out = self.c_locale_get_error_handler(encoding=':strict') out = self.c_locale_get_error_handler(encoding=':ignore')
self.assertEqual(out, self.assertEqual(out,
'stdin: strict\n' 'stdin: ignore\n'
'stdout: strict\n' 'stdout: ignore\n'
'stderr: backslashreplace\n') 'stderr: backslashreplace\n')
# force the encoding # force the encoding
out = self.c_locale_get_error_handler(encoding='iso8859-1') out = self.c_locale_get_error_handler(encoding='iso8859-1')
self.assertEqual(out,
'stdin: strict\n'
'stdout: strict\n'
'stderr: backslashreplace\n')
out = self.c_locale_get_error_handler(encoding='iso8859-1:')
self.assertEqual(out,
'stdin: strict\n'
'stdout: strict\n'
'stderr: backslashreplace\n')
# have no any effect
out = self.c_locale_get_error_handler(encoding=':')
self.assertEqual(out,
'stdin: surrogateescape\n'
'stdout: surrogateescape\n'
'stderr: backslashreplace\n')
out = self.c_locale_get_error_handler(encoding='')
self.assertEqual(out, self.assertEqual(out,
'stdin: surrogateescape\n' 'stdin: surrogateescape\n'
'stdout: surrogateescape\n' 'stdout: surrogateescape\n'
......
...@@ -10,6 +10,9 @@ Release date: tba ...@@ -10,6 +10,9 @@ Release date: tba
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #25339: PYTHONIOENCODING now has priority over locale in setting the
error handler for stdin and stdout.
- Issue #26494: Fixed crash on iterating exhausting iterators. - Issue #26494: Fixed crash on iterating exhausting iterators.
Affected classes are generic sequence iterators, iterators of str, bytes, Affected classes are generic sequence iterators, iterators of str, bytes,
bytearray, list, tuple, set, frozenset, dict, OrderedDict, corresponding bytearray, list, tuple, set, frozenset, dict, OrderedDict, corresponding
......
...@@ -1135,15 +1135,6 @@ initstdio(void) ...@@ -1135,15 +1135,6 @@ initstdio(void)
encoding = _Py_StandardStreamEncoding; encoding = _Py_StandardStreamEncoding;
errors = _Py_StandardStreamErrors; errors = _Py_StandardStreamErrors;
if (!encoding || !errors) { if (!encoding || !errors) {
if (!errors) {
/* When the LC_CTYPE locale is the POSIX locale ("C locale"),
stdin and stdout use the surrogateescape error handler by
default, instead of the strict error handler. */
char *loc = setlocale(LC_CTYPE, NULL);
if (loc != NULL && strcmp(loc, "C") == 0)
errors = "surrogateescape";
}
pythonioencoding = Py_GETENV("PYTHONIOENCODING"); pythonioencoding = Py_GETENV("PYTHONIOENCODING");
if (pythonioencoding) { if (pythonioencoding) {
char *err; char *err;
...@@ -1156,7 +1147,7 @@ initstdio(void) ...@@ -1156,7 +1147,7 @@ initstdio(void)
if (err) { if (err) {
*err = '\0'; *err = '\0';
err++; err++;
if (*err && !_Py_StandardStreamErrors) { if (*err && !errors) {
errors = err; errors = err;
} }
} }
...@@ -1164,6 +1155,14 @@ initstdio(void) ...@@ -1164,6 +1155,14 @@ initstdio(void)
encoding = pythonioencoding; encoding = pythonioencoding;
} }
} }
if (!errors && !(pythonioencoding && *pythonioencoding)) {
/* When the LC_CTYPE locale is the POSIX locale ("C locale"),
stdin and stdout use the surrogateescape error handler by
default, instead of the strict error handler. */
char *loc = setlocale(LC_CTYPE, NULL);
if (loc != NULL && strcmp(loc, "C") == 0)
errors = "surrogateescape";
}
} }
/* Set sys.stdin */ /* Set sys.stdin */
......
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