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 }