diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2017-06-11 13:16:15 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-11 13:16:15 +1000 |
commit | 6ea4186de32d65b1f1dc1533b6312b798d300466 (patch) | |
tree | bac8387f2da20d5b6d5f74bb09fb5708d1fbd61e /Programs | |
parent | Use Travis to make sure all generated files are up to date (GH-2080) (diff) | |
download | cpython-6ea4186de32d65b1f1dc1533b6312b798d300466.tar.gz cpython-6ea4186de32d65b1f1dc1533b6312b798d300466.tar.bz2 cpython-6ea4186de32d65b1f1dc1533b6312b798d300466.zip |
bpo-28180: Implementation for PEP 538 (#659)
- new PYTHONCOERCECLOCALE config setting
- coerces legacy C locale to C.UTF-8, C.utf8 or UTF-8 by default
- always uses C.UTF-8 on Android
- uses `surrogateescape` on stdin and stdout in the coercion
target locales
- configure option to disable locale coercion at build time
- configure option to disable C locale warning at build time
Diffstat (limited to 'Programs')
-rw-r--r-- | Programs/python.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Programs/python.c b/Programs/python.c index a7afbc774b3..03f8295045c 100644 --- a/Programs/python.c +++ b/Programs/python.c @@ -15,6 +15,21 @@ wmain(int argc, wchar_t **argv) } #else +/* Access private pylifecycle helper API to better handle the legacy C locale + * + * The legacy C locale assumes ASCII as the default text encoding, which + * causes problems not only for the CPython runtime, but also other + * components like GNU readline. + * + * Accordingly, when the CLI detects it, it attempts to coerce it to a + * more capable UTF-8 based alternative. + * + * See the documentation of the PYTHONCOERCECLOCALE setting for more details. + * + */ +extern int _Py_LegacyLocaleDetected(void); +extern void _Py_CoerceLegacyLocale(void); + int main(int argc, char **argv) { @@ -25,7 +40,11 @@ main(int argc, char **argv) char *oldloc; /* Force malloc() allocator to bootstrap Python */ +#ifdef Py_DEBUG + (void)_PyMem_SetupAllocators("malloc_debug"); +# else (void)_PyMem_SetupAllocators("malloc"); +# endif argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); @@ -49,7 +68,21 @@ main(int argc, char **argv) return 1; } +#ifdef __ANDROID__ + /* Passing "" to setlocale() on Android requests the C locale rather + * than checking environment variables, so request C.UTF-8 explicitly + */ + setlocale(LC_ALL, "C.UTF-8"); +#else + /* Reconfigure the locale to the default for this process */ setlocale(LC_ALL, ""); +#endif + + if (_Py_LegacyLocaleDetected()) { + _Py_CoerceLegacyLocale(); + } + + /* Convert from char to wchar_t based on the locale settings */ for (i = 0; i < argc; i++) { argv_copy[i] = Py_DecodeLocale(argv[i], NULL); if (!argv_copy[i]) { @@ -70,7 +103,11 @@ main(int argc, char **argv) /* Force again malloc() allocator to release memory blocks allocated before Py_Main() */ +#ifdef Py_DEBUG + (void)_PyMem_SetupAllocators("malloc_debug"); +# else (void)_PyMem_SetupAllocators("malloc"); +# endif for (i = 0; i < argc; i++) { PyMem_RawFree(argv_copy2[i]); |