mirror of
https://github.com/python/cpython.git
synced 2025-09-19 15:10:58 +00:00
Revert "bpo-34589: Add -X coerce_c_locale command line option (GH-9378)" (GH-9430)
* Revert "bpo-34589: Add -X coerce_c_locale command line option (GH-9378)" This reverts commitdbdee0073c
. * Revert "bpo-34589: C locale coercion off by default (GH-9073)" This reverts commit7a0791b699
. * Revert "bpo-34589: Make _PyCoreConfig.coerce_c_locale private (GH-9371)" This reverts commit188ebfa475
.
This commit is contained in:
parent
76531e2e82
commit
06e7608207
17 changed files with 87 additions and 242 deletions
|
@ -438,22 +438,13 @@ Miscellaneous options
|
||||||
* Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to
|
* Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to
|
||||||
``True``
|
``True``
|
||||||
|
|
||||||
* ``-X utf8`` enables UTF-8 mode (:pep:`540`) for operating system interfaces, overriding
|
* ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding
|
||||||
the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8
|
the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8
|
||||||
mode (even when it would otherwise activate automatically).
|
mode (even when it would otherwise activate automatically).
|
||||||
See :envvar:`PYTHONUTF8` for more details.
|
See :envvar:`PYTHONUTF8` for more details.
|
||||||
* ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel
|
* ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel
|
||||||
tree rooted at the given directory instead of to the code tree. See also
|
tree rooted at the given directory instead of to the code tree. See also
|
||||||
:envvar:`PYTHONPYCACHEPREFIX`.
|
:envvar:`PYTHONPYCACHEPREFIX`.
|
||||||
* ``-X coerce_c_locale`` or ``-X coerce_c_locale=1`` tries to coerce the C
|
|
||||||
locale (:pep:`538`).
|
|
||||||
``-X coerce_c_locale=0`` skips coercing the legacy ASCII-based C and POSIX
|
|
||||||
locales to a more capable UTF-8 based alternative.
|
|
||||||
``-X coerce_c_locale=warn`` will cause Python to emit warning messages on
|
|
||||||
``stderr`` if either the locale coercion activates, or else if a locale
|
|
||||||
that *would* have triggered coercion is still active when the Python
|
|
||||||
runtime is initialized.
|
|
||||||
See :envvar:`PYTHONCOERCECLOCALE` for more details.
|
|
||||||
|
|
||||||
It also allows passing arbitrary values and retrieving them through the
|
It also allows passing arbitrary values and retrieving them through the
|
||||||
:data:`sys._xoptions` dictionary.
|
:data:`sys._xoptions` dictionary.
|
||||||
|
@ -473,9 +464,6 @@ Miscellaneous options
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
The ``-X importtime``, ``-X dev`` and ``-X utf8`` options.
|
The ``-X importtime``, ``-X dev`` and ``-X utf8`` options.
|
||||||
|
|
||||||
.. versionadded:: 3.7.1
|
|
||||||
The ``-X coerce_c_locale`` option.
|
|
||||||
|
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
The ``-X pycache_prefix`` option.
|
The ``-X pycache_prefix`` option.
|
||||||
|
|
||||||
|
@ -862,8 +850,6 @@ conflict.
|
||||||
order to force the interpreter to use ``ASCII`` instead of ``UTF-8`` for
|
order to force the interpreter to use ``ASCII`` instead of ``UTF-8`` for
|
||||||
system interfaces.
|
system interfaces.
|
||||||
|
|
||||||
Also available as the :option:`-X` ``coerce_c_locale`` option.
|
|
||||||
|
|
||||||
Availability: \*nix
|
Availability: \*nix
|
||||||
|
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
|
|
|
@ -2494,10 +2494,3 @@ versions, it respected an ill-defined subset of those environment variables,
|
||||||
while in Python 3.7.0 it didn't read any of them due to :issue:`34247`). If
|
while in Python 3.7.0 it didn't read any of them due to :issue:`34247`). If
|
||||||
this behavior is unwanted, set :c:data:`Py_IgnoreEnvironmentFlag` to 1 before
|
this behavior is unwanted, set :c:data:`Py_IgnoreEnvironmentFlag` to 1 before
|
||||||
calling :c:func:`Py_Initialize`.
|
calling :c:func:`Py_Initialize`.
|
||||||
|
|
||||||
:c:func:`Py_Initialize` and :c:func:`Py_Main` cannot enable the C locale
|
|
||||||
coercion (:pep:`538`) anymore: it is always disabled. It can now only be
|
|
||||||
enabled by the Python program ("python3).
|
|
||||||
|
|
||||||
New :option:`-X` ``coerce_c_locale`` command line option to control C locale
|
|
||||||
coercion (:pep:`538`).
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ typedef struct {
|
||||||
int show_alloc_count; /* -X showalloccount */
|
int show_alloc_count; /* -X showalloccount */
|
||||||
int dump_refs; /* PYTHONDUMPREFS */
|
int dump_refs; /* PYTHONDUMPREFS */
|
||||||
int malloc_stats; /* PYTHONMALLOCSTATS */
|
int malloc_stats; /* PYTHONMALLOCSTATS */
|
||||||
|
int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */
|
||||||
|
int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */
|
||||||
|
|
||||||
/* Python filesystem encoding and error handler:
|
/* Python filesystem encoding and error handler:
|
||||||
sys.getfilesystemencoding() and sys.getfilesystemencodeerrors().
|
sys.getfilesystemencoding() and sys.getfilesystemencodeerrors().
|
||||||
|
@ -295,30 +297,6 @@ typedef struct {
|
||||||
If set to -1 (default), inherit Py_FrozenFlag value. */
|
If set to -1 (default), inherit Py_FrozenFlag value. */
|
||||||
int _frozen;
|
int _frozen;
|
||||||
|
|
||||||
/* C locale coercion (PEP 538).
|
|
||||||
|
|
||||||
The option is enabled by the PYTHONCOERCECLOCALE environment
|
|
||||||
variable. The option is also enabled if the LC_CTYPE locale is "C"
|
|
||||||
and a target locale (ex: "C.UTF-8") is supported by the platform.
|
|
||||||
|
|
||||||
Py_Initialize() and Py_Main() must not enable C locale coercion: it is
|
|
||||||
always disabled. The option can only be enabled by the Python program
|
|
||||||
("python3).
|
|
||||||
|
|
||||||
See also the _coerce_c_locale_warn option. */
|
|
||||||
int _coerce_c_locale;
|
|
||||||
|
|
||||||
/* C locale coercion warning (PEP 538).
|
|
||||||
|
|
||||||
Enabled by the PYTHONCOERCECLOCALE=warn environment variable.
|
|
||||||
|
|
||||||
Py_Initialize() and Py_Main() must not enable C locale coercion warning:
|
|
||||||
it is always disabled. The warning can only be enabled by the Python
|
|
||||||
program ("python3).
|
|
||||||
|
|
||||||
See also the _coerce_c_locale option. */
|
|
||||||
int _coerce_c_locale_warn;
|
|
||||||
|
|
||||||
} _PyCoreConfig;
|
} _PyCoreConfig;
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
@ -336,8 +314,7 @@ typedef struct {
|
||||||
.use_hash_seed = -1, \
|
.use_hash_seed = -1, \
|
||||||
.faulthandler = -1, \
|
.faulthandler = -1, \
|
||||||
.tracemalloc = -1, \
|
.tracemalloc = -1, \
|
||||||
._coerce_c_locale = 0, \
|
.coerce_c_locale = -1, \
|
||||||
._coerce_c_locale_warn = 0, \
|
|
||||||
.utf8_mode = -1, \
|
.utf8_mode = -1, \
|
||||||
.argc = -1, \
|
.argc = -1, \
|
||||||
.nmodule_search_path = -1, \
|
.nmodule_search_path = -1, \
|
||||||
|
|
|
@ -83,11 +83,7 @@ PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
|
||||||
/* Bootstrap __main__ (defined in Modules/main.c) */
|
/* Bootstrap __main__ (defined in Modules/main.c) */
|
||||||
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
|
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
|
||||||
#ifdef Py_BUILD_CORE
|
#ifdef Py_BUILD_CORE
|
||||||
# ifdef MS_WINDOWS
|
|
||||||
PyAPI_FUNC(int) _Py_WindowsMain(int argc, wchar_t **argv);
|
|
||||||
# else
|
|
||||||
PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv);
|
PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv);
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* In getpath.c */
|
/* In getpath.c */
|
||||||
|
|
|
@ -139,7 +139,7 @@ class EncodingDetails(_EncodingDetails):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_child_details(cls, env_vars, xoption=None):
|
def get_child_details(cls, env_vars):
|
||||||
"""Retrieves fsencoding and standard stream details from a child process
|
"""Retrieves fsencoding and standard stream details from a child process
|
||||||
|
|
||||||
Returns (encoding_details, stderr_lines):
|
Returns (encoding_details, stderr_lines):
|
||||||
|
@ -150,11 +150,10 @@ class EncodingDetails(_EncodingDetails):
|
||||||
The child is run in isolated mode if the current interpreter supports
|
The child is run in isolated mode if the current interpreter supports
|
||||||
that.
|
that.
|
||||||
"""
|
"""
|
||||||
args = []
|
result, py_cmd = run_python_until_end(
|
||||||
if xoption:
|
"-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT,
|
||||||
args.extend(("-X", f"coerce_c_locale={xoption}"))
|
**env_vars
|
||||||
args.extend(("-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT))
|
)
|
||||||
result, py_cmd = run_python_until_end(*args, **env_vars)
|
|
||||||
if not result.rc == 0:
|
if not result.rc == 0:
|
||||||
result.fail(py_cmd)
|
result.fail(py_cmd)
|
||||||
# All subprocess outputs in this test case should be pure ASCII
|
# All subprocess outputs in this test case should be pure ASCII
|
||||||
|
@ -213,8 +212,7 @@ class _LocaleHandlingTestCase(unittest.TestCase):
|
||||||
expected_fs_encoding,
|
expected_fs_encoding,
|
||||||
expected_stream_encoding,
|
expected_stream_encoding,
|
||||||
expected_warnings,
|
expected_warnings,
|
||||||
coercion_expected,
|
coercion_expected):
|
||||||
xoption=None):
|
|
||||||
"""Check the C locale handling for the given process environment
|
"""Check the C locale handling for the given process environment
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -222,7 +220,7 @@ class _LocaleHandlingTestCase(unittest.TestCase):
|
||||||
expected_stream_encoding: expected encoding for standard streams
|
expected_stream_encoding: expected encoding for standard streams
|
||||||
expected_warning: stderr output to expect (if any)
|
expected_warning: stderr output to expect (if any)
|
||||||
"""
|
"""
|
||||||
result = EncodingDetails.get_child_details(env_vars, xoption)
|
result = EncodingDetails.get_child_details(env_vars)
|
||||||
encoding_details, stderr_lines = result
|
encoding_details, stderr_lines = result
|
||||||
expected_details = EncodingDetails.get_expected_details(
|
expected_details = EncodingDetails.get_expected_details(
|
||||||
coercion_expected,
|
coercion_expected,
|
||||||
|
@ -292,7 +290,6 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
|
||||||
coerce_c_locale,
|
coerce_c_locale,
|
||||||
expected_warnings=None,
|
expected_warnings=None,
|
||||||
coercion_expected=True,
|
coercion_expected=True,
|
||||||
use_xoption=False,
|
|
||||||
**extra_vars):
|
**extra_vars):
|
||||||
"""Check the C locale handling for various configurations
|
"""Check the C locale handling for various configurations
|
||||||
|
|
||||||
|
@ -322,12 +319,8 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
|
||||||
"PYTHONCOERCECLOCALE": "",
|
"PYTHONCOERCECLOCALE": "",
|
||||||
}
|
}
|
||||||
base_var_dict.update(extra_vars)
|
base_var_dict.update(extra_vars)
|
||||||
xoption = None
|
|
||||||
if coerce_c_locale is not None:
|
if coerce_c_locale is not None:
|
||||||
if use_xoption:
|
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
|
||||||
xoption = coerce_c_locale
|
|
||||||
else:
|
|
||||||
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
|
|
||||||
|
|
||||||
# Check behaviour for the default locale
|
# Check behaviour for the default locale
|
||||||
with self.subTest(default_locale=True,
|
with self.subTest(default_locale=True,
|
||||||
|
@ -349,8 +342,7 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
|
||||||
fs_encoding,
|
fs_encoding,
|
||||||
stream_encoding,
|
stream_encoding,
|
||||||
_expected_warnings,
|
_expected_warnings,
|
||||||
_coercion_expected,
|
_coercion_expected)
|
||||||
xoption=xoption)
|
|
||||||
|
|
||||||
# Check behaviour for explicitly configured locales
|
# Check behaviour for explicitly configured locales
|
||||||
for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS:
|
for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS:
|
||||||
|
@ -365,8 +357,7 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
|
||||||
fs_encoding,
|
fs_encoding,
|
||||||
stream_encoding,
|
stream_encoding,
|
||||||
expected_warnings,
|
expected_warnings,
|
||||||
coercion_expected,
|
coercion_expected)
|
||||||
xoption=xoption)
|
|
||||||
|
|
||||||
def test_PYTHONCOERCECLOCALE_not_set(self):
|
def test_PYTHONCOERCECLOCALE_not_set(self):
|
||||||
# This should coerce to the first available target locale by default
|
# This should coerce to the first available target locale by default
|
||||||
|
@ -413,32 +404,6 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
|
||||||
expected_warnings=[LEGACY_LOCALE_WARNING],
|
expected_warnings=[LEGACY_LOCALE_WARNING],
|
||||||
coercion_expected=False)
|
coercion_expected=False)
|
||||||
|
|
||||||
def test_xoption_set_to_1(self):
|
|
||||||
self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale="1",
|
|
||||||
use_xoption=True)
|
|
||||||
|
|
||||||
def test_xoption_set_to_zero(self):
|
|
||||||
# The setting "0" should result in the locale coercion being disabled
|
|
||||||
self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,
|
|
||||||
EXPECTED_C_LOCALE_STREAM_ENCODING,
|
|
||||||
coerce_c_locale="0",
|
|
||||||
coercion_expected=False,
|
|
||||||
use_xoption=True)
|
|
||||||
# Setting LC_ALL=C shouldn't make any difference to the behaviour
|
|
||||||
self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,
|
|
||||||
EXPECTED_C_LOCALE_STREAM_ENCODING,
|
|
||||||
coerce_c_locale="0",
|
|
||||||
LC_ALL="C",
|
|
||||||
coercion_expected=False,
|
|
||||||
use_xoption=True)
|
|
||||||
|
|
||||||
def test_xoption_set_to_warn(self):
|
|
||||||
# -X coerce_c_locale=warn enables runtime warnings for legacy locales
|
|
||||||
self._check_c_locale_coercion("utf-8", "utf-8",
|
|
||||||
coerce_c_locale="warn",
|
|
||||||
expected_warnings=[CLI_COERCION_WARNING],
|
|
||||||
use_xoption=True)
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test.support.run_unittest(
|
test.support.run_unittest(
|
||||||
LocaleConfigurationTests,
|
LocaleConfigurationTests,
|
||||||
|
|
|
@ -159,16 +159,13 @@ class CmdLineTest(unittest.TestCase):
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
# Use C locale to get ascii for the locale encoding
|
# Use C locale to get ascii for the locale encoding
|
||||||
env['LC_ALL'] = 'C'
|
env['LC_ALL'] = 'C'
|
||||||
|
env['PYTHONCOERCECLOCALE'] = '0'
|
||||||
code = (
|
code = (
|
||||||
b'import locale; '
|
b'import locale; '
|
||||||
b'print(ascii("' + undecodable + b'"), '
|
b'print(ascii("' + undecodable + b'"), '
|
||||||
b'locale.getpreferredencoding())')
|
b'locale.getpreferredencoding())')
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
[sys.executable,
|
[sys.executable, "-c", code],
|
||||||
# Disable C locale coercion and UTF-8 Mode to not use UTF-8
|
|
||||||
"-X", "coerce_c_locale=0",
|
|
||||||
"-X", "utf8=0",
|
|
||||||
"-c", code],
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||||
env=env)
|
env=env)
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
|
|
|
@ -277,6 +277,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'filesystem_errors': None,
|
'filesystem_errors': None,
|
||||||
|
|
||||||
'utf8_mode': 0,
|
'utf8_mode': 0,
|
||||||
|
'coerce_c_locale': 0,
|
||||||
|
'coerce_c_locale_warn': 0,
|
||||||
|
|
||||||
'pycache_prefix': NULL_STR,
|
'pycache_prefix': NULL_STR,
|
||||||
'program_name': './_testembed',
|
'program_name': './_testembed',
|
||||||
|
@ -304,8 +306,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'_install_importlib': 1,
|
'_install_importlib': 1,
|
||||||
'_check_hash_pycs_mode': 'default',
|
'_check_hash_pycs_mode': 'default',
|
||||||
'_frozen': 0,
|
'_frozen': 0,
|
||||||
'_coerce_c_locale': 0,
|
|
||||||
'_coerce_c_locale_warn': 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_stdio_encoding(self, env):
|
def get_stdio_encoding(self, env):
|
||||||
|
@ -324,6 +324,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'print(sys.getfilesystemencoding(), '
|
'print(sys.getfilesystemencoding(), '
|
||||||
'sys.getfilesystemencodeerrors())')
|
'sys.getfilesystemencodeerrors())')
|
||||||
args = (sys.executable, '-c', code)
|
args = (sys.executable, '-c', code)
|
||||||
|
env = dict(env)
|
||||||
|
if not isolated:
|
||||||
|
env['PYTHONCOERCECLOCALE'] = '0'
|
||||||
|
env['PYTHONUTF8'] = '0'
|
||||||
proc = subprocess.run(args, text=True, env=env,
|
proc = subprocess.run(args, text=True, env=env,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
|
|
|
@ -656,8 +656,9 @@ class SysModuleTest(unittest.TestCase):
|
||||||
|
|
||||||
def c_locale_get_error_handler(self, locale, isolated=False, encoding=None):
|
def c_locale_get_error_handler(self, locale, isolated=False, encoding=None):
|
||||||
# Force the POSIX locale
|
# Force the POSIX locale
|
||||||
env = dict(os.environ)
|
env = os.environ.copy()
|
||||||
env["LC_ALL"] = locale
|
env["LC_ALL"] = locale
|
||||||
|
env["PYTHONCOERCECLOCALE"] = "0"
|
||||||
code = '\n'.join((
|
code = '\n'.join((
|
||||||
'import sys',
|
'import sys',
|
||||||
'def dump(name):',
|
'def dump(name):',
|
||||||
|
@ -667,10 +668,7 @@ class SysModuleTest(unittest.TestCase):
|
||||||
'dump("stdout")',
|
'dump("stdout")',
|
||||||
'dump("stderr")',
|
'dump("stderr")',
|
||||||
))
|
))
|
||||||
args = [sys.executable,
|
args = [sys.executable, "-X", "utf8=0", "-c", code]
|
||||||
"-X", "utf8=0",
|
|
||||||
"-X", "coerce_c_locale=0",
|
|
||||||
"-c", code]
|
|
||||||
if isolated:
|
if isolated:
|
||||||
args.append("-I")
|
args.append("-I")
|
||||||
if encoding is not None:
|
if encoding is not None:
|
||||||
|
|
|
@ -27,8 +27,6 @@ class UTF8ModeTests(unittest.TestCase):
|
||||||
return (loc in POSIX_LOCALES)
|
return (loc in POSIX_LOCALES)
|
||||||
|
|
||||||
def get_output(self, *args, failure=False, **kw):
|
def get_output(self, *args, failure=False, **kw):
|
||||||
# Always disable the C locale coercion (PEP 538)
|
|
||||||
args = ('-X', 'coerce_c_locale=0', *args)
|
|
||||||
kw = dict(self.DEFAULT_ENV, **kw)
|
kw = dict(self.DEFAULT_ENV, **kw)
|
||||||
if failure:
|
if failure:
|
||||||
out = assert_python_failure(*args, **kw)
|
out = assert_python_failure(*args, **kw)
|
||||||
|
@ -118,6 +116,7 @@ class UTF8ModeTests(unittest.TestCase):
|
||||||
# PYTHONLEGACYWINDOWSFSENCODING disables the UTF-8 mode
|
# PYTHONLEGACYWINDOWSFSENCODING disables the UTF-8 mode
|
||||||
# and has the priority over -X utf8 and PYTHONUTF8
|
# and has the priority over -X utf8 and PYTHONUTF8
|
||||||
out = self.get_output('-X', 'utf8', '-c', code,
|
out = self.get_output('-X', 'utf8', '-c', code,
|
||||||
|
PYTHONUTF8='strict',
|
||||||
PYTHONLEGACYWINDOWSFSENCODING='1')
|
PYTHONLEGACYWINDOWSFSENCODING='1')
|
||||||
self.assertEqual(out, 'mbcs/replace')
|
self.assertEqual(out, 'mbcs/replace')
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Py_Initialize() and Py_Main() cannot enable the C locale coercion (PEP 538)
|
|
||||||
anymore: it is always disabled. It can now only be enabled by the Python
|
|
||||||
program ("python3).
|
|
|
@ -1,2 +0,0 @@
|
||||||
Add a new :option:`-X` ``coerce_c_locale`` command line option to control C
|
|
||||||
locale coercion (:pep:`538`).
|
|
|
@ -4701,6 +4701,10 @@ get_coreconfig(PyObject *self, PyObject *Py_UNUSED(args))
|
||||||
PyLong_FromLong(config->dump_refs));
|
PyLong_FromLong(config->dump_refs));
|
||||||
SET_ITEM("malloc_stats",
|
SET_ITEM("malloc_stats",
|
||||||
PyLong_FromLong(config->malloc_stats));
|
PyLong_FromLong(config->malloc_stats));
|
||||||
|
SET_ITEM("coerce_c_locale",
|
||||||
|
PyLong_FromLong(config->coerce_c_locale));
|
||||||
|
SET_ITEM("coerce_c_locale_warn",
|
||||||
|
PyLong_FromLong(config->coerce_c_locale_warn));
|
||||||
SET_ITEM("filesystem_encoding",
|
SET_ITEM("filesystem_encoding",
|
||||||
FROM_STRING(config->filesystem_encoding));
|
FROM_STRING(config->filesystem_encoding));
|
||||||
SET_ITEM("filesystem_errors",
|
SET_ITEM("filesystem_errors",
|
||||||
|
@ -4779,10 +4783,6 @@ get_coreconfig(PyObject *self, PyObject *Py_UNUSED(args))
|
||||||
FROM_STRING(config->_check_hash_pycs_mode));
|
FROM_STRING(config->_check_hash_pycs_mode));
|
||||||
SET_ITEM("_frozen",
|
SET_ITEM("_frozen",
|
||||||
PyLong_FromLong(config->_frozen));
|
PyLong_FromLong(config->_frozen));
|
||||||
SET_ITEM("_coerce_c_locale",
|
|
||||||
PyLong_FromLong(config->_coerce_c_locale));
|
|
||||||
SET_ITEM("_coerce_c_locale_warn",
|
|
||||||
PyLong_FromLong(config->_coerce_c_locale_warn));
|
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
|
|
||||||
|
|
|
@ -1342,9 +1342,9 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
* See the documentation of the PYTHONCOERCECLOCALE setting for more
|
* See the documentation of the PYTHONCOERCECLOCALE setting for more
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
if (config->_coerce_c_locale && !locale_coerced) {
|
if (config->coerce_c_locale && !locale_coerced) {
|
||||||
locale_coerced = 1;
|
locale_coerced = 1;
|
||||||
_Py_CoerceLegacyLocale(config->_coerce_c_locale_warn);
|
_Py_CoerceLegacyLocale(config->coerce_c_locale_warn);
|
||||||
encoding_changed = 1;
|
encoding_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,7 +1367,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
/* Reset the configuration before reading again the configuration,
|
/* Reset the configuration before reading again the configuration,
|
||||||
just keep UTF-8 Mode value. */
|
just keep UTF-8 Mode value. */
|
||||||
int new_utf8_mode = config->utf8_mode;
|
int new_utf8_mode = config->utf8_mode;
|
||||||
int new_coerce_c_locale = config->_coerce_c_locale;
|
int new_coerce_c_locale = config->coerce_c_locale;
|
||||||
if (_PyCoreConfig_Copy(config, &save_config) < 0) {
|
if (_PyCoreConfig_Copy(config, &save_config) < 0) {
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -1375,7 +1375,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
pymain_clear_cmdline(pymain, cmdline);
|
pymain_clear_cmdline(pymain, cmdline);
|
||||||
memset(cmdline, 0, sizeof(*cmdline));
|
memset(cmdline, 0, sizeof(*cmdline));
|
||||||
config->utf8_mode = new_utf8_mode;
|
config->utf8_mode = new_utf8_mode;
|
||||||
config->_coerce_c_locale = new_coerce_c_locale;
|
config->coerce_c_locale = new_coerce_c_locale;
|
||||||
|
|
||||||
/* The encoding changed: read again the configuration
|
/* The encoding changed: read again the configuration
|
||||||
with the new encoding */
|
with the new encoding */
|
||||||
|
@ -1700,8 +1700,7 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init(_PyMain *pymain, PyInterpreterState **interp_p,
|
pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
|
||||||
int use_c_locale_coercion)
|
|
||||||
{
|
{
|
||||||
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
||||||
* and until C vendors implement C99's ways to control FP exceptions,
|
* and until C vendors implement C99's ways to control FP exceptions,
|
||||||
|
@ -1714,11 +1713,6 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p,
|
||||||
|
|
||||||
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
||||||
_PyCoreConfig *config = &local_config;
|
_PyCoreConfig *config = &local_config;
|
||||||
if (use_c_locale_coercion) {
|
|
||||||
/* set to -1 to be able to enable the feature */
|
|
||||||
config->_coerce_c_locale = -1;
|
|
||||||
config->_coerce_c_locale_warn = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyCoreConfig_GetGlobalConfig(config);
|
_PyCoreConfig_GetGlobalConfig(config);
|
||||||
|
|
||||||
|
@ -1753,10 +1747,10 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p,
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_main(_PyMain *pymain, int use_c_locale_coercion)
|
pymain_main(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
PyInterpreterState *interp;
|
PyInterpreterState *interp;
|
||||||
int res = pymain_init(pymain, &interp, use_c_locale_coercion);
|
int res = pymain_init(pymain, &interp);
|
||||||
if (res != 1) {
|
if (res != 1) {
|
||||||
if (pymain_run_python(pymain, interp) < 0) {
|
if (pymain_run_python(pymain, interp) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
|
@ -1783,22 +1777,10 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
pymain.argc = argc;
|
pymain.argc = argc;
|
||||||
pymain.wchar_argv = argv;
|
pymain.wchar_argv = argv;
|
||||||
|
|
||||||
return pymain_main(&pymain, 0);
|
return pymain_main(&pymain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
int
|
|
||||||
_Py_WindowsMain(int argc, wchar_t **argv)
|
|
||||||
{
|
|
||||||
_PyMain pymain = _PyMain_INIT;
|
|
||||||
pymain.use_bytes_argv = 0;
|
|
||||||
pymain.argc = argc;
|
|
||||||
pymain.wchar_argv = argv;
|
|
||||||
|
|
||||||
return pymain_main(&pymain, 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int
|
int
|
||||||
_Py_UnixMain(int argc, char **argv)
|
_Py_UnixMain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -1807,9 +1789,8 @@ _Py_UnixMain(int argc, char **argv)
|
||||||
pymain.argc = argc;
|
pymain.argc = argc;
|
||||||
pymain.bytes_argv = argv;
|
pymain.bytes_argv = argv;
|
||||||
|
|
||||||
return pymain_main(&pymain, 1);
|
return pymain_main(&pymain);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* this is gonna seem *real weird*, but if you put some other code between
|
/* this is gonna seem *real weird*, but if you put some other code between
|
||||||
|
|
|
@ -330,6 +330,8 @@ dump_config(void)
|
||||||
|
|
||||||
printf("filesystem_encoding = %s\n", config->filesystem_encoding);
|
printf("filesystem_encoding = %s\n", config->filesystem_encoding);
|
||||||
printf("filesystem_errors = %s\n", config->filesystem_errors);
|
printf("filesystem_errors = %s\n", config->filesystem_errors);
|
||||||
|
printf("coerce_c_locale = %i\n", config->coerce_c_locale);
|
||||||
|
printf("coerce_c_locale_warn = %i\n", config->coerce_c_locale_warn);
|
||||||
printf("utf8_mode = %i\n", config->utf8_mode);
|
printf("utf8_mode = %i\n", config->utf8_mode);
|
||||||
|
|
||||||
printf("pycache_prefix = %ls\n", config->pycache_prefix);
|
printf("pycache_prefix = %ls\n", config->pycache_prefix);
|
||||||
|
@ -383,8 +385,6 @@ dump_config(void)
|
||||||
printf("_install_importlib = %i\n", config->_install_importlib);
|
printf("_install_importlib = %i\n", config->_install_importlib);
|
||||||
printf("_check_hash_pycs_mode = %s\n", config->_check_hash_pycs_mode);
|
printf("_check_hash_pycs_mode = %s\n", config->_check_hash_pycs_mode);
|
||||||
printf("_frozen = %i\n", config->_frozen);
|
printf("_frozen = %i\n", config->_frozen);
|
||||||
printf("_coerce_c_locale = %i\n", config->_coerce_c_locale);
|
|
||||||
printf("_coerce_c_locale_warn = %i\n", config->_coerce_c_locale_warn);
|
|
||||||
|
|
||||||
#undef ASSERT_EQUAL
|
#undef ASSERT_EQUAL
|
||||||
#undef ASSERT_STR_EQUAL
|
#undef ASSERT_STR_EQUAL
|
||||||
|
@ -482,6 +482,8 @@ static int test_init_from_config(void)
|
||||||
putenv("PYTHONMALLOCSTATS=0");
|
putenv("PYTHONMALLOCSTATS=0");
|
||||||
config.malloc_stats = 1;
|
config.malloc_stats = 1;
|
||||||
|
|
||||||
|
/* FIXME: test coerce_c_locale and coerce_c_locale_warn */
|
||||||
|
|
||||||
putenv("PYTHONUTF8=0");
|
putenv("PYTHONUTF8=0");
|
||||||
Py_UTF8Mode = 0;
|
Py_UTF8Mode = 0;
|
||||||
config.utf8_mode = 1;
|
config.utf8_mode = 1;
|
||||||
|
@ -604,7 +606,8 @@ static int test_init_isolated(void)
|
||||||
/* Test _PyCoreConfig.isolated=1 */
|
/* Test _PyCoreConfig.isolated=1 */
|
||||||
_PyCoreConfig config = _PyCoreConfig_INIT;
|
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||||
|
|
||||||
/* Set utf8_mode to not depend on the locale */
|
/* Set coerce_c_locale and utf8_mode to not depend on the locale */
|
||||||
|
config.coerce_c_locale = 0;
|
||||||
config.utf8_mode = 0;
|
config.utf8_mode = 0;
|
||||||
/* Use path starting with "./" avoids a search along the PATH */
|
/* Use path starting with "./" avoids a search along the PATH */
|
||||||
config.program_name = L"./_testembed";
|
config.program_name = L"./_testembed";
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
int
|
int
|
||||||
wmain(int argc, wchar_t **argv)
|
wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
return _Py_WindowsMain(argc, argv);
|
return Py_Main(argc, argv);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|
|
@ -303,8 +303,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
COPY_ATTR(dump_refs);
|
COPY_ATTR(dump_refs);
|
||||||
COPY_ATTR(malloc_stats);
|
COPY_ATTR(malloc_stats);
|
||||||
|
|
||||||
COPY_ATTR(_coerce_c_locale);
|
COPY_ATTR(coerce_c_locale);
|
||||||
COPY_ATTR(_coerce_c_locale_warn);
|
COPY_ATTR(coerce_c_locale_warn);
|
||||||
COPY_ATTR(utf8_mode);
|
COPY_ATTR(utf8_mode);
|
||||||
|
|
||||||
COPY_WSTR_ATTR(pycache_prefix);
|
COPY_WSTR_ATTR(pycache_prefix);
|
||||||
|
@ -705,17 +705,6 @@ config_init_utf8_mode(_PyCoreConfig *config)
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MS_WINDOWS
|
|
||||||
/* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
|
|
||||||
const char *ctype_loc = setlocale(LC_CTYPE, NULL);
|
|
||||||
if (ctype_loc != NULL
|
|
||||||
&& (strcmp(ctype_loc, "C") == 0 || strcmp(ctype_loc, "POSIX") == 0))
|
|
||||||
{
|
|
||||||
config->utf8_mode = 1;
|
|
||||||
return _Py_INIT_OK();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +808,23 @@ config_read_env_vars(_PyCoreConfig *config)
|
||||||
config->malloc_stats = 1;
|
config->malloc_stats = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
|
||||||
|
if (env) {
|
||||||
|
if (strcmp(env, "0") == 0) {
|
||||||
|
if (config->coerce_c_locale < 0) {
|
||||||
|
config->coerce_c_locale = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(env, "warn") == 0) {
|
||||||
|
config->coerce_c_locale_warn = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (config->coerce_c_locale < 0) {
|
||||||
|
config->coerce_c_locale = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t *path;
|
wchar_t *path;
|
||||||
int res = _PyCoreConfig_GetEnvDup(config, &path,
|
int res = _PyCoreConfig_GetEnvDup(config, &path,
|
||||||
L"PYTHONPATH", "PYTHONPATH");
|
L"PYTHONPATH", "PYTHONPATH");
|
||||||
|
@ -958,76 +964,28 @@ config_read_complex_options(_PyCoreConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static _PyInitError
|
static void
|
||||||
config_init_coerce_c_locale(_PyCoreConfig *config)
|
config_init_locale(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
const wchar_t *xopt = config_get_xoption(config, L"coerce_c_locale");
|
if (config->coerce_c_locale < 0) {
|
||||||
if (xopt) {
|
|
||||||
wchar_t *sep = wcschr(xopt, L'=');
|
|
||||||
if (sep) {
|
|
||||||
xopt = sep + 1;
|
|
||||||
if (wcscmp(xopt, L"1") == 0) {
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
config->_coerce_c_locale = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (wcscmp(xopt, L"0") == 0) {
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
config->_coerce_c_locale = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (wcscmp(xopt, L"warn") == 0) {
|
|
||||||
if (config->_coerce_c_locale_warn < 0) {
|
|
||||||
config->_coerce_c_locale_warn = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _Py_INIT_USER_ERR("invalid -X coerce_c_locale option value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
config->_coerce_c_locale = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->_coerce_c_locale_warn < 0) {
|
|
||||||
config->_coerce_c_locale_warn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
|
|
||||||
if (env) {
|
|
||||||
if (strcmp(env, "0") == 0) {
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
config->_coerce_c_locale = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp(env, "warn") == 0) {
|
|
||||||
if (config->_coerce_c_locale_warn < 0) {
|
|
||||||
config->_coerce_c_locale_warn = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
config->_coerce_c_locale = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->_coerce_c_locale_warn < 0) {
|
|
||||||
config->_coerce_c_locale_warn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->_coerce_c_locale < 0) {
|
|
||||||
/* The C locale enables the C locale coercion (PEP 538) */
|
/* The C locale enables the C locale coercion (PEP 538) */
|
||||||
if (_Py_LegacyLocaleDetected()) {
|
if (_Py_LegacyLocaleDetected()) {
|
||||||
config->_coerce_c_locale = 1;
|
config->coerce_c_locale = 1;
|
||||||
return _Py_INIT_OK();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _Py_INIT_OK();
|
#ifndef MS_WINDOWS
|
||||||
|
if (config->utf8_mode < 0) {
|
||||||
|
/* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
|
||||||
|
const char *ctype_loc = setlocale(LC_CTYPE, NULL);
|
||||||
|
if (ctype_loc != NULL
|
||||||
|
&& (strcmp(ctype_loc, "C") == 0
|
||||||
|
|| strcmp(ctype_loc, "POSIX") == 0))
|
||||||
|
{
|
||||||
|
config->utf8_mode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1333,11 +1291,8 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->_coerce_c_locale < 0 || config->_coerce_c_locale_warn < 0) {
|
if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
|
||||||
err = config_init_coerce_c_locale(config);
|
config_init_locale(config);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->_install_importlib) {
|
if (config->_install_importlib) {
|
||||||
|
@ -1366,11 +1321,8 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
if (config->tracemalloc < 0) {
|
if (config->tracemalloc < 0) {
|
||||||
config->tracemalloc = 0;
|
config->tracemalloc = 0;
|
||||||
}
|
}
|
||||||
if (config->_coerce_c_locale < 0) {
|
if (config->coerce_c_locale < 0) {
|
||||||
config->_coerce_c_locale = 0;
|
config->coerce_c_locale = 0;
|
||||||
}
|
|
||||||
if (config->_coerce_c_locale_warn < 0) {
|
|
||||||
config->_coerce_c_locale_warn = 0;
|
|
||||||
}
|
}
|
||||||
if (config->utf8_mode < 0) {
|
if (config->utf8_mode < 0) {
|
||||||
config->utf8_mode = 0;
|
config->utf8_mode = 0;
|
||||||
|
@ -1391,8 +1343,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(config->_coerce_c_locale >= 0);
|
assert(config->coerce_c_locale >= 0);
|
||||||
assert(config->_coerce_c_locale_warn >= 0);
|
|
||||||
assert(config->use_environment >= 0);
|
assert(config->use_environment >= 0);
|
||||||
assert(config->filesystem_encoding != NULL);
|
assert(config->filesystem_encoding != NULL);
|
||||||
assert(config->filesystem_errors != NULL);
|
assert(config->filesystem_errors != NULL);
|
||||||
|
|
|
@ -295,7 +295,7 @@ static const char *_C_LOCALE_WARNING =
|
||||||
static void
|
static void
|
||||||
_emit_stderr_warning_for_legacy_locale(const _PyCoreConfig *core_config)
|
_emit_stderr_warning_for_legacy_locale(const _PyCoreConfig *core_config)
|
||||||
{
|
{
|
||||||
if (core_config->_coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
|
if (core_config->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
|
||||||
PySys_FormatStderr("%s", _C_LOCALE_WARNING);
|
PySys_FormatStderr("%s", _C_LOCALE_WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue