1 #include "Python.h"
2 #include "osdefs.h" /* DELIM */
3 #include "pycore_fileutils.h"
4 #include "pycore_getopt.h"
5 #include "pycore_initconfig.h"
6 #include "pycore_pathconfig.h"
7 #include "pycore_pyerrors.h"
8 #include "pycore_pylifecycle.h"
9 #include "pycore_pymem.h"
10 #include "pycore_pystate.h" /* _PyRuntime */
11 #include <locale.h> /* setlocale() */
12 #ifdef HAVE_LANGINFO_H
13 # include <langinfo.h> /* nl_langinfo(CODESET) */
14 #endif
15 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
16 # include <windows.h> /* GetACP() */
17 # ifdef HAVE_IO_H
18 # include <io.h>
19 # endif
20 # ifdef HAVE_FCNTL_H
21 # include <fcntl.h> /* O_BINARY */
22 # endif
23 #endif
24
25
26 /* --- Command line options --------------------------------------- */
27
28 /* Short usage message (with %s for argv0) */
29 static const char usage_line[] =
30 "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
31
32 /* Long usage message, split into parts < 512 bytes */
33 static const char usage_1[] = "\
34 Options and arguments (and corresponding environment variables):\n\
35 -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
36 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
37 -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
38 -c cmd : program passed in as string (terminates option list)\n\
39 -d : debug output from parser; also PYTHONDEBUG=x\n\
40 -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
41 -h : print this help message and exit (also --help)\n\
42 ";
43 static const char usage_2[] = "\
44 -i : inspect interactively after running script; forces a prompt even\n\
45 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
46 -I : isolate Python from the user's environment (implies -E and -s)\n\
47 -m mod : run library module as a script (terminates option list)\n\
48 -O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
49 .pyc extension; also PYTHONOPTIMIZE=x\n\
50 -OO : do -O changes and also discard docstrings; add .opt-2 before\n\
51 .pyc extension\n\
52 -q : don't print version and copyright messages on interactive startup\n\
53 -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
54 -S : don't imply 'import site' on initialization\n\
55 ";
56 static const char usage_3[] = "\
57 -u : force the stdout and stderr streams to be unbuffered;\n\
58 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
59 -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
60 can be supplied multiple times to increase verbosity\n\
61 -V : print the Python version number and exit (also --version)\n\
62 when given twice, print more information about the build\n\
63 -W arg : warning control; arg is action:message:category:module:lineno\n\
64 also PYTHONWARNINGS=arg\n\
65 -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
66 -X opt : set implementation-specific option\n\
67 --check-hash-based-pycs always|default|never:\n\
68 control how Python invalidates hash-based .pyc files\n\
69 ";
70 static const char usage_4[] = "\
71 file : program read from script file\n\
72 - : program read from stdin (default; interactive mode if a tty)\n\
73 arg ...: arguments passed to program in sys.argv[1:]\n\n\
74 Other environment variables:\n\
75 PYTHONSTARTUP: file executed on interactive startup (no default)\n\
76 PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
77 default module search path. The result is sys.path.\n\
78 ";
79 static const char usage_5[] =
80 "PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
81 " The default module search path uses %s.\n"
82 "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
83 "PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
84 "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
85 "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
86 static const char usage_6[] =
87 "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
88 " to seed the hashes of str and bytes objects. It can also be set to an\n"
89 " integer in the range [0,4294967295] to get hash values with a\n"
90 " predictable seed.\n"
91 "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
92 " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
93 " hooks.\n"
94 "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
95 " coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
96 " locale coercion and locale compatibility warnings on stderr.\n"
97 "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
98 " debugger. It can be set to the callable of your debugger of choice.\n"
99 "PYTHONDEVMODE: enable the development mode.\n"
100 "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
101
102 #if defined(MS_WINDOWS)
103 # define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
104 #else
105 # define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
106 #endif
107
108
109 /* --- Global configuration variables ----------------------------- */
110
111 /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
112 stdin and stdout error handler to "surrogateescape". */
113 int Py_UTF8Mode = 0;
114 int Py_DebugFlag = 0; /* Needed by parser.c */
115 int Py_VerboseFlag = 0; /* Needed by import.c */
116 int Py_QuietFlag = 0; /* Needed by sysmodule.c */
117 int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
118 int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
119 int Py_OptimizeFlag = 0; /* Needed by compile.c */
120 int Py_NoSiteFlag = 0; /* Suppress 'import site' */
121 int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
122 int Py_FrozenFlag = 0; /* Needed by getpath.c */
123 int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
124 int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
125 int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
126 int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
127 int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
128 int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
129 #ifdef MS_WINDOWS
130 int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
131 int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
132 #endif
133
134
135 static PyObject *
_Py_GetGlobalVariablesAsDict(void)136 _Py_GetGlobalVariablesAsDict(void)
137 {
138 PyObject *dict, *obj;
139
140 dict = PyDict_New();
141 if (dict == NULL) {
142 return NULL;
143 }
144
145 #define SET_ITEM(KEY, EXPR) \
146 do { \
147 obj = (EXPR); \
148 if (obj == NULL) { \
149 return NULL; \
150 } \
151 int res = PyDict_SetItemString(dict, (KEY), obj); \
152 Py_DECREF(obj); \
153 if (res < 0) { \
154 goto fail; \
155 } \
156 } while (0)
157 #define SET_ITEM_INT(VAR) \
158 SET_ITEM(#VAR, PyLong_FromLong(VAR))
159 #define FROM_STRING(STR) \
160 ((STR != NULL) ? \
161 PyUnicode_FromString(STR) \
162 : (Py_INCREF(Py_None), Py_None))
163 #define SET_ITEM_STR(VAR) \
164 SET_ITEM(#VAR, FROM_STRING(VAR))
165
166 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
167 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
168 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
169 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
170
171 SET_ITEM_INT(Py_UTF8Mode);
172 SET_ITEM_INT(Py_DebugFlag);
173 SET_ITEM_INT(Py_VerboseFlag);
174 SET_ITEM_INT(Py_QuietFlag);
175 SET_ITEM_INT(Py_InteractiveFlag);
176 SET_ITEM_INT(Py_InspectFlag);
177
178 SET_ITEM_INT(Py_OptimizeFlag);
179 SET_ITEM_INT(Py_NoSiteFlag);
180 SET_ITEM_INT(Py_BytesWarningFlag);
181 SET_ITEM_INT(Py_FrozenFlag);
182 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
183 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
184 SET_ITEM_INT(Py_NoUserSiteDirectory);
185 SET_ITEM_INT(Py_UnbufferedStdioFlag);
186 SET_ITEM_INT(Py_HashRandomizationFlag);
187 SET_ITEM_INT(Py_IsolatedFlag);
188
189 #ifdef MS_WINDOWS
190 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
191 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
192 #endif
193
194 return dict;
195
196 fail:
197 Py_DECREF(dict);
198 return NULL;
199
200 #undef FROM_STRING
201 #undef SET_ITEM
202 #undef SET_ITEM_INT
203 #undef SET_ITEM_STR
204 }
205
206
207 /* --- PyStatus ----------------------------------------------- */
208
PyStatus_Ok(void)209 PyStatus PyStatus_Ok(void)
210 { return _PyStatus_OK(); }
211
PyStatus_Error(const char * err_msg)212 PyStatus PyStatus_Error(const char *err_msg)
213 {
214 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
215 .err_msg = err_msg};
216 }
217
PyStatus_NoMemory(void)218 PyStatus PyStatus_NoMemory(void)
219 { return PyStatus_Error("memory allocation failed"); }
220
PyStatus_Exit(int exitcode)221 PyStatus PyStatus_Exit(int exitcode)
222 { return _PyStatus_EXIT(exitcode); }
223
224
PyStatus_IsError(PyStatus status)225 int PyStatus_IsError(PyStatus status)
226 { return _PyStatus_IS_ERROR(status); }
227
PyStatus_IsExit(PyStatus status)228 int PyStatus_IsExit(PyStatus status)
229 { return _PyStatus_IS_EXIT(status); }
230
PyStatus_Exception(PyStatus status)231 int PyStatus_Exception(PyStatus status)
232 { return _PyStatus_EXCEPTION(status); }
233
234
235 /* --- PyWideStringList ------------------------------------------------ */
236
237 #ifndef NDEBUG
238 int
_PyWideStringList_CheckConsistency(const PyWideStringList * list)239 _PyWideStringList_CheckConsistency(const PyWideStringList *list)
240 {
241 assert(list->length >= 0);
242 if (list->length != 0) {
243 assert(list->items != NULL);
244 }
245 for (Py_ssize_t i = 0; i < list->length; i++) {
246 assert(list->items[i] != NULL);
247 }
248 return 1;
249 }
250 #endif /* Py_DEBUG */
251
252
253 void
_PyWideStringList_Clear(PyWideStringList * list)254 _PyWideStringList_Clear(PyWideStringList *list)
255 {
256 assert(_PyWideStringList_CheckConsistency(list));
257 for (Py_ssize_t i=0; i < list->length; i++) {
258 PyMem_RawFree(list->items[i]);
259 }
260 PyMem_RawFree(list->items);
261 list->length = 0;
262 list->items = NULL;
263 }
264
265
266 int
_PyWideStringList_Copy(PyWideStringList * list,const PyWideStringList * list2)267 _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
268 {
269 assert(_PyWideStringList_CheckConsistency(list));
270 assert(_PyWideStringList_CheckConsistency(list2));
271
272 if (list2->length == 0) {
273 _PyWideStringList_Clear(list);
274 return 0;
275 }
276
277 PyWideStringList copy = _PyWideStringList_INIT;
278
279 size_t size = list2->length * sizeof(list2->items[0]);
280 copy.items = PyMem_RawMalloc(size);
281 if (copy.items == NULL) {
282 return -1;
283 }
284
285 for (Py_ssize_t i=0; i < list2->length; i++) {
286 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
287 if (item == NULL) {
288 _PyWideStringList_Clear(©);
289 return -1;
290 }
291 copy.items[i] = item;
292 copy.length = i + 1;
293 }
294
295 _PyWideStringList_Clear(list);
296 *list = copy;
297 return 0;
298 }
299
300
301 PyStatus
PyWideStringList_Insert(PyWideStringList * list,Py_ssize_t index,const wchar_t * item)302 PyWideStringList_Insert(PyWideStringList *list,
303 Py_ssize_t index, const wchar_t *item)
304 {
305 Py_ssize_t len = list->length;
306 if (len == PY_SSIZE_T_MAX) {
307 /* length+1 would overflow */
308 return _PyStatus_NO_MEMORY();
309 }
310 if (index < 0) {
311 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
312 }
313 if (index > len) {
314 index = len;
315 }
316
317 wchar_t *item2 = _PyMem_RawWcsdup(item);
318 if (item2 == NULL) {
319 return _PyStatus_NO_MEMORY();
320 }
321
322 size_t size = (len + 1) * sizeof(list->items[0]);
323 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
324 if (items2 == NULL) {
325 PyMem_RawFree(item2);
326 return _PyStatus_NO_MEMORY();
327 }
328
329 if (index < len) {
330 memmove(&items2[index + 1],
331 &items2[index],
332 (len - index) * sizeof(items2[0]));
333 }
334
335 items2[index] = item2;
336 list->items = items2;
337 list->length++;
338 return _PyStatus_OK();
339 }
340
341
342 PyStatus
PyWideStringList_Append(PyWideStringList * list,const wchar_t * item)343 PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
344 {
345 return PyWideStringList_Insert(list, list->length, item);
346 }
347
348
349 PyStatus
_PyWideStringList_Extend(PyWideStringList * list,const PyWideStringList * list2)350 _PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
351 {
352 for (Py_ssize_t i = 0; i < list2->length; i++) {
353 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
354 if (_PyStatus_EXCEPTION(status)) {
355 return status;
356 }
357 }
358 return _PyStatus_OK();
359 }
360
361
362 static int
_PyWideStringList_Find(PyWideStringList * list,const wchar_t * item)363 _PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
364 {
365 for (Py_ssize_t i = 0; i < list->length; i++) {
366 if (wcscmp(list->items[i], item) == 0) {
367 return 1;
368 }
369 }
370 return 0;
371 }
372
373
374 PyObject*
_PyWideStringList_AsList(const PyWideStringList * list)375 _PyWideStringList_AsList(const PyWideStringList *list)
376 {
377 assert(_PyWideStringList_CheckConsistency(list));
378
379 PyObject *pylist = PyList_New(list->length);
380 if (pylist == NULL) {
381 return NULL;
382 }
383
384 for (Py_ssize_t i = 0; i < list->length; i++) {
385 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
386 if (item == NULL) {
387 Py_DECREF(pylist);
388 return NULL;
389 }
390 PyList_SET_ITEM(pylist, i, item);
391 }
392 return pylist;
393 }
394
395
396 /* --- Py_SetStandardStreamEncoding() ----------------------------- */
397
398 /* Helper to allow an embedding application to override the normal
399 * mechanism that attempts to figure out an appropriate IO encoding
400 */
401
402 static char *_Py_StandardStreamEncoding = NULL;
403 static char *_Py_StandardStreamErrors = NULL;
404
405 int
Py_SetStandardStreamEncoding(const char * encoding,const char * errors)406 Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
407 {
408 if (Py_IsInitialized()) {
409 /* This is too late to have any effect */
410 return -1;
411 }
412
413 int res = 0;
414
415 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
416 but Py_Initialize() can change the allocator. Use a known allocator
417 to be able to release the memory later. */
418 PyMemAllocatorEx old_alloc;
419 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
420
421 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
422 * initialised yet.
423 *
424 * However, the raw memory allocators are initialised appropriately
425 * as C static variables, so _PyMem_RawStrdup is OK even though
426 * Py_Initialize hasn't been called yet.
427 */
428 if (encoding) {
429 PyMem_RawFree(_Py_StandardStreamEncoding);
430 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
431 if (!_Py_StandardStreamEncoding) {
432 res = -2;
433 goto done;
434 }
435 }
436 if (errors) {
437 PyMem_RawFree(_Py_StandardStreamErrors);
438 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
439 if (!_Py_StandardStreamErrors) {
440 PyMem_RawFree(_Py_StandardStreamEncoding);
441 _Py_StandardStreamEncoding = NULL;
442 res = -3;
443 goto done;
444 }
445 }
446 #ifdef MS_WINDOWS
447 if (_Py_StandardStreamEncoding) {
448 /* Overriding the stream encoding implies legacy streams */
449 Py_LegacyWindowsStdioFlag = 1;
450 }
451 #endif
452
453 done:
454 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
455
456 return res;
457 }
458
459
460 void
_Py_ClearStandardStreamEncoding(void)461 _Py_ClearStandardStreamEncoding(void)
462 {
463 /* Use the same allocator than Py_SetStandardStreamEncoding() */
464 PyMemAllocatorEx old_alloc;
465 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
466
467 /* We won't need them anymore. */
468 if (_Py_StandardStreamEncoding) {
469 PyMem_RawFree(_Py_StandardStreamEncoding);
470 _Py_StandardStreamEncoding = NULL;
471 }
472 if (_Py_StandardStreamErrors) {
473 PyMem_RawFree(_Py_StandardStreamErrors);
474 _Py_StandardStreamErrors = NULL;
475 }
476
477 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
478 }
479
480
481 /* --- Py_GetArgcArgv() ------------------------------------------- */
482
483 /* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
484 static PyWideStringList orig_argv = {.length = 0, .items = NULL};
485
486
487 void
_Py_ClearArgcArgv(void)488 _Py_ClearArgcArgv(void)
489 {
490 PyMemAllocatorEx old_alloc;
491 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
492
493 _PyWideStringList_Clear(&orig_argv);
494
495 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
496 }
497
498
499 static int
_Py_SetArgcArgv(Py_ssize_t argc,wchar_t * const * argv)500 _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
501 {
502 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
503 int res;
504
505 PyMemAllocatorEx old_alloc;
506 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
507
508 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
509
510 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
511 return res;
512 }
513
514
515 /* Make the *original* argc/argv available to other modules.
516 This is rare, but it is needed by the secureware extension. */
517 void
Py_GetArgcArgv(int * argc,wchar_t *** argv)518 Py_GetArgcArgv(int *argc, wchar_t ***argv)
519 {
520 *argc = (int)orig_argv.length;
521 *argv = orig_argv.items;
522 }
523
524
525 /* --- PyConfig ---------------------------------------------- */
526
527 #define DECODE_LOCALE_ERR(NAME, LEN) \
528 (((LEN) == -2) \
529 ? _PyStatus_ERR("cannot decode " NAME) \
530 : _PyStatus_NO_MEMORY())
531
532
533 /* Free memory allocated in config, but don't clear all attributes */
534 void
PyConfig_Clear(PyConfig * config)535 PyConfig_Clear(PyConfig *config)
536 {
537 #define CLEAR(ATTR) \
538 do { \
539 PyMem_RawFree(ATTR); \
540 ATTR = NULL; \
541 } while (0)
542
543 CLEAR(config->pycache_prefix);
544 CLEAR(config->pythonpath_env);
545 CLEAR(config->home);
546 CLEAR(config->program_name);
547
548 _PyWideStringList_Clear(&config->argv);
549 _PyWideStringList_Clear(&config->warnoptions);
550 _PyWideStringList_Clear(&config->xoptions);
551 _PyWideStringList_Clear(&config->module_search_paths);
552 config->module_search_paths_set = 0;
553
554 CLEAR(config->executable);
555 CLEAR(config->base_executable);
556 CLEAR(config->prefix);
557 CLEAR(config->base_prefix);
558 CLEAR(config->exec_prefix);
559 CLEAR(config->base_exec_prefix);
560
561 CLEAR(config->filesystem_encoding);
562 CLEAR(config->filesystem_errors);
563 CLEAR(config->stdio_encoding);
564 CLEAR(config->stdio_errors);
565 CLEAR(config->run_command);
566 CLEAR(config->run_module);
567 CLEAR(config->run_filename);
568 CLEAR(config->check_hash_pycs_mode);
569 #undef CLEAR
570 }
571
572
573 void
_PyConfig_InitCompatConfig(PyConfig * config)574 _PyConfig_InitCompatConfig(PyConfig *config)
575 {
576 memset(config, 0, sizeof(*config));
577
578 config->_config_init = (int)_PyConfig_INIT_COMPAT;
579 config->isolated = -1;
580 config->use_environment = -1;
581 config->dev_mode = -1;
582 config->install_signal_handlers = 1;
583 config->use_hash_seed = -1;
584 config->faulthandler = -1;
585 config->tracemalloc = -1;
586 config->module_search_paths_set = 0;
587 config->parse_argv = 0;
588 config->site_import = -1;
589 config->bytes_warning = -1;
590 config->inspect = -1;
591 config->interactive = -1;
592 config->optimization_level = -1;
593 config->parser_debug= -1;
594 config->write_bytecode = -1;
595 config->verbose = -1;
596 config->quiet = -1;
597 config->user_site_directory = -1;
598 config->configure_c_stdio = 0;
599 config->buffered_stdio = -1;
600 config->_install_importlib = 1;
601 config->check_hash_pycs_mode = NULL;
602 config->pathconfig_warnings = -1;
603 config->_init_main = 1;
604 #ifdef MS_WINDOWS
605 config->legacy_windows_stdio = -1;
606 #endif
607 }
608
609
610 static void
config_init_defaults(PyConfig * config)611 config_init_defaults(PyConfig *config)
612 {
613 _PyConfig_InitCompatConfig(config);
614
615 config->isolated = 0;
616 config->use_environment = 1;
617 config->site_import = 1;
618 config->bytes_warning = 0;
619 config->inspect = 0;
620 config->interactive = 0;
621 config->optimization_level = 0;
622 config->parser_debug= 0;
623 config->write_bytecode = 1;
624 config->verbose = 0;
625 config->quiet = 0;
626 config->user_site_directory = 1;
627 config->buffered_stdio = 1;
628 config->pathconfig_warnings = 1;
629 #ifdef MS_WINDOWS
630 config->legacy_windows_stdio = 0;
631 #endif
632 }
633
634
635 void
PyConfig_InitPythonConfig(PyConfig * config)636 PyConfig_InitPythonConfig(PyConfig *config)
637 {
638 config_init_defaults(config);
639
640 config->_config_init = (int)_PyConfig_INIT_PYTHON;
641 config->configure_c_stdio = 1;
642 config->parse_argv = 1;
643 }
644
645
646 void
PyConfig_InitIsolatedConfig(PyConfig * config)647 PyConfig_InitIsolatedConfig(PyConfig *config)
648 {
649 config_init_defaults(config);
650
651 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
652 config->isolated = 1;
653 config->use_environment = 0;
654 config->user_site_directory = 0;
655 config->dev_mode = 0;
656 config->install_signal_handlers = 0;
657 config->use_hash_seed = 0;
658 config->faulthandler = 0;
659 config->tracemalloc = 0;
660 config->pathconfig_warnings = 0;
661 #ifdef MS_WINDOWS
662 config->legacy_windows_stdio = 0;
663 #endif
664 }
665
666
667 /* Copy str into *config_str (duplicate the string) */
668 PyStatus
PyConfig_SetString(PyConfig * config,wchar_t ** config_str,const wchar_t * str)669 PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
670 {
671 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
672 if (_PyStatus_EXCEPTION(status)) {
673 return status;
674 }
675
676 wchar_t *str2;
677 if (str != NULL) {
678 str2 = _PyMem_RawWcsdup(str);
679 if (str2 == NULL) {
680 return _PyStatus_NO_MEMORY();
681 }
682 }
683 else {
684 str2 = NULL;
685 }
686 PyMem_RawFree(*config_str);
687 *config_str = str2;
688 return _PyStatus_OK();
689 }
690
691
692 static PyStatus
config_set_bytes_string(PyConfig * config,wchar_t ** config_str,const char * str,const char * decode_err_msg)693 config_set_bytes_string(PyConfig *config, wchar_t **config_str,
694 const char *str, const char *decode_err_msg)
695 {
696 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
697 if (_PyStatus_EXCEPTION(status)) {
698 return status;
699 }
700
701 wchar_t *str2;
702 if (str != NULL) {
703 size_t len;
704 str2 = Py_DecodeLocale(str, &len);
705 if (str2 == NULL) {
706 if (len == (size_t)-2) {
707 return _PyStatus_ERR(decode_err_msg);
708 }
709 else {
710 return _PyStatus_NO_MEMORY();
711 }
712 }
713 }
714 else {
715 str2 = NULL;
716 }
717 PyMem_RawFree(*config_str);
718 *config_str = str2;
719 return _PyStatus_OK();
720 }
721
722
723 #define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
724 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
725
726
727 /* Decode str using Py_DecodeLocale() and set the result into *config_str.
728 Pre-initialize Python if needed to ensure that encodings are properly
729 configured. */
730 PyStatus
PyConfig_SetBytesString(PyConfig * config,wchar_t ** config_str,const char * str)731 PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
732 const char *str)
733 {
734 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
735 }
736
737
738 PyStatus
_PyConfig_Copy(PyConfig * config,const PyConfig * config2)739 _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
740 {
741 PyStatus status;
742
743 PyConfig_Clear(config);
744
745 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
746 #define COPY_WSTR_ATTR(ATTR) \
747 do { \
748 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
749 if (_PyStatus_EXCEPTION(status)) { \
750 return status; \
751 } \
752 } while (0)
753 #define COPY_WSTRLIST(LIST) \
754 do { \
755 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
756 return _PyStatus_NO_MEMORY(); \
757 } \
758 } while (0)
759
760 COPY_ATTR(_config_init);
761 COPY_ATTR(isolated);
762 COPY_ATTR(use_environment);
763 COPY_ATTR(dev_mode);
764 COPY_ATTR(install_signal_handlers);
765 COPY_ATTR(use_hash_seed);
766 COPY_ATTR(hash_seed);
767 COPY_ATTR(_install_importlib);
768 COPY_ATTR(faulthandler);
769 COPY_ATTR(tracemalloc);
770 COPY_ATTR(import_time);
771 COPY_ATTR(show_ref_count);
772 COPY_ATTR(show_alloc_count);
773 COPY_ATTR(dump_refs);
774 COPY_ATTR(malloc_stats);
775
776 COPY_WSTR_ATTR(pycache_prefix);
777 COPY_WSTR_ATTR(pythonpath_env);
778 COPY_WSTR_ATTR(home);
779 COPY_WSTR_ATTR(program_name);
780
781 COPY_ATTR(parse_argv);
782 COPY_WSTRLIST(argv);
783 COPY_WSTRLIST(warnoptions);
784 COPY_WSTRLIST(xoptions);
785 COPY_WSTRLIST(module_search_paths);
786 COPY_ATTR(module_search_paths_set);
787
788 COPY_WSTR_ATTR(executable);
789 COPY_WSTR_ATTR(base_executable);
790 COPY_WSTR_ATTR(prefix);
791 COPY_WSTR_ATTR(base_prefix);
792 COPY_WSTR_ATTR(exec_prefix);
793 COPY_WSTR_ATTR(base_exec_prefix);
794
795 COPY_ATTR(site_import);
796 COPY_ATTR(bytes_warning);
797 COPY_ATTR(inspect);
798 COPY_ATTR(interactive);
799 COPY_ATTR(optimization_level);
800 COPY_ATTR(parser_debug);
801 COPY_ATTR(write_bytecode);
802 COPY_ATTR(verbose);
803 COPY_ATTR(quiet);
804 COPY_ATTR(user_site_directory);
805 COPY_ATTR(configure_c_stdio);
806 COPY_ATTR(buffered_stdio);
807 COPY_WSTR_ATTR(filesystem_encoding);
808 COPY_WSTR_ATTR(filesystem_errors);
809 COPY_WSTR_ATTR(stdio_encoding);
810 COPY_WSTR_ATTR(stdio_errors);
811 #ifdef MS_WINDOWS
812 COPY_ATTR(legacy_windows_stdio);
813 #endif
814 COPY_ATTR(skip_source_first_line);
815 COPY_WSTR_ATTR(run_command);
816 COPY_WSTR_ATTR(run_module);
817 COPY_WSTR_ATTR(run_filename);
818 COPY_WSTR_ATTR(check_hash_pycs_mode);
819 COPY_ATTR(pathconfig_warnings);
820 COPY_ATTR(_init_main);
821
822 #undef COPY_ATTR
823 #undef COPY_WSTR_ATTR
824 #undef COPY_WSTRLIST
825 return _PyStatus_OK();
826 }
827
828
829 static PyObject *
config_as_dict(const PyConfig * config)830 config_as_dict(const PyConfig *config)
831 {
832 PyObject *dict;
833
834 dict = PyDict_New();
835 if (dict == NULL) {
836 return NULL;
837 }
838
839 #define SET_ITEM(KEY, EXPR) \
840 do { \
841 PyObject *obj = (EXPR); \
842 if (obj == NULL) { \
843 goto fail; \
844 } \
845 int res = PyDict_SetItemString(dict, (KEY), obj); \
846 Py_DECREF(obj); \
847 if (res < 0) { \
848 goto fail; \
849 } \
850 } while (0)
851 #define SET_ITEM_INT(ATTR) \
852 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
853 #define SET_ITEM_UINT(ATTR) \
854 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
855 #define FROM_WSTRING(STR) \
856 ((STR != NULL) ? \
857 PyUnicode_FromWideChar(STR, -1) \
858 : (Py_INCREF(Py_None), Py_None))
859 #define SET_ITEM_WSTR(ATTR) \
860 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
861 #define SET_ITEM_WSTRLIST(LIST) \
862 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
863
864 SET_ITEM_INT(_config_init);
865 SET_ITEM_INT(isolated);
866 SET_ITEM_INT(use_environment);
867 SET_ITEM_INT(dev_mode);
868 SET_ITEM_INT(install_signal_handlers);
869 SET_ITEM_INT(use_hash_seed);
870 SET_ITEM_UINT(hash_seed);
871 SET_ITEM_INT(faulthandler);
872 SET_ITEM_INT(tracemalloc);
873 SET_ITEM_INT(import_time);
874 SET_ITEM_INT(show_ref_count);
875 SET_ITEM_INT(show_alloc_count);
876 SET_ITEM_INT(dump_refs);
877 SET_ITEM_INT(malloc_stats);
878 SET_ITEM_WSTR(filesystem_encoding);
879 SET_ITEM_WSTR(filesystem_errors);
880 SET_ITEM_WSTR(pycache_prefix);
881 SET_ITEM_WSTR(program_name);
882 SET_ITEM_INT(parse_argv);
883 SET_ITEM_WSTRLIST(argv);
884 SET_ITEM_WSTRLIST(xoptions);
885 SET_ITEM_WSTRLIST(warnoptions);
886 SET_ITEM_WSTR(pythonpath_env);
887 SET_ITEM_WSTR(home);
888 SET_ITEM_WSTRLIST(module_search_paths);
889 SET_ITEM_WSTR(executable);
890 SET_ITEM_WSTR(base_executable);
891 SET_ITEM_WSTR(prefix);
892 SET_ITEM_WSTR(base_prefix);
893 SET_ITEM_WSTR(exec_prefix);
894 SET_ITEM_WSTR(base_exec_prefix);
895 SET_ITEM_INT(site_import);
896 SET_ITEM_INT(bytes_warning);
897 SET_ITEM_INT(inspect);
898 SET_ITEM_INT(interactive);
899 SET_ITEM_INT(optimization_level);
900 SET_ITEM_INT(parser_debug);
901 SET_ITEM_INT(write_bytecode);
902 SET_ITEM_INT(verbose);
903 SET_ITEM_INT(quiet);
904 SET_ITEM_INT(user_site_directory);
905 SET_ITEM_INT(configure_c_stdio);
906 SET_ITEM_INT(buffered_stdio);
907 SET_ITEM_WSTR(stdio_encoding);
908 SET_ITEM_WSTR(stdio_errors);
909 #ifdef MS_WINDOWS
910 SET_ITEM_INT(legacy_windows_stdio);
911 #endif
912 SET_ITEM_INT(skip_source_first_line);
913 SET_ITEM_WSTR(run_command);
914 SET_ITEM_WSTR(run_module);
915 SET_ITEM_WSTR(run_filename);
916 SET_ITEM_INT(_install_importlib);
917 SET_ITEM_WSTR(check_hash_pycs_mode);
918 SET_ITEM_INT(pathconfig_warnings);
919 SET_ITEM_INT(_init_main);
920
921 return dict;
922
923 fail:
924 Py_DECREF(dict);
925 return NULL;
926
927 #undef FROM_WSTRING
928 #undef SET_ITEM
929 #undef SET_ITEM_INT
930 #undef SET_ITEM_UINT
931 #undef SET_ITEM_WSTR
932 #undef SET_ITEM_WSTRLIST
933 }
934
935
936 static const char*
config_get_env(const PyConfig * config,const char * name)937 config_get_env(const PyConfig *config, const char *name)
938 {
939 return _Py_GetEnv(config->use_environment, name);
940 }
941
942
943 /* Get a copy of the environment variable as wchar_t*.
944 Return 0 on success, but *dest can be NULL.
945 Return -1 on memory allocation failure. Return -2 on decoding error. */
946 static PyStatus
config_get_env_dup(PyConfig * config,wchar_t ** dest,wchar_t * wname,char * name,const char * decode_err_msg)947 config_get_env_dup(PyConfig *config,
948 wchar_t **dest,
949 wchar_t *wname, char *name,
950 const char *decode_err_msg)
951 {
952 assert(*dest == NULL);
953 assert(config->use_environment >= 0);
954
955 if (!config->use_environment) {
956 *dest = NULL;
957 return _PyStatus_OK();
958 }
959
960 #ifdef MS_WINDOWS
961 const wchar_t *var = _wgetenv(wname);
962 if (!var || var[0] == '\0') {
963 *dest = NULL;
964 return _PyStatus_OK();
965 }
966
967 return PyConfig_SetString(config, dest, var);
968 #else
969 const char *var = getenv(name);
970 if (!var || var[0] == '\0') {
971 *dest = NULL;
972 return _PyStatus_OK();
973 }
974
975 return config_set_bytes_string(config, dest, var, decode_err_msg);
976 #endif
977 }
978
979
980 #define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
981 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
982
983
984 static void
config_get_global_vars(PyConfig * config)985 config_get_global_vars(PyConfig *config)
986 {
987 if (config->_config_init != _PyConfig_INIT_COMPAT) {
988 /* Python and Isolated configuration ignore global variables */
989 return;
990 }
991
992 #define COPY_FLAG(ATTR, VALUE) \
993 if (config->ATTR == -1) { \
994 config->ATTR = VALUE; \
995 }
996 #define COPY_NOT_FLAG(ATTR, VALUE) \
997 if (config->ATTR == -1) { \
998 config->ATTR = !(VALUE); \
999 }
1000
1001 COPY_FLAG(isolated, Py_IsolatedFlag);
1002 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
1003 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1004 COPY_FLAG(inspect, Py_InspectFlag);
1005 COPY_FLAG(interactive, Py_InteractiveFlag);
1006 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1007 COPY_FLAG(parser_debug, Py_DebugFlag);
1008 COPY_FLAG(verbose, Py_VerboseFlag);
1009 COPY_FLAG(quiet, Py_QuietFlag);
1010 #ifdef MS_WINDOWS
1011 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1012 #endif
1013 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
1014
1015 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1016 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1017 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1018 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1019
1020 #undef COPY_FLAG
1021 #undef COPY_NOT_FLAG
1022 }
1023
1024
1025 /* Set Py_xxx global configuration variables from 'config' configuration. */
1026 static void
config_set_global_vars(const PyConfig * config)1027 config_set_global_vars(const PyConfig *config)
1028 {
1029 #define COPY_FLAG(ATTR, VAR) \
1030 if (config->ATTR != -1) { \
1031 VAR = config->ATTR; \
1032 }
1033 #define COPY_NOT_FLAG(ATTR, VAR) \
1034 if (config->ATTR != -1) { \
1035 VAR = !config->ATTR; \
1036 }
1037
1038 COPY_FLAG(isolated, Py_IsolatedFlag);
1039 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
1040 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1041 COPY_FLAG(inspect, Py_InspectFlag);
1042 COPY_FLAG(interactive, Py_InteractiveFlag);
1043 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1044 COPY_FLAG(parser_debug, Py_DebugFlag);
1045 COPY_FLAG(verbose, Py_VerboseFlag);
1046 COPY_FLAG(quiet, Py_QuietFlag);
1047 #ifdef MS_WINDOWS
1048 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1049 #endif
1050 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
1051
1052 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1053 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1054 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1055 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1056
1057 /* Random or non-zero hash seed */
1058 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1059 config->hash_seed != 0);
1060
1061 #undef COPY_FLAG
1062 #undef COPY_NOT_FLAG
1063 }
1064
1065
1066 /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1067 environment variables on macOS if available. */
1068 static PyStatus
config_init_program_name(PyConfig * config)1069 config_init_program_name(PyConfig *config)
1070 {
1071 PyStatus status;
1072
1073 /* If Py_SetProgramName() was called, use its value */
1074 const wchar_t *program_name = _Py_path_config.program_name;
1075 if (program_name != NULL) {
1076 config->program_name = _PyMem_RawWcsdup(program_name);
1077 if (config->program_name == NULL) {
1078 return _PyStatus_NO_MEMORY();
1079 }
1080 return _PyStatus_OK();
1081 }
1082
1083 #ifdef __APPLE__
1084 /* On MacOS X, when the Python interpreter is embedded in an
1085 application bundle, it gets executed by a bootstrapping script
1086 that does os.execve() with an argv[0] that's different from the
1087 actual Python executable. This is needed to keep the Finder happy,
1088 or rather, to work around Apple's overly strict requirements of
1089 the process name. However, we still need a usable sys.executable,
1090 so the actual executable path is passed in an environment variable.
1091 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1092 script. */
1093 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
1094 if (p != NULL) {
1095 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1096 "PYTHONEXECUTABLE environment variable");
1097 if (_PyStatus_EXCEPTION(status)) {
1098 return status;
1099 }
1100 return _PyStatus_OK();
1101 }
1102 #ifdef WITH_NEXT_FRAMEWORK
1103 else {
1104 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1105 if (pyvenv_launcher && *pyvenv_launcher) {
1106 /* Used by Mac/Tools/pythonw.c to forward
1107 * the argv0 of the stub executable
1108 */
1109 status = CONFIG_SET_BYTES_STR(config,
1110 &config->program_name,
1111 pyvenv_launcher,
1112 "__PYVENV_LAUNCHER__ environment variable");
1113 if (_PyStatus_EXCEPTION(status)) {
1114 return status;
1115 }
1116 return _PyStatus_OK();
1117 }
1118 }
1119 #endif /* WITH_NEXT_FRAMEWORK */
1120 #endif /* __APPLE__ */
1121
1122 /* Use argv[0] if available and non-empty */
1123 const PyWideStringList *argv = &config->argv;
1124 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1125 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1126 if (config->program_name == NULL) {
1127 return _PyStatus_NO_MEMORY();
1128 }
1129 return _PyStatus_OK();
1130 }
1131
1132 /* Last fall back: hardcoded name */
1133 #ifdef MS_WINDOWS
1134 const wchar_t *default_program_name = L"python";
1135 #else
1136 const wchar_t *default_program_name = L"python3";
1137 #endif
1138 status = PyConfig_SetString(config, &config->program_name,
1139 default_program_name);
1140 if (_PyStatus_EXCEPTION(status)) {
1141 return status;
1142 }
1143 return _PyStatus_OK();
1144 }
1145
1146 static PyStatus
config_init_executable(PyConfig * config)1147 config_init_executable(PyConfig *config)
1148 {
1149 assert(config->executable == NULL);
1150
1151 /* If Py_SetProgramFullPath() was called, use its value */
1152 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1153 if (program_full_path != NULL) {
1154 PyStatus status = PyConfig_SetString(config,
1155 &config->executable,
1156 program_full_path);
1157 if (_PyStatus_EXCEPTION(status)) {
1158 return status;
1159 }
1160 return _PyStatus_OK();
1161 }
1162 return _PyStatus_OK();
1163 }
1164
1165
1166 static const wchar_t*
config_get_xoption(const PyConfig * config,wchar_t * name)1167 config_get_xoption(const PyConfig *config, wchar_t *name)
1168 {
1169 return _Py_get_xoption(&config->xoptions, name);
1170 }
1171
1172
1173 static PyStatus
config_init_home(PyConfig * config)1174 config_init_home(PyConfig *config)
1175 {
1176 assert(config->home == NULL);
1177
1178 /* If Py_SetPythonHome() was called, use its value */
1179 wchar_t *home = _Py_path_config.home;
1180 if (home) {
1181 PyStatus status = PyConfig_SetString(config, &config->home, home);
1182 if (_PyStatus_EXCEPTION(status)) {
1183 return status;
1184 }
1185 return _PyStatus_OK();
1186 }
1187
1188 return CONFIG_GET_ENV_DUP(config, &config->home,
1189 L"PYTHONHOME", "PYTHONHOME");
1190 }
1191
1192
1193 static PyStatus
config_init_hash_seed(PyConfig * config)1194 config_init_hash_seed(PyConfig *config)
1195 {
1196 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
1197
1198 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1199 /* Convert a text seed to a numeric one */
1200 if (seed_text && strcmp(seed_text, "random") != 0) {
1201 const char *endptr = seed_text;
1202 unsigned long seed;
1203 errno = 0;
1204 seed = strtoul(seed_text, (char **)&endptr, 10);
1205 if (*endptr != '\0'
1206 || seed > 4294967295UL
1207 || (errno == ERANGE && seed == ULONG_MAX))
1208 {
1209 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
1210 "or an integer in range [0; 4294967295]");
1211 }
1212 /* Use a specific hash */
1213 config->use_hash_seed = 1;
1214 config->hash_seed = seed;
1215 }
1216 else {
1217 /* Use a random hash */
1218 config->use_hash_seed = 0;
1219 config->hash_seed = 0;
1220 }
1221 return _PyStatus_OK();
1222 }
1223
1224
1225 static int
config_wstr_to_int(const wchar_t * wstr,int * result)1226 config_wstr_to_int(const wchar_t *wstr, int *result)
1227 {
1228 const wchar_t *endptr = wstr;
1229 errno = 0;
1230 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1231 if (*endptr != '\0' || errno == ERANGE) {
1232 return -1;
1233 }
1234 if (value < INT_MIN || value > INT_MAX) {
1235 return -1;
1236 }
1237
1238 *result = (int)value;
1239 return 0;
1240 }
1241
1242
1243 static PyStatus
config_read_env_vars(PyConfig * config)1244 config_read_env_vars(PyConfig *config)
1245 {
1246 PyStatus status;
1247 int use_env = config->use_environment;
1248
1249 /* Get environment variables */
1250 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1251 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1252 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1253 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
1254
1255 int dont_write_bytecode = 0;
1256 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
1257 if (dont_write_bytecode) {
1258 config->write_bytecode = 0;
1259 }
1260
1261 int no_user_site_directory = 0;
1262 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
1263 if (no_user_site_directory) {
1264 config->user_site_directory = 0;
1265 }
1266
1267 int unbuffered_stdio = 0;
1268 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
1269 if (unbuffered_stdio) {
1270 config->buffered_stdio = 0;
1271 }
1272
1273 #ifdef MS_WINDOWS
1274 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
1275 "PYTHONLEGACYWINDOWSSTDIO");
1276 #endif
1277
1278 if (config_get_env(config, "PYTHONDUMPREFS")) {
1279 config->dump_refs = 1;
1280 }
1281 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
1282 config->malloc_stats = 1;
1283 }
1284
1285 if (config->pythonpath_env == NULL) {
1286 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1287 L"PYTHONPATH", "PYTHONPATH");
1288 if (_PyStatus_EXCEPTION(status)) {
1289 return status;
1290 }
1291 }
1292
1293 if (config->use_hash_seed < 0) {
1294 status = config_init_hash_seed(config);
1295 if (_PyStatus_EXCEPTION(status)) {
1296 return status;
1297 }
1298 }
1299
1300 return _PyStatus_OK();
1301 }
1302
1303
1304 static PyStatus
config_init_tracemalloc(PyConfig * config)1305 config_init_tracemalloc(PyConfig *config)
1306 {
1307 int nframe;
1308 int valid;
1309
1310 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
1311 if (env) {
1312 if (!_Py_str_to_int(env, &nframe)) {
1313 valid = (nframe >= 0);
1314 }
1315 else {
1316 valid = 0;
1317 }
1318 if (!valid) {
1319 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
1320 }
1321 config->tracemalloc = nframe;
1322 }
1323
1324 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1325 if (xoption) {
1326 const wchar_t *sep = wcschr(xoption, L'=');
1327 if (sep) {
1328 if (!config_wstr_to_int(sep + 1, &nframe)) {
1329 valid = (nframe >= 0);
1330 }
1331 else {
1332 valid = 0;
1333 }
1334 if (!valid) {
1335 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1336 "invalid number of frames");
1337 }
1338 }
1339 else {
1340 /* -X tracemalloc behaves as -X tracemalloc=1 */
1341 nframe = 1;
1342 }
1343 config->tracemalloc = nframe;
1344 }
1345 return _PyStatus_OK();
1346 }
1347
1348
1349 static PyStatus
config_init_pycache_prefix(PyConfig * config)1350 config_init_pycache_prefix(PyConfig *config)
1351 {
1352 assert(config->pycache_prefix == NULL);
1353
1354 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1355 if (xoption) {
1356 const wchar_t *sep = wcschr(xoption, L'=');
1357 if (sep && wcslen(sep) > 1) {
1358 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1359 if (config->pycache_prefix == NULL) {
1360 return _PyStatus_NO_MEMORY();
1361 }
1362 }
1363 else {
1364 // PYTHONPYCACHEPREFIX env var ignored
1365 // if "-X pycache_prefix=" option is used
1366 config->pycache_prefix = NULL;
1367 }
1368 return _PyStatus_OK();
1369 }
1370
1371 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1372 L"PYTHONPYCACHEPREFIX",
1373 "PYTHONPYCACHEPREFIX");
1374 }
1375
1376
1377 static PyStatus
config_read_complex_options(PyConfig * config)1378 config_read_complex_options(PyConfig *config)
1379 {
1380 /* More complex options configured by env var and -X option */
1381 if (config->faulthandler < 0) {
1382 if (config_get_env(config, "PYTHONFAULTHANDLER")
1383 || config_get_xoption(config, L"faulthandler")) {
1384 config->faulthandler = 1;
1385 }
1386 }
1387 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
1388 || config_get_xoption(config, L"importtime")) {
1389 config->import_time = 1;
1390 }
1391
1392 PyStatus status;
1393 if (config->tracemalloc < 0) {
1394 status = config_init_tracemalloc(config);
1395 if (_PyStatus_EXCEPTION(status)) {
1396 return status;
1397 }
1398 }
1399
1400 if (config->pycache_prefix == NULL) {
1401 status = config_init_pycache_prefix(config);
1402 if (_PyStatus_EXCEPTION(status)) {
1403 return status;
1404 }
1405 }
1406 return _PyStatus_OK();
1407 }
1408
1409
1410 static const wchar_t *
config_get_stdio_errors(const PyConfig * config)1411 config_get_stdio_errors(const PyConfig *config)
1412 {
1413 #ifndef MS_WINDOWS
1414 const char *loc = setlocale(LC_CTYPE, NULL);
1415 if (loc != NULL) {
1416 /* surrogateescape is the default in the legacy C and POSIX locales */
1417 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
1418 return L"surrogateescape";
1419 }
1420
1421 #ifdef PY_COERCE_C_LOCALE
1422 /* surrogateescape is the default in locale coercion target locales */
1423 if (_Py_IsLocaleCoercionTarget(loc)) {
1424 return L"surrogateescape";
1425 }
1426 #endif
1427 }
1428
1429 return L"strict";
1430 #else
1431 /* On Windows, always use surrogateescape by default */
1432 return L"surrogateescape";
1433 #endif
1434 }
1435
1436
1437 static PyStatus
config_get_locale_encoding(PyConfig * config,wchar_t ** locale_encoding)1438 config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
1439 {
1440 #ifdef MS_WINDOWS
1441 char encoding[20];
1442 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
1443 return PyConfig_SetBytesString(config, locale_encoding, encoding);
1444 #elif defined(_Py_FORCE_UTF8_LOCALE)
1445 return PyConfig_SetString(config, locale_encoding, L"utf-8");
1446 #else
1447 const char *encoding = nl_langinfo(CODESET);
1448 if (!encoding || encoding[0] == '\0') {
1449 return _PyStatus_ERR("failed to get the locale encoding: "
1450 "nl_langinfo(CODESET) failed");
1451 }
1452 /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
1453 return CONFIG_SET_BYTES_STR(config,
1454 locale_encoding, encoding,
1455 "nl_langinfo(CODESET)");
1456 #endif
1457 }
1458
1459
1460 static PyStatus
config_init_stdio_encoding(PyConfig * config,const PyPreConfig * preconfig)1461 config_init_stdio_encoding(PyConfig *config,
1462 const PyPreConfig *preconfig)
1463 {
1464 PyStatus status;
1465
1466 /* If Py_SetStandardStreamEncoding() have been called, use these
1467 parameters. */
1468 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
1469 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1470 _Py_StandardStreamEncoding,
1471 "_Py_StandardStreamEncoding");
1472 if (_PyStatus_EXCEPTION(status)) {
1473 return status;
1474 }
1475 }
1476
1477 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
1478 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1479 _Py_StandardStreamErrors,
1480 "_Py_StandardStreamErrors");
1481 if (_PyStatus_EXCEPTION(status)) {
1482 return status;
1483 }
1484 }
1485
1486 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1487 return _PyStatus_OK();
1488 }
1489
1490 /* PYTHONIOENCODING environment variable */
1491 const char *opt = config_get_env(config, "PYTHONIOENCODING");
1492 if (opt) {
1493 char *pythonioencoding = _PyMem_RawStrdup(opt);
1494 if (pythonioencoding == NULL) {
1495 return _PyStatus_NO_MEMORY();
1496 }
1497
1498 char *errors = strchr(pythonioencoding, ':');
1499 if (errors) {
1500 *errors = '\0';
1501 errors++;
1502 if (!errors[0]) {
1503 errors = NULL;
1504 }
1505 }
1506
1507 /* Does PYTHONIOENCODING contain an encoding? */
1508 if (pythonioencoding[0]) {
1509 if (config->stdio_encoding == NULL) {
1510 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1511 pythonioencoding,
1512 "PYTHONIOENCODING environment variable");
1513 if (_PyStatus_EXCEPTION(status)) {
1514 PyMem_RawFree(pythonioencoding);
1515 return status;
1516 }
1517 }
1518
1519 /* If the encoding is set but not the error handler,
1520 use "strict" error handler by default.
1521 PYTHONIOENCODING=latin1 behaves as
1522 PYTHONIOENCODING=latin1:strict. */
1523 if (!errors) {
1524 errors = "strict";
1525 }
1526 }
1527
1528 if (config->stdio_errors == NULL && errors != NULL) {
1529 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1530 errors,
1531 "PYTHONIOENCODING environment variable");
1532 if (_PyStatus_EXCEPTION(status)) {
1533 PyMem_RawFree(pythonioencoding);
1534 return status;
1535 }
1536 }
1537
1538 PyMem_RawFree(pythonioencoding);
1539 }
1540
1541 /* UTF-8 Mode uses UTF-8/surrogateescape */
1542 if (preconfig->utf8_mode) {
1543 if (config->stdio_encoding == NULL) {
1544 status = PyConfig_SetString(config, &config->stdio_encoding,
1545 L"utf-8");
1546 if (_PyStatus_EXCEPTION(status)) {
1547 return status;
1548 }
1549 }
1550 if (config->stdio_errors == NULL) {
1551 status = PyConfig_SetString(config, &config->stdio_errors,
1552 L"surrogateescape");
1553 if (_PyStatus_EXCEPTION(status)) {
1554 return status;
1555 }
1556 }
1557 }
1558
1559 /* Choose the default error handler based on the current locale. */
1560 if (config->stdio_encoding == NULL) {
1561 status = config_get_locale_encoding(config, &config->stdio_encoding);
1562 if (_PyStatus_EXCEPTION(status)) {
1563 return status;
1564 }
1565 }
1566 if (config->stdio_errors == NULL) {
1567 const wchar_t *errors = config_get_stdio_errors(config);
1568 assert(errors != NULL);
1569
1570 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1571 if (_PyStatus_EXCEPTION(status)) {
1572 return status;
1573 }
1574 }
1575
1576 return _PyStatus_OK();
1577 }
1578
1579
1580 static PyStatus
config_init_fs_encoding(PyConfig * config,const PyPreConfig * preconfig)1581 config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
1582 {
1583 PyStatus status;
1584
1585 if (config->filesystem_encoding == NULL) {
1586 #ifdef _Py_FORCE_UTF8_FS_ENCODING
1587 status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
1588 #else
1589
1590 #ifdef MS_WINDOWS
1591 if (preconfig->legacy_windows_fs_encoding) {
1592 /* Legacy Windows filesystem encoding: mbcs/replace */
1593 status = PyConfig_SetString(config, &config->filesystem_encoding,
1594 L"mbcs");
1595 }
1596 else
1597 #endif
1598 if (preconfig->utf8_mode) {
1599 status = PyConfig_SetString(config, &config->filesystem_encoding,
1600 L"utf-8");
1601 }
1602 #ifndef MS_WINDOWS
1603 else if (_Py_GetForceASCII()) {
1604 status = PyConfig_SetString(config, &config->filesystem_encoding,
1605 L"ascii");
1606 }
1607 #endif
1608 else {
1609 #ifdef MS_WINDOWS
1610 /* Windows defaults to utf-8/surrogatepass (PEP 529). */
1611 status = PyConfig_SetString(config, &config->filesystem_encoding,
1612 L"utf-8");
1613 #else
1614 status = config_get_locale_encoding(config,
1615 &config->filesystem_encoding);
1616 #endif
1617 }
1618 #endif /* !_Py_FORCE_UTF8_FS_ENCODING */
1619
1620 if (_PyStatus_EXCEPTION(status)) {
1621 return status;
1622 }
1623 }
1624
1625 if (config->filesystem_errors == NULL) {
1626 const wchar_t *errors;
1627 #ifdef MS_WINDOWS
1628 if (preconfig->legacy_windows_fs_encoding) {
1629 errors = L"replace";
1630 }
1631 else {
1632 errors = L"surrogatepass";
1633 }
1634 #else
1635 errors = L"surrogateescape";
1636 #endif
1637 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
1638 if (_PyStatus_EXCEPTION(status)) {
1639 return status;
1640 }
1641 }
1642 return _PyStatus_OK();
1643 }
1644
1645
1646 static PyStatus
config_read(PyConfig * config)1647 config_read(PyConfig *config)
1648 {
1649 PyStatus status;
1650 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
1651
1652 if (config->use_environment) {
1653 status = config_read_env_vars(config);
1654 if (_PyStatus_EXCEPTION(status)) {
1655 return status;
1656 }
1657 }
1658
1659 /* -X options */
1660 if (config_get_xoption(config, L"showrefcount")) {
1661 config->show_ref_count = 1;
1662 }
1663 if (config_get_xoption(config, L"showalloccount")) {
1664 config->show_alloc_count = 1;
1665 }
1666
1667 status = config_read_complex_options(config);
1668 if (_PyStatus_EXCEPTION(status)) {
1669 return status;
1670 }
1671
1672 if (config->home == NULL) {
1673 status = config_init_home(config);
1674 if (_PyStatus_EXCEPTION(status)) {
1675 return status;
1676 }
1677 }
1678
1679 if (config->executable == NULL) {
1680 status = config_init_executable(config);
1681 if (_PyStatus_EXCEPTION(status)) {
1682 return status;
1683 }
1684 }
1685
1686 if (config->_install_importlib) {
1687 status = _PyConfig_InitPathConfig(config);
1688 if (_PyStatus_EXCEPTION(status)) {
1689 return status;
1690 }
1691 }
1692
1693 /* default values */
1694 if (config->dev_mode) {
1695 if (config->faulthandler < 0) {
1696 config->faulthandler = 1;
1697 }
1698 }
1699 if (config->faulthandler < 0) {
1700 config->faulthandler = 0;
1701 }
1702 if (config->tracemalloc < 0) {
1703 config->tracemalloc = 0;
1704 }
1705 if (config->use_hash_seed < 0) {
1706 config->use_hash_seed = 0;
1707 config->hash_seed = 0;
1708 }
1709
1710 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
1711 status = config_init_fs_encoding(config, preconfig);
1712 if (_PyStatus_EXCEPTION(status)) {
1713 return status;
1714 }
1715 }
1716
1717 status = config_init_stdio_encoding(config, preconfig);
1718 if (_PyStatus_EXCEPTION(status)) {
1719 return status;
1720 }
1721
1722 if (config->argv.length < 1) {
1723 /* Ensure at least one (empty) argument is seen */
1724 status = PyWideStringList_Append(&config->argv, L"");
1725 if (_PyStatus_EXCEPTION(status)) {
1726 return status;
1727 }
1728 }
1729
1730 if (config->check_hash_pycs_mode == NULL) {
1731 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1732 L"default");
1733 if (_PyStatus_EXCEPTION(status)) {
1734 return status;
1735 }
1736 }
1737
1738 if (config->configure_c_stdio < 0) {
1739 config->configure_c_stdio = 1;
1740 }
1741
1742 return _PyStatus_OK();
1743 }
1744
1745
1746 static void
config_init_stdio(const PyConfig * config)1747 config_init_stdio(const PyConfig *config)
1748 {
1749 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
1750 /* don't translate newlines (\r\n <=> \n) */
1751 _setmode(fileno(stdin), O_BINARY);
1752 _setmode(fileno(stdout), O_BINARY);
1753 _setmode(fileno(stderr), O_BINARY);
1754 #endif
1755
1756 if (!config->buffered_stdio) {
1757 #ifdef HAVE_SETVBUF
1758 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1759 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1760 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1761 #else /* !HAVE_SETVBUF */
1762 setbuf(stdin, (char *)NULL);
1763 setbuf(stdout, (char *)NULL);
1764 setbuf(stderr, (char *)NULL);
1765 #endif /* !HAVE_SETVBUF */
1766 }
1767 else if (config->interactive) {
1768 #ifdef MS_WINDOWS
1769 /* Doesn't have to have line-buffered -- use unbuffered */
1770 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1771 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1772 #else /* !MS_WINDOWS */
1773 #ifdef HAVE_SETVBUF
1774 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1775 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1776 #endif /* HAVE_SETVBUF */
1777 #endif /* !MS_WINDOWS */
1778 /* Leave stderr alone - it should be unbuffered anyway. */
1779 }
1780 }
1781
1782
1783 /* Write the configuration:
1784
1785 - set Py_xxx global configuration variables
1786 - initialize C standard streams (stdin, stdout, stderr) */
1787 void
_PyConfig_Write(const PyConfig * config,_PyRuntimeState * runtime)1788 _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
1789 {
1790 config_set_global_vars(config);
1791
1792 if (config->configure_c_stdio) {
1793 config_init_stdio(config);
1794 }
1795
1796 /* Write the new pre-configuration into _PyRuntime */
1797 PyPreConfig *preconfig = &runtime->preconfig;
1798 preconfig->isolated = config->isolated;
1799 preconfig->use_environment = config->use_environment;
1800 preconfig->dev_mode = config->dev_mode;
1801 }
1802
1803
1804 /* --- PyConfig command line parser -------------------------- */
1805
1806 static void
config_usage(int error,const wchar_t * program)1807 config_usage(int error, const wchar_t* program)
1808 {
1809 FILE *f = error ? stderr : stdout;
1810
1811 fprintf(f, usage_line, program);
1812 if (error)
1813 fprintf(f, "Try `python -h' for more information.\n");
1814 else {
1815 fputs(usage_1, f);
1816 fputs(usage_2, f);
1817 fputs(usage_3, f);
1818 fprintf(f, usage_4, (wint_t)DELIM);
1819 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
1820 fputs(usage_6, f);
1821 }
1822 }
1823
1824
1825 /* Parse the command line arguments */
1826 static PyStatus
config_parse_cmdline(PyConfig * config,PyWideStringList * warnoptions,Py_ssize_t * opt_index)1827 config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
1828 Py_ssize_t *opt_index)
1829 {
1830 PyStatus status;
1831 const PyWideStringList *argv = &config->argv;
1832 int print_version = 0;
1833 const wchar_t* program = config->program_name;
1834
1835 _PyOS_ResetGetOpt();
1836 do {
1837 int longindex = -1;
1838 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
1839 if (c == EOF) {
1840 break;
1841 }
1842
1843 if (c == 'c') {
1844 if (config->run_command == NULL) {
1845 /* -c is the last option; following arguments
1846 that look like options are left for the
1847 command to interpret. */
1848 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
1849 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
1850 if (command == NULL) {
1851 return _PyStatus_NO_MEMORY();
1852 }
1853 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
1854 command[len - 2] = '\n';
1855 command[len - 1] = 0;
1856 config->run_command = command;
1857 }
1858 break;
1859 }
1860
1861 if (c == 'm') {
1862 /* -m is the last option; following arguments
1863 that look like options are left for the
1864 module to interpret. */
1865 if (config->run_module == NULL) {
1866 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
1867 if (config->run_module == NULL) {
1868 return _PyStatus_NO_MEMORY();
1869 }
1870 }
1871 break;
1872 }
1873
1874 switch (c) {
1875 case 0:
1876 // Handle long option.
1877 assert(longindex == 0); // Only one long option now.
1878 if (wcscmp(_PyOS_optarg, L"always") == 0
1879 || wcscmp(_PyOS_optarg, L"never") == 0
1880 || wcscmp(_PyOS_optarg, L"default") == 0)
1881 {
1882 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
1883 _PyOS_optarg);
1884 if (_PyStatus_EXCEPTION(status)) {
1885 return status;
1886 }
1887 } else {
1888 fprintf(stderr, "--check-hash-based-pycs must be one of "
1889 "'default', 'always', or 'never'\n");
1890 config_usage(1, program);
1891 return _PyStatus_EXIT(2);
1892 }
1893 break;
1894
1895 case 'b':
1896 config->bytes_warning++;
1897 break;
1898
1899 case 'd':
1900 config->parser_debug++;
1901 break;
1902
1903 case 'i':
1904 config->inspect++;
1905 config->interactive++;
1906 break;
1907
1908 case 'E':
1909 case 'I':
1910 case 'X':
1911 /* option handled by _PyPreCmdline_Read() */
1912 break;
1913
1914 /* case 'J': reserved for Jython */
1915
1916 case 'O':
1917 config->optimization_level++;
1918 break;
1919
1920 case 'B':
1921 config->write_bytecode = 0;
1922 break;
1923
1924 case 's':
1925 config->user_site_directory = 0;
1926 break;
1927
1928 case 'S':
1929 config->site_import = 0;
1930 break;
1931
1932 case 't':
1933 /* ignored for backwards compatibility */
1934 break;
1935
1936 case 'u':
1937 config->buffered_stdio = 0;
1938 break;
1939
1940 case 'v':
1941 config->verbose++;
1942 break;
1943
1944 case 'x':
1945 config->skip_source_first_line = 1;
1946 break;
1947
1948 case 'h':
1949 case '?':
1950 config_usage(0, program);
1951 return _PyStatus_EXIT(0);
1952
1953 case 'V':
1954 print_version++;
1955 break;
1956
1957 case 'W':
1958 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
1959 if (_PyStatus_EXCEPTION(status)) {
1960 return status;
1961 }
1962 break;
1963
1964 case 'q':
1965 config->quiet++;
1966 break;
1967
1968 case 'R':
1969 config->use_hash_seed = 0;
1970 break;
1971
1972 /* This space reserved for other options */
1973
1974 default:
1975 /* unknown argument: parsing failed */
1976 config_usage(1, program);
1977 return _PyStatus_EXIT(2);
1978 }
1979 } while (1);
1980
1981 if (print_version) {
1982 printf("Python %s\n",
1983 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
1984 return _PyStatus_EXIT(0);
1985 }
1986
1987 if (config->run_command == NULL && config->run_module == NULL
1988 && _PyOS_optind < argv->length
1989 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
1990 && config->run_filename == NULL)
1991 {
1992 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
1993 if (config->run_filename == NULL) {
1994 return _PyStatus_NO_MEMORY();
1995 }
1996 }
1997
1998 if (config->run_command != NULL || config->run_module != NULL) {
1999 /* Backup _PyOS_optind */
2000 _PyOS_optind--;
2001 }
2002
2003 *opt_index = _PyOS_optind;
2004
2005 return _PyStatus_OK();
2006 }
2007
2008
2009 #ifdef MS_WINDOWS
2010 # define WCSTOK wcstok_s
2011 #else
2012 # define WCSTOK wcstok
2013 #endif
2014
2015 /* Get warning options from PYTHONWARNINGS environment variable. */
2016 static PyStatus
config_init_env_warnoptions(PyConfig * config,PyWideStringList * warnoptions)2017 config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
2018 {
2019 PyStatus status;
2020 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2021 wchar_t *env = NULL;
2022 status = CONFIG_GET_ENV_DUP(config, &env,
2023 L"PYTHONWARNINGS", "PYTHONWARNINGS");
2024 if (_PyStatus_EXCEPTION(status)) {
2025 return status;
2026 }
2027
2028 /* env var is not set or is empty */
2029 if (env == NULL) {
2030 return _PyStatus_OK();
2031 }
2032
2033
2034 wchar_t *warning, *context = NULL;
2035 for (warning = WCSTOK(env, L",", &context);
2036 warning != NULL;
2037 warning = WCSTOK(NULL, L",", &context))
2038 {
2039 status = PyWideStringList_Append(warnoptions, warning);
2040 if (_PyStatus_EXCEPTION(status)) {
2041 PyMem_RawFree(env);
2042 return status;
2043 }
2044 }
2045 PyMem_RawFree(env);
2046 return _PyStatus_OK();
2047 }
2048
2049
2050 static PyStatus
warnoptions_append(PyConfig * config,PyWideStringList * options,const wchar_t * option)2051 warnoptions_append(PyConfig *config, PyWideStringList *options,
2052 const wchar_t *option)
2053 {
2054 /* config_init_warnoptions() add existing config warnoptions at the end:
2055 ensure that the new option is not already present in this list to
2056 prevent change the options order whne config_init_warnoptions() is
2057 called twice. */
2058 if (_PyWideStringList_Find(&config->warnoptions, option)) {
2059 /* Already present: do nothing */
2060 return _PyStatus_OK();
2061 }
2062 if (_PyWideStringList_Find(options, option)) {
2063 /* Already present: do nothing */
2064 return _PyStatus_OK();
2065 }
2066 return PyWideStringList_Append(options, option);
2067 }
2068
2069
2070 static PyStatus
warnoptions_extend(PyConfig * config,PyWideStringList * options,const PyWideStringList * options2)2071 warnoptions_extend(PyConfig *config, PyWideStringList *options,
2072 const PyWideStringList *options2)
2073 {
2074 const Py_ssize_t len = options2->length;
2075 wchar_t *const *items = options2->items;
2076
2077 for (Py_ssize_t i = 0; i < len; i++) {
2078 PyStatus status = warnoptions_append(config, options, items[i]);
2079 if (_PyStatus_EXCEPTION(status)) {
2080 return status;
2081 }
2082 }
2083 return _PyStatus_OK();
2084 }
2085
2086
2087 static PyStatus
config_init_warnoptions(PyConfig * config,const PyWideStringList * cmdline_warnoptions,const PyWideStringList * env_warnoptions,const PyWideStringList * sys_warnoptions)2088 config_init_warnoptions(PyConfig *config,
2089 const PyWideStringList *cmdline_warnoptions,
2090 const PyWideStringList *env_warnoptions,
2091 const PyWideStringList *sys_warnoptions)
2092 {
2093 PyStatus status;
2094 PyWideStringList options = _PyWideStringList_INIT;
2095
2096 /* Priority of warnings options, lowest to highest:
2097 *
2098 * - any implicit filters added by _warnings.c/warnings.py
2099 * - PyConfig.dev_mode: "default" filter
2100 * - PYTHONWARNINGS environment variable
2101 * - '-W' command line options
2102 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2103 * "default::BytesWarning" or "error::BytesWarning" filter
2104 * - early PySys_AddWarnOption() calls
2105 * - PyConfig.warnoptions
2106 *
2107 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2108 * module works on the basis of "the most recently added filter will be
2109 * checked first", we add the lowest precedence entries first so that later
2110 * entries override them.
2111 */
2112
2113 if (config->dev_mode) {
2114 status = warnoptions_append(config, &options, L"default");
2115 if (_PyStatus_EXCEPTION(status)) {
2116 goto error;
2117 }
2118 }
2119
2120 status = warnoptions_extend(config, &options, env_warnoptions);
2121 if (_PyStatus_EXCEPTION(status)) {
2122 goto error;
2123 }
2124
2125 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2126 if (_PyStatus_EXCEPTION(status)) {
2127 goto error;
2128 }
2129
2130 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2131 * don't even try to emit a warning, so we skip setting the filter in that
2132 * case.
2133 */
2134 if (config->bytes_warning) {
2135 const wchar_t *filter;
2136 if (config->bytes_warning> 1) {
2137 filter = L"error::BytesWarning";
2138 }
2139 else {
2140 filter = L"default::BytesWarning";
2141 }
2142 status = warnoptions_append(config, &options, filter);
2143 if (_PyStatus_EXCEPTION(status)) {
2144 goto error;
2145 }
2146 }
2147
2148 status = warnoptions_extend(config, &options, sys_warnoptions);
2149 if (_PyStatus_EXCEPTION(status)) {
2150 goto error;
2151 }
2152
2153 /* Always add all PyConfig.warnoptions options */
2154 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2155 if (_PyStatus_EXCEPTION(status)) {
2156 goto error;
2157 }
2158
2159 _PyWideStringList_Clear(&config->warnoptions);
2160 config->warnoptions = options;
2161 return _PyStatus_OK();
2162
2163 error:
2164 _PyWideStringList_Clear(&options);
2165 return status;
2166 }
2167
2168
2169 static PyStatus
config_update_argv(PyConfig * config,Py_ssize_t opt_index)2170 config_update_argv(PyConfig *config, Py_ssize_t opt_index)
2171 {
2172 const PyWideStringList *cmdline_argv = &config->argv;
2173 PyWideStringList config_argv = _PyWideStringList_INIT;
2174
2175 /* Copy argv to be able to modify it (to force -c/-m) */
2176 if (cmdline_argv->length <= opt_index) {
2177 /* Ensure at least one (empty) argument is seen */
2178 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2179 if (_PyStatus_EXCEPTION(status)) {
2180 return status;
2181 }
2182 }
2183 else {
2184 PyWideStringList slice;
2185 slice.length = cmdline_argv->length - opt_index;
2186 slice.items = &cmdline_argv->items[opt_index];
2187 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2188 return _PyStatus_NO_MEMORY();
2189 }
2190 }
2191 assert(config_argv.length >= 1);
2192
2193 wchar_t *arg0 = NULL;
2194 if (config->run_command != NULL) {
2195 /* Force sys.argv[0] = '-c' */
2196 arg0 = L"-c";
2197 }
2198 else if (config->run_module != NULL) {
2199 /* Force sys.argv[0] = '-m'*/
2200 arg0 = L"-m";
2201 }
2202 if (arg0 != NULL) {
2203 arg0 = _PyMem_RawWcsdup(arg0);
2204 if (arg0 == NULL) {
2205 _PyWideStringList_Clear(&config_argv);
2206 return _PyStatus_NO_MEMORY();
2207 }
2208
2209 PyMem_RawFree(config_argv.items[0]);
2210 config_argv.items[0] = arg0;
2211 }
2212
2213 _PyWideStringList_Clear(&config->argv);
2214 config->argv = config_argv;
2215 return _PyStatus_OK();
2216 }
2217
2218
2219 static PyStatus
core_read_precmdline(PyConfig * config,_PyPreCmdline * precmdline)2220 core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
2221 {
2222 PyStatus status;
2223
2224 if (config->parse_argv) {
2225 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2226 return _PyStatus_NO_MEMORY();
2227 }
2228 }
2229
2230 PyPreConfig preconfig;
2231
2232 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2233 if (_PyStatus_EXCEPTION(status)) {
2234 return status;
2235 }
2236
2237 _PyPreConfig_GetConfig(&preconfig, config);
2238
2239 status = _PyPreCmdline_Read(precmdline, &preconfig);
2240 if (_PyStatus_EXCEPTION(status)) {
2241 return status;
2242 }
2243
2244 status = _PyPreCmdline_SetConfig(precmdline, config);
2245 if (_PyStatus_EXCEPTION(status)) {
2246 return status;
2247 }
2248 return _PyStatus_OK();
2249 }
2250
2251
2252 static PyStatus
config_read_cmdline(PyConfig * config)2253 config_read_cmdline(PyConfig *config)
2254 {
2255 PyStatus status;
2256 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2257 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2258 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
2259
2260 if (config->parse_argv < 0) {
2261 config->parse_argv = 1;
2262 }
2263
2264 if (config->program_name == NULL) {
2265 status = config_init_program_name(config);
2266 if (_PyStatus_EXCEPTION(status)) {
2267 return status;
2268 }
2269 }
2270
2271 if (config->parse_argv) {
2272 Py_ssize_t opt_index;
2273 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2274 if (_PyStatus_EXCEPTION(status)) {
2275 goto done;
2276 }
2277
2278 status = config_update_argv(config, opt_index);
2279 if (_PyStatus_EXCEPTION(status)) {
2280 goto done;
2281 }
2282 }
2283
2284 if (config->use_environment) {
2285 status = config_init_env_warnoptions(config, &env_warnoptions);
2286 if (_PyStatus_EXCEPTION(status)) {
2287 goto done;
2288 }
2289 }
2290
2291 /* Handle early PySys_AddWarnOption() calls */
2292 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2293 if (_PyStatus_EXCEPTION(status)) {
2294 goto done;
2295 }
2296
2297 status = config_init_warnoptions(config,
2298 &cmdline_warnoptions,
2299 &env_warnoptions,
2300 &sys_warnoptions);
2301 if (_PyStatus_EXCEPTION(status)) {
2302 goto done;
2303 }
2304
2305 status = _PyStatus_OK();
2306
2307 done:
2308 _PyWideStringList_Clear(&cmdline_warnoptions);
2309 _PyWideStringList_Clear(&env_warnoptions);
2310 _PyWideStringList_Clear(&sys_warnoptions);
2311 return status;
2312 }
2313
2314
2315 PyStatus
_PyConfig_SetPyArgv(PyConfig * config,const _PyArgv * args)2316 _PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
2317 {
2318 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2319 if (_PyStatus_EXCEPTION(status)) {
2320 return status;
2321 }
2322
2323 return _PyArgv_AsWstrList(args, &config->argv);
2324 }
2325
2326
2327 /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2328 if needed to ensure that encodings are properly configured. */
2329 PyStatus
PyConfig_SetBytesArgv(PyConfig * config,Py_ssize_t argc,char * const * argv)2330 PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
2331 {
2332 _PyArgv args = {
2333 .argc = argc,
2334 .use_bytes_argv = 1,
2335 .bytes_argv = argv,
2336 .wchar_argv = NULL};
2337 return _PyConfig_SetPyArgv(config, &args);
2338 }
2339
2340
2341 PyStatus
PyConfig_SetArgv(PyConfig * config,Py_ssize_t argc,wchar_t * const * argv)2342 PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
2343 {
2344 _PyArgv args = {
2345 .argc = argc,
2346 .use_bytes_argv = 0,
2347 .bytes_argv = NULL,
2348 .wchar_argv = argv};
2349 return _PyConfig_SetPyArgv(config, &args);
2350 }
2351
2352
2353 PyStatus
PyConfig_SetWideStringList(PyConfig * config,PyWideStringList * list,Py_ssize_t length,wchar_t ** items)2354 PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2355 Py_ssize_t length, wchar_t **items)
2356 {
2357 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2358 if (_PyStatus_EXCEPTION(status)) {
2359 return status;
2360 }
2361
2362 PyWideStringList list2 = {.length = length, .items = items};
2363 if (_PyWideStringList_Copy(list, &list2) < 0) {
2364 return _PyStatus_NO_MEMORY();
2365 }
2366 return _PyStatus_OK();
2367 }
2368
2369
2370 /* Read the configuration into PyConfig from:
2371
2372 * Command line arguments
2373 * Environment variables
2374 * Py_xxx global configuration variables
2375
2376 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
2377 PyStatus
PyConfig_Read(PyConfig * config)2378 PyConfig_Read(PyConfig *config)
2379 {
2380 PyStatus status;
2381 PyWideStringList orig_argv = _PyWideStringList_INIT;
2382
2383 status = _Py_PreInitializeFromConfig(config, NULL);
2384 if (_PyStatus_EXCEPTION(status)) {
2385 return status;
2386 }
2387
2388 config_get_global_vars(config);
2389
2390 if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
2391 return _PyStatus_NO_MEMORY();
2392 }
2393
2394 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
2395 status = core_read_precmdline(config, &precmdline);
2396 if (_PyStatus_EXCEPTION(status)) {
2397 goto done;
2398 }
2399
2400 assert(config->isolated >= 0);
2401 if (config->isolated) {
2402 config->use_environment = 0;
2403 config->user_site_directory = 0;
2404 }
2405
2406 status = config_read_cmdline(config);
2407 if (_PyStatus_EXCEPTION(status)) {
2408 goto done;
2409 }
2410
2411 /* Handle early PySys_AddXOption() calls */
2412 status = _PySys_ReadPreinitXOptions(config);
2413 if (_PyStatus_EXCEPTION(status)) {
2414 goto done;
2415 }
2416
2417 status = config_read(config);
2418 if (_PyStatus_EXCEPTION(status)) {
2419 goto done;
2420 }
2421
2422 if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
2423 status = _PyStatus_NO_MEMORY();
2424 goto done;
2425 }
2426
2427 /* Check config consistency */
2428 assert(config->isolated >= 0);
2429 assert(config->use_environment >= 0);
2430 assert(config->dev_mode >= 0);
2431 assert(config->install_signal_handlers >= 0);
2432 assert(config->use_hash_seed >= 0);
2433 assert(config->faulthandler >= 0);
2434 assert(config->tracemalloc >= 0);
2435 assert(config->site_import >= 0);
2436 assert(config->bytes_warning >= 0);
2437 assert(config->inspect >= 0);
2438 assert(config->interactive >= 0);
2439 assert(config->optimization_level >= 0);
2440 assert(config->parser_debug >= 0);
2441 assert(config->write_bytecode >= 0);
2442 assert(config->verbose >= 0);
2443 assert(config->quiet >= 0);
2444 assert(config->user_site_directory >= 0);
2445 assert(config->parse_argv >= 0);
2446 assert(config->configure_c_stdio >= 0);
2447 assert(config->buffered_stdio >= 0);
2448 assert(config->program_name != NULL);
2449 assert(_PyWideStringList_CheckConsistency(&config->argv));
2450 /* sys.argv must be non-empty: empty argv is replaced with [''] */
2451 assert(config->argv.length >= 1);
2452 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
2453 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
2454 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
2455 if (config->_install_importlib) {
2456 assert(config->module_search_paths_set != 0);
2457 /* don't check config->module_search_paths */
2458 assert(config->executable != NULL);
2459 assert(config->base_executable != NULL);
2460 assert(config->prefix != NULL);
2461 assert(config->base_prefix != NULL);
2462 assert(config->exec_prefix != NULL);
2463 assert(config->base_exec_prefix != NULL);
2464 }
2465 assert(config->filesystem_encoding != NULL);
2466 assert(config->filesystem_errors != NULL);
2467 assert(config->stdio_encoding != NULL);
2468 assert(config->stdio_errors != NULL);
2469 #ifdef MS_WINDOWS
2470 assert(config->legacy_windows_stdio >= 0);
2471 #endif
2472 /* -c and -m options are exclusive */
2473 assert(!(config->run_command != NULL && config->run_module != NULL));
2474 assert(config->check_hash_pycs_mode != NULL);
2475 assert(config->_install_importlib >= 0);
2476 assert(config->pathconfig_warnings >= 0);
2477
2478 status = _PyStatus_OK();
2479
2480 done:
2481 _PyWideStringList_Clear(&orig_argv);
2482 _PyPreCmdline_Clear(&precmdline);
2483 return status;
2484 }
2485
2486
2487 PyObject*
_Py_GetConfigsAsDict(void)2488 _Py_GetConfigsAsDict(void)
2489 {
2490 PyObject *result = NULL;
2491 PyObject *dict = NULL;
2492
2493 result = PyDict_New();
2494 if (result == NULL) {
2495 goto error;
2496 }
2497
2498 /* global result */
2499 dict = _Py_GetGlobalVariablesAsDict();
2500 if (dict == NULL) {
2501 goto error;
2502 }
2503 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
2504 goto error;
2505 }
2506 Py_CLEAR(dict);
2507
2508 /* pre config */
2509 PyInterpreterState *interp = _PyInterpreterState_Get();
2510 const PyPreConfig *pre_config = &_PyRuntime.preconfig;
2511 dict = _PyPreConfig_AsDict(pre_config);
2512 if (dict == NULL) {
2513 goto error;
2514 }
2515 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
2516 goto error;
2517 }
2518 Py_CLEAR(dict);
2519
2520 /* core config */
2521 const PyConfig *config = &interp->config;
2522 dict = config_as_dict(config);
2523 if (dict == NULL) {
2524 goto error;
2525 }
2526 if (PyDict_SetItemString(result, "config", dict) < 0) {
2527 goto error;
2528 }
2529 Py_CLEAR(dict);
2530
2531 return result;
2532
2533 error:
2534 Py_XDECREF(result);
2535 Py_XDECREF(dict);
2536 return NULL;
2537 }
2538
2539
2540 static void
init_dump_ascii_wstr(const wchar_t * str)2541 init_dump_ascii_wstr(const wchar_t *str)
2542 {
2543 if (str == NULL) {
2544 PySys_WriteStderr("(not set)");
2545 return;
2546 }
2547
2548 PySys_WriteStderr("'");
2549 for (; *str != L'\0'; str++) {
2550 wchar_t ch = *str;
2551 if (ch == L'\'') {
2552 PySys_WriteStderr("\\'");
2553 } else if (0x20 <= ch && ch < 0x7f) {
2554 PySys_WriteStderr("%lc", ch);
2555 }
2556 else if (ch <= 0xff) {
2557 PySys_WriteStderr("\\x%02x", ch);
2558 }
2559 #if SIZEOF_WCHAR_T > 2
2560 else if (ch > 0xffff) {
2561 PySys_WriteStderr("\\U%08x", ch);
2562 }
2563 #endif
2564 else {
2565 PySys_WriteStderr("\\u%04x", ch);
2566 }
2567 }
2568 PySys_WriteStderr("'");
2569 }
2570
2571
2572 /* Dump the Python path configuration into sys.stderr */
2573 void
_Py_DumpPathConfig(PyThreadState * tstate)2574 _Py_DumpPathConfig(PyThreadState *tstate)
2575 {
2576 PyObject *exc_type, *exc_value, *exc_tb;
2577 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2578
2579 PySys_WriteStderr("Python path configuration:\n");
2580
2581 #define DUMP_CONFIG(NAME, FIELD) \
2582 do { \
2583 PySys_WriteStderr(" " NAME " = "); \
2584 init_dump_ascii_wstr(config->FIELD); \
2585 PySys_WriteStderr("\n"); \
2586 } while (0)
2587
2588 PyConfig *config = &tstate->interp->config;
2589 DUMP_CONFIG("PYTHONHOME", home);
2590 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2591 DUMP_CONFIG("program name", program_name);
2592 PySys_WriteStderr(" isolated = %i\n", config->isolated);
2593 PySys_WriteStderr(" environment = %i\n", config->use_environment);
2594 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
2595 PySys_WriteStderr(" import site = %i\n", config->site_import);
2596 #undef DUMP_CONFIG
2597
2598 #define DUMP_SYS(NAME) \
2599 do { \
2600 obj = PySys_GetObject(#NAME); \
2601 PySys_FormatStderr(" sys.%s = ", #NAME); \
2602 if (obj != NULL) { \
2603 PySys_FormatStderr("%A", obj); \
2604 } \
2605 else { \
2606 PySys_WriteStderr("(not set)"); \
2607 } \
2608 PySys_FormatStderr("\n"); \
2609 } while (0)
2610
2611 PyObject *obj;
2612 DUMP_SYS(_base_executable);
2613 DUMP_SYS(base_prefix);
2614 DUMP_SYS(base_exec_prefix);
2615 DUMP_SYS(executable);
2616 DUMP_SYS(prefix);
2617 DUMP_SYS(exec_prefix);
2618 #undef DUMP_SYS
2619
2620 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
2621 if (sys_path != NULL && PyList_Check(sys_path)) {
2622 PySys_WriteStderr(" sys.path = [\n");
2623 Py_ssize_t len = PyList_GET_SIZE(sys_path);
2624 for (Py_ssize_t i=0; i < len; i++) {
2625 PyObject *path = PyList_GET_ITEM(sys_path, i);
2626 PySys_FormatStderr(" %A,\n", path);
2627 }
2628 PySys_WriteStderr(" ]\n");
2629 }
2630
2631 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
2632 }
2633