mirror of https://github.com/python/cpython
Issue #9548: Add a minimal "_bootlocale" module that is imported by the _io module instead of the full locale module.
This commit is contained in:
parent
73abc527eb
commit
fd4722cacf
|
@ -0,0 +1,34 @@
|
||||||
|
"""A minimal subset of the locale module used at interpreter startup
|
||||||
|
(imported by the _io module), in order to reduce startup time.
|
||||||
|
|
||||||
|
Don't import directly from third-party code; use the `locale` module instead!
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import _locale
|
||||||
|
|
||||||
|
if sys.platform.startswith("win"):
|
||||||
|
def getpreferredencoding(do_setlocale=True):
|
||||||
|
return _locale._getdefaultlocale()[1]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
_locale.CODESET
|
||||||
|
except ImportError:
|
||||||
|
def getpreferredencoding(do_setlocale=True):
|
||||||
|
# This path for legacy systems needs the more complex
|
||||||
|
# getdefaultlocale() function, import the full locale module.
|
||||||
|
import locale
|
||||||
|
return locale.getpreferredencoding(do_setlocale)
|
||||||
|
else:
|
||||||
|
def getpreferredencoding(do_setlocale=True):
|
||||||
|
assert not do_setlocale
|
||||||
|
result = _locale.nl_langinfo(_locale.CODESET)
|
||||||
|
if not result and sys.platform == 'darwin':
|
||||||
|
# nl_langinfo can return an empty string
|
||||||
|
# when the setting has an invalid value.
|
||||||
|
# Default to UTF-8 in that case because
|
||||||
|
# UTF-8 is the default charset on OSX and
|
||||||
|
# returning nothing will crash the
|
||||||
|
# interpreter.
|
||||||
|
result = 'UTF-8'
|
||||||
|
return result
|
|
@ -554,8 +554,8 @@ if sys.platform.startswith("win"):
|
||||||
# On Win32, this will return the ANSI code page
|
# On Win32, this will return the ANSI code page
|
||||||
def getpreferredencoding(do_setlocale = True):
|
def getpreferredencoding(do_setlocale = True):
|
||||||
"""Return the charset that the user is likely using."""
|
"""Return the charset that the user is likely using."""
|
||||||
import _locale
|
import _bootlocale
|
||||||
return _locale._getdefaultlocale()[1]
|
return _bootlocale.getpreferredencoding(False)
|
||||||
else:
|
else:
|
||||||
# On Unix, if CODESET is available, use that.
|
# On Unix, if CODESET is available, use that.
|
||||||
try:
|
try:
|
||||||
|
@ -574,27 +574,16 @@ else:
|
||||||
def getpreferredencoding(do_setlocale = True):
|
def getpreferredencoding(do_setlocale = True):
|
||||||
"""Return the charset that the user is likely using,
|
"""Return the charset that the user is likely using,
|
||||||
according to the system configuration."""
|
according to the system configuration."""
|
||||||
|
import _bootlocale
|
||||||
if do_setlocale:
|
if do_setlocale:
|
||||||
oldloc = setlocale(LC_CTYPE)
|
oldloc = setlocale(LC_CTYPE)
|
||||||
try:
|
try:
|
||||||
setlocale(LC_CTYPE, "")
|
setlocale(LC_CTYPE, "")
|
||||||
except Error:
|
except Error:
|
||||||
pass
|
pass
|
||||||
result = nl_langinfo(CODESET)
|
result = _bootlocale.getpreferredencoding(False)
|
||||||
if not result and sys.platform == 'darwin':
|
if do_setlocale:
|
||||||
# nl_langinfo can return an empty string
|
|
||||||
# when the setting has an invalid value.
|
|
||||||
# Default to UTF-8 in that case because
|
|
||||||
# UTF-8 is the default charset on OSX and
|
|
||||||
# returning nothing will crash the
|
|
||||||
# interpreter.
|
|
||||||
result = 'UTF-8'
|
|
||||||
setlocale(LC_CTYPE, oldloc)
|
setlocale(LC_CTYPE, oldloc)
|
||||||
else:
|
|
||||||
result = nl_langinfo(CODESET)
|
|
||||||
if not result and sys.platform == 'darwin':
|
|
||||||
# See above for explanation
|
|
||||||
result = 'UTF-8'
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -426,8 +426,8 @@ def aliasmbcs():
|
||||||
while they are always available as "mbcs" in each locale. Make
|
while they are always available as "mbcs" in each locale. Make
|
||||||
them usable by aliasing to "mbcs" in such a case."""
|
them usable by aliasing to "mbcs" in such a case."""
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
import locale, codecs
|
import _bootlocale, codecs
|
||||||
enc = locale.getdefaultlocale()[1]
|
enc = _bootlocale.getpreferredencoding(False)
|
||||||
if enc.startswith('cp'): # "cp***" ?
|
if enc.startswith('cp'): # "cp***" ?
|
||||||
try:
|
try:
|
||||||
codecs.lookup(enc)
|
codecs.lookup(enc)
|
||||||
|
|
|
@ -883,8 +883,9 @@ class ProcessTestCase(BaseTestCase):
|
||||||
#
|
#
|
||||||
# UTF-16 and UTF-32-BE are sufficient to check both with BOM and
|
# UTF-16 and UTF-32-BE are sufficient to check both with BOM and
|
||||||
# without, and UTF-16 and UTF-32.
|
# without, and UTF-16 and UTF-32.
|
||||||
|
import _bootlocale
|
||||||
for encoding in ['utf-16', 'utf-32-be']:
|
for encoding in ['utf-16', 'utf-32-be']:
|
||||||
old_getpreferredencoding = locale.getpreferredencoding
|
old_getpreferredencoding = _bootlocale.getpreferredencoding
|
||||||
# Indirectly via io.TextIOWrapper, Popen() defaults to
|
# Indirectly via io.TextIOWrapper, Popen() defaults to
|
||||||
# locale.getpreferredencoding(False) and earlier in Python 3.2 to
|
# locale.getpreferredencoding(False) and earlier in Python 3.2 to
|
||||||
# locale.getpreferredencoding().
|
# locale.getpreferredencoding().
|
||||||
|
@ -895,7 +896,7 @@ class ProcessTestCase(BaseTestCase):
|
||||||
encoding)
|
encoding)
|
||||||
args = [sys.executable, '-c', code]
|
args = [sys.executable, '-c', code]
|
||||||
try:
|
try:
|
||||||
locale.getpreferredencoding = getpreferredencoding
|
_bootlocale.getpreferredencoding = getpreferredencoding
|
||||||
# We set stdin to be non-None because, as of this writing,
|
# We set stdin to be non-None because, as of this writing,
|
||||||
# a different code path is used when the number of pipes is
|
# a different code path is used when the number of pipes is
|
||||||
# zero or one.
|
# zero or one.
|
||||||
|
@ -904,7 +905,7 @@ class ProcessTestCase(BaseTestCase):
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
stdout, stderr = popen.communicate(input='')
|
stdout, stderr = popen.communicate(input='')
|
||||||
finally:
|
finally:
|
||||||
locale.getpreferredencoding = old_getpreferredencoding
|
_bootlocale.getpreferredencoding = old_getpreferredencoding
|
||||||
self.assertEqual(stdout, '1\n2\n3\n4')
|
self.assertEqual(stdout, '1\n2\n3\n4')
|
||||||
|
|
||||||
def test_no_leaking(self):
|
def test_no_leaking(self):
|
||||||
|
|
|
@ -36,6 +36,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #9548: Add a minimal "_bootlocale" module that is imported by the
|
||||||
|
_io module instead of the full locale module.
|
||||||
|
|
||||||
- Issue #18764: remove the 'print' alias for the PDB 'p' command so that it no
|
- Issue #18764: remove the 'print' alias for the PDB 'p' command so that it no
|
||||||
longer shadows the print function.
|
longer shadows the print function.
|
||||||
|
|
||||||
|
|
|
@ -546,7 +546,7 @@ _PyIO_get_locale_module(_PyIO_State *state)
|
||||||
}
|
}
|
||||||
Py_CLEAR(state->locale_module);
|
Py_CLEAR(state->locale_module);
|
||||||
}
|
}
|
||||||
mod = PyImport_ImportModule("locale");
|
mod = PyImport_ImportModule("_bootlocale");
|
||||||
if (mod == NULL)
|
if (mod == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
state->locale_module = PyWeakref_NewRef(mod, NULL);
|
state->locale_module = PyWeakref_NewRef(mod, NULL);
|
||||||
|
|
Loading…
Reference in New Issue