blob: fae32e533aa9cd5bc261a33acc25cf378ea3ab54 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner6c785c02018-08-01 17:56:14 +02002#include "internal/pystate.h"
Victor Stinner5cb25892018-08-28 12:35:44 +02003#include <locale.h>
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02004#ifdef HAVE_LANGINFO_H
5# include <langinfo.h>
6#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02007
Victor Stinnerb2457ef2018-08-29 13:25:36 +02008#include <locale.h> /* setlocale() */
9#ifdef HAVE_LANGINFO_H
10#include <langinfo.h> /* nl_langinfo(CODESET) */
11#endif
12
Victor Stinner6c785c02018-08-01 17:56:14 +020013
14#define DECODE_LOCALE_ERR(NAME, LEN) \
15 (((LEN) == -2) \
16 ? _Py_INIT_USER_ERR("cannot decode " NAME) \
17 : _Py_INIT_NO_MEMORY())
18
19
20/* Global configuration variables */
21
Victor Stinnerde427552018-08-29 23:26:55 +020022/* The filesystem encoding is chosen by config_init_fs_encoding(),
23 see also initfsencoding(). */
24const char *Py_FileSystemDefaultEncoding = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +020025int Py_HasFileSystemDefaultEncoding = 0;
Victor Stinnerde427552018-08-29 23:26:55 +020026const char *Py_FileSystemDefaultEncodeErrors = NULL;
27static int _Py_HasFileSystemDefaultEncodeErrors = 0;
Victor Stinnerb2457ef2018-08-29 13:25:36 +020028
Victor Stinner6c785c02018-08-01 17:56:14 +020029/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
30 stdin and stdout error handler to "surrogateescape". It is equal to
31 -1 by default: unknown, will be set by Py_Main() */
32int Py_UTF8Mode = -1;
33int Py_DebugFlag = 0; /* Needed by parser.c */
34int Py_VerboseFlag = 0; /* Needed by import.c */
35int Py_QuietFlag = 0; /* Needed by sysmodule.c */
36int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
37int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
38int Py_OptimizeFlag = 0; /* Needed by compile.c */
39int Py_NoSiteFlag = 0; /* Suppress 'import site' */
40int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
41int Py_FrozenFlag = 0; /* Needed by getpath.c */
42int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
43int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
44int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
45int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
46int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
47int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
48#ifdef MS_WINDOWS
49int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
50int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
51#endif
Victor Stinner6c785c02018-08-01 17:56:14 +020052
53
54void
55_Py_wstrlist_clear(int len, wchar_t **list)
56{
57 for (int i=0; i < len; i++) {
58 PyMem_RawFree(list[i]);
59 }
60 PyMem_RawFree(list);
61}
62
63
64wchar_t**
65_Py_wstrlist_copy(int len, wchar_t **list)
66{
67 assert((len > 0 && list != NULL) || len == 0);
68 size_t size = len * sizeof(list[0]);
69 wchar_t **list_copy = PyMem_RawMalloc(size);
Alexey Izbysheveb746db2018-08-25 02:34:56 +030070 if (list_copy == NULL) {
71 return NULL;
72 }
Victor Stinner6c785c02018-08-01 17:56:14 +020073 for (int i=0; i < len; i++) {
74 wchar_t* arg = _PyMem_RawWcsdup(list[i]);
75 if (arg == NULL) {
Alexey Izbysheveb746db2018-08-25 02:34:56 +030076 _Py_wstrlist_clear(i, list_copy);
Victor Stinner6c785c02018-08-01 17:56:14 +020077 return NULL;
78 }
79 list_copy[i] = arg;
80 }
81 return list_copy;
82}
83
84
Victor Stinnerb2457ef2018-08-29 13:25:36 +020085void
86_Py_ClearFileSystemEncoding(void)
87{
88 if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
89 PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
90 Py_FileSystemDefaultEncoding = NULL;
91 }
92 if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) {
93 PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
94 Py_FileSystemDefaultEncodeErrors = NULL;
95 }
96}
97
98
99/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
100 global configuration variables. */
101int
102_Py_SetFileSystemEncoding(const char *encoding, const char *errors)
103{
104 char *encoding2 = _PyMem_RawStrdup(encoding);
105 if (encoding2 == NULL) {
106 return -1;
107 }
108
109 char *errors2 = _PyMem_RawStrdup(errors);
110 if (errors2 == NULL) {
111 PyMem_RawFree(encoding2);
112 return -1;
113 }
114
115 _Py_ClearFileSystemEncoding();
116
117 Py_FileSystemDefaultEncoding = encoding2;
118 Py_HasFileSystemDefaultEncoding = 0;
119
120 Py_FileSystemDefaultEncodeErrors = errors2;
121 _Py_HasFileSystemDefaultEncodeErrors = 0;
122 return 0;
123}
124
125
Victor Stinner124b9eb2018-08-29 01:29:06 +0200126/* Helper to allow an embedding application to override the normal
127 * mechanism that attempts to figure out an appropriate IO encoding
128 */
129
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200130static char *_Py_StandardStreamEncoding = NULL;
131static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200132
133int
134Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
135{
136 if (Py_IsInitialized()) {
137 /* This is too late to have any effect */
138 return -1;
139 }
140
141 int res = 0;
142
143 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
144 but Py_Initialize() can change the allocator. Use a known allocator
145 to be able to release the memory later. */
146 PyMemAllocatorEx old_alloc;
147 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
148
149 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
150 * initialised yet.
151 *
152 * However, the raw memory allocators are initialised appropriately
153 * as C static variables, so _PyMem_RawStrdup is OK even though
154 * Py_Initialize hasn't been called yet.
155 */
156 if (encoding) {
157 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
158 if (!_Py_StandardStreamEncoding) {
159 res = -2;
160 goto done;
161 }
162 }
163 if (errors) {
164 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
165 if (!_Py_StandardStreamErrors) {
166 if (_Py_StandardStreamEncoding) {
167 PyMem_RawFree(_Py_StandardStreamEncoding);
168 }
169 res = -3;
170 goto done;
171 }
172 }
173#ifdef MS_WINDOWS
174 if (_Py_StandardStreamEncoding) {
175 /* Overriding the stream encoding implies legacy streams */
176 Py_LegacyWindowsStdioFlag = 1;
177 }
178#endif
179
180done:
181 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
182
183 return res;
184}
185
186
187void
188_Py_ClearStandardStreamEncoding(void)
189{
190 /* Use the same allocator than Py_SetStandardStreamEncoding() */
191 PyMemAllocatorEx old_alloc;
192 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
193
194 /* We won't need them anymore. */
195 if (_Py_StandardStreamEncoding) {
196 PyMem_RawFree(_Py_StandardStreamEncoding);
197 _Py_StandardStreamEncoding = NULL;
198 }
199 if (_Py_StandardStreamErrors) {
200 PyMem_RawFree(_Py_StandardStreamErrors);
201 _Py_StandardStreamErrors = NULL;
202 }
203
204 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
205}
206
207
Victor Stinner6c785c02018-08-01 17:56:14 +0200208/* Free memory allocated in config, but don't clear all attributes */
209void
210_PyCoreConfig_Clear(_PyCoreConfig *config)
211{
212#define CLEAR(ATTR) \
213 do { \
214 PyMem_RawFree(ATTR); \
215 ATTR = NULL; \
216 } while (0)
217#define CLEAR_WSTRLIST(LEN, LIST) \
218 do { \
219 _Py_wstrlist_clear(LEN, LIST); \
220 LEN = 0; \
221 LIST = NULL; \
222 } while (0)
223
224 CLEAR(config->pycache_prefix);
225 CLEAR(config->module_search_path_env);
226 CLEAR(config->home);
227 CLEAR(config->program_name);
228 CLEAR(config->program);
229
230 CLEAR_WSTRLIST(config->argc, config->argv);
231 config->argc = -1;
232
233 CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
234 CLEAR_WSTRLIST(config->nxoption, config->xoptions);
235 CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
236 config->nmodule_search_path = -1;
237
238 CLEAR(config->executable);
239 CLEAR(config->prefix);
240 CLEAR(config->base_prefix);
241 CLEAR(config->exec_prefix);
242#ifdef MS_WINDOWS
243 CLEAR(config->dll_path);
244#endif
245 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200246
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200247 CLEAR(config->filesystem_encoding);
248 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200249 CLEAR(config->stdio_encoding);
250 CLEAR(config->stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200251#undef CLEAR
252#undef CLEAR_WSTRLIST
253}
254
255
256int
257_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
258{
259 _PyCoreConfig_Clear(config);
260
261#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200262#define COPY_STR_ATTR(ATTR) \
263 do { \
264 if (config2->ATTR != NULL) { \
265 config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
266 if (config->ATTR == NULL) { \
267 return -1; \
268 } \
269 } \
270 } while (0)
Victor Stinner124b9eb2018-08-29 01:29:06 +0200271#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200272 do { \
273 if (config2->ATTR != NULL) { \
274 config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
275 if (config->ATTR == NULL) { \
276 return -1; \
277 } \
278 } \
279 } while (0)
280#define COPY_WSTRLIST(LEN, LIST) \
281 do { \
282 if (config2->LIST != NULL) { \
283 config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \
284 if (config->LIST == NULL) { \
285 return -1; \
286 } \
287 } \
288 config->LEN = config2->LEN; \
289 } while (0)
290
291 COPY_ATTR(install_signal_handlers);
292 COPY_ATTR(use_environment);
293 COPY_ATTR(use_hash_seed);
294 COPY_ATTR(hash_seed);
295 COPY_ATTR(_install_importlib);
296 COPY_ATTR(allocator);
297 COPY_ATTR(dev_mode);
298 COPY_ATTR(faulthandler);
299 COPY_ATTR(tracemalloc);
300 COPY_ATTR(import_time);
301 COPY_ATTR(show_ref_count);
302 COPY_ATTR(show_alloc_count);
303 COPY_ATTR(dump_refs);
304 COPY_ATTR(malloc_stats);
305
306 COPY_ATTR(coerce_c_locale);
307 COPY_ATTR(coerce_c_locale_warn);
308 COPY_ATTR(utf8_mode);
309
Victor Stinner124b9eb2018-08-29 01:29:06 +0200310 COPY_WSTR_ATTR(pycache_prefix);
311 COPY_WSTR_ATTR(module_search_path_env);
312 COPY_WSTR_ATTR(home);
313 COPY_WSTR_ATTR(program_name);
314 COPY_WSTR_ATTR(program);
Victor Stinner6c785c02018-08-01 17:56:14 +0200315
316 COPY_WSTRLIST(argc, argv);
317 COPY_WSTRLIST(nwarnoption, warnoptions);
318 COPY_WSTRLIST(nxoption, xoptions);
319 COPY_WSTRLIST(nmodule_search_path, module_search_paths);
320
Victor Stinner124b9eb2018-08-29 01:29:06 +0200321 COPY_WSTR_ATTR(executable);
322 COPY_WSTR_ATTR(prefix);
323 COPY_WSTR_ATTR(base_prefix);
324 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200325#ifdef MS_WINDOWS
Victor Stinner124b9eb2018-08-29 01:29:06 +0200326 COPY_WSTR_ATTR(dll_path);
Victor Stinner6c785c02018-08-01 17:56:14 +0200327#endif
Victor Stinner124b9eb2018-08-29 01:29:06 +0200328 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200329
330 COPY_ATTR(isolated);
331 COPY_ATTR(site_import);
332 COPY_ATTR(bytes_warning);
333 COPY_ATTR(inspect);
334 COPY_ATTR(interactive);
335 COPY_ATTR(optimization_level);
336 COPY_ATTR(parser_debug);
337 COPY_ATTR(write_bytecode);
338 COPY_ATTR(verbose);
339 COPY_ATTR(quiet);
340 COPY_ATTR(user_site_directory);
341 COPY_ATTR(buffered_stdio);
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200342 COPY_STR_ATTR(filesystem_encoding);
343 COPY_STR_ATTR(filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200344 COPY_STR_ATTR(stdio_encoding);
345 COPY_STR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200346#ifdef MS_WINDOWS
347 COPY_ATTR(legacy_windows_fs_encoding);
348 COPY_ATTR(legacy_windows_stdio);
349#endif
350 COPY_ATTR(_check_hash_pycs_mode);
351 COPY_ATTR(_frozen);
352
353#undef COPY_ATTR
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200354#undef COPY_STR_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200355#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200356#undef COPY_WSTRLIST
357 return 0;
358}
359
360
361const char*
362_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
363{
364 assert(config->use_environment >= 0);
365
366 if (!config->use_environment) {
367 return NULL;
368 }
369
370 const char *var = getenv(name);
371 if (var && var[0] != '\0') {
372 return var;
373 }
374 else {
375 return NULL;
376 }
377}
378
379
380int
381_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
382 wchar_t **dest,
383 wchar_t *wname, char *name)
384{
385 assert(config->use_environment >= 0);
386
387 if (!config->use_environment) {
388 *dest = NULL;
389 return 0;
390 }
391
392#ifdef MS_WINDOWS
393 const wchar_t *var = _wgetenv(wname);
394 if (!var || var[0] == '\0') {
395 *dest = NULL;
396 return 0;
397 }
398
399 wchar_t *copy = _PyMem_RawWcsdup(var);
400 if (copy == NULL) {
401 return -1;
402 }
403
404 *dest = copy;
405#else
406 const char *var = getenv(name);
407 if (!var || var[0] == '\0') {
408 *dest = NULL;
409 return 0;
410 }
411
412 size_t len;
413 wchar_t *wvar = Py_DecodeLocale(var, &len);
414 if (!wvar) {
415 if (len == (size_t)-2) {
416 return -2;
417 }
418 else {
419 return -1;
420 }
421 }
422 *dest = wvar;
423#endif
424 return 0;
425}
426
427
428void
429_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
430{
431#define COPY_FLAG(ATTR, VALUE) \
432 if (config->ATTR == -1) { \
433 config->ATTR = VALUE; \
434 }
435#define COPY_NOT_FLAG(ATTR, VALUE) \
436 if (config->ATTR == -1) { \
437 config->ATTR = !(VALUE); \
438 }
439
440 COPY_FLAG(utf8_mode, Py_UTF8Mode);
441 COPY_FLAG(isolated, Py_IsolatedFlag);
442 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
443 COPY_FLAG(inspect, Py_InspectFlag);
444 COPY_FLAG(interactive, Py_InteractiveFlag);
445 COPY_FLAG(optimization_level, Py_OptimizeFlag);
446 COPY_FLAG(parser_debug, Py_DebugFlag);
447 COPY_FLAG(verbose, Py_VerboseFlag);
448 COPY_FLAG(quiet, Py_QuietFlag);
449#ifdef MS_WINDOWS
450 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
451 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
452#endif
453 COPY_FLAG(_frozen, Py_FrozenFlag);
454
455 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
456 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
457 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
458 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
459 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
460
Victor Stinner6c785c02018-08-01 17:56:14 +0200461#undef COPY_FLAG
462#undef COPY_NOT_FLAG
463}
464
465
466/* Set Py_xxx global configuration variables from 'config' configuration. */
467void
468_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
469{
470#define COPY_FLAG(ATTR, VAR) \
471 if (config->ATTR != -1) { \
472 VAR = config->ATTR; \
473 }
474#define COPY_NOT_FLAG(ATTR, VAR) \
475 if (config->ATTR != -1) { \
476 VAR = !config->ATTR; \
477 }
478
479 COPY_FLAG(utf8_mode, Py_UTF8Mode);
480 COPY_FLAG(isolated, Py_IsolatedFlag);
481 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
482 COPY_FLAG(inspect, Py_InspectFlag);
483 COPY_FLAG(interactive, Py_InteractiveFlag);
484 COPY_FLAG(optimization_level, Py_OptimizeFlag);
485 COPY_FLAG(parser_debug, Py_DebugFlag);
486 COPY_FLAG(verbose, Py_VerboseFlag);
487 COPY_FLAG(quiet, Py_QuietFlag);
488#ifdef MS_WINDOWS
489 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
490 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
491#endif
492
493 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
494 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
495 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
496 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
497 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
498
Victor Stinner6c785c02018-08-01 17:56:14 +0200499 /* Random or non-zero hash seed */
500 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
501 config->hash_seed != 0);
502
503#undef COPY_FLAG
504#undef COPY_NOT_FLAG
505}
506
507
508/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
509 environment variables on macOS if available. */
510static _PyInitError
511config_init_program_name(_PyCoreConfig *config)
512{
Victor Stinner5a953fd2018-08-03 22:49:07 +0200513 assert(config->program_name == NULL);
514
Victor Stinner6c785c02018-08-01 17:56:14 +0200515 /* If Py_SetProgramName() was called, use its value */
516 const wchar_t *program_name = _Py_path_config.program_name;
517 if (program_name != NULL) {
518 config->program_name = _PyMem_RawWcsdup(program_name);
519 if (config->program_name == NULL) {
520 return _Py_INIT_NO_MEMORY();
521 }
522 return _Py_INIT_OK();
523 }
524
525#ifdef __APPLE__
526 /* On MacOS X, when the Python interpreter is embedded in an
527 application bundle, it gets executed by a bootstrapping script
528 that does os.execve() with an argv[0] that's different from the
529 actual Python executable. This is needed to keep the Finder happy,
530 or rather, to work around Apple's overly strict requirements of
531 the process name. However, we still need a usable sys.executable,
532 so the actual executable path is passed in an environment variable.
533 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
534 script. */
535 const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
536 if (p != NULL) {
537 size_t len;
538 wchar_t* program_name = Py_DecodeLocale(p, &len);
539 if (program_name == NULL) {
540 return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
541 "variable", (Py_ssize_t)len);
542 }
543 config->program_name = program_name;
544 return _Py_INIT_OK();
545 }
546#ifdef WITH_NEXT_FRAMEWORK
547 else {
548 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
549 if (pyvenv_launcher && *pyvenv_launcher) {
550 /* Used by Mac/Tools/pythonw.c to forward
551 * the argv0 of the stub executable
552 */
553 size_t len;
554 wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
555 if (program_name == NULL) {
556 return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
557 "variable", (Py_ssize_t)len);
558 }
559 config->program_name = program_name;
560 return _Py_INIT_OK();
561 }
562 }
563#endif /* WITH_NEXT_FRAMEWORK */
564#endif /* __APPLE__ */
565
566 /* Use argv[0] by default, if available */
567 if (config->program != NULL) {
568 config->program_name = _PyMem_RawWcsdup(config->program);
569 if (config->program_name == NULL) {
570 return _Py_INIT_NO_MEMORY();
571 }
572 return _Py_INIT_OK();
573 }
574
575 /* Last fall back: hardcoded string */
576#ifdef MS_WINDOWS
577 const wchar_t *default_program_name = L"python";
578#else
579 const wchar_t *default_program_name = L"python3";
580#endif
581 config->program_name = _PyMem_RawWcsdup(default_program_name);
582 if (config->program_name == NULL) {
583 return _Py_INIT_NO_MEMORY();
584 }
585 return _Py_INIT_OK();
586}
587
588
589static const wchar_t*
590config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
591{
592 int nxoption = config->nxoption;
593 wchar_t **xoptions = config->xoptions;
594 for (int i=0; i < nxoption; i++) {
595 wchar_t *option = xoptions[i];
596 size_t len;
597 wchar_t *sep = wcschr(option, L'=');
598 if (sep != NULL) {
599 len = (sep - option);
600 }
601 else {
602 len = wcslen(option);
603 }
604 if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
605 return option;
606 }
607 }
608 return NULL;
609}
610
611
612static _PyInitError
613config_init_home(_PyCoreConfig *config)
614{
615 wchar_t *home;
616
617 /* If Py_SetPythonHome() was called, use its value */
618 home = _Py_path_config.home;
619 if (home) {
620 config->home = _PyMem_RawWcsdup(home);
621 if (config->home == NULL) {
622 return _Py_INIT_NO_MEMORY();
623 }
624 return _Py_INIT_OK();
625 }
626
627 int res = _PyCoreConfig_GetEnvDup(config, &home,
628 L"PYTHONHOME", "PYTHONHOME");
629 if (res < 0) {
630 return DECODE_LOCALE_ERR("PYTHONHOME", res);
631 }
632 config->home = home;
633 return _Py_INIT_OK();
634}
635
636
637static _PyInitError
638config_init_hash_seed(_PyCoreConfig *config)
639{
640 const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
641
642 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
643 /* Convert a text seed to a numeric one */
644 if (seed_text && strcmp(seed_text, "random") != 0) {
645 const char *endptr = seed_text;
646 unsigned long seed;
647 errno = 0;
648 seed = strtoul(seed_text, (char **)&endptr, 10);
649 if (*endptr != '\0'
650 || seed > 4294967295UL
651 || (errno == ERANGE && seed == ULONG_MAX))
652 {
653 return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
654 "or an integer in range [0; 4294967295]");
655 }
656 /* Use a specific hash */
657 config->use_hash_seed = 1;
658 config->hash_seed = seed;
659 }
660 else {
661 /* Use a random hash */
662 config->use_hash_seed = 0;
663 config->hash_seed = 0;
664 }
665 return _Py_INIT_OK();
666}
667
668
669static _PyInitError
670config_init_utf8_mode(_PyCoreConfig *config)
671{
672 const wchar_t *xopt = config_get_xoption(config, L"utf8");
673 if (xopt) {
674 wchar_t *sep = wcschr(xopt, L'=');
675 if (sep) {
676 xopt = sep + 1;
677 if (wcscmp(xopt, L"1") == 0) {
678 config->utf8_mode = 1;
679 }
680 else if (wcscmp(xopt, L"0") == 0) {
681 config->utf8_mode = 0;
682 }
683 else {
684 return _Py_INIT_USER_ERR("invalid -X utf8 option value");
685 }
686 }
687 else {
688 config->utf8_mode = 1;
689 }
690 return _Py_INIT_OK();
691 }
692
693 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONUTF8");
694 if (opt) {
695 if (strcmp(opt, "1") == 0) {
696 config->utf8_mode = 1;
697 }
698 else if (strcmp(opt, "0") == 0) {
699 config->utf8_mode = 0;
700 }
701 else {
702 return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
703 "variable value");
704 }
705 return _Py_INIT_OK();
706 }
707
708 return _Py_INIT_OK();
709}
710
711
712static int
713config_str_to_int(const char *str, int *result)
714{
715 const char *endptr = str;
716 errno = 0;
717 long value = strtol(str, (char **)&endptr, 10);
718 if (*endptr != '\0' || errno == ERANGE) {
719 return -1;
720 }
721 if (value < INT_MIN || value > INT_MAX) {
722 return -1;
723 }
724
725 *result = (int)value;
726 return 0;
727}
728
729
730static int
731config_wstr_to_int(const wchar_t *wstr, int *result)
732{
733 const wchar_t *endptr = wstr;
734 errno = 0;
735 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
736 if (*endptr != '\0' || errno == ERANGE) {
737 return -1;
738 }
739 if (value < INT_MIN || value > INT_MAX) {
740 return -1;
741 }
742
743 *result = (int)value;
744 return 0;
745}
746
747
748static void
749get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
750{
751 const char *var = _PyCoreConfig_GetEnv(config, name);
752 if (!var) {
753 return;
754 }
755 int value;
756 if (config_str_to_int(var, &value) < 0 || value < 0) {
757 /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
758 value = 1;
759 }
760 if (*flag < value) {
761 *flag = value;
762 }
763}
764
765
766static _PyInitError
767config_read_env_vars(_PyCoreConfig *config)
768{
Victor Stinner6c785c02018-08-01 17:56:14 +0200769 /* Get environment variables */
770 get_env_flag(config, &config->parser_debug, "PYTHONDEBUG");
771 get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
772 get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
773 get_env_flag(config, &config->inspect, "PYTHONINSPECT");
774
775 int dont_write_bytecode = 0;
776 get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
777 if (dont_write_bytecode) {
778 config->write_bytecode = 0;
779 }
780
781 int no_user_site_directory = 0;
782 get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
783 if (no_user_site_directory) {
784 config->user_site_directory = 0;
785 }
786
787 int unbuffered_stdio = 0;
788 get_env_flag(config, &unbuffered_stdio, "PYTHONUNBUFFERED");
789 if (unbuffered_stdio) {
790 config->buffered_stdio = 0;
791 }
792
793#ifdef MS_WINDOWS
794 get_env_flag(config, &config->legacy_windows_fs_encoding,
795 "PYTHONLEGACYWINDOWSFSENCODING");
796 get_env_flag(config, &config->legacy_windows_stdio,
797 "PYTHONLEGACYWINDOWSSTDIO");
798#endif
799
800 if (config->allocator == NULL) {
801 config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC");
802 }
803
804 if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
805 config->dump_refs = 1;
806 }
807 if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
808 config->malloc_stats = 1;
809 }
810
Victor Stinner2c8ddcf2018-08-29 00:16:53 +0200811 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
812 if (env) {
813 if (strcmp(env, "0") == 0) {
814 if (config->coerce_c_locale < 0) {
Victor Stinner5a953fd2018-08-03 22:49:07 +0200815 config->coerce_c_locale = 0;
816 }
Victor Stinner2c8ddcf2018-08-29 00:16:53 +0200817 }
818 else if (strcmp(env, "warn") == 0) {
819 config->coerce_c_locale_warn = 1;
820 }
821 else {
822 if (config->coerce_c_locale < 0) {
Victor Stinner5a953fd2018-08-03 22:49:07 +0200823 config->coerce_c_locale = 1;
824 }
Victor Stinner6c785c02018-08-01 17:56:14 +0200825 }
826 }
827
828 wchar_t *path;
829 int res = _PyCoreConfig_GetEnvDup(config, &path,
830 L"PYTHONPATH", "PYTHONPATH");
831 if (res < 0) {
832 return DECODE_LOCALE_ERR("PYTHONPATH", res);
833 }
834 config->module_search_path_env = path;
835
836 if (config->use_hash_seed < 0) {
837 _PyInitError err = config_init_hash_seed(config);
838 if (_Py_INIT_FAILED(err)) {
839 return err;
840 }
841 }
842
843 return _Py_INIT_OK();
844}
845
846
847static _PyInitError
848config_init_tracemalloc(_PyCoreConfig *config)
849{
850 int nframe;
851 int valid;
852
853 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
854 if (env) {
855 if (!config_str_to_int(env, &nframe)) {
856 valid = (nframe >= 0);
857 }
858 else {
859 valid = 0;
860 }
861 if (!valid) {
862 return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
863 "of frames");
864 }
865 config->tracemalloc = nframe;
866 }
867
868 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
869 if (xoption) {
870 const wchar_t *sep = wcschr(xoption, L'=');
871 if (sep) {
872 if (!config_wstr_to_int(sep + 1, &nframe)) {
873 valid = (nframe >= 0);
874 }
875 else {
876 valid = 0;
877 }
878 if (!valid) {
879 return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
880 "invalid number of frames");
881 }
882 }
883 else {
884 /* -X tracemalloc behaves as -X tracemalloc=1 */
885 nframe = 1;
886 }
887 config->tracemalloc = nframe;
888 }
889 return _Py_INIT_OK();
890}
891
892
893static _PyInitError
894config_init_pycache_prefix(_PyCoreConfig *config)
895{
896 assert(config->pycache_prefix == NULL);
897
898 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
899 if (xoption) {
900 const wchar_t *sep = wcschr(xoption, L'=');
901 if (sep && wcslen(sep) > 1) {
902 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
903 if (config->pycache_prefix == NULL) {
904 return _Py_INIT_NO_MEMORY();
905 }
906 }
907 else {
908 // -X pycache_prefix= can cancel the env var
909 config->pycache_prefix = NULL;
910 }
911 }
912 else {
913 wchar_t *env;
914 int res = _PyCoreConfig_GetEnvDup(config, &env,
915 L"PYTHONPYCACHEPREFIX",
916 "PYTHONPYCACHEPREFIX");
917 if (res < 0) {
918 return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res);
919 }
920
921 if (env) {
922 config->pycache_prefix = env;
923 }
924 }
925 return _Py_INIT_OK();
926}
927
928
929static _PyInitError
930config_read_complex_options(_PyCoreConfig *config)
931{
932 /* More complex options configured by env var and -X option */
933 if (config->faulthandler < 0) {
934 if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
935 || config_get_xoption(config, L"faulthandler")) {
936 config->faulthandler = 1;
937 }
938 }
939 if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
940 || config_get_xoption(config, L"importtime")) {
941 config->import_time = 1;
942 }
943 if (config_get_xoption(config, L"dev" ) ||
944 _PyCoreConfig_GetEnv(config, "PYTHONDEVMODE"))
945 {
946 config->dev_mode = 1;
947 }
948
949 _PyInitError err;
950 if (config->tracemalloc < 0) {
951 err = config_init_tracemalloc(config);
952 if (_Py_INIT_FAILED(err)) {
953 return err;
954 }
955 }
956
957 if (config->pycache_prefix == NULL) {
958 err = config_init_pycache_prefix(config);
959 if (_Py_INIT_FAILED(err)) {
960 return err;
961 }
962 }
963 return _Py_INIT_OK();
964}
965
966
967static void
968config_init_locale(_PyCoreConfig *config)
969{
Victor Stinnerd500e532018-08-28 17:27:36 +0200970 if (config->coerce_c_locale < 0) {
Victor Stinner5cb25892018-08-28 12:35:44 +0200971 /* The C locale enables the C locale coercion (PEP 538) */
Victor Stinnerd500e532018-08-28 17:27:36 +0200972 if (_Py_LegacyLocaleDetected()) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200973 config->coerce_c_locale = 1;
974 }
Victor Stinner6c785c02018-08-01 17:56:14 +0200975 }
Victor Stinnerd500e532018-08-28 17:27:36 +0200976
Victor Stinner5cb25892018-08-28 12:35:44 +0200977#ifndef MS_WINDOWS
Victor Stinnerd500e532018-08-28 17:27:36 +0200978 if (config->utf8_mode < 0) {
Victor Stinner5cb25892018-08-28 12:35:44 +0200979 /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
Victor Stinnerd500e532018-08-28 17:27:36 +0200980 const char *ctype_loc = setlocale(LC_CTYPE, NULL);
981 if (ctype_loc != NULL
982 && (strcmp(ctype_loc, "C") == 0
983 || strcmp(ctype_loc, "POSIX") == 0))
984 {
Victor Stinner5cb25892018-08-28 12:35:44 +0200985 config->utf8_mode = 1;
986 }
987 }
988#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200989}
990
991
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200992static const char *
993get_stdio_errors(const _PyCoreConfig *config)
994{
995#ifndef MS_WINDOWS
996 const char *loc = setlocale(LC_CTYPE, NULL);
997 if (loc != NULL) {
998 /* surrogateescape is the default in the legacy C and POSIX locales */
999 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
1000 return "surrogateescape";
1001 }
1002
1003#ifdef PY_COERCE_C_LOCALE
1004 /* surrogateescape is the default in locale coercion target locales */
1005 if (_Py_IsLocaleCoercionTarget(loc)) {
1006 return "surrogateescape";
1007 }
1008#endif
1009 }
1010
1011 return "strict";
1012#else
1013 /* On Windows, always use surrogateescape by default */
1014 return "surrogateescape";
1015#endif
1016}
1017
1018
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001019static _PyInitError
1020get_locale_encoding(char **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001021{
1022#ifdef MS_WINDOWS
1023 char encoding[20];
1024 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
1025#elif defined(__ANDROID__)
1026 const char *encoding = "UTF-8";
1027#else
1028 const char *encoding = nl_langinfo(CODESET);
1029 if (!encoding || encoding[0] == '\0') {
1030 return _Py_INIT_USER_ERR("failed to get the locale encoding: "
1031 "nl_langinfo(CODESET) failed");
1032 }
1033#endif
1034 *locale_encoding = _PyMem_RawStrdup(encoding);
1035 if (*locale_encoding == NULL) {
1036 return _Py_INIT_NO_MEMORY();
1037 }
1038 return _Py_INIT_OK();
1039}
1040
1041
1042static _PyInitError
1043config_init_stdio_encoding(_PyCoreConfig *config)
1044{
1045 /* If Py_SetStandardStreamEncoding() have been called, use these
1046 parameters. */
1047 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
1048 config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding);
1049 if (config->stdio_encoding == NULL) {
1050 return _Py_INIT_NO_MEMORY();
1051 }
1052 }
1053
1054 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
1055 config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors);
1056 if (config->stdio_errors == NULL) {
1057 return _Py_INIT_NO_MEMORY();
1058 }
1059 }
1060
1061 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1062 return _Py_INIT_OK();
1063 }
1064
1065 /* PYTHONIOENCODING environment variable */
1066 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
1067 if (opt) {
1068 char *pythonioencoding = _PyMem_RawStrdup(opt);
1069 if (pythonioencoding == NULL) {
1070 return _Py_INIT_NO_MEMORY();
1071 }
1072
1073 char *err = strchr(pythonioencoding, ':');
1074 if (err) {
1075 *err = '\0';
1076 err++;
1077 if (!err[0]) {
1078 err = NULL;
1079 }
1080 }
1081
1082 /* Does PYTHONIOENCODING contain an encoding? */
1083 if (pythonioencoding[0]) {
1084 if (config->stdio_encoding == NULL) {
1085 config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding);
1086 if (config->stdio_encoding == NULL) {
1087 PyMem_RawFree(pythonioencoding);
1088 return _Py_INIT_NO_MEMORY();
1089 }
1090 }
1091
1092 /* If the encoding is set but not the error handler,
1093 use "strict" error handler by default.
1094 PYTHONIOENCODING=latin1 behaves as
1095 PYTHONIOENCODING=latin1:strict. */
1096 if (!err) {
1097 err = "strict";
1098 }
1099 }
1100
1101 if (config->stdio_errors == NULL && err != NULL) {
1102 config->stdio_errors = _PyMem_RawStrdup(err);
1103 if (config->stdio_errors == NULL) {
1104 PyMem_RawFree(pythonioencoding);
1105 return _Py_INIT_NO_MEMORY();
1106 }
1107 }
1108
1109 PyMem_RawFree(pythonioencoding);
1110 }
1111
1112 /* UTF-8 Mode uses UTF-8/surrogateescape */
1113 if (config->utf8_mode) {
1114 if (config->stdio_encoding == NULL) {
1115 config->stdio_encoding = _PyMem_RawStrdup("utf-8");
1116 if (config->stdio_encoding == NULL) {
1117 return _Py_INIT_NO_MEMORY();
1118 }
1119 }
1120 if (config->stdio_errors == NULL) {
1121 config->stdio_errors = _PyMem_RawStrdup("surrogateescape");
1122 if (config->stdio_errors == NULL) {
1123 return _Py_INIT_NO_MEMORY();
1124 }
1125 }
1126 }
1127
1128 /* Choose the default error handler based on the current locale. */
1129 if (config->stdio_encoding == NULL) {
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001130 _PyInitError err = get_locale_encoding(&config->stdio_encoding);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001131 if (_Py_INIT_FAILED(err)) {
1132 return err;
1133 }
1134 }
1135 if (config->stdio_errors == NULL) {
1136 const char *errors = get_stdio_errors(config);
1137 config->stdio_errors = _PyMem_RawStrdup(errors);
1138 if (config->stdio_errors == NULL) {
1139 return _Py_INIT_NO_MEMORY();
1140 }
1141 }
1142
1143 return _Py_INIT_OK();
1144}
1145
1146
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001147static _PyInitError
1148config_init_fs_encoding(_PyCoreConfig *config)
1149{
1150#ifdef MS_WINDOWS
1151 if (config->legacy_windows_fs_encoding) {
1152 /* Legacy Windows filesystem encoding: mbcs/replace */
1153 if (config->filesystem_encoding == NULL) {
1154 config->filesystem_encoding = _PyMem_RawStrdup("mbcs");
1155 if (config->filesystem_encoding == NULL) {
1156 return _Py_INIT_NO_MEMORY();
1157 }
1158 }
1159 if (config->filesystem_errors == NULL) {
1160 config->filesystem_errors = _PyMem_RawStrdup("replace");
1161 if (config->filesystem_errors == NULL) {
1162 return _Py_INIT_NO_MEMORY();
1163 }
1164 }
1165 }
1166
1167 /* Windows defaults to utf-8/surrogatepass (PEP 529) */
1168 if (config->filesystem_encoding == NULL) {
1169 config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
1170 if (config->filesystem_encoding == NULL) {
1171 return _Py_INIT_NO_MEMORY();
1172 }
1173 }
1174 if (config->filesystem_errors == NULL) {
1175 config->filesystem_errors = _PyMem_RawStrdup("surrogatepass");
1176 if (config->filesystem_errors == NULL) {
1177 return _Py_INIT_NO_MEMORY();
1178 }
1179 }
1180#else
1181 if (config->utf8_mode) {
1182 /* UTF-8 Mode use: utf-8/surrogateescape */
1183 if (config->filesystem_encoding == NULL) {
1184 config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
1185 if (config->filesystem_encoding == NULL) {
1186 return _Py_INIT_NO_MEMORY();
1187 }
1188 }
1189 /* errors defaults to surrogateescape above */
1190 }
1191
1192 if (config->filesystem_encoding == NULL) {
1193 /* macOS and Android use UTF-8, other platforms use
1194 the locale encoding. */
1195 char *locale_encoding;
1196#if defined(__APPLE__) || defined(__ANDROID__)
1197 locale_encoding = "UTF-8";
1198#else
1199 _PyInitError err = get_locale_encoding(&locale_encoding);
1200 if (_Py_INIT_FAILED(err)) {
1201 return err;
1202 }
1203#endif
1204 config->filesystem_encoding = _PyMem_RawStrdup(locale_encoding);
1205 if (config->filesystem_encoding == NULL) {
1206 return _Py_INIT_NO_MEMORY();
1207 }
1208 }
1209
1210 if (config->filesystem_errors == NULL) {
1211 /* by default, use the "surrogateescape" error handler */
1212 config->filesystem_errors = _PyMem_RawStrdup("surrogateescape");
1213 if (config->filesystem_errors == NULL) {
1214 return _Py_INIT_NO_MEMORY();
1215 }
1216 }
1217#endif
1218 return _Py_INIT_OK();
1219}
1220
1221
Victor Stinner6c785c02018-08-01 17:56:14 +02001222/* Read configuration settings from standard locations
1223 *
1224 * This function doesn't make any changes to the interpreter state - it
1225 * merely populates any missing configuration settings. This allows an
1226 * embedding application to completely override a config option by
1227 * setting it before calling this function, or else modify the default
1228 * setting before passing the fully populated config to Py_EndInitialization.
1229 *
1230 * More advanced selective initialization tricks are possible by calling
1231 * this function multiple times with various preconfigured settings.
1232 */
1233
1234_PyInitError
1235_PyCoreConfig_Read(_PyCoreConfig *config)
1236{
1237 _PyInitError err;
1238
1239 _PyCoreConfig_GetGlobalConfig(config);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001240 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001241
1242 if (config->isolated > 0) {
1243 config->use_environment = 0;
1244 config->user_site_directory = 0;
1245 }
1246
1247#ifdef MS_WINDOWS
1248 if (config->legacy_windows_fs_encoding) {
1249 config->utf8_mode = 0;
1250 }
1251#endif
1252
Victor Stinner6c785c02018-08-01 17:56:14 +02001253 if (config->use_environment) {
1254 err = config_read_env_vars(config);
1255 if (_Py_INIT_FAILED(err)) {
1256 return err;
1257 }
1258 }
1259
1260 /* -X options */
1261 if (config_get_xoption(config, L"showrefcount")) {
1262 config->show_ref_count = 1;
1263 }
1264 if (config_get_xoption(config, L"showalloccount")) {
1265 config->show_alloc_count = 1;
1266 }
1267
1268 err = config_read_complex_options(config);
1269 if (_Py_INIT_FAILED(err)) {
1270 return err;
1271 }
1272
1273 if (config->utf8_mode < 0) {
1274 err = config_init_utf8_mode(config);
1275 if (_Py_INIT_FAILED(err)) {
1276 return err;
1277 }
1278 }
1279
1280 if (config->home == NULL) {
1281 err = config_init_home(config);
1282 if (_Py_INIT_FAILED(err)) {
1283 return err;
1284 }
1285 }
1286
1287 if (config->program_name == NULL) {
1288 err = config_init_program_name(config);
1289 if (_Py_INIT_FAILED(err)) {
1290 return err;
1291 }
1292 }
1293
Victor Stinner5a953fd2018-08-03 22:49:07 +02001294 if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
1295 config_init_locale(config);
1296 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001297
1298 if (config->_install_importlib) {
1299 err = _PyCoreConfig_InitPathConfig(config);
1300 if (_Py_INIT_FAILED(err)) {
1301 return err;
1302 }
1303 }
1304
1305 /* default values */
1306 if (config->dev_mode) {
1307 if (config->faulthandler < 0) {
1308 config->faulthandler = 1;
1309 }
1310 if (config->allocator == NULL) {
1311 config->allocator = "debug";
1312 }
1313 }
1314 if (config->use_hash_seed < 0) {
1315 config->use_hash_seed = 0;
1316 config->hash_seed = 0;
1317 }
1318 if (config->faulthandler < 0) {
1319 config->faulthandler = 0;
1320 }
1321 if (config->tracemalloc < 0) {
1322 config->tracemalloc = 0;
1323 }
1324 if (config->coerce_c_locale < 0) {
1325 config->coerce_c_locale = 0;
1326 }
1327 if (config->utf8_mode < 0) {
1328 config->utf8_mode = 0;
1329 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001330 if (config->argc < 0) {
1331 config->argc = 0;
1332 }
1333
Victor Stinner70fead22018-08-29 13:45:34 +02001334 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001335 err = config_init_fs_encoding(config);
1336 if (_Py_INIT_FAILED(err)) {
1337 return err;
1338 }
1339 }
1340
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001341 err = config_init_stdio_encoding(config);
1342 if (_Py_INIT_FAILED(err)) {
1343 return err;
1344 }
1345
Victor Stinner124b9eb2018-08-29 01:29:06 +02001346 assert(config->coerce_c_locale >= 0);
1347 assert(config->use_environment >= 0);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001348 assert(config->filesystem_encoding != NULL);
1349 assert(config->filesystem_errors != NULL);
1350 assert(config->stdio_encoding != NULL);
1351 assert(config->stdio_errors != NULL);
Victor Stinnerde427552018-08-29 23:26:55 +02001352 assert(config->_check_hash_pycs_mode != NULL);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001353
Victor Stinner6c785c02018-08-01 17:56:14 +02001354 return _Py_INIT_OK();
1355}