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