Mercurial > cpython-lru_cache-weakref
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 |
