Mercurial > cpython-lru_cache-weakref
comparison Python/pythonrun.c @ 86399:9cd88b39ef62
Issue #16129: Add `Py_SetStandardStreamEncoding`
This new pre-initialization API allows embedding
applications like Blender to force a particular
encoding and error handler for the standard IO streams.
Also refactors Modules/_testembed.c to let us start
testing multiple embedding scenarios.
(Initial patch by Bastien Montagne)
| author | Nick Coghlan <ncoghlan@gmail.com> |
|---|---|
| date | Thu, 17 Oct 2013 22:35:35 +1000 |
| parents | c13ef65f3dcf |
| children | 12d7b6171b28 |
comparison
equal
deleted
inserted
replaced
| 86398:4e2b08c78b3d | 86399:9cd88b39ef62 |
|---|---|
| 132 Py_IsInitialized(void) | 132 Py_IsInitialized(void) |
| 133 { | 133 { |
| 134 return initialized; | 134 return initialized; |
| 135 } | 135 } |
| 136 | 136 |
| 137 /* Helper to allow an embedding application to override the normal | |
| 138 * mechanism that attempts to figure out an appropriate IO encoding | |
| 139 */ | |
| 140 | |
| 141 static char *_Py_StandardStreamEncoding = NULL; | |
| 142 static char *_Py_StandardStreamErrors = NULL; | |
| 143 | |
| 144 int | |
| 145 Py_SetStandardStreamEncoding(const char *encoding, const char *errors) | |
| 146 { | |
| 147 if (Py_IsInitialized()) { | |
| 148 /* This is too late to have any effect */ | |
| 149 return -1; | |
| 150 } | |
| 151 if (encoding) { | |
| 152 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); | |
| 153 if (!_Py_StandardStreamEncoding) { | |
| 154 PyErr_NoMemory(); | |
| 155 return -1; | |
| 156 } | |
| 157 } | |
| 158 if (errors) { | |
| 159 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); | |
| 160 if (!_Py_StandardStreamErrors) { | |
| 161 if (_Py_StandardStreamEncoding) { | |
| 162 PyMem_RawFree(_Py_StandardStreamEncoding); | |
| 163 } | |
| 164 PyErr_NoMemory(); | |
| 165 return -1; | |
| 166 } | |
| 167 } | |
| 168 return 0; | |
| 169 } | |
| 170 | |
| 137 /* Global initializations. Can be undone by Py_Finalize(). Don't | 171 /* Global initializations. Can be undone by Py_Finalize(). Don't |
| 138 call this twice without an intervening Py_Finalize() call. When | 172 call this twice without an intervening Py_Finalize() call. When |
| 139 initializations fail, a fatal error is issued and the function does | 173 initializations fail, a fatal error is issued and the function does |
| 140 not return. On return, the first thread and interpreter state have | 174 not return. On return, the first thread and interpreter state have |
| 141 been created. | 175 been created. |
| 1086 Py_DECREF(wrapper); | 1120 Py_DECREF(wrapper); |
| 1087 goto error; | 1121 goto error; |
| 1088 } | 1122 } |
| 1089 Py_DECREF(wrapper); | 1123 Py_DECREF(wrapper); |
| 1090 | 1124 |
| 1091 pythonioencoding = Py_GETENV("PYTHONIOENCODING"); | 1125 encoding = _Py_StandardStreamEncoding; |
| 1092 encoding = errors = NULL; | 1126 errors = _Py_StandardStreamErrors; |
| 1093 if (pythonioencoding) { | 1127 if (!encoding || !errors) { |
| 1094 pythonioencoding = _PyMem_Strdup(pythonioencoding); | 1128 pythonioencoding = Py_GETENV("PYTHONIOENCODING"); |
| 1095 if (pythonioencoding == NULL) { | 1129 if (pythonioencoding) { |
| 1096 PyErr_NoMemory(); | 1130 char *err; |
| 1097 goto error; | 1131 pythonioencoding = _PyMem_Strdup(pythonioencoding); |
| 1098 } | 1132 if (pythonioencoding == NULL) { |
| 1099 errors = strchr(pythonioencoding, ':'); | 1133 PyErr_NoMemory(); |
| 1100 if (errors) { | 1134 goto error; |
| 1101 *errors = '\0'; | 1135 } |
| 1102 errors++; | 1136 err = strchr(pythonioencoding, ':'); |
| 1103 if (!*errors) | 1137 if (err) { |
| 1104 errors = NULL; | 1138 *err = '\0'; |
| 1105 } | 1139 err++; |
| 1106 if (*pythonioencoding) | 1140 if (*err && !errors) { |
| 1107 encoding = pythonioencoding; | 1141 errors = err; |
| 1142 } | |
| 1143 } | |
| 1144 if (*pythonioencoding && !encoding) { | |
| 1145 encoding = pythonioencoding; | |
| 1146 } | |
| 1147 } | |
| 1108 } | 1148 } |
| 1109 | 1149 |
| 1110 /* Set sys.stdin */ | 1150 /* Set sys.stdin */ |
| 1111 fd = fileno(stdin); | 1151 fd = fileno(stdin); |
| 1112 /* Under some conditions stdin, stdout and stderr may not be connected | 1152 /* Under some conditions stdin, stdout and stderr may not be connected |
| 1182 if (0) { | 1222 if (0) { |
| 1183 error: | 1223 error: |
| 1184 status = -1; | 1224 status = -1; |
| 1185 } | 1225 } |
| 1186 | 1226 |
| 1227 /* We won't need them anymore. */ | |
| 1228 if (_Py_StandardStreamEncoding) { | |
| 1229 PyMem_RawFree(_Py_StandardStreamEncoding); | |
| 1230 _Py_StandardStreamEncoding = NULL; | |
| 1231 } | |
| 1232 if (_Py_StandardStreamErrors) { | |
| 1233 PyMem_RawFree(_Py_StandardStreamErrors); | |
| 1234 _Py_StandardStreamErrors = NULL; | |
| 1235 } | |
| 1187 PyMem_Free(pythonioencoding); | 1236 PyMem_Free(pythonioencoding); |
| 1188 Py_XDECREF(bimod); | 1237 Py_XDECREF(bimod); |
| 1189 Py_XDECREF(iomod); | 1238 Py_XDECREF(iomod); |
| 1190 return status; | 1239 return status; |
| 1191 } | 1240 } |
