@@ -244,22 +244,26 @@ get_codec_name(const char *encoding)
244244 return NULL ;
245245}
246246
247- static char *
248- get_locale_encoding (void )
247+ static _PyInitError
248+ get_locale_encoding (char * * locale_encoding )
249249{
250- #if defined(HAVE_LANGINFO_H ) && defined(CODESET )
251- char * codeset = nl_langinfo (CODESET );
252- if (!codeset || codeset [0 ] == '\0' ) {
253- PyErr_SetString (PyExc_ValueError , "CODESET is not set or empty" );
254- return NULL ;
255- }
256- return get_codec_name (codeset );
250+ #ifdef MS_WINDOWS
251+ char encoding [20 ];
252+ PyOS_snprintf (encoding , sizeof (encoding ), "cp%d" , GetACP ());
257253#elif defined(__ANDROID__ )
258- return get_codec_name ( "UTF-8" ) ;
254+ const char * encoding = "UTF-8" ;
259255#else
260- PyErr_SetNone (PyExc_NotImplementedError );
261- return NULL ;
256+ const char * encoding = nl_langinfo (CODESET );
257+ if (!encoding || encoding [0 ] == '\0' ) {
258+ return _Py_INIT_USER_ERR ("failed to get the locale encoding: "
259+ "nl_langinfo(CODESET) failed" );
260+ }
262261#endif
262+ * locale_encoding = _PyMem_RawStrdup (encoding );
263+ if (* locale_encoding == NULL ) {
264+ return _Py_INIT_NO_MEMORY ();
265+ }
266+ return _Py_INIT_OK ();
263267}
264268
265269static _PyInitError
@@ -397,7 +401,7 @@ static _LocaleCoercionTarget _TARGET_LOCALES[] = {
397401};
398402
399403static const char *
400- get_default_standard_stream_error_handler (void )
404+ get_stdio_errors (void )
401405{
402406 const char * ctype_loc = setlocale (LC_CTYPE , NULL );
403407 if (ctype_loc != NULL ) {
@@ -417,8 +421,7 @@ get_default_standard_stream_error_handler(void)
417421#endif
418422 }
419423
420- /* Otherwise return NULL to request the typical default error handler */
421- return NULL ;
424+ return "strict" ;
422425}
423426
424427#ifdef PY_COERCE_C_LOCALE
@@ -1586,9 +1589,17 @@ initfsencoding(PyInterpreterState *interp)
15861589 Py_HasFileSystemDefaultEncoding = 1 ;
15871590 }
15881591 else {
1589- Py_FileSystemDefaultEncoding = get_locale_encoding ();
1592+ char * locale_encoding ;
1593+ _PyInitError err = get_locale_encoding (& locale_encoding );
1594+ if (_Py_INIT_FAILED (err )) {
1595+ return err ;
1596+ }
1597+
1598+ Py_FileSystemDefaultEncoding = get_codec_name (locale_encoding );
1599+ PyMem_RawFree (locale_encoding );
15901600 if (Py_FileSystemDefaultEncoding == NULL ) {
1591- return _Py_INIT_ERR ("Unable to get the locale encoding" );
1601+ return _Py_INIT_ERR ("failed to get the Python codec "
1602+ "of the locale encoding" );
15921603 }
15931604
15941605 Py_HasFileSystemDefaultEncoding = 0 ;
@@ -1787,6 +1798,8 @@ init_sys_streams(PyInterpreterState *interp)
17871798 PyObject * encoding_attr ;
17881799 char * pythonioencoding = NULL ;
17891800 const char * encoding , * errors ;
1801+ char * locale_encoding = NULL ;
1802+ char * codec_name = NULL ;
17901803 _PyInitError res = _Py_INIT_OK ();
17911804
17921805 /* Hack to avoid a nasty recursion issue when Python is invoked
@@ -1838,21 +1851,46 @@ init_sys_streams(PyInterpreterState *interp)
18381851 errors = err ;
18391852 }
18401853 }
1841- if (* pythonioencoding && ! encoding ) {
1854+ if (! encoding && * pythonioencoding ) {
18421855 encoding = pythonioencoding ;
1856+ if (!errors ) {
1857+ errors = "strict" ;
1858+ }
18431859 }
18441860 }
1845- else if (interp -> core_config .utf8_mode ) {
1846- encoding = "utf-8" ;
1847- errors = "surrogateescape" ;
1861+
1862+ if (interp -> core_config .utf8_mode ) {
1863+ if (!encoding ) {
1864+ encoding = "utf-8" ;
1865+ }
1866+ if (!errors ) {
1867+ errors = "surrogateescape" ;
1868+ }
18481869 }
18491870
1850- if (!errors && ! pythonioencoding ) {
1871+ if (!errors ) {
18511872 /* Choose the default error handler based on the current locale */
1852- errors = get_default_standard_stream_error_handler ();
1873+ errors = get_stdio_errors ();
18531874 }
18541875 }
18551876
1877+ if (encoding == NULL ) {
1878+ _PyInitError err = get_locale_encoding (& locale_encoding );
1879+ if (_Py_INIT_FAILED (err )) {
1880+ return err ;
1881+ }
1882+ encoding = locale_encoding ;
1883+ }
1884+
1885+ codec_name = get_codec_name (encoding );
1886+ if (codec_name == NULL ) {
1887+ PyErr_SetString (PyExc_RuntimeError ,
1888+ "failed to get the Python codec name "
1889+ "of stdio encoding" );
1890+ goto error ;
1891+ }
1892+ encoding = codec_name ;
1893+
18561894 /* Set sys.stdin */
18571895 fd = fileno (stdin );
18581896 /* Under some conditions stdin, stdout and stderr may not be connected
@@ -1928,6 +1966,8 @@ init_sys_streams(PyInterpreterState *interp)
19281966
19291967 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
19301968
1969+ PyMem_RawFree (locale_encoding );
1970+ PyMem_RawFree (codec_name );
19311971 PyMem_Free (pythonioencoding );
19321972 Py_XDECREF (bimod );
19331973 Py_XDECREF (iomod );
0 commit comments