Skip to content

Commit 06e7608

Browse files
authored
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 commit dbdee00. * Revert "bpo-34589: C locale coercion off by default (GH-9073)" This reverts commit 7a0791b. * Revert "bpo-34589: Make _PyCoreConfig.coerce_c_locale private (GH-9371)" This reverts commit 188ebfa.
1 parent 76531e2 commit 06e7608

File tree

17 files changed

+87
-242
lines changed

17 files changed

+87
-242
lines changed

Doc/using/cmdline.rst

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -438,22 +438,13 @@ Miscellaneous options
438438
* Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to
439439
``True``
440440

441-
* ``-X utf8`` enables UTF-8 mode (:pep:`540`) for operating system interfaces, overriding
441+
* ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding
442442
the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8
443443
mode (even when it would otherwise activate automatically).
444444
See :envvar:`PYTHONUTF8` for more details.
445445
* ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel
446446
tree rooted at the given directory instead of to the code tree. See also
447447
:envvar:`PYTHONPYCACHEPREFIX`.
448-
* ``-X coerce_c_locale`` or ``-X coerce_c_locale=1`` tries to coerce the C
449-
locale (:pep:`538`).
450-
``-X coerce_c_locale=0`` skips coercing the legacy ASCII-based C and POSIX
451-
locales to a more capable UTF-8 based alternative.
452-
``-X coerce_c_locale=warn`` will cause Python to emit warning messages on
453-
``stderr`` if either the locale coercion activates, or else if a locale
454-
that *would* have triggered coercion is still active when the Python
455-
runtime is initialized.
456-
See :envvar:`PYTHONCOERCECLOCALE` for more details.
457448

458449
It also allows passing arbitrary values and retrieving them through the
459450
:data:`sys._xoptions` dictionary.
@@ -473,9 +464,6 @@ Miscellaneous options
473464
.. versionadded:: 3.7
474465
The ``-X importtime``, ``-X dev`` and ``-X utf8`` options.
475466

476-
.. versionadded:: 3.7.1
477-
The ``-X coerce_c_locale`` option.
478-
479467
.. versionadded:: 3.8
480468
The ``-X pycache_prefix`` option.
481469

@@ -862,8 +850,6 @@ conflict.
862850
order to force the interpreter to use ``ASCII`` instead of ``UTF-8`` for
863851
system interfaces.
864852

865-
Also available as the :option:`-X` ``coerce_c_locale`` option.
866-
867853
Availability: \*nix
868854

869855
.. versionadded:: 3.7

Doc/whatsnew/3.7.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,10 +2494,3 @@ versions, it respected an ill-defined subset of those environment variables,
24942494
while in Python 3.7.0 it didn't read any of them due to :issue:`34247`). If
24952495
this behavior is unwanted, set :c:data:`Py_IgnoreEnvironmentFlag` to 1 before
24962496
calling :c:func:`Py_Initialize`.
2497-
2498-
:c:func:`Py_Initialize` and :c:func:`Py_Main` cannot enable the C locale
2499-
coercion (:pep:`538`) anymore: it is always disabled. It can now only be
2500-
enabled by the Python program ("python3).
2501-
2502-
New :option:`-X` ``coerce_c_locale`` command line option to control C locale
2503-
coercion (:pep:`538`).

Include/coreconfig.h

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ typedef struct {
6363
int show_alloc_count; /* -X showalloccount */
6464
int dump_refs; /* PYTHONDUMPREFS */
6565
int malloc_stats; /* PYTHONMALLOCSTATS */
66+
int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */
67+
int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */
6668

6769
/* Python filesystem encoding and error handler:
6870
sys.getfilesystemencoding() and sys.getfilesystemencodeerrors().
@@ -295,30 +297,6 @@ typedef struct {
295297
If set to -1 (default), inherit Py_FrozenFlag value. */
296298
int _frozen;
297299

298-
/* C locale coercion (PEP 538).
299-
300-
The option is enabled by the PYTHONCOERCECLOCALE environment
301-
variable. The option is also enabled if the LC_CTYPE locale is "C"
302-
and a target locale (ex: "C.UTF-8") is supported by the platform.
303-
304-
Py_Initialize() and Py_Main() must not enable C locale coercion: it is
305-
always disabled. The option can only be enabled by the Python program
306-
("python3).
307-
308-
See also the _coerce_c_locale_warn option. */
309-
int _coerce_c_locale;
310-
311-
/* C locale coercion warning (PEP 538).
312-
313-
Enabled by the PYTHONCOERCECLOCALE=warn environment variable.
314-
315-
Py_Initialize() and Py_Main() must not enable C locale coercion warning:
316-
it is always disabled. The warning can only be enabled by the Python
317-
program ("python3).
318-
319-
See also the _coerce_c_locale option. */
320-
int _coerce_c_locale_warn;
321-
322300
} _PyCoreConfig;
323301

324302
#ifdef MS_WINDOWS
@@ -336,8 +314,7 @@ typedef struct {
336314
.use_hash_seed = -1, \
337315
.faulthandler = -1, \
338316
.tracemalloc = -1, \
339-
._coerce_c_locale = 0, \
340-
._coerce_c_locale_warn = 0, \
317+
.coerce_c_locale = -1, \
341318
.utf8_mode = -1, \
342319
.argc = -1, \
343320
.nmodule_search_path = -1, \

Include/pylifecycle.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,7 @@ PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
8383
/* Bootstrap __main__ (defined in Modules/main.c) */
8484
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
8585
#ifdef Py_BUILD_CORE
86-
# ifdef MS_WINDOWS
87-
PyAPI_FUNC(int) _Py_WindowsMain(int argc, wchar_t **argv);
88-
# else
8986
PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv);
90-
# endif
9187
#endif
9288

9389
/* In getpath.c */

Lib/test/test_c_locale_coercion.py

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def _handle_output_variations(data):
139139
return data
140140

141141
@classmethod
142-
def get_child_details(cls, env_vars, xoption=None):
142+
def get_child_details(cls, env_vars):
143143
"""Retrieves fsencoding and standard stream details from a child process
144144
145145
Returns (encoding_details, stderr_lines):
@@ -150,11 +150,10 @@ def get_child_details(cls, env_vars, xoption=None):
150150
The child is run in isolated mode if the current interpreter supports
151151
that.
152152
"""
153-
args = []
154-
if xoption:
155-
args.extend(("-X", f"coerce_c_locale={xoption}"))
156-
args.extend(("-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT))
157-
result, py_cmd = run_python_until_end(*args, **env_vars)
153+
result, py_cmd = run_python_until_end(
154+
"-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT,
155+
**env_vars
156+
)
158157
if not result.rc == 0:
159158
result.fail(py_cmd)
160159
# All subprocess outputs in this test case should be pure ASCII
@@ -213,16 +212,15 @@ def _check_child_encoding_details(self,
213212
expected_fs_encoding,
214213
expected_stream_encoding,
215214
expected_warnings,
216-
coercion_expected,
217-
xoption=None):
215+
coercion_expected):
218216
"""Check the C locale handling for the given process environment
219217
220218
Parameters:
221219
expected_fs_encoding: expected sys.getfilesystemencoding() result
222220
expected_stream_encoding: expected encoding for standard streams
223221
expected_warning: stderr output to expect (if any)
224222
"""
225-
result = EncodingDetails.get_child_details(env_vars, xoption)
223+
result = EncodingDetails.get_child_details(env_vars)
226224
encoding_details, stderr_lines = result
227225
expected_details = EncodingDetails.get_expected_details(
228226
coercion_expected,
@@ -292,7 +290,6 @@ def _check_c_locale_coercion(self,
292290
coerce_c_locale,
293291
expected_warnings=None,
294292
coercion_expected=True,
295-
use_xoption=False,
296293
**extra_vars):
297294
"""Check the C locale handling for various configurations
298295
@@ -322,12 +319,8 @@ def _check_c_locale_coercion(self,
322319
"PYTHONCOERCECLOCALE": "",
323320
}
324321
base_var_dict.update(extra_vars)
325-
xoption = None
326322
if coerce_c_locale is not None:
327-
if use_xoption:
328-
xoption = coerce_c_locale
329-
else:
330-
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
323+
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
331324

332325
# Check behaviour for the default locale
333326
with self.subTest(default_locale=True,
@@ -349,8 +342,7 @@ def _check_c_locale_coercion(self,
349342
fs_encoding,
350343
stream_encoding,
351344
_expected_warnings,
352-
_coercion_expected,
353-
xoption=xoption)
345+
_coercion_expected)
354346

355347
# Check behaviour for explicitly configured locales
356348
for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS:
@@ -365,8 +357,7 @@ def _check_c_locale_coercion(self,
365357
fs_encoding,
366358
stream_encoding,
367359
expected_warnings,
368-
coercion_expected,
369-
xoption=xoption)
360+
coercion_expected)
370361

371362
def test_PYTHONCOERCECLOCALE_not_set(self):
372363
# This should coerce to the first available target locale by default
@@ -413,32 +404,6 @@ def test_LC_ALL_set_to_C(self):
413404
expected_warnings=[LEGACY_LOCALE_WARNING],
414405
coercion_expected=False)
415406

416-
def test_xoption_set_to_1(self):
417-
self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale="1",
418-
use_xoption=True)
419-
420-
def test_xoption_set_to_zero(self):
421-
# The setting "0" should result in the locale coercion being disabled
422-
self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,
423-
EXPECTED_C_LOCALE_STREAM_ENCODING,
424-
coerce_c_locale="0",
425-
coercion_expected=False,
426-
use_xoption=True)
427-
# Setting LC_ALL=C shouldn't make any difference to the behaviour
428-
self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,
429-
EXPECTED_C_LOCALE_STREAM_ENCODING,
430-
coerce_c_locale="0",
431-
LC_ALL="C",
432-
coercion_expected=False,
433-
use_xoption=True)
434-
435-
def test_xoption_set_to_warn(self):
436-
# -X coerce_c_locale=warn enables runtime warnings for legacy locales
437-
self._check_c_locale_coercion("utf-8", "utf-8",
438-
coerce_c_locale="warn",
439-
expected_warnings=[CLI_COERCION_WARNING],
440-
use_xoption=True)
441-
442407
def test_main():
443408
test.support.run_unittest(
444409
LocaleConfigurationTests,

Lib/test/test_cmd_line.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,13 @@ def test_undecodable_code(self):
159159
env = os.environ.copy()
160160
# Use C locale to get ascii for the locale encoding
161161
env['LC_ALL'] = 'C'
162+
env['PYTHONCOERCECLOCALE'] = '0'
162163
code = (
163164
b'import locale; '
164165
b'print(ascii("' + undecodable + b'"), '
165166
b'locale.getpreferredencoding())')
166167
p = subprocess.Popen(
167-
[sys.executable,
168-
# Disable C locale coercion and UTF-8 Mode to not use UTF-8
169-
"-X", "coerce_c_locale=0",
170-
"-X", "utf8=0",
171-
"-c", code],
168+
[sys.executable, "-c", code],
172169
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
173170
env=env)
174171
stdout, stderr = p.communicate()

Lib/test/test_embed.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
277277
'filesystem_errors': None,
278278

279279
'utf8_mode': 0,
280+
'coerce_c_locale': 0,
281+
'coerce_c_locale_warn': 0,
280282

281283
'pycache_prefix': NULL_STR,
282284
'program_name': './_testembed',
@@ -304,8 +306,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
304306
'_install_importlib': 1,
305307
'_check_hash_pycs_mode': 'default',
306308
'_frozen': 0,
307-
'_coerce_c_locale': 0,
308-
'_coerce_c_locale_warn': 0,
309309
}
310310

311311
def get_stdio_encoding(self, env):
@@ -324,6 +324,10 @@ def get_filesystem_encoding(self, isolated, env):
324324
'print(sys.getfilesystemencoding(), '
325325
'sys.getfilesystemencodeerrors())')
326326
args = (sys.executable, '-c', code)
327+
env = dict(env)
328+
if not isolated:
329+
env['PYTHONCOERCECLOCALE'] = '0'
330+
env['PYTHONUTF8'] = '0'
327331
proc = subprocess.run(args, text=True, env=env,
328332
stdout=subprocess.PIPE,
329333
stderr=subprocess.PIPE)

Lib/test/test_sys.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,9 @@ def test_getfilesystemencoding(self):
656656

657657
def c_locale_get_error_handler(self, locale, isolated=False, encoding=None):
658658
# Force the POSIX locale
659-
env = dict(os.environ)
659+
env = os.environ.copy()
660660
env["LC_ALL"] = locale
661+
env["PYTHONCOERCECLOCALE"] = "0"
661662
code = '\n'.join((
662663
'import sys',
663664
'def dump(name):',
@@ -667,10 +668,7 @@ def c_locale_get_error_handler(self, locale, isolated=False, encoding=None):
667668
'dump("stdout")',
668669
'dump("stderr")',
669670
))
670-
args = [sys.executable,
671-
"-X", "utf8=0",
672-
"-X", "coerce_c_locale=0",
673-
"-c", code]
671+
args = [sys.executable, "-X", "utf8=0", "-c", code]
674672
if isolated:
675673
args.append("-I")
676674
if encoding is not None:

Lib/test/test_utf8_mode.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ def posix_locale(self):
2727
return (loc in POSIX_LOCALES)
2828

2929
def get_output(self, *args, failure=False, **kw):
30-
# Always disable the C locale coercion (PEP 538)
31-
args = ('-X', 'coerce_c_locale=0', *args)
3230
kw = dict(self.DEFAULT_ENV, **kw)
3331
if failure:
3432
out = assert_python_failure(*args, **kw)
@@ -118,6 +116,7 @@ def test_filesystemencoding(self):
118116
# PYTHONLEGACYWINDOWSFSENCODING disables the UTF-8 mode
119117
# and has the priority over -X utf8 and PYTHONUTF8
120118
out = self.get_output('-X', 'utf8', '-c', code,
119+
PYTHONUTF8='strict',
121120
PYTHONLEGACYWINDOWSFSENCODING='1')
122121
self.assertEqual(out, 'mbcs/replace')
123122

Misc/NEWS.d/next/C API/2018-09-18-00-09-31.bpo-34589.C7bUpq.rst

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)