Issue #8622: Add PYTHONFSENCODING environment variable to override the

filesystem encoding.

initfsencoding() displays also a better error message if get_codeset() failed.
This commit is contained in:
Victor Stinner 2010-08-18 21:23:25 +00:00
parent 56ab01b66a
commit 94908bbc15
7 changed files with 93 additions and 34 deletions

View file

@ -134,18 +134,13 @@ add_flag(int flag, const char *envs)
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 @@ get_codeset(void)
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 @@ initfsencoding(void)
{
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;
}