Skip to content

Commit 7a0791b

Browse files
authored
bpo-34589: C locale coercion off by default (GH-9073)
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). test_embed: get_filesystem_encoding() doesn't have to set PYTHONUTF8 nor PYTHONCOERCECLOCALE, these variables are already set in the parent.
1 parent 1fa2ec4 commit 7a0791b

File tree

8 files changed

+49
-16
lines changed

8 files changed

+49
-16
lines changed

Include/coreconfig.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,21 @@ typedef struct {
301301
variable. The option is also enabled if the LC_CTYPE locale is "C"
302302
and a target locale (ex: "C.UTF-8") is supported by the platform.
303303
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+
304308
See also the _coerce_c_locale_warn option. */
305309
int _coerce_c_locale;
306310

307311
/* C locale coercion warning (PEP 538).
308312
309313
Enabled by the PYTHONCOERCECLOCALE=warn environment variable.
310314
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+
311319
See also the _coerce_c_locale option. */
312320
int _coerce_c_locale_warn;
313321

@@ -328,7 +336,8 @@ typedef struct {
328336
.use_hash_seed = -1, \
329337
.faulthandler = -1, \
330338
.tracemalloc = -1, \
331-
._coerce_c_locale = -1, \
339+
._coerce_c_locale = 0, \
340+
._coerce_c_locale_warn = 0, \
332341
.utf8_mode = -1, \
333342
.argc = -1, \
334343
.nmodule_search_path = -1, \

Include/pylifecycle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ 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
8689
PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv);
90+
# endif
8791
#endif
8892

8993
/* In getpath.c */

Lib/test/test_embed.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,6 @@ 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'
331327
proc = subprocess.run(args, text=True, env=env,
332328
stdout=subprocess.PIPE,
333329
stderr=subprocess.PIPE)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Py_Initialize() and Py_Main() cannot enable the C locale coercion (PEP 538)
2+
anymore: it is always disabled. It can now only be enabled by the Python
3+
program ("python3).

Modules/main.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,8 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
17001700

17011701

17021702
static int
1703-
pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
1703+
pymain_init(_PyMain *pymain, PyInterpreterState **interp_p,
1704+
int use_c_locale_coercion)
17041705
{
17051706
/* 754 requires that FP exceptions run in "no stop" mode by default,
17061707
* and until C vendors implement C99's ways to control FP exceptions,
@@ -1713,6 +1714,11 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
17131714

17141715
_PyCoreConfig local_config = _PyCoreConfig_INIT;
17151716
_PyCoreConfig *config = &local_config;
1717+
if (use_c_locale_coercion) {
1718+
/* set to -1 to be able to enable the feature */
1719+
config->_coerce_c_locale = -1;
1720+
config->_coerce_c_locale_warn = -1;
1721+
}
17161722

17171723
_PyCoreConfig_GetGlobalConfig(config);
17181724

@@ -1747,10 +1753,10 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
17471753

17481754

17491755
static int
1750-
pymain_main(_PyMain *pymain)
1756+
pymain_main(_PyMain *pymain, int use_c_locale_coercion)
17511757
{
17521758
PyInterpreterState *interp;
1753-
int res = pymain_init(pymain, &interp);
1759+
int res = pymain_init(pymain, &interp, use_c_locale_coercion);
17541760
if (res != 1) {
17551761
if (pymain_run_python(pymain, interp) < 0) {
17561762
_Py_FatalInitError(pymain->err);
@@ -1777,10 +1783,22 @@ Py_Main(int argc, wchar_t **argv)
17771783
pymain.argc = argc;
17781784
pymain.wchar_argv = argv;
17791785

1780-
return pymain_main(&pymain);
1786+
return pymain_main(&pymain, 0);
17811787
}
17821788

17831789

1790+
#ifdef MS_WINDOWS
1791+
int
1792+
_Py_WindowsMain(int argc, wchar_t **argv)
1793+
{
1794+
_PyMain pymain = _PyMain_INIT;
1795+
pymain.use_bytes_argv = 0;
1796+
pymain.argc = argc;
1797+
pymain.wchar_argv = argv;
1798+
1799+
return pymain_main(&pymain, 1);
1800+
}
1801+
#else
17841802
int
17851803
_Py_UnixMain(int argc, char **argv)
17861804
{
@@ -1789,8 +1807,9 @@ _Py_UnixMain(int argc, char **argv)
17891807
pymain.argc = argc;
17901808
pymain.bytes_argv = argv;
17911809

1792-
return pymain_main(&pymain);
1810+
return pymain_main(&pymain, 1);
17931811
}
1812+
#endif
17941813

17951814

17961815
/* this is gonna seem *real weird*, but if you put some other code between

Programs/_testembed.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,6 @@ static int test_init_from_config(void)
482482
putenv("PYTHONMALLOCSTATS=0");
483483
config.malloc_stats = 1;
484484

485-
/* FIXME: test _coerce_c_locale and _coerce_c_locale_warn */
486-
487485
putenv("PYTHONUTF8=0");
488486
Py_UTF8Mode = 0;
489487
config.utf8_mode = 1;
@@ -606,8 +604,7 @@ static int test_init_isolated(void)
606604
/* Test _PyCoreConfig.isolated=1 */
607605
_PyCoreConfig config = _PyCoreConfig_INIT;
608606

609-
/* Set _coerce_c_locale and utf8_mode to not depend on the locale */
610-
config._coerce_c_locale = 0;
607+
/* Set utf8_mode to not depend on the locale */
611608
config.utf8_mode = 0;
612609
/* Use path starting with "./" avoids a search along the PATH */
613610
config.program_name = L"./_testembed";

Programs/python.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
int
77
wmain(int argc, wchar_t **argv)
88
{
9-
return Py_Main(argc, argv);
9+
return _Py_WindowsMain(argc, argv);
1010
}
1111
#else
1212
int

Python/coreconfig.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,9 @@ config_read_env_vars(_PyCoreConfig *config)
816816
}
817817
}
818818
else if (strcmp(env, "warn") == 0) {
819-
config->_coerce_c_locale_warn = 1;
819+
if (config->_coerce_c_locale_warn < 0) {
820+
config->_coerce_c_locale_warn = 1;
821+
}
820822
}
821823
else {
822824
if (config->_coerce_c_locale < 0) {
@@ -1324,6 +1326,9 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
13241326
if (config->_coerce_c_locale < 0) {
13251327
config->_coerce_c_locale = 0;
13261328
}
1329+
if (config->_coerce_c_locale_warn < 0) {
1330+
config->_coerce_c_locale_warn = 0;
1331+
}
13271332
if (config->utf8_mode < 0) {
13281333
config->utf8_mode = 0;
13291334
}

0 commit comments

Comments
 (0)