Mercurial > cpython-lru_cache-weakref
diff Python/pythonrun.c @ 64151:687cc854cb4b
Issue #8622: Add PYTHONFSENCODING environment variable to override the
filesystem encoding.
initfsencoding() displays also a better error message if get_codeset() failed.
| author | Victor Stinner <victor.stinner@haypocalc.com> |
|---|---|
| date | Wed, 18 Aug 2010 21:23:25 +0000 |
| parents | 686b18bffb86 |
| children | 557e2537c9ae |
line wrap: on
line diff
--- a/Python/pythonrun.c Wed Aug 18 21:12:52 2010 +0000 +++ b/Python/pythonrun.c Wed Aug 18 21:23:25 2010 +0000 @@ -134,18 +134,13 @@ return flag; } -#if defined(HAVE_LANGINFO_H) && defined(CODESET) static char* -get_codeset(void) +get_codec_name(const char *encoding) { - char* codeset, *name_str; + char *name_utf8, *name_str; PyObject *codec, *name = NULL; - codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') - return NULL; - - codec = _PyCodec_Lookup(codeset); + codec = _PyCodec_Lookup(encoding); if (!codec) goto error; @@ -154,18 +149,34 @@ if (!name) goto error; - name_str = _PyUnicode_AsString(name); + name_utf8 = _PyUnicode_AsString(name); if (name == NULL) goto error; - codeset = strdup(name_str); + name_str = strdup(name_utf8); Py_DECREF(name); - return codeset; + if (name_str == NULL) { + PyErr_NoMemory(); + return NULL; + } + return name_str; error: Py_XDECREF(codec); Py_XDECREF(name); return NULL; } + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) +static char* +get_codeset(void) +{ + char* codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); + return NULL; + } + return get_codec_name(codeset); +} #endif void @@ -706,25 +717,35 @@ { PyObject *codec; #if defined(HAVE_LANGINFO_H) && defined(CODESET) - char *codeset; + char *codeset = NULL; if (Py_FileSystemDefaultEncoding == NULL) { - /* 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. */ - codeset = get_codeset(); + const char *env_encoding = Py_GETENV("PYTHONFSENCODING"); + if (env_encoding != NULL) { + codeset = get_codec_name(env_encoding); + if (!codeset) { + fprintf(stderr, "PYTHONFSENCODING is not a valid encoding:\n"); + PyErr_Print(); + } + } + if (!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. */ + codeset = get_codeset(); + } if (codeset != NULL) { Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; return; + } else { + fprintf(stderr, "Unable to get the locale encoding:\n"); + PyErr_Print(); } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); + fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n"); Py_FileSystemDefaultEncoding = "utf-8"; Py_HasFileSystemDefaultEncoding = 1; }
