blob: c81cd8bab775d4a38d2ebec86f3ded68f0ae6f65 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner9fc57a32018-11-07 00:44:03 +01002#include "pycore_fileutils.h"
Victor Stinnera1c249c2018-11-01 03:15:58 +01003#include "pycore_lifecycle.h"
Victor Stinner27e2d1f2018-11-01 00:52:28 +01004#include "pycore_mem.h"
Victor Stinnera1c249c2018-11-01 03:15:58 +01005#include "pycore_pathconfig.h"
Victor Stinner27e2d1f2018-11-01 00:52:28 +01006#include "pycore_state.h"
Victor Stinner5cb25892018-08-28 12:35:44 +02007#include <locale.h>
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02008#ifdef HAVE_LANGINFO_H
9# include <langinfo.h>
10#endif
Victor Stinner6c785c02018-08-01 17:56:14 +020011
Victor Stinnerb2457ef2018-08-29 13:25:36 +020012#include <locale.h> /* setlocale() */
13#ifdef HAVE_LANGINFO_H
14#include <langinfo.h> /* nl_langinfo(CODESET) */
15#endif
16
Victor Stinner6c785c02018-08-01 17:56:14 +020017
18#define DECODE_LOCALE_ERR(NAME, LEN) \
19 (((LEN) == -2) \
20 ? _Py_INIT_USER_ERR("cannot decode " NAME) \
21 : _Py_INIT_NO_MEMORY())
22
23
24/* Global configuration variables */
25
Victor Stinnerde427552018-08-29 23:26:55 +020026/* The filesystem encoding is chosen by config_init_fs_encoding(),
27 see also initfsencoding(). */
28const char *Py_FileSystemDefaultEncoding = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +020029int Py_HasFileSystemDefaultEncoding = 0;
Victor Stinnerde427552018-08-29 23:26:55 +020030const char *Py_FileSystemDefaultEncodeErrors = NULL;
31static int _Py_HasFileSystemDefaultEncodeErrors = 0;
Victor Stinnerb2457ef2018-08-29 13:25:36 +020032
Victor Stinner6c785c02018-08-01 17:56:14 +020033/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
34 stdin and stdout error handler to "surrogateescape". It is equal to
35 -1 by default: unknown, will be set by Py_Main() */
36int Py_UTF8Mode = -1;
37int Py_DebugFlag = 0; /* Needed by parser.c */
38int Py_VerboseFlag = 0; /* Needed by import.c */
39int Py_QuietFlag = 0; /* Needed by sysmodule.c */
40int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
41int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
42int Py_OptimizeFlag = 0; /* Needed by compile.c */
43int Py_NoSiteFlag = 0; /* Suppress 'import site' */
44int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
45int Py_FrozenFlag = 0; /* Needed by getpath.c */
46int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
47int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
48int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
49int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
50int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
51int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
52#ifdef MS_WINDOWS
53int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
54int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
55#endif
Victor Stinner6c785c02018-08-01 17:56:14 +020056
57
58void
59_Py_wstrlist_clear(int len, wchar_t **list)
60{
61 for (int i=0; i < len; i++) {
62 PyMem_RawFree(list[i]);
63 }
64 PyMem_RawFree(list);
65}
66
67
68wchar_t**
69_Py_wstrlist_copy(int len, wchar_t **list)
70{
71 assert((len > 0 && list != NULL) || len == 0);
72 size_t size = len * sizeof(list[0]);
73 wchar_t **list_copy = PyMem_RawMalloc(size);
Alexey Izbysheveb746db2018-08-25 02:34:56 +030074 if (list_copy == NULL) {
75 return NULL;
76 }
Victor Stinner6c785c02018-08-01 17:56:14 +020077 for (int i=0; i < len; i++) {
78 wchar_t* arg = _PyMem_RawWcsdup(list[i]);
79 if (arg == NULL) {
Alexey Izbysheveb746db2018-08-25 02:34:56 +030080 _Py_wstrlist_clear(i, list_copy);
Victor Stinner6c785c02018-08-01 17:56:14 +020081 return NULL;
82 }
83 list_copy[i] = arg;
84 }
85 return list_copy;
86}
87
88
Victor Stinnerb2457ef2018-08-29 13:25:36 +020089void
90_Py_ClearFileSystemEncoding(void)
91{
92 if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
93 PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
94 Py_FileSystemDefaultEncoding = NULL;
95 }
96 if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) {
97 PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
98 Py_FileSystemDefaultEncodeErrors = NULL;
99 }
100}
101
102
103/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
104 global configuration variables. */
105int
106_Py_SetFileSystemEncoding(const char *encoding, const char *errors)
107{
108 char *encoding2 = _PyMem_RawStrdup(encoding);
109 if (encoding2 == NULL) {
110 return -1;
111 }
112
113 char *errors2 = _PyMem_RawStrdup(errors);
114 if (errors2 == NULL) {
115 PyMem_RawFree(encoding2);
116 return -1;
117 }
118
119 _Py_ClearFileSystemEncoding();
120
121 Py_FileSystemDefaultEncoding = encoding2;
122 Py_HasFileSystemDefaultEncoding = 0;
123
124 Py_FileSystemDefaultEncodeErrors = errors2;
125 _Py_HasFileSystemDefaultEncodeErrors = 0;
126 return 0;
127}
128
129
Victor Stinner124b9eb2018-08-29 01:29:06 +0200130/* Helper to allow an embedding application to override the normal
131 * mechanism that attempts to figure out an appropriate IO encoding
132 */
133
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200134static char *_Py_StandardStreamEncoding = NULL;
135static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200136
137int
138Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
139{
140 if (Py_IsInitialized()) {
141 /* This is too late to have any effect */
142 return -1;
143 }
144
145 int res = 0;
146
147 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
148 but Py_Initialize() can change the allocator. Use a known allocator
149 to be able to release the memory later. */
150 PyMemAllocatorEx old_alloc;
151 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
152
153 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
154 * initialised yet.
155 *
156 * However, the raw memory allocators are initialised appropriately
157 * as C static variables, so _PyMem_RawStrdup is OK even though
158 * Py_Initialize hasn't been called yet.
159 */
160 if (encoding) {
161 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
162 if (!_Py_StandardStreamEncoding) {
163 res = -2;
164 goto done;
165 }
166 }
167 if (errors) {
168 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
169 if (!_Py_StandardStreamErrors) {
170 if (_Py_StandardStreamEncoding) {
171 PyMem_RawFree(_Py_StandardStreamEncoding);
172 }
173 res = -3;
174 goto done;
175 }
176 }
177#ifdef MS_WINDOWS
178 if (_Py_StandardStreamEncoding) {
179 /* Overriding the stream encoding implies legacy streams */
180 Py_LegacyWindowsStdioFlag = 1;
181 }
182#endif
183
184done:
185 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
186
187 return res;
188}
189
190
191void
192_Py_ClearStandardStreamEncoding(void)
193{
194 /* Use the same allocator than Py_SetStandardStreamEncoding() */
195 PyMemAllocatorEx old_alloc;
196 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
197
198 /* We won't need them anymore. */
199 if (_Py_StandardStreamEncoding) {
200 PyMem_RawFree(_Py_StandardStreamEncoding);
201 _Py_StandardStreamEncoding = NULL;
202 }
203 if (_Py_StandardStreamErrors) {
204 PyMem_RawFree(_Py_StandardStreamErrors);
205 _Py_StandardStreamErrors = NULL;
206 }
207
208 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
209}
210
211
Victor Stinner6c785c02018-08-01 17:56:14 +0200212/* Free memory allocated in config, but don't clear all attributes */
213void
214_PyCoreConfig_Clear(_PyCoreConfig *config)
215{
216#define CLEAR(ATTR) \
217 do { \
218 PyMem_RawFree(ATTR); \
219 ATTR = NULL; \
220 } while (0)
221#define CLEAR_WSTRLIST(LEN, LIST) \
222 do { \
223 _Py_wstrlist_clear(LEN, LIST); \
224 LEN = 0; \
225 LIST = NULL; \
226 } while (0)
227
228 CLEAR(config->pycache_prefix);
229 CLEAR(config->module_search_path_env);
230 CLEAR(config->home);
231 CLEAR(config->program_name);
232 CLEAR(config->program);
233
234 CLEAR_WSTRLIST(config->argc, config->argv);
235 config->argc = -1;
236
237 CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
238 CLEAR_WSTRLIST(config->nxoption, config->xoptions);
239 CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
240 config->nmodule_search_path = -1;
241
242 CLEAR(config->executable);
243 CLEAR(config->prefix);
244 CLEAR(config->base_prefix);
245 CLEAR(config->exec_prefix);
246#ifdef MS_WINDOWS
247 CLEAR(config->dll_path);
248#endif
249 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200250
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200251 CLEAR(config->filesystem_encoding);
252 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200253 CLEAR(config->stdio_encoding);
254 CLEAR(config->stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200255#undef CLEAR
256#undef CLEAR_WSTRLIST
257}
258
259
260int
261_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
262{
263 _PyCoreConfig_Clear(config);
264
265#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200266#define COPY_STR_ATTR(ATTR) \
267 do { \
268 if (config2->ATTR != NULL) { \
269 config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
270 if (config->ATTR == NULL) { \
271 return -1; \
272 } \
273 } \
274 } while (0)
Victor Stinner124b9eb2018-08-29 01:29:06 +0200275#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200276 do { \
277 if (config2->ATTR != NULL) { \
278 config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
279 if (config->ATTR == NULL) { \
280 return -1; \
281 } \
282 } \
283 } while (0)
284#define COPY_WSTRLIST(LEN, LIST) \
285 do { \
286 if (config2->LIST != NULL) { \
287 config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \
288 if (config->LIST == NULL) { \
289 return -1; \
290 } \
291 } \
292 config->LEN = config2->LEN; \
293 } while (0)
294
295 COPY_ATTR(install_signal_handlers);
296 COPY_ATTR(use_environment);
297 COPY_ATTR(use_hash_seed);
298 COPY_ATTR(hash_seed);
299 COPY_ATTR(_install_importlib);
300 COPY_ATTR(allocator);
301 COPY_ATTR(dev_mode);
302 COPY_ATTR(faulthandler);
303 COPY_ATTR(tracemalloc);
304 COPY_ATTR(import_time);
305 COPY_ATTR(show_ref_count);
306 COPY_ATTR(show_alloc_count);
307 COPY_ATTR(dump_refs);
308 COPY_ATTR(malloc_stats);
309
Victor Stinner06e76082018-09-19 14:56:36 -0700310 COPY_ATTR(coerce_c_locale);
311 COPY_ATTR(coerce_c_locale_warn);
Victor Stinner6c785c02018-08-01 17:56:14 +0200312 COPY_ATTR(utf8_mode);
313
Victor Stinner124b9eb2018-08-29 01:29:06 +0200314 COPY_WSTR_ATTR(pycache_prefix);
315 COPY_WSTR_ATTR(module_search_path_env);
316 COPY_WSTR_ATTR(home);
317 COPY_WSTR_ATTR(program_name);
318 COPY_WSTR_ATTR(program);
Victor Stinner6c785c02018-08-01 17:56:14 +0200319
320 COPY_WSTRLIST(argc, argv);
321 COPY_WSTRLIST(nwarnoption, warnoptions);
322 COPY_WSTRLIST(nxoption, xoptions);
323 COPY_WSTRLIST(nmodule_search_path, module_search_paths);
324
Victor Stinner124b9eb2018-08-29 01:29:06 +0200325 COPY_WSTR_ATTR(executable);
326 COPY_WSTR_ATTR(prefix);
327 COPY_WSTR_ATTR(base_prefix);
328 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200329#ifdef MS_WINDOWS
Victor Stinner124b9eb2018-08-29 01:29:06 +0200330 COPY_WSTR_ATTR(dll_path);
Victor Stinner6c785c02018-08-01 17:56:14 +0200331#endif
Victor Stinner124b9eb2018-08-29 01:29:06 +0200332 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200333
334 COPY_ATTR(isolated);
335 COPY_ATTR(site_import);
336 COPY_ATTR(bytes_warning);
337 COPY_ATTR(inspect);
338 COPY_ATTR(interactive);
339 COPY_ATTR(optimization_level);
340 COPY_ATTR(parser_debug);
341 COPY_ATTR(write_bytecode);
342 COPY_ATTR(verbose);
343 COPY_ATTR(quiet);
344 COPY_ATTR(user_site_directory);
345 COPY_ATTR(buffered_stdio);
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200346 COPY_STR_ATTR(filesystem_encoding);
347 COPY_STR_ATTR(filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200348 COPY_STR_ATTR(stdio_encoding);
349 COPY_STR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200350#ifdef MS_WINDOWS
351 COPY_ATTR(legacy_windows_fs_encoding);
352 COPY_ATTR(legacy_windows_stdio);
353#endif
354 COPY_ATTR(_check_hash_pycs_mode);
355 COPY_ATTR(_frozen);
356
357#undef COPY_ATTR
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200358#undef COPY_STR_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200359#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200360#undef COPY_WSTRLIST
361 return 0;
362}
363
364
365const char*
366_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
367{
368 assert(config->use_environment >= 0);
369
370 if (!config->use_environment) {
371 return NULL;
372 }
373
374 const char *var = getenv(name);
375 if (var && var[0] != '\0') {
376 return var;
377 }
378 else {
379 return NULL;
380 }
381}
382
383
384int
385_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
386 wchar_t **dest,
387 wchar_t *wname, char *name)
388{
389 assert(config->use_environment >= 0);
390
391 if (!config->use_environment) {
392 *dest = NULL;
393 return 0;
394 }
395
396#ifdef MS_WINDOWS
397 const wchar_t *var = _wgetenv(wname);
398 if (!var || var[0] == '\0') {
399 *dest = NULL;
400 return 0;
401 }
402
403 wchar_t *copy = _PyMem_RawWcsdup(var);
404 if (copy == NULL) {
405 return -1;
406 }
407
408 *dest = copy;
409#else
410 const char *var = getenv(name);
411 if (!var || var[0] == '\0') {
412 *dest = NULL;
413 return 0;
414 }
415
416 size_t len;
417 wchar_t *wvar = Py_DecodeLocale(var, &len);
418 if (!wvar) {
419 if (len == (size_t)-2) {
420 return -2;
421 }
422 else {
423 return -1;
424 }
425 }
426 *dest = wvar;
427#endif
428 return 0;
429}
430
431
432void
433_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
434{
435#define COPY_FLAG(ATTR, VALUE) \
436 if (config->ATTR == -1) { \
437 config->ATTR = VALUE; \
438 }
439#define COPY_NOT_FLAG(ATTR, VALUE) \
440 if (config->ATTR == -1) { \
441 config->ATTR = !(VALUE); \
442 }
443
444 COPY_FLAG(utf8_mode, Py_UTF8Mode);
445 COPY_FLAG(isolated, Py_IsolatedFlag);
446 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
447 COPY_FLAG(inspect, Py_InspectFlag);
448 COPY_FLAG(interactive, Py_InteractiveFlag);
449 COPY_FLAG(optimization_level, Py_OptimizeFlag);
450 COPY_FLAG(parser_debug, Py_DebugFlag);
451 COPY_FLAG(verbose, Py_VerboseFlag);
452 COPY_FLAG(quiet, Py_QuietFlag);
453#ifdef MS_WINDOWS
454 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
455 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
456#endif
457 COPY_FLAG(_frozen, Py_FrozenFlag);
458
459 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
460 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
461 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
462 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
463 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
464
Victor Stinner6c785c02018-08-01 17:56:14 +0200465#undef COPY_FLAG
466#undef COPY_NOT_FLAG
467}
468
469
470/* Set Py_xxx global configuration variables from 'config' configuration. */
471void
472_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
473{
474#define COPY_FLAG(ATTR, VAR) \
475 if (config->ATTR != -1) { \
476 VAR = config->ATTR; \
477 }
478#define COPY_NOT_FLAG(ATTR, VAR) \
479 if (config->ATTR != -1) { \
480 VAR = !config->ATTR; \
481 }
482
483 COPY_FLAG(utf8_mode, Py_UTF8Mode);
484 COPY_FLAG(isolated, Py_IsolatedFlag);
485 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
486 COPY_FLAG(inspect, Py_InspectFlag);
487 COPY_FLAG(interactive, Py_InteractiveFlag);
488 COPY_FLAG(optimization_level, Py_OptimizeFlag);
489 COPY_FLAG(parser_debug, Py_DebugFlag);
490 COPY_FLAG(verbose, Py_VerboseFlag);
491 COPY_FLAG(quiet, Py_QuietFlag);
492#ifdef MS_WINDOWS
493 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
494 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
495#endif
496
497 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
498 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
499 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
500 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
501 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
502
Victor Stinner6c785c02018-08-01 17:56:14 +0200503 /* Random or non-zero hash seed */
504 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
505 config->hash_seed != 0);
506
507#undef COPY_FLAG
508#undef COPY_NOT_FLAG
509}
510
511
512/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
513 environment variables on macOS if available. */
514static _PyInitError
515config_init_program_name(_PyCoreConfig *config)
516{
Victor Stinner5a953fd2018-08-03 22:49:07 +0200517 assert(config->program_name == NULL);
518
Victor Stinner6c785c02018-08-01 17:56:14 +0200519 /* If Py_SetProgramName() was called, use its value */
520 const wchar_t *program_name = _Py_path_config.program_name;
521 if (program_name != NULL) {
522 config->program_name = _PyMem_RawWcsdup(program_name);
523 if (config->program_name == NULL) {
524 return _Py_INIT_NO_MEMORY();
525 }
526 return _Py_INIT_OK();
527 }
528
529#ifdef __APPLE__
530 /* On MacOS X, when the Python interpreter is embedded in an
531 application bundle, it gets executed by a bootstrapping script
532 that does os.execve() with an argv[0] that's different from the
533 actual Python executable. This is needed to keep the Finder happy,
534 or rather, to work around Apple's overly strict requirements of
535 the process name. However, we still need a usable sys.executable,
536 so the actual executable path is passed in an environment variable.
537 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
538 script. */
539 const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
540 if (p != NULL) {
541 size_t len;
542 wchar_t* program_name = Py_DecodeLocale(p, &len);
543 if (program_name == NULL) {
544 return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
545 "variable", (Py_ssize_t)len);
546 }
547 config->program_name = program_name;
548 return _Py_INIT_OK();
549 }
550#ifdef WITH_NEXT_FRAMEWORK
551 else {
552 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
553 if (pyvenv_launcher && *pyvenv_launcher) {
554 /* Used by Mac/Tools/pythonw.c to forward
555 * the argv0 of the stub executable
556 */
557 size_t len;
558 wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
559 if (program_name == NULL) {
560 return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
561 "variable", (Py_ssize_t)len);
562 }
563 config->program_name = program_name;
564 return _Py_INIT_OK();
565 }
566 }
567#endif /* WITH_NEXT_FRAMEWORK */
568#endif /* __APPLE__ */
569
570 /* Use argv[0] by default, if available */
571 if (config->program != NULL) {
572 config->program_name = _PyMem_RawWcsdup(config->program);
573 if (config->program_name == NULL) {
574 return _Py_INIT_NO_MEMORY();
575 }
576 return _Py_INIT_OK();
577 }
578
579 /* Last fall back: hardcoded string */
580#ifdef MS_WINDOWS
581 const wchar_t *default_program_name = L"python";
582#else
583 const wchar_t *default_program_name = L"python3";
584#endif
585 config->program_name = _PyMem_RawWcsdup(default_program_name);
586 if (config->program_name == NULL) {
587 return _Py_INIT_NO_MEMORY();
588 }
589 return _Py_INIT_OK();
590}
591
592
593static const wchar_t*
594config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
595{
596 int nxoption = config->nxoption;
597 wchar_t **xoptions = config->xoptions;
598 for (int i=0; i < nxoption; i++) {
599 wchar_t *option = xoptions[i];
600 size_t len;
601 wchar_t *sep = wcschr(option, L'=');
602 if (sep != NULL) {
603 len = (sep - option);
604 }
605 else {
606 len = wcslen(option);
607 }
608 if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
609 return option;
610 }
611 }
612 return NULL;
613}
614
615
616static _PyInitError
617config_init_home(_PyCoreConfig *config)
618{
619 wchar_t *home;
620
621 /* If Py_SetPythonHome() was called, use its value */
622 home = _Py_path_config.home;
623 if (home) {
624 config->home = _PyMem_RawWcsdup(home);
625 if (config->home == NULL) {
626 return _Py_INIT_NO_MEMORY();
627 }
628 return _Py_INIT_OK();
629 }
630
631 int res = _PyCoreConfig_GetEnvDup(config, &home,
632 L"PYTHONHOME", "PYTHONHOME");
633 if (res < 0) {
634 return DECODE_LOCALE_ERR("PYTHONHOME", res);
635 }
636 config->home = home;
637 return _Py_INIT_OK();
638}
639
640
641static _PyInitError
642config_init_hash_seed(_PyCoreConfig *config)
643{
644 const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
645
646 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
647 /* Convert a text seed to a numeric one */
648 if (seed_text && strcmp(seed_text, "random") != 0) {
649 const char *endptr = seed_text;
650 unsigned long seed;
651 errno = 0;
652 seed = strtoul(seed_text, (char **)&endptr, 10);
653 if (*endptr != '\0'
654 || seed > 4294967295UL
655 || (errno == ERANGE && seed == ULONG_MAX))
656 {
657 return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
658 "or an integer in range [0; 4294967295]");
659 }
660 /* Use a specific hash */
661 config->use_hash_seed = 1;
662 config->hash_seed = seed;
663 }
664 else {
665 /* Use a random hash */
666 config->use_hash_seed = 0;
667 config->hash_seed = 0;
668 }
669 return _Py_INIT_OK();
670}
671
672
673static _PyInitError
674config_init_utf8_mode(_PyCoreConfig *config)
675{
676 const wchar_t *xopt = config_get_xoption(config, L"utf8");
677 if (xopt) {
678 wchar_t *sep = wcschr(xopt, L'=');
679 if (sep) {
680 xopt = sep + 1;
681 if (wcscmp(xopt, L"1") == 0) {
682 config->utf8_mode = 1;
683 }
684 else if (wcscmp(xopt, L"0") == 0) {
685 config->utf8_mode = 0;
686 }
687 else {
688 return _Py_INIT_USER_ERR("invalid -X utf8 option value");
689 }
690 }
691 else {
692 config->utf8_mode = 1;
693 }
694 return _Py_INIT_OK();
695 }
696
697 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONUTF8");
698 if (opt) {
699 if (strcmp(opt, "1") == 0) {
700 config->utf8_mode = 1;
701 }
702 else if (strcmp(opt, "0") == 0) {
703 config->utf8_mode = 0;
704 }
705 else {
706 return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
707 "variable value");
708 }
709 return _Py_INIT_OK();
710 }
711
712 return _Py_INIT_OK();
713}
714
715
716static int
717config_str_to_int(const char *str, int *result)
718{
719 const char *endptr = str;
720 errno = 0;
721 long value = strtol(str, (char **)&endptr, 10);
722 if (*endptr != '\0' || errno == ERANGE) {
723 return -1;
724 }
725 if (value < INT_MIN || value > INT_MAX) {
726 return -1;
727 }
728
729 *result = (int)value;
730 return 0;
731}
732
733
734static int
735config_wstr_to_int(const wchar_t *wstr, int *result)
736{
737 const wchar_t *endptr = wstr;
738 errno = 0;
739 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
740 if (*endptr != '\0' || errno == ERANGE) {
741 return -1;
742 }
743 if (value < INT_MIN || value > INT_MAX) {
744 return -1;
745 }
746
747 *result = (int)value;
748 return 0;
749}
750
751
752static void
753get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
754{
755 const char *var = _PyCoreConfig_GetEnv(config, name);
756 if (!var) {
757 return;
758 }
759 int value;
760 if (config_str_to_int(var, &value) < 0 || value < 0) {
761 /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
762 value = 1;
763 }
764 if (*flag < value) {
765 *flag = value;
766 }
767}
768
769
770static _PyInitError
771config_read_env_vars(_PyCoreConfig *config)
772{
Victor Stinner6c785c02018-08-01 17:56:14 +0200773 /* Get environment variables */
774 get_env_flag(config, &config->parser_debug, "PYTHONDEBUG");
775 get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
776 get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
777 get_env_flag(config, &config->inspect, "PYTHONINSPECT");
778
779 int dont_write_bytecode = 0;
780 get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
781 if (dont_write_bytecode) {
782 config->write_bytecode = 0;
783 }
784
785 int no_user_site_directory = 0;
786 get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
787 if (no_user_site_directory) {
788 config->user_site_directory = 0;
789 }
790
791 int unbuffered_stdio = 0;
792 get_env_flag(config, &unbuffered_stdio, "PYTHONUNBUFFERED");
793 if (unbuffered_stdio) {
794 config->buffered_stdio = 0;
795 }
796
797#ifdef MS_WINDOWS
798 get_env_flag(config, &config->legacy_windows_fs_encoding,
799 "PYTHONLEGACYWINDOWSFSENCODING");
800 get_env_flag(config, &config->legacy_windows_stdio,
801 "PYTHONLEGACYWINDOWSSTDIO");
802#endif
803
804 if (config->allocator == NULL) {
805 config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC");
806 }
807
808 if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
809 config->dump_refs = 1;
810 }
811 if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
812 config->malloc_stats = 1;
813 }
814
Victor Stinner06e76082018-09-19 14:56:36 -0700815 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
816 if (env) {
817 if (strcmp(env, "0") == 0) {
818 if (config->coerce_c_locale < 0) {
819 config->coerce_c_locale = 0;
820 }
821 }
822 else if (strcmp(env, "warn") == 0) {
823 config->coerce_c_locale_warn = 1;
824 }
825 else {
826 if (config->coerce_c_locale < 0) {
827 config->coerce_c_locale = 1;
828 }
829 }
830 }
831
Victor Stinner6c785c02018-08-01 17:56:14 +0200832 wchar_t *path;
833 int res = _PyCoreConfig_GetEnvDup(config, &path,
834 L"PYTHONPATH", "PYTHONPATH");
835 if (res < 0) {
836 return DECODE_LOCALE_ERR("PYTHONPATH", res);
837 }
838 config->module_search_path_env = path;
839
840 if (config->use_hash_seed < 0) {
841 _PyInitError err = config_init_hash_seed(config);
842 if (_Py_INIT_FAILED(err)) {
843 return err;
844 }
845 }
846
847 return _Py_INIT_OK();
848}
849
850
851static _PyInitError
852config_init_tracemalloc(_PyCoreConfig *config)
853{
854 int nframe;
855 int valid;
856
857 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
858 if (env) {
859 if (!config_str_to_int(env, &nframe)) {
860 valid = (nframe >= 0);
861 }
862 else {
863 valid = 0;
864 }
865 if (!valid) {
866 return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
867 "of frames");
868 }
869 config->tracemalloc = nframe;
870 }
871
872 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
873 if (xoption) {
874 const wchar_t *sep = wcschr(xoption, L'=');
875 if (sep) {
876 if (!config_wstr_to_int(sep + 1, &nframe)) {
877 valid = (nframe >= 0);
878 }
879 else {
880 valid = 0;
881 }
882 if (!valid) {
883 return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
884 "invalid number of frames");
885 }
886 }
887 else {
888 /* -X tracemalloc behaves as -X tracemalloc=1 */
889 nframe = 1;
890 }
891 config->tracemalloc = nframe;
892 }
893 return _Py_INIT_OK();
894}
895
896
897static _PyInitError
898config_init_pycache_prefix(_PyCoreConfig *config)
899{
900 assert(config->pycache_prefix == NULL);
901
902 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
903 if (xoption) {
904 const wchar_t *sep = wcschr(xoption, L'=');
905 if (sep && wcslen(sep) > 1) {
906 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
907 if (config->pycache_prefix == NULL) {
908 return _Py_INIT_NO_MEMORY();
909 }
910 }
911 else {
912 // -X pycache_prefix= can cancel the env var
913 config->pycache_prefix = NULL;
914 }
915 }
916 else {
917 wchar_t *env;
918 int res = _PyCoreConfig_GetEnvDup(config, &env,
919 L"PYTHONPYCACHEPREFIX",
920 "PYTHONPYCACHEPREFIX");
921 if (res < 0) {
922 return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res);
923 }
924
925 if (env) {
926 config->pycache_prefix = env;
927 }
928 }
929 return _Py_INIT_OK();
930}
931
932
933static _PyInitError
934config_read_complex_options(_PyCoreConfig *config)
935{
936 /* More complex options configured by env var and -X option */
937 if (config->faulthandler < 0) {
938 if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
939 || config_get_xoption(config, L"faulthandler")) {
940 config->faulthandler = 1;
941 }
942 }
943 if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
944 || config_get_xoption(config, L"importtime")) {
945 config->import_time = 1;
946 }
947 if (config_get_xoption(config, L"dev" ) ||
948 _PyCoreConfig_GetEnv(config, "PYTHONDEVMODE"))
949 {
950 config->dev_mode = 1;
951 }
952
953 _PyInitError err;
954 if (config->tracemalloc < 0) {
955 err = config_init_tracemalloc(config);
956 if (_Py_INIT_FAILED(err)) {
957 return err;
958 }
959 }
960
961 if (config->pycache_prefix == NULL) {
962 err = config_init_pycache_prefix(config);
963 if (_Py_INIT_FAILED(err)) {
964 return err;
965 }
966 }
967 return _Py_INIT_OK();
968}
969
970
Victor Stinner06e76082018-09-19 14:56:36 -0700971static void
972config_init_locale(_PyCoreConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200973{
Victor Stinner06e76082018-09-19 14:56:36 -0700974 if (config->coerce_c_locale < 0) {
Victor Stinner5cb25892018-08-28 12:35:44 +0200975 /* The C locale enables the C locale coercion (PEP 538) */
Victor Stinnerd500e532018-08-28 17:27:36 +0200976 if (_Py_LegacyLocaleDetected()) {
Victor Stinner06e76082018-09-19 14:56:36 -0700977 config->coerce_c_locale = 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200978 }
Victor Stinner6c785c02018-08-01 17:56:14 +0200979 }
Victor Stinnerd500e532018-08-28 17:27:36 +0200980
Victor Stinner06e76082018-09-19 14:56:36 -0700981#ifndef MS_WINDOWS
982 if (config->utf8_mode < 0) {
983 /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
984 const char *ctype_loc = setlocale(LC_CTYPE, NULL);
985 if (ctype_loc != NULL
986 && (strcmp(ctype_loc, "C") == 0
987 || strcmp(ctype_loc, "POSIX") == 0))
988 {
989 config->utf8_mode = 1;
990 }
991 }
992#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200993}
994
995
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200996static const char *
997get_stdio_errors(const _PyCoreConfig *config)
998{
999#ifndef MS_WINDOWS
1000 const char *loc = setlocale(LC_CTYPE, NULL);
1001 if (loc != NULL) {
1002 /* surrogateescape is the default in the legacy C and POSIX locales */
1003 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
1004 return "surrogateescape";
1005 }
1006
1007#ifdef PY_COERCE_C_LOCALE
1008 /* surrogateescape is the default in locale coercion target locales */
1009 if (_Py_IsLocaleCoercionTarget(loc)) {
1010 return "surrogateescape";
1011 }
1012#endif
1013 }
1014
1015 return "strict";
1016#else
1017 /* On Windows, always use surrogateescape by default */
1018 return "surrogateescape";
1019#endif
1020}
1021
1022
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001023static _PyInitError
1024get_locale_encoding(char **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001025{
1026#ifdef MS_WINDOWS
1027 char encoding[20];
1028 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
1029#elif defined(__ANDROID__)
1030 const char *encoding = "UTF-8";
1031#else
1032 const char *encoding = nl_langinfo(CODESET);
1033 if (!encoding || encoding[0] == '\0') {
1034 return _Py_INIT_USER_ERR("failed to get the locale encoding: "
1035 "nl_langinfo(CODESET) failed");
1036 }
1037#endif
1038 *locale_encoding = _PyMem_RawStrdup(encoding);
1039 if (*locale_encoding == NULL) {
1040 return _Py_INIT_NO_MEMORY();
1041 }
1042 return _Py_INIT_OK();
1043}
1044
1045
1046static _PyInitError
1047config_init_stdio_encoding(_PyCoreConfig *config)
1048{
1049 /* If Py_SetStandardStreamEncoding() have been called, use these
1050 parameters. */
1051 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
1052 config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding);
1053 if (config->stdio_encoding == NULL) {
1054 return _Py_INIT_NO_MEMORY();
1055 }
1056 }
1057
1058 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
1059 config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors);
1060 if (config->stdio_errors == NULL) {
1061 return _Py_INIT_NO_MEMORY();
1062 }
1063 }
1064
1065 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1066 return _Py_INIT_OK();
1067 }
1068
1069 /* PYTHONIOENCODING environment variable */
1070 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
1071 if (opt) {
1072 char *pythonioencoding = _PyMem_RawStrdup(opt);
1073 if (pythonioencoding == NULL) {
1074 return _Py_INIT_NO_MEMORY();
1075 }
1076
1077 char *err = strchr(pythonioencoding, ':');
1078 if (err) {
1079 *err = '\0';
1080 err++;
1081 if (!err[0]) {
1082 err = NULL;
1083 }
1084 }
1085
1086 /* Does PYTHONIOENCODING contain an encoding? */
1087 if (pythonioencoding[0]) {
1088 if (config->stdio_encoding == NULL) {
1089 config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding);
1090 if (config->stdio_encoding == NULL) {
1091 PyMem_RawFree(pythonioencoding);
1092 return _Py_INIT_NO_MEMORY();
1093 }
1094 }
1095
1096 /* If the encoding is set but not the error handler,
1097 use "strict" error handler by default.
1098 PYTHONIOENCODING=latin1 behaves as
1099 PYTHONIOENCODING=latin1:strict. */
1100 if (!err) {
1101 err = "strict";
1102 }
1103 }
1104
1105 if (config->stdio_errors == NULL && err != NULL) {
1106 config->stdio_errors = _PyMem_RawStrdup(err);
1107 if (config->stdio_errors == NULL) {
1108 PyMem_RawFree(pythonioencoding);
1109 return _Py_INIT_NO_MEMORY();
1110 }
1111 }
1112
1113 PyMem_RawFree(pythonioencoding);
1114 }
1115
1116 /* UTF-8 Mode uses UTF-8/surrogateescape */
1117 if (config->utf8_mode) {
1118 if (config->stdio_encoding == NULL) {
1119 config->stdio_encoding = _PyMem_RawStrdup("utf-8");
1120 if (config->stdio_encoding == NULL) {
1121 return _Py_INIT_NO_MEMORY();
1122 }
1123 }
1124 if (config->stdio_errors == NULL) {
1125 config->stdio_errors = _PyMem_RawStrdup("surrogateescape");
1126 if (config->stdio_errors == NULL) {
1127 return _Py_INIT_NO_MEMORY();
1128 }
1129 }
1130 }
1131
1132 /* Choose the default error handler based on the current locale. */
1133 if (config->stdio_encoding == NULL) {
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001134 _PyInitError err = get_locale_encoding(&config->stdio_encoding);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001135 if (_Py_INIT_FAILED(err)) {
1136 return err;
1137 }
1138 }
1139 if (config->stdio_errors == NULL) {
1140 const char *errors = get_stdio_errors(config);
1141 config->stdio_errors = _PyMem_RawStrdup(errors);
1142 if (config->stdio_errors == NULL) {
1143 return _Py_INIT_NO_MEMORY();
1144 }
1145 }
1146
1147 return _Py_INIT_OK();
1148}
1149
1150
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001151static _PyInitError
1152config_init_fs_encoding(_PyCoreConfig *config)
1153{
1154#ifdef MS_WINDOWS
1155 if (config->legacy_windows_fs_encoding) {
1156 /* Legacy Windows filesystem encoding: mbcs/replace */
1157 if (config->filesystem_encoding == NULL) {
1158 config->filesystem_encoding = _PyMem_RawStrdup("mbcs");
1159 if (config->filesystem_encoding == NULL) {
1160 return _Py_INIT_NO_MEMORY();
1161 }
1162 }
1163 if (config->filesystem_errors == NULL) {
1164 config->filesystem_errors = _PyMem_RawStrdup("replace");
1165 if (config->filesystem_errors == NULL) {
1166 return _Py_INIT_NO_MEMORY();
1167 }
1168 }
1169 }
1170
Victor Stinner905f1ac2018-10-30 12:58:10 +01001171 /* Windows defaults to utf-8/surrogatepass (PEP 529).
1172
1173 Note: UTF-8 Mode takes the same code path and the Legacy Windows FS
1174 encoding has the priortiy over UTF-8 Mode. */
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001175 if (config->filesystem_encoding == NULL) {
1176 config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
1177 if (config->filesystem_encoding == NULL) {
1178 return _Py_INIT_NO_MEMORY();
1179 }
1180 }
Victor Stinner905f1ac2018-10-30 12:58:10 +01001181
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001182 if (config->filesystem_errors == NULL) {
1183 config->filesystem_errors = _PyMem_RawStrdup("surrogatepass");
1184 if (config->filesystem_errors == NULL) {
1185 return _Py_INIT_NO_MEMORY();
1186 }
1187 }
1188#else
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001189 if (config->filesystem_encoding == NULL) {
Victor Stinner905f1ac2018-10-30 12:58:10 +01001190 if (config->utf8_mode) {
1191 /* UTF-8 Mode use: utf-8/surrogateescape */
1192 config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
1193 /* errors defaults to surrogateescape above */
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001194 }
Victor Stinner905f1ac2018-10-30 12:58:10 +01001195 else if (_Py_GetForceASCII()) {
1196 config->filesystem_encoding = _PyMem_RawStrdup("ascii");
1197 }
1198 else {
1199 /* macOS and Android use UTF-8,
1200 other platforms use the locale encoding. */
1201#if defined(__APPLE__) || defined(__ANDROID__)
1202 config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
1203#else
1204 _PyInitError err = get_locale_encoding(&config->filesystem_encoding);
1205 if (_Py_INIT_FAILED(err)) {
1206 return err;
1207 }
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001208#endif
Victor Stinner905f1ac2018-10-30 12:58:10 +01001209 }
1210
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001211 if (config->filesystem_encoding == NULL) {
1212 return _Py_INIT_NO_MEMORY();
1213 }
1214 }
1215
1216 if (config->filesystem_errors == NULL) {
1217 /* by default, use the "surrogateescape" error handler */
1218 config->filesystem_errors = _PyMem_RawStrdup("surrogateescape");
1219 if (config->filesystem_errors == NULL) {
1220 return _Py_INIT_NO_MEMORY();
1221 }
1222 }
1223#endif
1224 return _Py_INIT_OK();
1225}
1226
1227
Victor Stinner6c785c02018-08-01 17:56:14 +02001228/* Read configuration settings from standard locations
1229 *
1230 * This function doesn't make any changes to the interpreter state - it
1231 * merely populates any missing configuration settings. This allows an
1232 * embedding application to completely override a config option by
1233 * setting it before calling this function, or else modify the default
1234 * setting before passing the fully populated config to Py_EndInitialization.
1235 *
1236 * More advanced selective initialization tricks are possible by calling
1237 * this function multiple times with various preconfigured settings.
1238 */
1239
1240_PyInitError
1241_PyCoreConfig_Read(_PyCoreConfig *config)
1242{
1243 _PyInitError err;
1244
1245 _PyCoreConfig_GetGlobalConfig(config);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001246 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001247
1248 if (config->isolated > 0) {
1249 config->use_environment = 0;
1250 config->user_site_directory = 0;
1251 }
1252
1253#ifdef MS_WINDOWS
1254 if (config->legacy_windows_fs_encoding) {
1255 config->utf8_mode = 0;
1256 }
1257#endif
1258
Victor Stinner6c785c02018-08-01 17:56:14 +02001259 if (config->use_environment) {
1260 err = config_read_env_vars(config);
1261 if (_Py_INIT_FAILED(err)) {
1262 return err;
1263 }
1264 }
1265
1266 /* -X options */
1267 if (config_get_xoption(config, L"showrefcount")) {
1268 config->show_ref_count = 1;
1269 }
1270 if (config_get_xoption(config, L"showalloccount")) {
1271 config->show_alloc_count = 1;
1272 }
1273
1274 err = config_read_complex_options(config);
1275 if (_Py_INIT_FAILED(err)) {
1276 return err;
1277 }
1278
1279 if (config->utf8_mode < 0) {
1280 err = config_init_utf8_mode(config);
1281 if (_Py_INIT_FAILED(err)) {
1282 return err;
1283 }
1284 }
1285
1286 if (config->home == NULL) {
1287 err = config_init_home(config);
1288 if (_Py_INIT_FAILED(err)) {
1289 return err;
1290 }
1291 }
1292
1293 if (config->program_name == NULL) {
1294 err = config_init_program_name(config);
1295 if (_Py_INIT_FAILED(err)) {
1296 return err;
1297 }
1298 }
1299
Victor Stinner06e76082018-09-19 14:56:36 -07001300 if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
1301 config_init_locale(config);
Victor Stinner5a953fd2018-08-03 22:49:07 +02001302 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001303
1304 if (config->_install_importlib) {
1305 err = _PyCoreConfig_InitPathConfig(config);
1306 if (_Py_INIT_FAILED(err)) {
1307 return err;
1308 }
1309 }
1310
1311 /* default values */
1312 if (config->dev_mode) {
1313 if (config->faulthandler < 0) {
1314 config->faulthandler = 1;
1315 }
1316 if (config->allocator == NULL) {
1317 config->allocator = "debug";
1318 }
1319 }
1320 if (config->use_hash_seed < 0) {
1321 config->use_hash_seed = 0;
1322 config->hash_seed = 0;
1323 }
1324 if (config->faulthandler < 0) {
1325 config->faulthandler = 0;
1326 }
1327 if (config->tracemalloc < 0) {
1328 config->tracemalloc = 0;
1329 }
Victor Stinner06e76082018-09-19 14:56:36 -07001330 if (config->coerce_c_locale < 0) {
1331 config->coerce_c_locale = 0;
Victor Stinner7a0791b2018-09-17 16:22:29 -07001332 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001333 if (config->utf8_mode < 0) {
1334 config->utf8_mode = 0;
1335 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001336 if (config->argc < 0) {
1337 config->argc = 0;
1338 }
1339
Victor Stinner70fead22018-08-29 13:45:34 +02001340 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001341 err = config_init_fs_encoding(config);
1342 if (_Py_INIT_FAILED(err)) {
1343 return err;
1344 }
1345 }
1346
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001347 err = config_init_stdio_encoding(config);
1348 if (_Py_INIT_FAILED(err)) {
1349 return err;
1350 }
1351
Victor Stinner06e76082018-09-19 14:56:36 -07001352 assert(config->coerce_c_locale >= 0);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001353 assert(config->use_environment >= 0);
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001354 assert(config->filesystem_encoding != NULL);
1355 assert(config->filesystem_errors != NULL);
1356 assert(config->stdio_encoding != NULL);
1357 assert(config->stdio_errors != NULL);
Victor Stinnerde427552018-08-29 23:26:55 +02001358 assert(config->_check_hash_pycs_mode != NULL);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001359
Victor Stinner6c785c02018-08-01 17:56:14 +02001360 return _Py_INIT_OK();
1361}
Victor Stinner5ed69952018-11-06 15:59:52 +01001362
1363
1364PyObject *
1365_PyCoreConfig_AsDict(const _PyCoreConfig *config)
1366{
1367 PyObject *dict, *obj;
1368
1369 dict = PyDict_New();
1370 if (dict == NULL) {
1371 return NULL;
1372 }
1373
1374#define FROM_STRING(STR) \
1375 ((STR != NULL) ? \
1376 PyUnicode_FromString(STR) \
1377 : (Py_INCREF(Py_None), Py_None))
1378#define FROM_WSTRING(STR) \
1379 ((STR != NULL) ? \
1380 PyUnicode_FromWideChar(STR, -1) \
1381 : (Py_INCREF(Py_None), Py_None))
1382#define SET_ITEM(KEY, EXPR) \
1383 do { \
1384 obj = (EXPR); \
1385 if (obj == NULL) { \
1386 return NULL; \
1387 } \
1388 int res = PyDict_SetItemString(dict, (KEY), obj); \
1389 Py_DECREF(obj); \
1390 if (res < 0) { \
1391 goto fail; \
1392 } \
1393 } while (0)
1394
1395 SET_ITEM("install_signal_handlers",
1396 PyLong_FromLong(config->install_signal_handlers));
1397 SET_ITEM("use_environment",
1398 PyLong_FromLong(config->use_environment));
1399 SET_ITEM("use_hash_seed",
1400 PyLong_FromLong(config->use_hash_seed));
1401 SET_ITEM("hash_seed",
1402 PyLong_FromUnsignedLong(config->hash_seed));
1403 SET_ITEM("allocator",
1404 FROM_STRING(config->allocator));
1405 SET_ITEM("dev_mode",
1406 PyLong_FromLong(config->dev_mode));
1407 SET_ITEM("faulthandler",
1408 PyLong_FromLong(config->faulthandler));
1409 SET_ITEM("tracemalloc",
1410 PyLong_FromLong(config->tracemalloc));
1411 SET_ITEM("import_time",
1412 PyLong_FromLong(config->import_time));
1413 SET_ITEM("show_ref_count",
1414 PyLong_FromLong(config->show_ref_count));
1415 SET_ITEM("show_alloc_count",
1416 PyLong_FromLong(config->show_alloc_count));
1417 SET_ITEM("dump_refs",
1418 PyLong_FromLong(config->dump_refs));
1419 SET_ITEM("malloc_stats",
1420 PyLong_FromLong(config->malloc_stats));
1421 SET_ITEM("coerce_c_locale",
1422 PyLong_FromLong(config->coerce_c_locale));
1423 SET_ITEM("coerce_c_locale_warn",
1424 PyLong_FromLong(config->coerce_c_locale_warn));
1425 SET_ITEM("filesystem_encoding",
1426 FROM_STRING(config->filesystem_encoding));
1427 SET_ITEM("filesystem_errors",
1428 FROM_STRING(config->filesystem_errors));
1429 SET_ITEM("stdio_encoding",
1430 FROM_STRING(config->stdio_encoding));
1431 SET_ITEM("utf8_mode",
1432 PyLong_FromLong(config->utf8_mode));
1433 SET_ITEM("pycache_prefix",
1434 FROM_WSTRING(config->pycache_prefix));
1435 SET_ITEM("program_name",
1436 FROM_WSTRING(config->program_name));
1437 SET_ITEM("argv",
1438 _Py_wstrlist_as_pylist(config->argc, config->argv));
1439 SET_ITEM("program",
1440 FROM_WSTRING(config->program));
1441 SET_ITEM("warnoptions",
1442 _Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions));
1443 SET_ITEM("module_search_path_env",
1444 FROM_WSTRING(config->module_search_path_env));
1445 SET_ITEM("home",
1446 FROM_WSTRING(config->home));
1447 SET_ITEM("module_search_paths",
1448 _Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths));
1449 SET_ITEM("executable",
1450 FROM_WSTRING(config->executable));
1451 SET_ITEM("prefix",
1452 FROM_WSTRING(config->prefix));
1453 SET_ITEM("base_prefix",
1454 FROM_WSTRING(config->base_prefix));
1455 SET_ITEM("exec_prefix",
1456 FROM_WSTRING(config->exec_prefix));
1457 SET_ITEM("base_exec_prefix",
1458 FROM_WSTRING(config->base_exec_prefix));
1459#ifdef MS_WINDOWS
1460 SET_ITEM("dll_path",
1461 FROM_WSTRING(config->dll_path));
1462#endif
1463 SET_ITEM("isolated",
1464 PyLong_FromLong(config->isolated));
1465 SET_ITEM("site_import",
1466 PyLong_FromLong(config->site_import));
1467 SET_ITEM("bytes_warning",
1468 PyLong_FromLong(config->bytes_warning));
1469 SET_ITEM("inspect",
1470 PyLong_FromLong(config->inspect));
1471 SET_ITEM("interactive",
1472 PyLong_FromLong(config->interactive));
1473 SET_ITEM("optimization_level",
1474 PyLong_FromLong(config->optimization_level));
1475 SET_ITEM("parser_debug",
1476 PyLong_FromLong(config->parser_debug));
1477 SET_ITEM("write_bytecode",
1478 PyLong_FromLong(config->write_bytecode));
1479 SET_ITEM("verbose",
1480 PyLong_FromLong(config->verbose));
1481 SET_ITEM("quiet",
1482 PyLong_FromLong(config->quiet));
1483 SET_ITEM("user_site_directory",
1484 PyLong_FromLong(config->user_site_directory));
1485 SET_ITEM("buffered_stdio",
1486 PyLong_FromLong(config->buffered_stdio));
1487 SET_ITEM("stdio_encoding",
1488 FROM_STRING(config->stdio_encoding));
1489 SET_ITEM("stdio_errors",
1490 FROM_STRING(config->stdio_errors));
1491#ifdef MS_WINDOWS
1492 SET_ITEM("legacy_windows_fs_encoding",
1493 PyLong_FromLong(config->legacy_windows_fs_encoding));
1494 SET_ITEM("legacy_windows_stdio",
1495 PyLong_FromLong(config->legacy_windows_stdio));
1496#endif
1497 SET_ITEM("_install_importlib",
1498 PyLong_FromLong(config->_install_importlib));
1499 SET_ITEM("_check_hash_pycs_mode",
1500 FROM_STRING(config->_check_hash_pycs_mode));
1501 SET_ITEM("_frozen",
1502 PyLong_FromLong(config->_frozen));
1503
1504 return dict;
1505
1506fail:
1507 Py_DECREF(dict);
1508 return NULL;
1509
1510#undef FROM_STRING
1511#undef FROM_WSTRING
1512#undef SET_ITEM
1513}