[Python-checkins] cpython: Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.

serhiy.storchaka python-checkins at python.org
Fri Sep 13 10:46:52 CEST 2013


http://hg.python.org/cpython/rev/c7fdb0637d0b
changeset:   85673:c7fdb0637d0b
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Fri Sep 13 11:46:24 2013 +0300
summary:
  Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.

files:
  Doc/using/cmdline.rst |   9 +++++--
  Lib/test/test_sys.py  |  36 +++++++++++++++++++++++++++++++
  Misc/NEWS             |   2 +
  Python/pythonrun.c    |  20 ++++++++++------
  4 files changed, 56 insertions(+), 11 deletions(-)


diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -538,13 +538,16 @@
 .. envvar:: PYTHONIOENCODING
 
    If this is set before running the interpreter, it overrides the encoding used
-   for stdin/stdout/stderr, in the syntax ``encodingname:errorhandler``. The
-   ``:errorhandler`` part is optional and has the same meaning as in
-   :func:`str.encode`.
+   for stdin/stdout/stderr, in the syntax ``encodingname:errorhandler``.  Both
+   the ``encodingname`` and the ``:errorhandler`` parts are optional and have
+   the same meaning as in :func:`str.encode`.
 
    For stderr, the ``:errorhandler`` part is ignored; the handler will always be
    ``'backslashreplace'``.
 
+   .. versionchanged:: 3.4
+      The ``encodingname`` part is now optional.
+
 
 .. envvar:: PYTHONNOUSERSITE
 
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -544,6 +544,42 @@
         out = p.communicate()[0].strip()
         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,
                      'Test is not venv-compatible')
     def test_executable(self):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -7,6 +7,8 @@
 Core and Builtins
 -----------------
 
+- Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional.
+
 Library
 -------
 
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1056,7 +1056,7 @@
     PyObject *std = NULL;
     int status = 0, fd;
     PyObject * encoding_attr;
-    char *encoding = NULL, *errors;
+    char *pythonioencoding = NULL, *encoding, *errors;
 
     /* Hack to avoid a nasty recursion issue when Python is invoked
        in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
@@ -1088,19 +1088,23 @@
     }
     Py_DECREF(wrapper);
 
-    encoding = Py_GETENV("PYTHONIOENCODING");
-    errors = NULL;
-    if (encoding) {
-        encoding = _PyMem_Strdup(encoding);
-        if (encoding == NULL) {
+    pythonioencoding = Py_GETENV("PYTHONIOENCODING");
+    encoding = errors = NULL;
+    if (pythonioencoding) {
+        pythonioencoding = _PyMem_Strdup(pythonioencoding);
+        if (pythonioencoding == NULL) {
             PyErr_NoMemory();
             goto error;
         }
-        errors = strchr(encoding, ':');
+        errors = strchr(pythonioencoding, ':');
         if (errors) {
             *errors = '\0';
             errors++;
+            if (!*errors)
+                errors = NULL;
         }
+        if (*pythonioencoding)
+            encoding = pythonioencoding;
     }
 
     /* Set sys.stdin */
@@ -1180,7 +1184,7 @@
         status = -1;
     }
 
-    PyMem_Free(encoding);
+    PyMem_Free(pythonioencoding);
     Py_XDECREF(bimod);
     Py_XDECREF(iomod);
     return status;

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list