@@ -821,43 +821,87 @@ _Py_EncodeLocaleEx(const wchar_t *text, char **str,
821821}
822822823823824-// Get the current locale encoding: locale.getpreferredencoding(False).
824+// Get the current locale encoding name:
825+//
826+// - Return "UTF-8" if _Py_FORCE_UTF8_LOCALE macro is defined (ex: on Android)
827+// - Return "UTF-8" if the UTF-8 Mode is enabled
828+// - On Windows, return the ANSI code page (ex: "cp1250")
829+// - Return "UTF-8" if nl_langinfo(CODESET) returns an empty string
830+// and if the _Py_FORCE_UTF8_FS_ENCODING macro is defined (ex: on macOS).
831+// - Otherwise, return nl_langinfo(CODESET).
832+//
833+// Return NULL and set errmsg to an error message
834+// if nl_langinfo(CODESET) fails.
835+//
836+// Return NULL and set errmsg to NULL on memory allocation failure.
837+//
825838// See also config_get_locale_encoding()
826-PyObject*
827-_Py_GetLocaleEncoding(void)
839+wchar_t*
840+_Py_GetLocaleEncoding(constchar**errmsg)
828841{
842+*errmsg=NULL;
829843#ifdef_Py_FORCE_UTF8_LOCALE
830844// On Android langinfo.h and CODESET are missing,
831845// and UTF-8 is always used in mbstowcs() and wcstombs().
832-returnPyUnicode_FromString("UTF-8");
846+return_PyMem_RawWcsdup(L"UTF-8");
833847#else
834848constPyPreConfig*preconfig=&_PyRuntime.preconfig;
835849if (preconfig->utf8_mode) {
836-returnPyUnicode_FromString("UTF-8");
850+return_PyMem_RawWcsdup(L"UTF-8");
837851 }
838852839-#if defined(MS_WINDOWS)
840-returnPyUnicode_FromFormat("cp%u", GetACP());
853+#ifdefMS_WINDOWS
854+wchar_tencoding[23];
855+unsigned intansi_codepage=GetACP();
856+swprintf(encoding, Py_ARRAY_LENGTH(encoding), L"cp%u", ansi_codepage);
857+encoding[Py_ARRAY_LENGTH(encoding) -1] =0;
858+return_PyMem_RawWcsdup(encoding);
841859#else
842860constchar*encoding=nl_langinfo(CODESET);
843861if (!encoding||encoding[0] =='\0') {
844862#ifdef_Py_FORCE_UTF8_FS_ENCODING
845863// nl_langinfo() can return an empty string when the LC_CTYPE locale is
846864// not supported. Default to UTF-8 in that case, because UTF-8 is the
847865// default charset on macOS.
848-encoding="UTF-8";
866+return_PyMem_RawWcsdup(L"UTF-8");
849867#else
850-PyErr_SetString(PyExc_ValueError,
851-"failed to get the locale encoding: "
852-"nl_langinfo(CODESET) returns an empty string");
868+*errmsg="failed to get the locale encoding: "
869+"nl_langinfo(CODESET) returns an empty string";
853870returnNULL;
854871#endif
855872 }
856-// Decode from UTF-8
857-returnPyUnicode_FromString(encoding);
858-#endif// !CODESET
859873860-#endif
874+wchar_t*wstr;
875+intres=decode_current_locale(encoding, &wstr, NULL,
876+errmsg, _Py_ERROR_SURROGATEESCAPE);
877+if (res<0) {
878+returnNULL;
879+ }
880+returnwstr;
881+#endif// !MS_WINDOWS
882+883+#endif// !_Py_FORCE_UTF8_LOCALE
884+}
885+886+887+PyObject*
888+_Py_GetLocaleEncodingObject(void)
889+{
890+constchar*errmsg;
891+wchar_t*encoding=_Py_GetLocaleEncoding(&errmsg);
892+if (encoding==NULL) {
893+if (errmsg!=NULL) {
894+PyErr_SetString(PyExc_ValueError, errmsg);
895+ }
896+else {
897+PyErr_NoMemory();
898+ }
899+returnNULL;
900+ }
901+902+PyObject*str=PyUnicode_FromWideChar(encoding, -1);
903+PyMem_RawFree(encoding);
904+returnstr;
861905}
862906863907