(original) (raw)

changeset: 85673:c7fdb0637d0b user: Serhiy Storchaka storchaka@gmail.com date: Fri Sep 13 11:46:24 2013 +0300 files: Doc/using/cmdline.rst Lib/test/test_sys.py Misc/NEWS Python/pythonrun.c description: Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional. diff -r b85c9d2a5227 -r c7fdb0637d0b Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst Fri Sep 13 00:22:45 2013 -0700 +++ b/Doc/using/cmdline.rst Fri Sep 13 11:46:24 2013 +0300 @@ -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 -r b85c9d2a5227 -r c7fdb0637d0b Lib/test/test_sys.py --- a/Lib/test/test_sys.py Fri Sep 13 00:22:45 2013 -0700 +++ b/Lib/test/test_sys.py Fri Sep 13 11:46:24 2013 +0300 @@ -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 -r b85c9d2a5227 -r c7fdb0637d0b Misc/NEWS --- a/Misc/NEWS Fri Sep 13 00:22:45 2013 -0700 +++ b/Misc/NEWS Fri Sep 13 11:46:24 2013 +0300 @@ -7,6 +7,8 @@ Core and Builtins ----------------- +- Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional. + Library ------- diff -r b85c9d2a5227 -r c7fdb0637d0b Python/pythonrun.c --- a/Python/pythonrun.c Fri Sep 13 00:22:45 2013 -0700 +++ b/Python/pythonrun.c Fri Sep 13 11:46:24 2013 +0300 @@ -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; /storchaka@gmail.com