comparison 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
comparison
equal deleted inserted replaced
64150:23a598c01911 64151:687cc854cb4b
132 if (flag < 1) 132 if (flag < 1)
133 flag = 1; 133 flag = 1;
134 return flag; 134 return flag;
135 } 135 }
136 136
137 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
138 static char* 137 static char*
139 get_codeset(void) 138 get_codec_name(const char *encoding)
140 { 139 {
141 char* codeset, *name_str; 140 char *name_utf8, *name_str;
142 PyObject *codec, *name = NULL; 141 PyObject *codec, *name = NULL;
143 142
144 codeset = nl_langinfo(CODESET); 143 codec = _PyCodec_Lookup(encoding);
145 if (!codeset || codeset[0] == '\0')
146 return NULL;
147
148 codec = _PyCodec_Lookup(codeset);
149 if (!codec) 144 if (!codec)
150 goto error; 145 goto error;
151 146
152 name = PyObject_GetAttrString(codec, "name"); 147 name = PyObject_GetAttrString(codec, "name");
153 Py_CLEAR(codec); 148 Py_CLEAR(codec);
154 if (!name) 149 if (!name)
155 goto error; 150 goto error;
156 151
157 name_str = _PyUnicode_AsString(name); 152 name_utf8 = _PyUnicode_AsString(name);
158 if (name == NULL) 153 if (name == NULL)
159 goto error; 154 goto error;
160 codeset = strdup(name_str); 155 name_str = strdup(name_utf8);
161 Py_DECREF(name); 156 Py_DECREF(name);
162 return codeset; 157 if (name_str == NULL) {
158 PyErr_NoMemory();
159 return NULL;
160 }
161 return name_str;
163 162
164 error: 163 error:
165 Py_XDECREF(codec); 164 Py_XDECREF(codec);
166 Py_XDECREF(name); 165 Py_XDECREF(name);
167 return NULL; 166 return NULL;
167 }
168
169 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
170 static char*
171 get_codeset(void)
172 {
173 char* codeset = nl_langinfo(CODESET);
174 if (!codeset || codeset[0] == '\0') {
175 PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty");
176 return NULL;
177 }
178 return get_codec_name(codeset);
168 } 179 }
169 #endif 180 #endif
170 181
171 void 182 void
172 Py_InitializeEx(int install_sigs) 183 Py_InitializeEx(int install_sigs)
704 static void 715 static void
705 initfsencoding(void) 716 initfsencoding(void)
706 { 717 {
707 PyObject *codec; 718 PyObject *codec;
708 #if defined(HAVE_LANGINFO_H) && defined(CODESET) 719 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
709 char *codeset; 720 char *codeset = NULL;
710 721
711 if (Py_FileSystemDefaultEncoding == NULL) { 722 if (Py_FileSystemDefaultEncoding == NULL) {
712 /* On Unix, set the file system encoding according to the 723 const char *env_encoding = Py_GETENV("PYTHONFSENCODING");
713 user's preference, if the CODESET names a well-known 724 if (env_encoding != NULL) {
714 Python codec, and Py_FileSystemDefaultEncoding isn't 725 codeset = get_codec_name(env_encoding);
715 initialized by other means. Also set the encoding of 726 if (!codeset) {
716 stdin and stdout if these are terminals. */ 727 fprintf(stderr, "PYTHONFSENCODING is not a valid encoding:\n");
717 codeset = get_codeset(); 728 PyErr_Print();
729 }
730 }
731 if (!codeset) {
732 /* On Unix, set the file system encoding according to the
733 user's preference, if the CODESET names a well-known
734 Python codec, and Py_FileSystemDefaultEncoding isn't
735 initialized by other means. Also set the encoding of
736 stdin and stdout if these are terminals. */
737 codeset = get_codeset();
738 }
718 if (codeset != NULL) { 739 if (codeset != NULL) {
719 Py_FileSystemDefaultEncoding = codeset; 740 Py_FileSystemDefaultEncoding = codeset;
720 Py_HasFileSystemDefaultEncoding = 0; 741 Py_HasFileSystemDefaultEncoding = 0;
721 return; 742 return;
743 } else {
744 fprintf(stderr, "Unable to get the locale encoding:\n");
745 PyErr_Print();
722 } 746 }
723 747
724 PyErr_Clear(); 748 fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n");
725 fprintf(stderr,
726 "Unable to get the locale encoding: "
727 "fallback to utf-8\n");
728 Py_FileSystemDefaultEncoding = "utf-8"; 749 Py_FileSystemDefaultEncoding = "utf-8";
729 Py_HasFileSystemDefaultEncoding = 1; 750 Py_HasFileSystemDefaultEncoding = 1;
730 } 751 }
731 #endif 752 #endif
732 753