diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-06-01 07:20:46 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-06-01 07:20:46 (GMT) |
commit | 99815892f685e9ab20dfdade9c1e8a295139140c (patch) | |
tree | 92d2aeaee0a925df71471b296c5fa7ff28a451b8 /Python | |
parent | 7f7ca35f5bf22b698135de62d2179a13f5c94c7f (diff) | |
download | cpython-99815892f685e9ab20dfdade9c1e8a295139140c.zip cpython-99815892f685e9ab20dfdade9c1e8a295139140c.tar.gz cpython-99815892f685e9ab20dfdade9c1e8a295139140c.tar.bz2 |
New environment variable PYTHONIOENCODING.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pythonrun.c | 103 | ||||
-rw-r--r-- | Python/sysmodule.c | 20 |
2 files changed, 74 insertions, 49 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 6a9cb25..c30bf65 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -132,11 +132,20 @@ Py_InitializeEx(int install_sigs) PyThreadState *tstate; PyObject *bimod, *sysmod; char *p; + char *icodeset; /* On Windows, input codeset may theoretically + differ from output codeset. */ + char *codeset = NULL; + char *errors = NULL; + int free_codeset = 0; + int overridden = 0; #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) - char *codeset; - char *saved_locale; + char *saved_locale, *loc_codeset; PyObject *sys_stream, *sys_isatty; #endif +#ifdef MS_WINDOWS + char ibuf[128]; + char buf[128]; +#endif extern void _Py_ReadyTypes(void); if (initialized) @@ -238,38 +247,75 @@ Py_InitializeEx(int install_sigs) _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ + if ((p = Py_GETENV("PYTHONIOENCODING")) && *p != '\0') { + p = icodeset = codeset = strdup(p); + free_codeset = 1; + errors = strchr(p, ':'); + if (errors) { + *errors = '\0'; + errors++; + } + overridden = 1; + } + #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) /* On Unix, set the file system encoding according to the user's preference, if the CODESET names a well-known Python codec, and Py_FileSystemDefaultEncoding isn't initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - - saved_locale = strdup(setlocale(LC_CTYPE, NULL)); - setlocale(LC_CTYPE, ""); - codeset = nl_langinfo(CODESET); - if (codeset && *codeset) { - PyObject *enc = PyCodec_Encoder(codeset); - if (enc) { - codeset = strdup(codeset); - Py_DECREF(enc); - } else { - codeset = NULL; - PyErr_Clear(); + stdin and stdout if these are terminals, unless overridden. */ + + if (!overridden || !Py_FileSystemDefaultEncoding) { + saved_locale = strdup(setlocale(LC_CTYPE, NULL)); + setlocale(LC_CTYPE, ""); + loc_codeset = nl_langinfo(CODESET); + if (loc_codeset && *loc_codeset) { + PyObject *enc = PyCodec_Encoder(loc_codeset); + if (enc) { + loc_codeset = strdup(loc_codeset); + Py_DECREF(enc); + } else { + loc_codeset = NULL; + PyErr_Clear(); + } + } else + loc_codeset = NULL; + setlocale(LC_CTYPE, saved_locale); + free(saved_locale); + + if (!overridden) { + codeset = icodeset = loc_codeset; + free_codeset = 1; + } + + /* Initialize Py_FileSystemDefaultEncoding from + locale even if PYTHONIOENCODING is set. */ + if (!Py_FileSystemDefaultEncoding) { + Py_FileSystemDefaultEncoding = loc_codeset; + if (!overridden) + free_codeset = 0; } - } else - codeset = NULL; - setlocale(LC_CTYPE, saved_locale); - free(saved_locale); + } +#endif + +#ifdef MS_WINDOWS + if (!overridden) { + icodeset = ibuf; + encoding = buf; + sprintf(ibuf, "cp%d", GetConsoleCP()); + sprintf(buf, "cp%d", GetConsoleOutputCP()); + } +#endif if (codeset) { sys_stream = PySys_GetObject("stdin"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); - if(sys_isatty && PyObject_IsTrue(sys_isatty) && + if ((overridden || + (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { - if (!PyFile_SetEncoding(sys_stream, codeset)) + if (!PyFile_SetEncodingAndErrors(sys_stream, icodeset, errors)) Py_FatalError("Cannot set codeset of stdin"); } Py_XDECREF(sys_isatty); @@ -278,9 +324,10 @@ Py_InitializeEx(int install_sigs) sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); - if(sys_isatty && PyObject_IsTrue(sys_isatty) && + if ((overridden || + (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { - if (!PyFile_SetEncoding(sys_stream, codeset)) + if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stdout"); } Py_XDECREF(sys_isatty); @@ -289,19 +336,17 @@ Py_InitializeEx(int install_sigs) sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); - if(sys_isatty && PyObject_IsTrue(sys_isatty) && + if((overridden || + (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { - if (!PyFile_SetEncoding(sys_stream, codeset)) + if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stderr"); } Py_XDECREF(sys_isatty); - if (!Py_FileSystemDefaultEncoding) - Py_FileSystemDefaultEncoding = codeset; - else + if (free_codeset) free(codeset); } -#endif } void diff --git a/Python/sysmodule.c b/Python/sysmodule.c index b248429..e4fcc50 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1232,9 +1232,6 @@ _PySys_Init(void) PyObject *m, *v, *sysdict; PyObject *sysin, *sysout, *syserr; char *s; -#ifdef MS_WINDOWS - char buf[128]; -#endif m = Py_InitModule3("sys", sys_methods, sys_doc); if (m == NULL) @@ -1272,23 +1269,6 @@ _PySys_Init(void) syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush); if (PyErr_Occurred()) return NULL; -#ifdef MS_WINDOWS - if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) { - sprintf(buf, "cp%d", GetConsoleCP()); - if (!PyFile_SetEncoding(sysin, buf)) - return NULL; - } - if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) { - sprintf(buf, "cp%d", GetConsoleOutputCP()); - if (!PyFile_SetEncoding(sysout, buf)) - return NULL; - } - if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) { - sprintf(buf, "cp%d", GetConsoleOutputCP()); - if (!PyFile_SetEncoding(syserr, buf)) - return NULL; - } -#endif PyDict_SetItemString(sysdict, "stdin", sysin); PyDict_SetItemString(sysdict, "stdout", sysout); |