@@ -132,10 +132,19 @@ Py_InitializeEx(int install_sigs)
132132 PyThreadState * tstate ;
133133 PyObject * bimod , * sysmod ;
134134 char * p ;
135+ char * icodeset ; /* On Windows, input codeset may theoretically
136+ differ from output codeset. */
137+ char * codeset = NULL ;
138+ char * errors = NULL ;
139+ int free_codeset = 0 ;
140+ int overridden = 0 ;
135141#if defined(Py_USING_UNICODE ) && defined(HAVE_LANGINFO_H ) && defined(CODESET )
136- char * codeset ;
137- char * saved_locale ;
142+ char * saved_locale , * loc_codeset ;
138143 PyObject * sys_stream , * sys_isatty ;
144+ #endif
145+ #ifdef MS_WINDOWS
146+ char ibuf [128 ];
147+ char buf [128 ];
139148#endif
140149 extern void _Py_ReadyTypes (void );
141150
@@ -238,38 +247,75 @@ Py_InitializeEx(int install_sigs)
238247 _PyGILState_Init (interp , tstate );
239248#endif /* WITH_THREAD */
240249
250+ if ((p = Py_GETENV ("PYTHONIOENCODING" )) && * p != '\0' ) {
251+ p = icodeset = codeset = strdup (p );
252+ free_codeset = 1 ;
253+ errors = strchr (p , ':' );
254+ if (errors ) {
255+ * errors = '\0' ;
256+ errors ++ ;
257+ }
258+ overridden = 1 ;
259+ }
260+
241261#if defined(Py_USING_UNICODE ) && defined(HAVE_LANGINFO_H ) && defined(CODESET )
242262 /* On Unix, set the file system encoding according to the
243263 user's preference, if the CODESET names a well-known
244264 Python codec, and Py_FileSystemDefaultEncoding isn't
245265 initialized by other means. Also set the encoding of
246- stdin and stdout if these are terminals. */
247-
248- saved_locale = strdup (setlocale (LC_CTYPE , NULL ));
249- setlocale (LC_CTYPE , "" );
250- codeset = nl_langinfo (CODESET );
251- if (codeset && * codeset ) {
252- PyObject * enc = PyCodec_Encoder (codeset );
253- if (enc ) {
254- codeset = strdup (codeset );
255- Py_DECREF (enc );
256- } else {
257- codeset = NULL ;
258- PyErr_Clear ();
266+ stdin and stdout if these are terminals, unless overridden. */
267+
268+ if (!overridden || !Py_FileSystemDefaultEncoding ) {
269+ saved_locale = strdup (setlocale (LC_CTYPE , NULL ));
270+ setlocale (LC_CTYPE , "" );
271+ loc_codeset = nl_langinfo (CODESET );
272+ if (loc_codeset && * loc_codeset ) {
273+ PyObject * enc = PyCodec_Encoder (loc_codeset );
274+ if (enc ) {
275+ loc_codeset = strdup (loc_codeset );
276+ Py_DECREF (enc );
277+ } else {
278+ loc_codeset = NULL ;
279+ PyErr_Clear ();
280+ }
281+ } else
282+ loc_codeset = NULL ;
283+ setlocale (LC_CTYPE , saved_locale );
284+ free (saved_locale );
285+
286+ if (!overridden ) {
287+ codeset = icodeset = loc_codeset ;
288+ free_codeset = 1 ;
289+ }
290+
291+ /* Initialize Py_FileSystemDefaultEncoding from
292+ locale even if PYTHONIOENCODING is set. */
293+ if (!Py_FileSystemDefaultEncoding ) {
294+ Py_FileSystemDefaultEncoding = loc_codeset ;
295+ if (!overridden )
296+ free_codeset = 0 ;
259297 }
260- } else
261- codeset = NULL ;
262- setlocale (LC_CTYPE , saved_locale );
263- free (saved_locale );
298+ }
299+ #endif
300+
301+ #ifdef MS_WINDOWS
302+ if (!overridden ) {
303+ icodeset = ibuf ;
304+ encoding = buf ;
305+ sprintf (ibuf , "cp%d" , GetConsoleCP ());
306+ sprintf (buf , "cp%d" , GetConsoleOutputCP ());
307+ }
308+ #endif
264309
265310 if (codeset ) {
266311 sys_stream = PySys_GetObject ("stdin" );
267312 sys_isatty = PyObject_CallMethod (sys_stream , "isatty" , "" );
268313 if (!sys_isatty )
269314 PyErr_Clear ();
270- if (sys_isatty && PyObject_IsTrue (sys_isatty ) &&
315+ if ((overridden ||
316+ (sys_isatty && PyObject_IsTrue (sys_isatty ))) &&
271317 PyFile_Check (sys_stream )) {
272- if (!PyFile_SetEncoding (sys_stream , codeset ))
318+ if (!PyFile_SetEncodingAndErrors (sys_stream , icodeset , errors ))
273319 Py_FatalError ("Cannot set codeset of stdin" );
274320 }
275321 Py_XDECREF (sys_isatty );
@@ -278,9 +324,10 @@ Py_InitializeEx(int install_sigs)
278324 sys_isatty = PyObject_CallMethod (sys_stream , "isatty" , "" );
279325 if (!sys_isatty )
280326 PyErr_Clear ();
281- if (sys_isatty && PyObject_IsTrue (sys_isatty ) &&
327+ if ((overridden ||
328+ (sys_isatty && PyObject_IsTrue (sys_isatty ))) &&
282329 PyFile_Check (sys_stream )) {
283- if (!PyFile_SetEncoding (sys_stream , codeset ))
330+ if (!PyFile_SetEncodingAndErrors (sys_stream , codeset , errors ))
284331 Py_FatalError ("Cannot set codeset of stdout" );
285332 }
286333 Py_XDECREF (sys_isatty );
@@ -289,19 +336,17 @@ Py_InitializeEx(int install_sigs)
289336 sys_isatty = PyObject_CallMethod (sys_stream , "isatty" , "" );
290337 if (!sys_isatty )
291338 PyErr_Clear ();
292- if (sys_isatty && PyObject_IsTrue (sys_isatty ) &&
339+ if ((overridden ||
340+ (sys_isatty && PyObject_IsTrue (sys_isatty ))) &&
293341 PyFile_Check (sys_stream )) {
294- if (!PyFile_SetEncoding (sys_stream , codeset ))
342+ if (!PyFile_SetEncodingAndErrors (sys_stream , codeset , errors ))
295343 Py_FatalError ("Cannot set codeset of stderr" );
296344 }
297345 Py_XDECREF (sys_isatty );
298346
299- if (!Py_FileSystemDefaultEncoding )
300- Py_FileSystemDefaultEncoding = codeset ;
301- else
347+ if (free_codeset )
302348 free (codeset );
303349 }
304- #endif
305350}
306351
307352void
0 commit comments