]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #25339: PYTHONIOENCODING now has priority over locale in setting the
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 10 Apr 2016 11:34:13 +0000 (14:34 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 10 Apr 2016 11:34:13 +0000 (14:34 +0300)
error handler for stdin and stdout.

Lib/test/test_sys.py
Misc/NEWS
Python/pylifecycle.c

index 6046671c9c381ac487d79723382dc2636010dcae..2aa16fc1e60485dd32db24b126abdc8be93d9266 100644 (file)
@@ -691,8 +691,10 @@ class SysModuleTest(unittest.TestCase):
         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,
@@ -709,14 +711,31 @@ class SysModuleTest(unittest.TestCase):
                          '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'
index 676f37e7e76b4db574867f7e35e60aa4eabe3253..2ce06204d970a81e2aab07dc3b9dff140204bc18 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
index 35ca88fd3b54043f0139841cd24acff0da30a858..ce52990496931ca13937dbfd3e7f8c1defec070e 100644 (file)
@@ -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;
@@ -1156,7 +1147,7 @@ initstdio(void)
             if (err) {
                 *err = '\0';
                 err++;
-                if (*err && !_Py_StandardStreamErrors) {
+                if (*err && !errors) {
                     errors = err;
                 }
             }
@@ -1164,6 +1155,14 @@ initstdio(void)
                 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 */