Skip to content

Commit

Permalink
Issue #25339: PYTHONIOENCODING now has priority over locale in settin…
Browse files Browse the repository at this point in the history
…g the

error handler for stdin and stdout.
  • Loading branch information
serhiy-storchaka committed Apr 10, 2016
1 parent 731b1b1 commit fc43511
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
27 changes: 23 additions & 4 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,10 @@ def c_locale_get_error_handler(self, isolated=False, encoding=None):
args = [sys.executable, "-c", code]
if isolated:
args.append("-I")
elif encoding:
if encoding is not None:
env['PYTHONIOENCODING'] = encoding
else:
env.pop('PYTHONIOENCODING', None)
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand All @@ -709,14 +711,31 @@ def test_c_locale_surrogateescape(self):
'stderr: backslashreplace\n')

# 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,
'stdin: strict\n'
'stdout: strict\n'
'stdin: ignore\n'
'stdout: ignore\n'
'stderr: backslashreplace\n')

# force the encoding
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,
'stdin: surrogateescape\n'
'stdout: surrogateescape\n'
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Release date: tba
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.
Affected classes are generic sequence iterators, iterators of str, bytes,
bytearray, list, tuple, set, frozenset, dict, OrderedDict, corresponding
Expand Down
19 changes: 9 additions & 10 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1135,15 +1135,6 @@ initstdio(void)
encoding = _Py_StandardStreamEncoding;
errors = _Py_StandardStreamErrors;
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");
if (pythonioencoding) {
char *err;
Expand All @@ -1156,14 +1147,22 @@ initstdio(void)
if (err) {
*err = '\0';
err++;
if (*err && !_Py_StandardStreamErrors) {
if (*err && !errors) {
errors = err;
}
}
if (*pythonioencoding && !encoding) {
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 */
Expand Down

0 comments on commit fc43511

Please sign in to comment.