From 0f5998911c0a39400a42bad781e84eba822fed38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Mon, 2 Jun 2008 11:13:03 +0000 Subject: Forward-port PYTHONIOENCODING. --- Doc/using/cmdline.rst | 7 +++++++ Lib/test/test_sys.py | 20 ++++++++++++++++++++ Modules/main.c | 1 + Python/pythonrun.c | 23 +++++++++++++++++------ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index ae661ce..a6a6ecf 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -467,6 +467,13 @@ if Python was configured with the :option:`--with-pydebug` build option. If set, Python will dump objects and reference counts still alive after shutting down the interpreter. +.. envvar:: PYTHONIOENCODING + + Overrides the encoding used for stdin/stdout/stderr, in the syntax + encodingname:errorhandler, with the :errors part being optional. + + .. versionadded:: 2.6 + .. envvar:: PYTHONMALLOCSTATS diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 231b460..e1bc98d 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -349,6 +349,26 @@ class SysModuleTest(unittest.TestCase): #self.assert_(r[0][1] > 100, r[0][1]) #self.assert_(r[0][2] > 100, r[0][2]) + def test_ioencoding(self): + import subprocess,os + env = dict(os.environ) + + # Test character: cent sign, encoded as 0x4A (ASCII J) in CP424, + # not representable in ASCII. + + env["PYTHONIOENCODING"] = "cp424" + p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'], + stdout = subprocess.PIPE, env=env) + out = p.stdout.read() + self.assertEqual(out, "\xa2\n".encode("cp424")) + + env["PYTHONIOENCODING"] = "ascii:replace" + p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'], + stdout = subprocess.PIPE, env=env) + out = p.stdout.read().strip() + self.assertEqual(out, b'?') + + def test_main(): test.support.run_unittest(SysModuleTest) diff --git a/Modules/main.c b/Modules/main.c index 27b8493..b762b0f 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -96,6 +96,7 @@ static char *usage_5 = "\ PYTHONHOME : alternate directory (or %c).\n\ The default module search path uses %s.\n\ PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\ +PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\ "; #ifndef MS_WINDOWS diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 2e93a3a..f2f14ed 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -701,6 +701,7 @@ initstdio(void) PyObject *std = NULL; int status = 0, fd; PyObject * encoding_attr; + char *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 */ @@ -730,6 +731,16 @@ initstdio(void) goto error; } + encoding = Py_GETENV("PYTHONIOENCODING"); + if (encoding) { + encoding = strdup(encoding); + errors = strchr(encoding, ':'); + if (errors) { + *errors = '\0'; + errors++; + } + } + /* Set sys.stdin */ fd = fileno(stdin); /* Under some conditions stdin, stdout and stderr may not be connected @@ -745,8 +756,8 @@ initstdio(void) #endif } else { - if (!(std = PyFile_FromFd(fd, "", "r", -1, NULL, NULL, - "\n", 0))) { + if (!(std = PyFile_FromFd(fd, "", "r", -1, encoding, + errors, "\n", 0))) { goto error; } } /* if (fd < 0) */ @@ -765,8 +776,8 @@ initstdio(void) #endif } else { - if (!(std = PyFile_FromFd(fd, "", "w", -1, NULL, NULL, - "\n", 0))) { + if (!(std = PyFile_FromFd(fd, "", "w", -1, encoding, + errors, "\n", 0))) { goto error; } } /* if (fd < 0) */ @@ -786,8 +797,8 @@ initstdio(void) #endif } else { - if (!(std = PyFile_FromFd(fd, "", "w", -1, NULL, NULL, - "\n", 0))) { + if (!(std = PyFile_FromFd(fd, "", "w", -1, encoding, + errors, "\n", 0))) { goto error; } } /* if (fd < 0) */ -- cgit v0.12