blob: a6d1346eb4e1f70f07f63ec2ab21088a1cfa85cc [file] [log] [blame]
Victor Stinner91b9ecf2019-03-01 17:52:56 +01001#include "Python.h"
2#include "pycore_coreconfig.h"
Victor Stinner6dcb5422019-03-05 02:44:12 +01003#include "pycore_getopt.h"
Victor Stinner5a02e0d2019-03-05 12:32:09 +01004#include "pycore_pystate.h" /* _PyRuntime_Initialize() */
5#include <locale.h> /* setlocale() */
Victor Stinner91b9ecf2019-03-01 17:52:56 +01006
7
8#define DECODE_LOCALE_ERR(NAME, LEN) \
9 (((LEN) == -2) \
Victor Stinnerdb719752019-05-01 05:35:33 +020010 ? _Py_INIT_ERR("cannot decode " NAME) \
Victor Stinner91b9ecf2019-03-01 17:52:56 +010011 : _Py_INIT_NO_MEMORY())
12
13
14/* --- File system encoding/errors -------------------------------- */
15
16/* The filesystem encoding is chosen by config_init_fs_encoding(),
Victor Stinner709d23d2019-05-02 14:56:30 -040017 see also initfsencoding().
18
19 Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
20 are encoded to UTF-8. */
Victor Stinner91b9ecf2019-03-01 17:52:56 +010021const char *Py_FileSystemDefaultEncoding = NULL;
22int Py_HasFileSystemDefaultEncoding = 0;
23const char *Py_FileSystemDefaultEncodeErrors = NULL;
24int _Py_HasFileSystemDefaultEncodeErrors = 0;
25
26void
27_Py_ClearFileSystemEncoding(void)
28{
29 if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
30 PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
31 Py_FileSystemDefaultEncoding = NULL;
32 }
33 if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) {
34 PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
35 Py_FileSystemDefaultEncodeErrors = NULL;
36 }
37}
38
39
40/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
41 global configuration variables. */
42int
43_Py_SetFileSystemEncoding(const char *encoding, const char *errors)
44{
45 char *encoding2 = _PyMem_RawStrdup(encoding);
46 if (encoding2 == NULL) {
47 return -1;
48 }
49
50 char *errors2 = _PyMem_RawStrdup(errors);
51 if (errors2 == NULL) {
52 PyMem_RawFree(encoding2);
53 return -1;
54 }
55
56 _Py_ClearFileSystemEncoding();
57
58 Py_FileSystemDefaultEncoding = encoding2;
59 Py_HasFileSystemDefaultEncoding = 0;
60
61 Py_FileSystemDefaultEncodeErrors = errors2;
62 _Py_HasFileSystemDefaultEncodeErrors = 0;
63 return 0;
64}
65
66
67/* --- _PyArgv ---------------------------------------------------- */
68
Victor Stinnerf8ba6f52019-03-26 16:58:50 +010069/* Decode bytes_argv using Py_DecodeLocale() */
Victor Stinner91b9ecf2019-03-01 17:52:56 +010070_PyInitError
Victor Stinner74f65682019-03-15 15:08:05 +010071_PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
Victor Stinner91b9ecf2019-03-01 17:52:56 +010072{
Victor Stinner74f65682019-03-15 15:08:05 +010073 _PyWstrList wargv = _PyWstrList_INIT;
Victor Stinner91b9ecf2019-03-01 17:52:56 +010074 if (args->use_bytes_argv) {
Victor Stinner74f65682019-03-15 15:08:05 +010075 size_t size = sizeof(wchar_t*) * args->argc;
76 wargv.items = (wchar_t **)PyMem_RawMalloc(size);
77 if (wargv.items == NULL) {
Victor Stinner91b9ecf2019-03-01 17:52:56 +010078 return _Py_INIT_NO_MEMORY();
79 }
80
Victor Stinner74f65682019-03-15 15:08:05 +010081 for (Py_ssize_t i = 0; i < args->argc; i++) {
Victor Stinner91b9ecf2019-03-01 17:52:56 +010082 size_t len;
83 wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len);
84 if (arg == NULL) {
Victor Stinner74f65682019-03-15 15:08:05 +010085 _PyWstrList_Clear(&wargv);
Victor Stinner91b9ecf2019-03-01 17:52:56 +010086 return DECODE_LOCALE_ERR("command line arguments",
87 (Py_ssize_t)len);
88 }
Victor Stinner74f65682019-03-15 15:08:05 +010089 wargv.items[i] = arg;
90 wargv.length++;
Victor Stinner91b9ecf2019-03-01 17:52:56 +010091 }
Victor Stinner74f65682019-03-15 15:08:05 +010092
93 _PyWstrList_Clear(list);
94 *list = wargv;
Victor Stinner91b9ecf2019-03-01 17:52:56 +010095 }
96 else {
Victor Stinner74f65682019-03-15 15:08:05 +010097 wargv.length = args->argc;
Victor Stinner6d1c4672019-05-20 11:02:00 +020098 wargv.items = (wchar_t **)args->wchar_argv;
Victor Stinner74f65682019-03-15 15:08:05 +010099 if (_PyWstrList_Copy(list, &wargv) < 0) {
100 return _Py_INIT_NO_MEMORY();
101 }
Victor Stinner91b9ecf2019-03-01 17:52:56 +0100102 }
Victor Stinner91b9ecf2019-03-01 17:52:56 +0100103 return _Py_INIT_OK();
104}
Victor Stinnercad1f742019-03-05 02:01:27 +0100105
106
Victor Stinner6dcb5422019-03-05 02:44:12 +0100107/* --- _PyPreCmdline ------------------------------------------------- */
108
Victor Stinnerfa153762019-03-20 04:25:38 +0100109void
110_PyPreCmdline_Clear(_PyPreCmdline *cmdline)
Victor Stinner6dcb5422019-03-05 02:44:12 +0100111{
Victor Stinner74f65682019-03-15 15:08:05 +0100112 _PyWstrList_Clear(&cmdline->argv);
113 _PyWstrList_Clear(&cmdline->xoptions);
Victor Stinner6dcb5422019-03-05 02:44:12 +0100114}
115
116
Victor Stinnerfa153762019-03-20 04:25:38 +0100117_PyInitError
Victor Stinnerf72346c2019-03-25 17:54:58 +0100118_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args)
Victor Stinnerfa153762019-03-20 04:25:38 +0100119{
120 return _PyArgv_AsWstrList(args, &cmdline->argv);
121}
122
123
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100124static void
Victor Stinnerf72346c2019-03-25 17:54:58 +0100125_PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
126{
127#define COPY_ATTR(ATTR) \
128 if (config->ATTR != -1) { \
129 cmdline->ATTR = config->ATTR; \
130 }
131
Victor Stinnerf72346c2019-03-25 17:54:58 +0100132 COPY_ATTR(isolated);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100133 COPY_ATTR(use_environment);
Victor Stinner20004952019-03-26 02:31:11 +0100134 COPY_ATTR(dev_mode);
135
136#undef COPY_ATTR
137}
138
139
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100140static void
Victor Stinner20004952019-03-26 02:31:11 +0100141_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
142{
143#define COPY_ATTR(ATTR) \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100144 config->ATTR = cmdline->ATTR
Victor Stinner20004952019-03-26 02:31:11 +0100145
Victor Stinner20004952019-03-26 02:31:11 +0100146 COPY_ATTR(isolated);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100147 COPY_ATTR(use_environment);
Victor Stinner20004952019-03-26 02:31:11 +0100148 COPY_ATTR(dev_mode);
Victor Stinnerf72346c2019-03-25 17:54:58 +0100149
150#undef COPY_ATTR
151}
152
153
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100154int
Victor Stinnera6fbc4e2019-03-25 18:37:10 +0100155_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
156{
157#define COPY_ATTR(ATTR) \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100158 config->ATTR = cmdline->ATTR
159
160 if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) {
161 return -1;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +0100162 }
163
Victor Stinnera6fbc4e2019-03-25 18:37:10 +0100164 COPY_ATTR(isolated);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100165 COPY_ATTR(use_environment);
Victor Stinner20004952019-03-26 02:31:11 +0100166 COPY_ATTR(dev_mode);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100167 return 0;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +0100168
169#undef COPY_ATTR
170}
171
172
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100173/* Parse the command line arguments */
174static _PyInitError
175precmdline_parse_cmdline(_PyPreCmdline *cmdline)
176{
Victor Stinner870b0352019-05-17 03:15:12 +0200177 const _PyWstrList *argv = &cmdline->argv;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100178
179 _PyOS_ResetGetOpt();
180 /* Don't log parsing errors into stderr here: _PyCoreConfig_Read()
181 is responsible for that */
182 _PyOS_opterr = 0;
183 do {
184 int longindex = -1;
185 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
186
187 if (c == EOF || c == 'c' || c == 'm') {
188 break;
189 }
190
191 switch (c) {
192 case 'E':
193 cmdline->use_environment = 0;
194 break;
195
196 case 'I':
197 cmdline->isolated = 1;
198 break;
199
200 case 'X':
201 {
202 if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) {
203 return _Py_INIT_NO_MEMORY();
204 }
205 break;
206 }
207
208 default:
209 /* ignore other argument:
210 handled by _PyCoreConfig_Read() */
211 break;
212 }
213 } while (1);
214
215 return _Py_INIT_OK();
216}
217
218
219_PyInitError
Victor Stinner6d1c4672019-05-20 11:02:00 +0200220_PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100221{
Victor Stinner6d1c4672019-05-20 11:02:00 +0200222 _PyPreCmdline_GetPreConfig(cmdline, preconfig);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100223
Victor Stinner6d1c4672019-05-20 11:02:00 +0200224 if (preconfig->parse_argv) {
225 _PyInitError err = precmdline_parse_cmdline(cmdline);
226 if (_Py_INIT_FAILED(err)) {
227 return err;
228 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100229 }
230
231 /* isolated, use_environment */
232 if (cmdline->isolated < 0) {
233 cmdline->isolated = 0;
234 }
235 if (cmdline->isolated > 0) {
236 cmdline->use_environment = 0;
237 }
238 if (cmdline->use_environment < 0) {
239 cmdline->use_environment = 0;
240 }
241
242 /* dev_mode */
Victor Stinnerbab0db62019-05-18 03:21:27 +0200243 if ((cmdline->dev_mode < 0)
244 && (_Py_get_xoption(&cmdline->xoptions, L"dev")
245 || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE")))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100246 {
247 cmdline->dev_mode = 1;
248 }
249 if (cmdline->dev_mode < 0) {
250 cmdline->dev_mode = 0;
251 }
252
253 assert(cmdline->use_environment >= 0);
254 assert(cmdline->isolated >= 0);
255 assert(cmdline->dev_mode >= 0);
256
257 return _Py_INIT_OK();
258}
259
260
Victor Stinnercad1f742019-03-05 02:01:27 +0100261/* --- _PyPreConfig ----------------------------------------------- */
262
Victor Stinnerbab0db62019-05-18 03:21:27 +0200263
Victor Stinnercab5d072019-05-17 19:01:14 +0200264void
Victor Stinner022be022019-05-22 23:58:50 +0200265_PyPreConfig_InitCompatConfig(_PyPreConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200266{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200267 memset(config, 0, sizeof(*config));
268
269 config->_config_version = _Py_CONFIG_VERSION;
Victor Stinner022be022019-05-22 23:58:50 +0200270 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200271 config->parse_argv = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200272 config->isolated = -1;
273 config->use_environment = -1;
274 config->configure_locale = 1;
Victor Stinner20e1e252019-05-23 04:12:27 +0200275
276 /* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
277 are disabled by default using the Compat configuration.
278
279 Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable
280 is ignored (even if use_environment=1). */
281 config->utf8_mode = 0;
282 config->coerce_c_locale = 0;
283 config->coerce_c_locale_warn = 0;
284
Victor Stinnerbab0db62019-05-18 03:21:27 +0200285 config->dev_mode = -1;
286 config->allocator = PYMEM_ALLOCATOR_NOT_SET;
287#ifdef MS_WINDOWS
288 config->legacy_windows_fs_encoding = -1;
289#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200290}
291
292
293void
294_PyPreConfig_InitPythonConfig(_PyPreConfig *config)
295{
Victor Stinner022be022019-05-22 23:58:50 +0200296 _PyPreConfig_InitCompatConfig(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200297
Victor Stinner022be022019-05-22 23:58:50 +0200298 config->_config_init = (int)_PyConfig_INIT_PYTHON;
299 config->isolated = 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200300 config->parse_argv = 1;
Victor Stinner022be022019-05-22 23:58:50 +0200301 config->use_environment = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200302 /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
303 depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE
304 environment variables. */
305 config->coerce_c_locale = -1;
306 config->coerce_c_locale_warn = -1;
307 config->utf8_mode = -1;
Victor Stinner022be022019-05-22 23:58:50 +0200308#ifdef MS_WINDOWS
309 config->legacy_windows_fs_encoding = 0;
310#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200311}
312
313
314void
315_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
316{
Victor Stinner022be022019-05-22 23:58:50 +0200317 _PyPreConfig_InitCompatConfig(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200318
Victor Stinner022be022019-05-22 23:58:50 +0200319 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200320 config->configure_locale = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200321 config->isolated = 1;
322 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200323 config->utf8_mode = 0;
324 config->dev_mode = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200325#ifdef MS_WINDOWS
326 config->legacy_windows_fs_encoding = 0;
327#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200328}
329
330
Victor Stinnerb5947842019-05-18 00:38:16 +0200331void
Victor Stinner6d1c4672019-05-20 11:02:00 +0200332_PyPreConfig_InitFromPreConfig(_PyPreConfig *config,
333 const _PyPreConfig *config2)
334{
Victor Stinner022be022019-05-22 23:58:50 +0200335 _PyPreConfig_InitCompatConfig(config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200336 _PyPreConfig_Copy(config, config2);
337}
338
339
340void
341_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config,
342 const _PyCoreConfig *coreconfig)
343{
Victor Stinner022be022019-05-22 23:58:50 +0200344 _PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200345 switch (config_init) {
Victor Stinner022be022019-05-22 23:58:50 +0200346 case _PyConfig_INIT_PYTHON:
Victor Stinner6d1c4672019-05-20 11:02:00 +0200347 _PyPreConfig_InitPythonConfig(config);
348 break;
Victor Stinner022be022019-05-22 23:58:50 +0200349 case _PyConfig_INIT_ISOLATED:
Victor Stinner6d1c4672019-05-20 11:02:00 +0200350 _PyPreConfig_InitIsolatedConfig(config);
351 break;
Victor Stinner022be022019-05-22 23:58:50 +0200352 case _PyConfig_INIT_COMPAT:
Victor Stinner6d1c4672019-05-20 11:02:00 +0200353 default:
Victor Stinner022be022019-05-22 23:58:50 +0200354 _PyPreConfig_InitCompatConfig(config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200355 }
356 _PyPreConfig_GetCoreConfig(config, coreconfig);
357}
358
359
360void
Victor Stinnercad1f742019-03-05 02:01:27 +0100361_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
362{
Victor Stinnercad1f742019-03-05 02:01:27 +0100363#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
364
Victor Stinner20e1e252019-05-23 04:12:27 +0200365 COPY_ATTR(_config_init);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200366 COPY_ATTR(parse_argv);
Victor Stinnercad1f742019-03-05 02:01:27 +0100367 COPY_ATTR(isolated);
368 COPY_ATTR(use_environment);
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200369 COPY_ATTR(configure_locale);
Victor Stinner20004952019-03-26 02:31:11 +0100370 COPY_ATTR(dev_mode);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100371 COPY_ATTR(coerce_c_locale);
372 COPY_ATTR(coerce_c_locale_warn);
Victor Stinnerb5947842019-05-18 00:38:16 +0200373 COPY_ATTR(utf8_mode);
374 COPY_ATTR(allocator);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100375#ifdef MS_WINDOWS
376 COPY_ATTR(legacy_windows_fs_encoding);
377#endif
Victor Stinnercad1f742019-03-05 02:01:27 +0100378
379#undef COPY_ATTR
Victor Stinnercad1f742019-03-05 02:01:27 +0100380}
381
382
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100383PyObject*
384_PyPreConfig_AsDict(const _PyPreConfig *config)
385{
386 PyObject *dict;
387
388 dict = PyDict_New();
389 if (dict == NULL) {
390 return NULL;
391 }
392
Victor Stinner6d1c4672019-05-20 11:02:00 +0200393#define SET_ITEM_INT(ATTR) \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100394 do { \
Victor Stinner6d1c4672019-05-20 11:02:00 +0200395 PyObject *obj = PyLong_FromLong(config->ATTR); \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100396 if (obj == NULL) { \
397 goto fail; \
398 } \
Victor Stinner6d1c4672019-05-20 11:02:00 +0200399 int res = PyDict_SetItemString(dict, #ATTR, obj); \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100400 Py_DECREF(obj); \
401 if (res < 0) { \
402 goto fail; \
403 } \
404 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100405
Victor Stinner20e1e252019-05-23 04:12:27 +0200406 SET_ITEM_INT(_config_init);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200407 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100408 SET_ITEM_INT(isolated);
409 SET_ITEM_INT(use_environment);
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200410 SET_ITEM_INT(configure_locale);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100411 SET_ITEM_INT(coerce_c_locale);
412 SET_ITEM_INT(coerce_c_locale_warn);
413 SET_ITEM_INT(utf8_mode);
414#ifdef MS_WINDOWS
415 SET_ITEM_INT(legacy_windows_fs_encoding);
416#endif
417 SET_ITEM_INT(dev_mode);
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200418 SET_ITEM_INT(allocator);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100419 return dict;
420
421fail:
422 Py_DECREF(dict);
423 return NULL;
424
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100425#undef SET_ITEM_INT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100426}
427
428
Victor Stinner5ac27a52019-03-27 13:40:14 +0100429void
Victor Stinnercab5d072019-05-17 19:01:14 +0200430_PyPreConfig_GetCoreConfig(_PyPreConfig *config,
Victor Stinner5ac27a52019-03-27 13:40:14 +0100431 const _PyCoreConfig *core_config)
432{
433#define COPY_ATTR(ATTR) \
434 if (core_config->ATTR != -1) { \
435 config->ATTR = core_config->ATTR; \
436 }
437
Victor Stinner6d1c4672019-05-20 11:02:00 +0200438 COPY_ATTR(parse_argv);
Victor Stinner5ac27a52019-03-27 13:40:14 +0100439 COPY_ATTR(isolated);
440 COPY_ATTR(use_environment);
441 COPY_ATTR(dev_mode);
442
443#undef COPY_ATTR
444}
445
446
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100447static void
Victor Stinnercad1f742019-03-05 02:01:27 +0100448_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
449{
Victor Stinner022be022019-05-22 23:58:50 +0200450 if (config->_config_init != _PyConfig_INIT_COMPAT) {
451 /* Python and Isolated configuration ignore global variables */
452 return;
453 }
454
Victor Stinnercad1f742019-03-05 02:01:27 +0100455#define COPY_FLAG(ATTR, VALUE) \
Victor Stinnercab5d072019-05-17 19:01:14 +0200456 if (config->ATTR < 0) { \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100457 config->ATTR = VALUE; \
458 }
Victor Stinnercad1f742019-03-05 02:01:27 +0100459#define COPY_NOT_FLAG(ATTR, VALUE) \
Victor Stinnercab5d072019-05-17 19:01:14 +0200460 if (config->ATTR < 0) { \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100461 config->ATTR = !(VALUE); \
462 }
Victor Stinnercad1f742019-03-05 02:01:27 +0100463
464 COPY_FLAG(isolated, Py_IsolatedFlag);
465 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner20e1e252019-05-23 04:12:27 +0200466 if (Py_UTF8Mode > 0) {
467 config->utf8_mode = Py_UTF8Mode;
468 }
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100469#ifdef MS_WINDOWS
470 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
471#endif
Victor Stinnercad1f742019-03-05 02:01:27 +0100472
473#undef COPY_FLAG
474#undef COPY_NOT_FLAG
475}
476
477
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100478static void
Victor Stinnercad1f742019-03-05 02:01:27 +0100479_PyPreConfig_SetGlobalConfig(const _PyPreConfig *config)
480{
481#define COPY_FLAG(ATTR, VAR) \
Victor Stinnercab5d072019-05-17 19:01:14 +0200482 if (config->ATTR >= 0) { \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100483 VAR = config->ATTR; \
484 }
Victor Stinnercad1f742019-03-05 02:01:27 +0100485#define COPY_NOT_FLAG(ATTR, VAR) \
Victor Stinnercab5d072019-05-17 19:01:14 +0200486 if (config->ATTR >= 0) { \
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100487 VAR = !config->ATTR; \
488 }
Victor Stinnercad1f742019-03-05 02:01:27 +0100489
490 COPY_FLAG(isolated, Py_IsolatedFlag);
491 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100492#ifdef MS_WINDOWS
493 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
494#endif
495 COPY_FLAG(utf8_mode, Py_UTF8Mode);
Victor Stinnercad1f742019-03-05 02:01:27 +0100496
497#undef COPY_FLAG
498#undef COPY_NOT_FLAG
499}
500
501
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100502const char*
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100503_Py_GetEnv(int use_environment, const char *name)
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100504{
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100505 assert(use_environment >= 0);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100506
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100507 if (!use_environment) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100508 return NULL;
509 }
510
511 const char *var = getenv(name);
512 if (var && var[0] != '\0') {
513 return var;
514 }
515 else {
516 return NULL;
517 }
518}
519
520
521int
522_Py_str_to_int(const char *str, int *result)
523{
524 const char *endptr = str;
525 errno = 0;
526 long value = strtol(str, (char **)&endptr, 10);
527 if (*endptr != '\0' || errno == ERANGE) {
528 return -1;
529 }
530 if (value < INT_MIN || value > INT_MAX) {
531 return -1;
532 }
533
534 *result = (int)value;
535 return 0;
536}
537
538
539void
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100540_Py_get_env_flag(int use_environment, int *flag, const char *name)
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100541{
Victor Stinnerf78a5e92019-03-26 00:03:15 +0100542 const char *var = _Py_GetEnv(use_environment, name);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100543 if (!var) {
544 return;
545 }
546 int value;
547 if (_Py_str_to_int(var, &value) < 0 || value < 0) {
548 /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
549 value = 1;
550 }
551 if (*flag < value) {
552 *flag = value;
553 }
554}
555
556
557const wchar_t*
Victor Stinner74f65682019-03-15 15:08:05 +0100558_Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name)
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100559{
Victor Stinner74f65682019-03-15 15:08:05 +0100560 for (Py_ssize_t i=0; i < xoptions->length; i++) {
561 const wchar_t *option = xoptions->items[i];
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100562 size_t len;
563 wchar_t *sep = wcschr(option, L'=');
564 if (sep != NULL) {
565 len = (sep - option);
566 }
567 else {
568 len = wcslen(option);
569 }
570 if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
571 return option;
572 }
573 }
574 return NULL;
575}
576
577
578static _PyInitError
579preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
580{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100581#ifdef MS_WINDOWS
582 if (config->legacy_windows_fs_encoding) {
583 config->utf8_mode = 0;
584 }
585#endif
586
587 if (config->utf8_mode >= 0) {
588 return _Py_INIT_OK();
589 }
590
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100591 const wchar_t *xopt;
Victor Stinner022be022019-05-22 23:58:50 +0200592 xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100593 if (xopt) {
594 wchar_t *sep = wcschr(xopt, L'=');
595 if (sep) {
596 xopt = sep + 1;
597 if (wcscmp(xopt, L"1") == 0) {
598 config->utf8_mode = 1;
599 }
600 else if (wcscmp(xopt, L"0") == 0) {
601 config->utf8_mode = 0;
602 }
603 else {
Victor Stinnerdb719752019-05-01 05:35:33 +0200604 return _Py_INIT_ERR("invalid -X utf8 option value");
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100605 }
606 }
607 else {
608 config->utf8_mode = 1;
609 }
610 return _Py_INIT_OK();
611 }
612
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100613 const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8");
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100614 if (opt) {
615 if (strcmp(opt, "1") == 0) {
616 config->utf8_mode = 1;
617 }
618 else if (strcmp(opt, "0") == 0) {
619 config->utf8_mode = 0;
620 }
621 else {
Victor Stinnerdb719752019-05-01 05:35:33 +0200622 return _Py_INIT_ERR("invalid PYTHONUTF8 environment "
623 "variable value");
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100624 }
625 return _Py_INIT_OK();
626 }
627
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100628
629#ifndef MS_WINDOWS
630 if (config->utf8_mode < 0) {
631 /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
632 const char *ctype_loc = setlocale(LC_CTYPE, NULL);
633 if (ctype_loc != NULL
634 && (strcmp(ctype_loc, "C") == 0
635 || strcmp(ctype_loc, "POSIX") == 0))
636 {
637 config->utf8_mode = 1;
638 }
639 }
640#endif
641
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100642 if (config->utf8_mode < 0) {
643 config->utf8_mode = 0;
644 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100645 return _Py_INIT_OK();
646}
647
648
649static void
650preconfig_init_coerce_c_locale(_PyPreConfig *config)
651{
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200652 if (!config->configure_locale) {
653 config->coerce_c_locale = 0;
654 config->coerce_c_locale_warn = 0;
655 return;
656 }
657
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100658 const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE");
659 if (env) {
660 if (strcmp(env, "0") == 0) {
661 if (config->coerce_c_locale < 0) {
662 config->coerce_c_locale = 0;
663 }
664 }
665 else if (strcmp(env, "warn") == 0) {
Victor Stinnercab5d072019-05-17 19:01:14 +0200666 if (config->coerce_c_locale_warn < 0) {
667 config->coerce_c_locale_warn = 1;
668 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100669 }
670 else {
671 if (config->coerce_c_locale < 0) {
672 config->coerce_c_locale = 1;
673 }
674 }
675 }
676
677 /* Test if coerce_c_locale equals to -1 or equals to 1:
678 PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced.
679 It is only coerced if if the LC_CTYPE locale is "C". */
Victor Stinnercab5d072019-05-17 19:01:14 +0200680 if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) {
681 /* The C locale enables the C locale coercion (PEP 538) */
Victor Stinner0f721472019-05-20 17:16:38 +0200682 if (_Py_LegacyLocaleDetected(0)) {
Victor Stinnercab5d072019-05-17 19:01:14 +0200683 config->coerce_c_locale = 2;
684 }
685 else {
686 config->coerce_c_locale = 0;
687 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100688 }
689
Victor Stinnercab5d072019-05-17 19:01:14 +0200690 if (config->coerce_c_locale_warn < 0) {
691 config->coerce_c_locale_warn = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100692 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100693}
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100694
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100695
696static _PyInitError
697preconfig_init_allocator(_PyPreConfig *config)
698{
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200699 if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
Victor Stinner25d13f32019-03-06 12:51:53 +0100700 /* bpo-34247. The PYTHONMALLOC environment variable has the priority
701 over PYTHONDEV env var and "-X dev" command line option.
702 For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory
703 allocators to "malloc" (and not to "debug"). */
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200704 const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC");
705 if (envvar) {
Victor Stinner6d1c4672019-05-20 11:02:00 +0200706 PyMemAllocatorName name;
707 if (_PyMem_GetAllocatorName(envvar, &name) < 0) {
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200708 return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator");
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100709 }
Victor Stinner6d1c4672019-05-20 11:02:00 +0200710 config->allocator = (int)name;
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100711 }
712 }
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100713
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200714 if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
715 config->allocator = PYMEM_ALLOCATOR_DEBUG;
Victor Stinner25d13f32019-03-06 12:51:53 +0100716 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100717 return _Py_INIT_OK();
718}
719
720
721static _PyInitError
Victor Stinner5ac27a52019-03-27 13:40:14 +0100722preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100723{
724 _PyInitError err;
725
Victor Stinner5ac27a52019-03-27 13:40:14 +0100726 err = _PyPreCmdline_Read(cmdline, config);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100727 if (_Py_INIT_FAILED(err)) {
728 return err;
729 }
730
731 _PyPreCmdline_SetPreConfig(cmdline, config);
732
733 /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */
734#ifdef MS_WINDOWS
735 _Py_get_env_flag(config->use_environment,
736 &config->legacy_windows_fs_encoding,
737 "PYTHONLEGACYWINDOWSFSENCODING");
738#endif
739
740 preconfig_init_coerce_c_locale(config);
741
742 err = preconfig_init_utf8_mode(config, cmdline);
743 if (_Py_INIT_FAILED(err)) {
744 return err;
745 }
746
747 /* allocator */
748 err = preconfig_init_allocator(config);
749 if (_Py_INIT_FAILED(err)) {
750 return err;
751 }
Victor Stinner25d13f32019-03-06 12:51:53 +0100752
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100753 assert(config->coerce_c_locale >= 0);
Victor Stinnercab5d072019-05-17 19:01:14 +0200754 assert(config->coerce_c_locale_warn >= 0);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100755#ifdef MS_WINDOWS
756 assert(config->legacy_windows_fs_encoding >= 0);
757#endif
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100758 assert(config->utf8_mode >= 0);
Victor Stinner6dcb5422019-03-05 02:44:12 +0100759 assert(config->isolated >= 0);
Victor Stinnercad1f742019-03-05 02:01:27 +0100760 assert(config->use_environment >= 0);
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100761 assert(config->dev_mode >= 0);
Victor Stinnercad1f742019-03-05 02:01:27 +0100762
763 return _Py_INIT_OK();
764}
765
766
Victor Stinner4fffd382019-03-06 01:44:31 +0100767/* Read the configuration from:
768
769 - command line arguments
770 - environment variables
771 - Py_xxx global configuration variables
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100772 - the LC_CTYPE locale */
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100773_PyInitError
Victor Stinner5ac27a52019-03-27 13:40:14 +0100774_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100775{
776 _PyInitError err;
777
778 err = _PyRuntime_Initialize();
779 if (_Py_INIT_FAILED(err)) {
780 return err;
781 }
782
Victor Stinnerf29084d2019-03-20 02:20:13 +0100783 _PyPreConfig_GetGlobalConfig(config);
784
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100785 /* Copy LC_CTYPE locale, since it's modified later */
786 const char *loc = setlocale(LC_CTYPE, NULL);
787 if (loc == NULL) {
788 return _Py_INIT_ERR("failed to LC_CTYPE locale");
789 }
790 char *init_ctype_locale = _PyMem_RawStrdup(loc);
791 if (init_ctype_locale == NULL) {
792 return _Py_INIT_NO_MEMORY();
793 }
794
795 /* Save the config to be able to restore it if encodings change */
Victor Stinnercab5d072019-05-17 19:01:14 +0200796 _PyPreConfig save_config;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200797 _PyPreConfig_InitFromPreConfig(&save_config, config);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100798
799 /* Set LC_CTYPE to the user preferred locale */
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200800 if (config->configure_locale) {
801 _Py_SetLocaleFromEnv(LC_CTYPE);
802 }
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100803
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100804 _PyPreCmdline cmdline = _PyPreCmdline_INIT;
Victor Stinner6a8c3132019-04-05 11:44:04 +0200805 int init_utf8_mode = Py_UTF8Mode;
806#ifdef MS_WINDOWS
807 int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag;
808#endif
809
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100810 if (args) {
811 err = _PyPreCmdline_SetArgv(&cmdline, args);
812 if (_Py_INIT_FAILED(err)) {
813 goto done;
814 }
815 }
816
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100817 int locale_coerced = 0;
818 int loops = 0;
819
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100820 while (1) {
821 int utf8_mode = config->utf8_mode;
822
823 /* Watchdog to prevent an infinite loop */
824 loops++;
825 if (loops == 3) {
826 err = _Py_INIT_ERR("Encoding changed twice while "
827 "reading the configuration");
828 goto done;
829 }
830
831 /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend
832 on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */
833 Py_UTF8Mode = config->utf8_mode;
834#ifdef MS_WINDOWS
835 Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
836#endif
837
Victor Stinner5ac27a52019-03-27 13:40:14 +0100838 err = preconfig_read(config, &cmdline);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100839 if (_Py_INIT_FAILED(err)) {
840 goto done;
841 }
842
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100843 /* The legacy C locale assumes ASCII as the default text encoding, which
844 * causes problems not only for the CPython runtime, but also other
845 * components like GNU readline.
846 *
847 * Accordingly, when the CLI detects it, it attempts to coerce it to a
848 * more capable UTF-8 based alternative.
849 *
850 * See the documentation of the PYTHONCOERCECLOCALE setting for more
851 * details.
852 */
853 int encoding_changed = 0;
854 if (config->coerce_c_locale && !locale_coerced) {
855 locale_coerced = 1;
856 _Py_CoerceLegacyLocale(0);
857 encoding_changed = 1;
858 }
859
860 if (utf8_mode == -1) {
861 if (config->utf8_mode == 1) {
862 /* UTF-8 Mode enabled */
863 encoding_changed = 1;
864 }
865 }
866 else {
867 if (config->utf8_mode != utf8_mode) {
868 encoding_changed = 1;
869 }
870 }
871
872 if (!encoding_changed) {
873 break;
874 }
875
876 /* Reset the configuration before reading again the configuration,
877 just keep UTF-8 Mode value. */
878 int new_utf8_mode = config->utf8_mode;
879 int new_coerce_c_locale = config->coerce_c_locale;
Victor Stinnerb5947842019-05-18 00:38:16 +0200880 _PyPreConfig_Copy(config, &save_config);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100881 config->utf8_mode = new_utf8_mode;
882 config->coerce_c_locale = new_coerce_c_locale;
883
884 /* The encoding changed: read again the configuration
885 with the new encoding */
886 }
887 err = _Py_INIT_OK();
888
889done:
890 if (init_ctype_locale != NULL) {
891 setlocale(LC_CTYPE, init_ctype_locale);
Victor Stinnerc1834442019-03-18 22:24:28 +0100892 PyMem_RawFree(init_ctype_locale);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100893 }
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100894 Py_UTF8Mode = init_utf8_mode ;
895#ifdef MS_WINDOWS
896 Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding;
897#endif
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100898 _PyPreCmdline_Clear(&cmdline);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100899 return err;
900}
901
902
Victor Stinner4fffd382019-03-06 01:44:31 +0100903/* Write the pre-configuration:
904
905 - set the memory allocators
906 - set Py_xxx global configuration variables
907 - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode
908 (PEP 540)
Victor Stinnerc656e252019-03-06 01:13:43 +0100909
Victor Stinner0f721472019-05-20 17:16:38 +0200910 The applied configuration is written into _PyRuntime.preconfig.
911 If the C locale cannot be coerced, set coerce_c_locale to 0.
Victor Stinner4fffd382019-03-06 01:44:31 +0100912
913 Do nothing if called after Py_Initialize(): ignore the new
914 pre-configuration. */
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100915_PyInitError
Victor Stinner0f721472019-05-20 17:16:38 +0200916_PyPreConfig_Write(const _PyPreConfig *src_config)
Victor Stinner6dcb5422019-03-05 02:44:12 +0100917{
Victor Stinner0f721472019-05-20 17:16:38 +0200918 _PyPreConfig config;
919 _PyPreConfig_InitFromPreConfig(&config, src_config);
920
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100921 if (_PyRuntime.core_initialized) {
Victor Stinner4fffd382019-03-06 01:44:31 +0100922 /* bpo-34008: Calling this functions after Py_Initialize() ignores
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100923 the new configuration. */
Victor Stinnerc656e252019-03-06 01:13:43 +0100924 return _Py_INIT_OK();
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100925 }
926
Victor Stinner0f721472019-05-20 17:16:38 +0200927 PyMemAllocatorName name = (PyMemAllocatorName)config.allocator;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200928 if (name != PYMEM_ALLOCATOR_NOT_SET) {
929 if (_PyMem_SetupAllocators(name) < 0) {
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200930 return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator");
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100931 }
932 }
933
Victor Stinner0f721472019-05-20 17:16:38 +0200934 _PyPreConfig_SetGlobalConfig(&config);
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100935
Victor Stinner0f721472019-05-20 17:16:38 +0200936 if (config.configure_locale) {
937 if (config.coerce_c_locale) {
938 if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) {
939 /* C locale not coerced */
940 config.coerce_c_locale = 0;
941 }
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200942 }
Victor Stinner5a02e0d2019-03-05 12:32:09 +0100943
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200944 /* Set LC_CTYPE to the user preferred locale */
945 _Py_SetLocaleFromEnv(LC_CTYPE);
946 }
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100947
Victor Stinner6d5ee972019-03-23 12:05:43 +0100948 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner0f721472019-05-20 17:16:38 +0200949 _PyPreConfig_Copy(&_PyRuntime.preconfig, &config);
Victor Stinner6d5ee972019-03-23 12:05:43 +0100950
Victor Stinner7d2ef3e2019-03-06 00:36:56 +0100951 return _Py_INIT_OK();
Victor Stinner6dcb5422019-03-05 02:44:12 +0100952}