blob: 1fcc3600aa4666bb0e6d6ec20593d5dcecf1311c [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner4f98f462020-04-15 04:01:58 +02002#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
3#include "pycore_getopt.h" // _PyOS_GetOpt()
4#include "pycore_initconfig.h" // _PyStatus_OK()
Victor Stinnere5014be2020-04-14 17:52:15 +02005#include "pycore_interp.h" // _PyInterpreterState.runtime
Victor Stinner4f98f462020-04-15 04:01:58 +02006#include "pycore_pathconfig.h" // _Py_path_config
7#include "pycore_pyerrors.h" // _PyErr_Fetch()
8#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
Victor Stinnerd9ea5ca2020-04-15 02:57:50 +02009#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
Victor Stinnere5014be2020-04-14 17:52:15 +020010#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinner4f98f462020-04-15 04:01:58 +020011
12#include "osdefs.h" // DELIM
Victor Stinnere5014be2020-04-14 17:52:15 +020013#include <locale.h> // setlocale()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010014#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015# ifdef HAVE_IO_H
16# include <io.h>
17# endif
18# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020019# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010020# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020021#endif
22
Sandro Mani8f023a22020-06-08 17:28:11 +020023#ifndef PLATLIBDIR
24# error "PLATLIBDIR macro must be defined"
25#endif
26
Victor Stinner6c785c02018-08-01 17:56:14 +020027
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* --- Command line options --------------------------------------- */
29
Victor Stinner95e2cbf2019-03-01 16:25:19 +010030/* Short usage message (with %s for argv0) */
31static const char usage_line[] =
32"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
33
34/* Long usage message, split into parts < 512 bytes */
35static const char usage_1[] = "\
36Options and arguments (and corresponding environment variables):\n\
37-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
38 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
39-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
40-c cmd : program passed in as string (terminates option list)\n\
41-d : debug output from parser; also PYTHONDEBUG=x\n\
42-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
43-h : print this help message and exit (also --help)\n\
44";
45static const char usage_2[] = "\
46-i : inspect interactively after running script; forces a prompt even\n\
47 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
48-I : isolate Python from the user's environment (implies -E and -s)\n\
49-m mod : run library module as a script (terminates option list)\n\
50-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
51 .pyc extension; also PYTHONOPTIMIZE=x\n\
52-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
53 .pyc extension\n\
54-q : don't print version and copyright messages on interactive startup\n\
55-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
56-S : don't imply 'import site' on initialization\n\
57";
58static const char usage_3[] = "\
59-u : force the stdout and stderr streams to be unbuffered;\n\
60 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
61-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
62 can be supplied multiple times to increase verbosity\n\
63-V : print the Python version number and exit (also --version)\n\
64 when given twice, print more information about the build\n\
65-W arg : warning control; arg is action:message:category:module:lineno\n\
66 also PYTHONWARNINGS=arg\n\
67-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000068-X opt : set implementation-specific option. The following options are available:\n\
69\n\
70 -X faulthandler: enable faulthandler\n\
71 -X showrefcount: output the total reference count and number of used\n\
72 memory blocks when the program finishes or after each statement in the\n\
73 interactive interpreter. This only works on debug builds\n\
74 -X tracemalloc: start tracing Python memory allocations using the\n\
75 tracemalloc module. By default, only the most recent frame is stored in a\n\
76 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
77 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000078 -X importtime: show how long each import takes. It shows module name,\n\
79 cumulative time (including nested imports) and self time (excluding\n\
80 nested imports). Note that its output may be broken in multi-threaded\n\
81 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
Serhiy Storchaka58de1dd2020-09-09 03:28:02 +030082 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000083 checks which are too expensive to be enabled by default. Effect of the\n\
84 developer mode:\n\
85 * Add default warning filter, as -W default\n\
86 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
87 * Enable the faulthandler module to dump the Python traceback on a crash\n\
88 * Enable asyncio debug mode\n\
89 * Set the dev_mode attribute of sys.flags to True\n\
90 * io.IOBase destructor logs close() exceptions\n\
91 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
92 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
93 otherwise activate automatically)\n\
94 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
95 given directory instead of to the code tree\n\
96\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010097--check-hash-based-pycs always|default|never:\n\
98 control how Python invalidates hash-based .pyc files\n\
99";
100static const char usage_4[] = "\
101file : program read from script file\n\
102- : program read from stdin (default; interactive mode if a tty)\n\
103arg ...: arguments passed to program in sys.argv[1:]\n\n\
104Other environment variables:\n\
105PYTHONSTARTUP: file executed on interactive startup (no default)\n\
106PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
107 default module search path. The result is sys.path.\n\
108";
109static const char usage_5[] =
110"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
111" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200112"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900114"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
116"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
117static const char usage_6[] =
118"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300119" to seed the hashes of str and bytes objects. It can also be set to an\n"
120" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121" predictable seed.\n"
122"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
123" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
124" hooks.\n"
125"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
126" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
127" locale coercion and locale compatibility warnings on stderr.\n"
128"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
129" debugger. It can be set to the callable of your debugger of choice.\n"
130"PYTHONDEVMODE: enable the development mode.\n"
131"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
132
133#if defined(MS_WINDOWS)
134# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
135#else
136# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
137#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200138
139
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100140/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200141
Victor Stinner6c785c02018-08-01 17:56:14 +0200142/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200143 stdin and stdout error handler to "surrogateescape". */
144int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200145int Py_DebugFlag = 0; /* Needed by parser.c */
146int Py_VerboseFlag = 0; /* Needed by import.c */
147int Py_QuietFlag = 0; /* Needed by sysmodule.c */
148int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
149int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
150int Py_OptimizeFlag = 0; /* Needed by compile.c */
151int Py_NoSiteFlag = 0; /* Suppress 'import site' */
152int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
153int Py_FrozenFlag = 0; /* Needed by getpath.c */
154int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
155int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
156int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
157int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
158int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
159int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
160#ifdef MS_WINDOWS
161int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
162int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
163#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200164
165
Victor Stinner1075d162019-03-25 23:19:57 +0100166static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100167_Py_GetGlobalVariablesAsDict(void)
168{
169 PyObject *dict, *obj;
170
171 dict = PyDict_New();
172 if (dict == NULL) {
173 return NULL;
174 }
175
176#define SET_ITEM(KEY, EXPR) \
177 do { \
178 obj = (EXPR); \
179 if (obj == NULL) { \
180 return NULL; \
181 } \
182 int res = PyDict_SetItemString(dict, (KEY), obj); \
183 Py_DECREF(obj); \
184 if (res < 0) { \
185 goto fail; \
186 } \
187 } while (0)
188#define SET_ITEM_INT(VAR) \
189 SET_ITEM(#VAR, PyLong_FromLong(VAR))
190#define FROM_STRING(STR) \
191 ((STR != NULL) ? \
192 PyUnicode_FromString(STR) \
193 : (Py_INCREF(Py_None), Py_None))
194#define SET_ITEM_STR(VAR) \
195 SET_ITEM(#VAR, FROM_STRING(VAR))
196
197 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
198 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
199 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
200 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
201
202 SET_ITEM_INT(Py_UTF8Mode);
203 SET_ITEM_INT(Py_DebugFlag);
204 SET_ITEM_INT(Py_VerboseFlag);
205 SET_ITEM_INT(Py_QuietFlag);
206 SET_ITEM_INT(Py_InteractiveFlag);
207 SET_ITEM_INT(Py_InspectFlag);
208
209 SET_ITEM_INT(Py_OptimizeFlag);
210 SET_ITEM_INT(Py_NoSiteFlag);
211 SET_ITEM_INT(Py_BytesWarningFlag);
212 SET_ITEM_INT(Py_FrozenFlag);
213 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
214 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
215 SET_ITEM_INT(Py_NoUserSiteDirectory);
216 SET_ITEM_INT(Py_UnbufferedStdioFlag);
217 SET_ITEM_INT(Py_HashRandomizationFlag);
218 SET_ITEM_INT(Py_IsolatedFlag);
219
220#ifdef MS_WINDOWS
221 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
222 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
223#endif
224
225 return dict;
226
227fail:
228 Py_DECREF(dict);
229 return NULL;
230
231#undef FROM_STRING
232#undef SET_ITEM
233#undef SET_ITEM_INT
234#undef SET_ITEM_STR
235}
236
237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Ok(void)
241{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200244{
Victor Stinner048a3562020-11-05 00:45:56 +0100245 assert(err_msg != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +0200246 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner048a3562020-11-05 00:45:56 +0100247 .err_msg = err_msg};
Victor Stinner871ff772019-05-17 23:54:00 +0200248}
249
Victor Stinner331a6a52019-05-27 16:39:22 +0200250PyStatus PyStatus_NoMemory(void)
251{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200252
Victor Stinner331a6a52019-05-27 16:39:22 +0200253PyStatus PyStatus_Exit(int exitcode)
254{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200255
256
Victor Stinner331a6a52019-05-27 16:39:22 +0200257int PyStatus_IsError(PyStatus status)
258{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200259
Victor Stinner331a6a52019-05-27 16:39:22 +0200260int PyStatus_IsExit(PyStatus status)
261{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200262
Victor Stinner331a6a52019-05-27 16:39:22 +0200263int PyStatus_Exception(PyStatus status)
264{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200265
Victor Stinner048a3562020-11-05 00:45:56 +0100266PyObject*
267_PyErr_SetFromPyStatus(PyStatus status)
268{
269 if (!_PyStatus_IS_ERROR(status)) {
270 PyErr_Format(PyExc_SystemError,
271 "%s() expects an error PyStatus",
272 _PyStatus_GET_FUNC());
273 }
274 else if (status.func) {
275 PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
276 }
277 else {
278 PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
279 }
280 return NULL;
281}
282
Victor Stinner871ff772019-05-17 23:54:00 +0200283
Victor Stinner331a6a52019-05-27 16:39:22 +0200284/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100285
286#ifndef NDEBUG
287int
Victor Stinner331a6a52019-05-27 16:39:22 +0200288_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100289{
290 assert(list->length >= 0);
291 if (list->length != 0) {
292 assert(list->items != NULL);
293 }
294 for (Py_ssize_t i = 0; i < list->length; i++) {
295 assert(list->items[i] != NULL);
296 }
297 return 1;
298}
299#endif /* Py_DEBUG */
300
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100301
Victor Stinner6c785c02018-08-01 17:56:14 +0200302void
Victor Stinner331a6a52019-05-27 16:39:22 +0200303_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200304{
Victor Stinner331a6a52019-05-27 16:39:22 +0200305 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100306 for (Py_ssize_t i=0; i < list->length; i++) {
307 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200308 }
Victor Stinner74f65682019-03-15 15:08:05 +0100309 PyMem_RawFree(list->items);
310 list->length = 0;
311 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200312}
313
314
Victor Stinner74f65682019-03-15 15:08:05 +0100315int
Victor Stinner331a6a52019-05-27 16:39:22 +0200316_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200317{
Victor Stinner331a6a52019-05-27 16:39:22 +0200318 assert(_PyWideStringList_CheckConsistency(list));
319 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100320
321 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200322 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100323 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300324 }
Victor Stinner74f65682019-03-15 15:08:05 +0100325
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200326 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100327
328 size_t size = list2->length * sizeof(list2->items[0]);
329 copy.items = PyMem_RawMalloc(size);
330 if (copy.items == NULL) {
331 return -1;
332 }
333
334 for (Py_ssize_t i=0; i < list2->length; i++) {
335 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
336 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200337 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100338 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200339 }
Victor Stinner74f65682019-03-15 15:08:05 +0100340 copy.items[i] = item;
341 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200342 }
Victor Stinner74f65682019-03-15 15:08:05 +0100343
Victor Stinner331a6a52019-05-27 16:39:22 +0200344 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100345 *list = copy;
346 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200347}
348
349
Victor Stinner331a6a52019-05-27 16:39:22 +0200350PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100351PyWideStringList_Insert(PyWideStringList *list,
352 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100353{
Victor Stinner3842f292019-08-23 16:57:54 +0100354 Py_ssize_t len = list->length;
355 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000356 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100358 }
Victor Stinner3842f292019-08-23 16:57:54 +0100359 if (index < 0) {
360 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
361 }
362 if (index > len) {
363 index = len;
364 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100365
Victor Stinner74f65682019-03-15 15:08:05 +0100366 wchar_t *item2 = _PyMem_RawWcsdup(item);
367 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200368 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100369 }
Victor Stinner74f65682019-03-15 15:08:05 +0100370
Victor Stinner3842f292019-08-23 16:57:54 +0100371 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100372 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
373 if (items2 == NULL) {
374 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200375 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100376 }
377
Victor Stinner3842f292019-08-23 16:57:54 +0100378 if (index < len) {
379 memmove(&items2[index + 1],
380 &items2[index],
381 (len - index) * sizeof(items2[0]));
382 }
383
384 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100385 list->items = items2;
386 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200387 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100388}
389
390
Victor Stinner331a6a52019-05-27 16:39:22 +0200391PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100392PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
393{
394 return PyWideStringList_Insert(list, list->length, item);
395}
396
397
398PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200399_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100400{
401 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200402 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
403 if (_PyStatus_EXCEPTION(status)) {
404 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100405 }
406 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200407 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100408}
409
410
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100411static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200412_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100413{
414 for (Py_ssize_t i = 0; i < list->length; i++) {
415 if (wcscmp(list->items[i], item) == 0) {
416 return 1;
417 }
418 }
419 return 0;
420}
421
422
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100423PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200424_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100425{
Victor Stinner331a6a52019-05-27 16:39:22 +0200426 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427
Victor Stinner74f65682019-03-15 15:08:05 +0100428 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100429 if (pylist == NULL) {
430 return NULL;
431 }
432
Victor Stinner74f65682019-03-15 15:08:05 +0100433 for (Py_ssize_t i = 0; i < list->length; i++) {
434 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
435 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100436 Py_DECREF(pylist);
437 return NULL;
438 }
Victor Stinner74f65682019-03-15 15:08:05 +0100439 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100440 }
441 return pylist;
442}
443
444
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100445/* --- Py_SetStandardStreamEncoding() ----------------------------- */
446
Victor Stinner124b9eb2018-08-29 01:29:06 +0200447/* Helper to allow an embedding application to override the normal
448 * mechanism that attempts to figure out an appropriate IO encoding
449 */
450
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200451static char *_Py_StandardStreamEncoding = NULL;
452static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200453
454int
455Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
456{
457 if (Py_IsInitialized()) {
458 /* This is too late to have any effect */
459 return -1;
460 }
461
462 int res = 0;
463
464 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
465 but Py_Initialize() can change the allocator. Use a known allocator
466 to be able to release the memory later. */
467 PyMemAllocatorEx old_alloc;
468 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
469
470 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
471 * initialised yet.
472 *
473 * However, the raw memory allocators are initialised appropriately
474 * as C static variables, so _PyMem_RawStrdup is OK even though
475 * Py_Initialize hasn't been called yet.
476 */
477 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200478 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200479 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
480 if (!_Py_StandardStreamEncoding) {
481 res = -2;
482 goto done;
483 }
484 }
485 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200486 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200487 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
488 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200489 PyMem_RawFree(_Py_StandardStreamEncoding);
490 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200491 res = -3;
492 goto done;
493 }
494 }
495#ifdef MS_WINDOWS
496 if (_Py_StandardStreamEncoding) {
497 /* Overriding the stream encoding implies legacy streams */
498 Py_LegacyWindowsStdioFlag = 1;
499 }
500#endif
501
502done:
503 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
504
505 return res;
506}
507
508
509void
510_Py_ClearStandardStreamEncoding(void)
511{
512 /* Use the same allocator than Py_SetStandardStreamEncoding() */
513 PyMemAllocatorEx old_alloc;
514 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
515
516 /* We won't need them anymore. */
517 if (_Py_StandardStreamEncoding) {
518 PyMem_RawFree(_Py_StandardStreamEncoding);
519 _Py_StandardStreamEncoding = NULL;
520 }
521 if (_Py_StandardStreamErrors) {
522 PyMem_RawFree(_Py_StandardStreamErrors);
523 _Py_StandardStreamErrors = NULL;
524 }
525
526 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527}
528
529
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530/* --- Py_GetArgcArgv() ------------------------------------------- */
531
532/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200533static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100534
535
536void
537_Py_ClearArgcArgv(void)
538{
539 PyMemAllocatorEx old_alloc;
540 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
541
Victor Stinner331a6a52019-05-27 16:39:22 +0200542 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100543
544 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
545}
546
547
Victor Stinner4fffd382019-03-06 01:44:31 +0100548static int
Victor Stinner74f65682019-03-15 15:08:05 +0100549_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100550{
Victor Stinner331a6a52019-05-27 16:39:22 +0200551 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100552 int res;
553
554 PyMemAllocatorEx old_alloc;
555 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
556
Victor Stinner331a6a52019-05-27 16:39:22 +0200557 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100558
559 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
560 return res;
561}
562
563
Victor Stinner4b9aad42020-11-02 16:49:54 +0100564// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100565void
566Py_GetArgcArgv(int *argc, wchar_t ***argv)
567{
Victor Stinner74f65682019-03-15 15:08:05 +0100568 *argc = (int)orig_argv.length;
569 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100570}
571
572
Victor Stinner331a6a52019-05-27 16:39:22 +0200573/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100574
575#define DECODE_LOCALE_ERR(NAME, LEN) \
576 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 ? _PyStatus_ERR("cannot decode " NAME) \
578 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100579
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100580#define MAX_HASH_SEED 4294967295UL
581
582
583#ifndef NDEBUG
584static int
585config_check_consistency(const PyConfig *config)
586{
587 /* Check config consistency */
588 assert(config->isolated >= 0);
589 assert(config->use_environment >= 0);
590 assert(config->dev_mode >= 0);
591 assert(config->install_signal_handlers >= 0);
592 assert(config->use_hash_seed >= 0);
593 assert(config->hash_seed <= MAX_HASH_SEED);
594 assert(config->faulthandler >= 0);
595 assert(config->tracemalloc >= 0);
596 assert(config->import_time >= 0);
597 assert(config->show_ref_count >= 0);
598 assert(config->dump_refs >= 0);
599 assert(config->malloc_stats >= 0);
600 assert(config->site_import >= 0);
601 assert(config->bytes_warning >= 0);
602 assert(config->inspect >= 0);
603 assert(config->interactive >= 0);
604 assert(config->optimization_level >= 0);
605 assert(config->parser_debug >= 0);
606 assert(config->write_bytecode >= 0);
607 assert(config->verbose >= 0);
608 assert(config->quiet >= 0);
609 assert(config->user_site_directory >= 0);
610 assert(config->parse_argv >= 0);
611 assert(config->configure_c_stdio >= 0);
612 assert(config->buffered_stdio >= 0);
613 assert(config->program_name != NULL);
614 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
615 assert(_PyWideStringList_CheckConsistency(&config->argv));
616 /* sys.argv must be non-empty: empty argv is replaced with [''] */
617 assert(config->argv.length >= 1);
618 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
619 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
620 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
621 assert(config->module_search_paths_set >= 0);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100622 assert(config->platlibdir != NULL);
623 assert(config->filesystem_encoding != NULL);
624 assert(config->filesystem_errors != NULL);
625 assert(config->stdio_encoding != NULL);
626 assert(config->stdio_errors != NULL);
627#ifdef MS_WINDOWS
628 assert(config->legacy_windows_stdio >= 0);
629#endif
630 /* -c and -m options are exclusive */
631 assert(!(config->run_command != NULL && config->run_module != NULL));
632 assert(config->check_hash_pycs_mode != NULL);
633 assert(config->_install_importlib >= 0);
634 assert(config->pathconfig_warnings >= 0);
635 return 1;
636}
637#endif
638
Victor Stinner441b10c2019-09-28 04:28:35 +0200639
Victor Stinner6c785c02018-08-01 17:56:14 +0200640/* Free memory allocated in config, but don't clear all attributes */
641void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200643{
644#define CLEAR(ATTR) \
645 do { \
646 PyMem_RawFree(ATTR); \
647 ATTR = NULL; \
648 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200649
650 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200651 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200652 CLEAR(config->home);
653 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200654
Victor Stinner331a6a52019-05-27 16:39:22 +0200655 _PyWideStringList_Clear(&config->argv);
656 _PyWideStringList_Clear(&config->warnoptions);
657 _PyWideStringList_Clear(&config->xoptions);
658 _PyWideStringList_Clear(&config->module_search_paths);
659 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200660
661 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700662 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200663 CLEAR(config->prefix);
664 CLEAR(config->base_prefix);
665 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200666 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200667 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200668
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200669 CLEAR(config->filesystem_encoding);
670 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200671 CLEAR(config->stdio_encoding);
672 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100673 CLEAR(config->run_command);
674 CLEAR(config->run_module);
675 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400676 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200677
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200678 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200679#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200680}
681
682
Victor Stinner8462a492019-10-01 12:06:16 +0200683void
Victor Stinner331a6a52019-05-27 16:39:22 +0200684_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200685{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200686 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200687
Victor Stinner022be022019-05-22 23:58:50 +0200688 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200689 config->isolated = -1;
690 config->use_environment = -1;
691 config->dev_mode = -1;
692 config->install_signal_handlers = 1;
693 config->use_hash_seed = -1;
694 config->faulthandler = -1;
695 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200696 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200697 config->parse_argv = 0;
698 config->site_import = -1;
699 config->bytes_warning = -1;
700 config->inspect = -1;
701 config->interactive = -1;
702 config->optimization_level = -1;
703 config->parser_debug= -1;
704 config->write_bytecode = -1;
705 config->verbose = -1;
706 config->quiet = -1;
707 config->user_site_directory = -1;
708 config->configure_c_stdio = 0;
709 config->buffered_stdio = -1;
710 config->_install_importlib = 1;
711 config->check_hash_pycs_mode = NULL;
712 config->pathconfig_warnings = -1;
713 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200714 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200715#ifdef MS_WINDOWS
716 config->legacy_windows_stdio = -1;
717#endif
718}
719
720
Victor Stinner8462a492019-10-01 12:06:16 +0200721static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200722config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200723{
Victor Stinner8462a492019-10-01 12:06:16 +0200724 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200725
726 config->isolated = 0;
727 config->use_environment = 1;
728 config->site_import = 1;
729 config->bytes_warning = 0;
730 config->inspect = 0;
731 config->interactive = 0;
732 config->optimization_level = 0;
733 config->parser_debug= 0;
734 config->write_bytecode = 1;
735 config->verbose = 0;
736 config->quiet = 0;
737 config->user_site_directory = 1;
738 config->buffered_stdio = 1;
739 config->pathconfig_warnings = 1;
740#ifdef MS_WINDOWS
741 config->legacy_windows_stdio = 0;
742#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200743}
744
745
Victor Stinner8462a492019-10-01 12:06:16 +0200746void
Victor Stinner331a6a52019-05-27 16:39:22 +0200747PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200748{
Victor Stinner8462a492019-10-01 12:06:16 +0200749 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200750
Victor Stinner022be022019-05-22 23:58:50 +0200751 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200752 config->configure_c_stdio = 1;
753 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200754}
755
756
Victor Stinner8462a492019-10-01 12:06:16 +0200757void
Victor Stinner331a6a52019-05-27 16:39:22 +0200758PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200759{
Victor Stinner8462a492019-10-01 12:06:16 +0200760 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200761
Victor Stinner022be022019-05-22 23:58:50 +0200762 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200763 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200764 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200765 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200766 config->dev_mode = 0;
767 config->install_signal_handlers = 0;
768 config->use_hash_seed = 0;
769 config->faulthandler = 0;
770 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200771 config->pathconfig_warnings = 0;
772#ifdef MS_WINDOWS
773 config->legacy_windows_stdio = 0;
774#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200775}
776
777
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200778/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200779PyStatus
780PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200781{
Victor Stinner331a6a52019-05-27 16:39:22 +0200782 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
783 if (_PyStatus_EXCEPTION(status)) {
784 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200785 }
786
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200787 wchar_t *str2;
788 if (str != NULL) {
789 str2 = _PyMem_RawWcsdup(str);
790 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200791 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200792 }
793 }
794 else {
795 str2 = NULL;
796 }
797 PyMem_RawFree(*config_str);
798 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200799 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200800}
801
802
Victor Stinner331a6a52019-05-27 16:39:22 +0200803static PyStatus
804config_set_bytes_string(PyConfig *config, wchar_t **config_str,
805 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200806{
Victor Stinner331a6a52019-05-27 16:39:22 +0200807 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
808 if (_PyStatus_EXCEPTION(status)) {
809 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400810 }
811
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200812 wchar_t *str2;
813 if (str != NULL) {
814 size_t len;
815 str2 = Py_DecodeLocale(str, &len);
816 if (str2 == NULL) {
817 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200818 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200819 }
820 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200821 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200822 }
823 }
824 }
825 else {
826 str2 = NULL;
827 }
828 PyMem_RawFree(*config_str);
829 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200830 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200831}
832
833
Victor Stinner331a6a52019-05-27 16:39:22 +0200834#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
835 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400836
837
Victor Stinner70005ac2019-05-02 15:25:34 -0400838/* Decode str using Py_DecodeLocale() and set the result into *config_str.
839 Pre-initialize Python if needed to ensure that encodings are properly
840 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200841PyStatus
842PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100843 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400844{
Victor Stinner331a6a52019-05-27 16:39:22 +0200845 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400846}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200847
848
Victor Stinner331a6a52019-05-27 16:39:22 +0200849PyStatus
850_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200851{
Victor Stinner331a6a52019-05-27 16:39:22 +0200852 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200853
Victor Stinner331a6a52019-05-27 16:39:22 +0200854 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200855
856#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200857#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200858 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200859 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
860 if (_PyStatus_EXCEPTION(status)) { \
861 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200862 } \
863 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100864#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200865 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200866 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200867 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200868 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200869 } while (0)
870
Victor Stinner6d1c4672019-05-20 11:02:00 +0200871 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100872 COPY_ATTR(isolated);
873 COPY_ATTR(use_environment);
874 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200875 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200876 COPY_ATTR(use_hash_seed);
877 COPY_ATTR(hash_seed);
878 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200879 COPY_ATTR(faulthandler);
880 COPY_ATTR(tracemalloc);
881 COPY_ATTR(import_time);
882 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200883 COPY_ATTR(dump_refs);
884 COPY_ATTR(malloc_stats);
885
Victor Stinner124b9eb2018-08-29 01:29:06 +0200886 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200887 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200888 COPY_WSTR_ATTR(home);
889 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200890
Victor Stinnerae239f62019-05-16 17:02:56 +0200891 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100892 COPY_WSTRLIST(argv);
893 COPY_WSTRLIST(warnoptions);
894 COPY_WSTRLIST(xoptions);
895 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200897
Victor Stinner124b9eb2018-08-29 01:29:06 +0200898 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700899 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200900 COPY_WSTR_ATTR(prefix);
901 COPY_WSTR_ATTR(base_prefix);
902 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200903 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200904 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200905
Victor Stinner6c785c02018-08-01 17:56:14 +0200906 COPY_ATTR(site_import);
907 COPY_ATTR(bytes_warning);
908 COPY_ATTR(inspect);
909 COPY_ATTR(interactive);
910 COPY_ATTR(optimization_level);
911 COPY_ATTR(parser_debug);
912 COPY_ATTR(write_bytecode);
913 COPY_ATTR(verbose);
914 COPY_ATTR(quiet);
915 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200916 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200917 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400918 COPY_WSTR_ATTR(filesystem_encoding);
919 COPY_WSTR_ATTR(filesystem_errors);
920 COPY_WSTR_ATTR(stdio_encoding);
921 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200922#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200923 COPY_ATTR(legacy_windows_stdio);
924#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100925 COPY_ATTR(skip_source_first_line);
926 COPY_WSTR_ATTR(run_command);
927 COPY_WSTR_ATTR(run_module);
928 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400929 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200930 COPY_ATTR(pathconfig_warnings);
931 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200932 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200933 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200934
935#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200936#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200937#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200938 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200939}
940
941
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100942PyObject *
943_PyConfig_AsDict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100944{
Victor Stinner8f427482020-07-08 00:20:37 +0200945 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100946 if (dict == NULL) {
947 return NULL;
948 }
949
950#define SET_ITEM(KEY, EXPR) \
951 do { \
952 PyObject *obj = (EXPR); \
953 if (obj == NULL) { \
954 goto fail; \
955 } \
956 int res = PyDict_SetItemString(dict, (KEY), obj); \
957 Py_DECREF(obj); \
958 if (res < 0) { \
959 goto fail; \
960 } \
961 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#define SET_ITEM_INT(ATTR) \
963 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
964#define SET_ITEM_UINT(ATTR) \
965 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#define FROM_WSTRING(STR) \
967 ((STR != NULL) ? \
968 PyUnicode_FromWideChar(STR, -1) \
969 : (Py_INCREF(Py_None), Py_None))
970#define SET_ITEM_WSTR(ATTR) \
971 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
972#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200973 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974
Victor Stinner6d1c4672019-05-20 11:02:00 +0200975 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100976 SET_ITEM_INT(isolated);
977 SET_ITEM_INT(use_environment);
978 SET_ITEM_INT(dev_mode);
979 SET_ITEM_INT(install_signal_handlers);
980 SET_ITEM_INT(use_hash_seed);
981 SET_ITEM_UINT(hash_seed);
982 SET_ITEM_INT(faulthandler);
983 SET_ITEM_INT(tracemalloc);
984 SET_ITEM_INT(import_time);
985 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100986 SET_ITEM_INT(dump_refs);
987 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400988 SET_ITEM_WSTR(filesystem_encoding);
989 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100990 SET_ITEM_WSTR(pycache_prefix);
991 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200992 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100993 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100994 SET_ITEM_WSTRLIST(xoptions);
995 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200996 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100997 SET_ITEM_WSTR(home);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100998 SET_ITEM_INT(module_search_paths_set);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100999 SET_ITEM_WSTRLIST(module_search_paths);
1000 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -07001001 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001002 SET_ITEM_WSTR(prefix);
1003 SET_ITEM_WSTR(base_prefix);
1004 SET_ITEM_WSTR(exec_prefix);
1005 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02001006 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001007 SET_ITEM_INT(site_import);
1008 SET_ITEM_INT(bytes_warning);
1009 SET_ITEM_INT(inspect);
1010 SET_ITEM_INT(interactive);
1011 SET_ITEM_INT(optimization_level);
1012 SET_ITEM_INT(parser_debug);
1013 SET_ITEM_INT(write_bytecode);
1014 SET_ITEM_INT(verbose);
1015 SET_ITEM_INT(quiet);
1016 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001017 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001018 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -04001019 SET_ITEM_WSTR(stdio_encoding);
1020 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001021#ifdef MS_WINDOWS
1022 SET_ITEM_INT(legacy_windows_stdio);
1023#endif
1024 SET_ITEM_INT(skip_source_first_line);
1025 SET_ITEM_WSTR(run_command);
1026 SET_ITEM_WSTR(run_module);
1027 SET_ITEM_WSTR(run_filename);
1028 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001029 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001030 SET_ITEM_INT(pathconfig_warnings);
1031 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +02001032 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001033 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001034
1035 return dict;
1036
1037fail:
1038 Py_DECREF(dict);
1039 return NULL;
1040
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001041#undef FROM_WSTRING
1042#undef SET_ITEM
1043#undef SET_ITEM_INT
1044#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001045#undef SET_ITEM_WSTR
1046#undef SET_ITEM_WSTRLIST
1047}
1048
1049
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001050static PyObject*
1051config_dict_get(PyObject *dict, const char *name)
1052{
1053 PyObject *item = PyDict_GetItemString(dict, name);
1054 if (item == NULL) {
1055 PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1056 return NULL;
1057 }
1058 return item;
1059}
1060
1061
1062static void
1063config_dict_invalid_value(const char *name)
1064{
1065 PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1066}
1067
1068
1069static void
1070config_dict_invalid_type(const char *name)
1071{
1072 PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1073}
1074
1075
1076static int
1077config_dict_get_int(PyObject *dict, const char *name, int *result)
1078{
1079 PyObject *item = config_dict_get(dict, name);
1080 if (item == NULL) {
1081 return -1;
1082 }
1083 int value = _PyLong_AsInt(item);
1084 if (value == -1 && PyErr_Occurred()) {
1085 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1086 config_dict_invalid_type(name);
1087 }
1088 else {
1089 config_dict_invalid_value(name);
1090 }
1091 return -1;
1092 }
1093 *result = value;
1094 return 0;
1095}
1096
1097
1098static int
1099config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1100{
1101 PyObject *item = config_dict_get(dict, name);
1102 if (item == NULL) {
1103 return -1;
1104 }
1105 unsigned long value = PyLong_AsUnsignedLong(item);
1106 if (value == (unsigned long)-1 && PyErr_Occurred()) {
1107 config_dict_invalid_value(name);
1108 return -1;
1109 }
1110 *result = value;
1111 return 0;
1112}
1113
1114
1115static int
1116config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1117 wchar_t **result)
1118{
1119 PyObject *item = config_dict_get(dict, name);
1120 if (item == NULL) {
1121 return -1;
1122 }
1123 PyStatus status;
1124 if (item == Py_None) {
1125 status = PyConfig_SetString(config, result, NULL);
1126 }
1127 else if (!PyUnicode_Check(item)) {
1128 config_dict_invalid_type(name);
1129 return -1;
1130 }
1131 else {
1132 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1133 if (wstr == NULL) {
1134 return -1;
1135 }
1136 status = PyConfig_SetString(config, result, wstr);
1137 PyMem_Free(wstr);
1138 }
1139 if (_PyStatus_EXCEPTION(status)) {
1140 PyErr_NoMemory();
1141 return -1;
1142 }
1143 return 0;
1144}
1145
1146
1147static int
1148config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1149 PyWideStringList *result)
1150{
1151 PyObject *list = config_dict_get(dict, name);
1152 if (list == NULL) {
1153 return -1;
1154 }
1155
1156 if (!PyList_CheckExact(list)) {
1157 config_dict_invalid_type(name);
1158 return -1;
1159 }
1160
1161 PyWideStringList wstrlist = _PyWideStringList_INIT;
1162 for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1163 PyObject *item = PyList_GET_ITEM(list, i);
1164
1165 if (item == Py_None) {
1166 config_dict_invalid_value(name);
1167 goto error;
1168 }
1169 else if (!PyUnicode_Check(item)) {
1170 config_dict_invalid_type(name);
1171 goto error;
1172 }
1173 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1174 if (wstr == NULL) {
1175 goto error;
1176 }
1177 PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1178 PyMem_Free(wstr);
1179 if (_PyStatus_EXCEPTION(status)) {
1180 PyErr_NoMemory();
1181 goto error;
1182 }
1183 }
1184
1185 if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1186 PyErr_NoMemory();
1187 goto error;
1188 }
1189 _PyWideStringList_Clear(&wstrlist);
1190 return 0;
1191
1192error:
1193 _PyWideStringList_Clear(&wstrlist);
1194 return -1;
1195}
1196
1197
1198int
1199_PyConfig_FromDict(PyConfig *config, PyObject *dict)
1200{
1201 if (!PyDict_Check(dict)) {
1202 PyErr_SetString(PyExc_TypeError, "dict expected");
1203 return -1;
1204 }
1205
1206#define CHECK_VALUE(NAME, TEST) \
1207 if (!(TEST)) { \
1208 config_dict_invalid_value(NAME); \
1209 return -1; \
1210 }
1211#define GET_UINT(KEY) \
1212 do { \
1213 if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1214 return -1; \
1215 } \
1216 CHECK_VALUE(#KEY, config->KEY >= 0); \
1217 } while (0)
1218#define GET_WSTR(KEY) \
1219 do { \
1220 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1221 return -1; \
1222 } \
1223 CHECK_VALUE(#KEY, config->KEY != NULL); \
1224 } while (0)
1225#define GET_WSTR_OPT(KEY) \
1226 do { \
1227 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1228 return -1; \
1229 } \
1230 } while (0)
1231#define GET_WSTRLIST(KEY) \
1232 do { \
1233 if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1234 return -1; \
1235 } \
1236 } while (0)
1237
1238 GET_UINT(_config_init);
1239 CHECK_VALUE("_config_init",
1240 config->_config_init == _PyConfig_INIT_COMPAT
1241 || config->_config_init == _PyConfig_INIT_PYTHON
1242 || config->_config_init == _PyConfig_INIT_ISOLATED);
1243 GET_UINT(isolated);
1244 GET_UINT(use_environment);
1245 GET_UINT(dev_mode);
1246 GET_UINT(install_signal_handlers);
1247 GET_UINT(use_hash_seed);
1248 if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1249 return -1;
1250 }
1251 CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1252 GET_UINT(faulthandler);
1253 GET_UINT(tracemalloc);
1254 GET_UINT(import_time);
1255 GET_UINT(show_ref_count);
1256 GET_UINT(dump_refs);
1257 GET_UINT(malloc_stats);
1258 GET_WSTR(filesystem_encoding);
1259 GET_WSTR(filesystem_errors);
1260 GET_WSTR_OPT(pycache_prefix);
1261 GET_UINT(parse_argv);
1262 GET_WSTRLIST(orig_argv);
1263 GET_WSTRLIST(argv);
1264 GET_WSTRLIST(xoptions);
1265 GET_WSTRLIST(warnoptions);
1266 GET_UINT(site_import);
1267 GET_UINT(bytes_warning);
1268 GET_UINT(inspect);
1269 GET_UINT(interactive);
1270 GET_UINT(optimization_level);
1271 GET_UINT(parser_debug);
1272 GET_UINT(write_bytecode);
1273 GET_UINT(verbose);
1274 GET_UINT(quiet);
1275 GET_UINT(user_site_directory);
1276 GET_UINT(configure_c_stdio);
1277 GET_UINT(buffered_stdio);
1278 GET_WSTR(stdio_encoding);
1279 GET_WSTR(stdio_errors);
1280#ifdef MS_WINDOWS
1281 GET_UINT(legacy_windows_stdio);
1282#endif
1283 GET_WSTR(check_hash_pycs_mode);
1284
1285 GET_UINT(pathconfig_warnings);
1286 GET_WSTR(program_name);
1287 GET_WSTR_OPT(pythonpath_env);
1288 GET_WSTR_OPT(home);
1289 GET_WSTR(platlibdir);
1290
Victor Stinner9e1b8282020-11-10 13:21:52 +01001291 // Path configuration output
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001292 GET_UINT(module_search_paths_set);
1293 GET_WSTRLIST(module_search_paths);
Victor Stinner9e1b8282020-11-10 13:21:52 +01001294 GET_WSTR_OPT(executable);
1295 GET_WSTR_OPT(base_executable);
1296 GET_WSTR_OPT(prefix);
1297 GET_WSTR_OPT(base_prefix);
1298 GET_WSTR_OPT(exec_prefix);
1299 GET_WSTR_OPT(base_exec_prefix);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001300
1301 GET_UINT(skip_source_first_line);
1302 GET_WSTR_OPT(run_command);
1303 GET_WSTR_OPT(run_module);
1304 GET_WSTR_OPT(run_filename);
1305
1306 GET_UINT(_install_importlib);
1307 GET_UINT(_init_main);
1308 GET_UINT(_isolated_interpreter);
1309
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001310#undef CHECK_VALUE
1311#undef GET_UINT
1312#undef GET_WSTR
1313#undef GET_WSTR_OPT
1314 return 0;
1315}
1316
1317
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001318static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +02001319config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001320{
Victor Stinner20004952019-03-26 02:31:11 +01001321 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001322}
1323
1324
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001325/* Get a copy of the environment variable as wchar_t*.
1326 Return 0 on success, but *dest can be NULL.
1327 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001328static PyStatus
1329config_get_env_dup(PyConfig *config,
1330 wchar_t **dest,
1331 wchar_t *wname, char *name,
1332 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +02001333{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001334 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001335 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001336
Victor Stinner20004952019-03-26 02:31:11 +01001337 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001338 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001339 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001340 }
1341
1342#ifdef MS_WINDOWS
1343 const wchar_t *var = _wgetenv(wname);
1344 if (!var || var[0] == '\0') {
1345 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001346 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001347 }
1348
Victor Stinner331a6a52019-05-27 16:39:22 +02001349 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001350#else
1351 const char *var = getenv(name);
1352 if (!var || var[0] == '\0') {
1353 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001354 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001355 }
1356
Victor Stinner331a6a52019-05-27 16:39:22 +02001357 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001358#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001359}
1360
1361
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001362#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001363 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001364
1365
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001366static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001367config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001368{
Victor Stinner022be022019-05-22 23:58:50 +02001369 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1370 /* Python and Isolated configuration ignore global variables */
1371 return;
1372 }
1373
Victor Stinner6c785c02018-08-01 17:56:14 +02001374#define COPY_FLAG(ATTR, VALUE) \
1375 if (config->ATTR == -1) { \
1376 config->ATTR = VALUE; \
1377 }
1378#define COPY_NOT_FLAG(ATTR, VALUE) \
1379 if (config->ATTR == -1) { \
1380 config->ATTR = !(VALUE); \
1381 }
1382
Victor Stinner20004952019-03-26 02:31:11 +01001383 COPY_FLAG(isolated, Py_IsolatedFlag);
1384 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001385 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1386 COPY_FLAG(inspect, Py_InspectFlag);
1387 COPY_FLAG(interactive, Py_InteractiveFlag);
1388 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1389 COPY_FLAG(parser_debug, Py_DebugFlag);
1390 COPY_FLAG(verbose, Py_VerboseFlag);
1391 COPY_FLAG(quiet, Py_QuietFlag);
1392#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001393 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1394#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001395 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001396
Victor Stinner6c785c02018-08-01 17:56:14 +02001397 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1398 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1399 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1400 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1401
Victor Stinner6c785c02018-08-01 17:56:14 +02001402#undef COPY_FLAG
1403#undef COPY_NOT_FLAG
1404}
1405
1406
1407/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001408static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001409config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001410{
1411#define COPY_FLAG(ATTR, VAR) \
1412 if (config->ATTR != -1) { \
1413 VAR = config->ATTR; \
1414 }
1415#define COPY_NOT_FLAG(ATTR, VAR) \
1416 if (config->ATTR != -1) { \
1417 VAR = !config->ATTR; \
1418 }
1419
Victor Stinner20004952019-03-26 02:31:11 +01001420 COPY_FLAG(isolated, Py_IsolatedFlag);
1421 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001422 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1423 COPY_FLAG(inspect, Py_InspectFlag);
1424 COPY_FLAG(interactive, Py_InteractiveFlag);
1425 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1426 COPY_FLAG(parser_debug, Py_DebugFlag);
1427 COPY_FLAG(verbose, Py_VerboseFlag);
1428 COPY_FLAG(quiet, Py_QuietFlag);
1429#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001430 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1431#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001432 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001433
Victor Stinner6c785c02018-08-01 17:56:14 +02001434 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1435 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1436 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1437 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1438
Victor Stinner6c785c02018-08-01 17:56:14 +02001439 /* Random or non-zero hash seed */
1440 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1441 config->hash_seed != 0);
1442
1443#undef COPY_FLAG
1444#undef COPY_NOT_FLAG
1445}
1446
1447
1448/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1449 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001450static PyStatus
1451config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001452{
Victor Stinner331a6a52019-05-27 16:39:22 +02001453 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001454
Victor Stinner6c785c02018-08-01 17:56:14 +02001455 /* If Py_SetProgramName() was called, use its value */
1456 const wchar_t *program_name = _Py_path_config.program_name;
1457 if (program_name != NULL) {
1458 config->program_name = _PyMem_RawWcsdup(program_name);
1459 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001460 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001461 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001462 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001463 }
1464
1465#ifdef __APPLE__
1466 /* On MacOS X, when the Python interpreter is embedded in an
1467 application bundle, it gets executed by a bootstrapping script
1468 that does os.execve() with an argv[0] that's different from the
1469 actual Python executable. This is needed to keep the Finder happy,
1470 or rather, to work around Apple's overly strict requirements of
1471 the process name. However, we still need a usable sys.executable,
1472 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001473 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001474 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001475 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001476 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001477 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1478 "PYTHONEXECUTABLE environment variable");
1479 if (_PyStatus_EXCEPTION(status)) {
1480 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001481 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001482 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001483 }
1484#ifdef WITH_NEXT_FRAMEWORK
1485 else {
1486 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1487 if (pyvenv_launcher && *pyvenv_launcher) {
1488 /* Used by Mac/Tools/pythonw.c to forward
1489 * the argv0 of the stub executable
1490 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001491 status = CONFIG_SET_BYTES_STR(config,
1492 &config->program_name,
1493 pyvenv_launcher,
1494 "__PYVENV_LAUNCHER__ environment variable");
1495 if (_PyStatus_EXCEPTION(status)) {
1496 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001497 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001498
1499 /*
1500 * This environment variable is used to communicate between
1501 * the stub launcher and the real interpreter and isn't needed
1502 * beyond this point.
1503 *
1504 * Clean up to avoid problems when launching other programs
1505 * later on.
1506 */
1507 (void)unsetenv("__PYVENV_LAUNCHER__");
1508
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001510 }
1511 }
1512#endif /* WITH_NEXT_FRAMEWORK */
1513#endif /* __APPLE__ */
1514
Victor Stinnerfed02e12019-05-17 11:12:09 +02001515 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001516 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001517 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1518 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1519 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001520 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001521 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001523 }
1524
Victor Stinnerfed02e12019-05-17 11:12:09 +02001525 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001526#ifdef MS_WINDOWS
1527 const wchar_t *default_program_name = L"python";
1528#else
1529 const wchar_t *default_program_name = L"python3";
1530#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001531 status = PyConfig_SetString(config, &config->program_name,
1532 default_program_name);
1533 if (_PyStatus_EXCEPTION(status)) {
1534 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001535 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001537}
1538
Victor Stinner331a6a52019-05-27 16:39:22 +02001539static PyStatus
1540config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001541{
1542 assert(config->executable == NULL);
1543
1544 /* If Py_SetProgramFullPath() was called, use its value */
1545 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1546 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001547 PyStatus status = PyConfig_SetString(config,
1548 &config->executable,
1549 program_full_path);
1550 if (_PyStatus_EXCEPTION(status)) {
1551 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001552 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001553 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001554 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001555 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001556}
Victor Stinner6c785c02018-08-01 17:56:14 +02001557
Victor Stinner4fffd382019-03-06 01:44:31 +01001558
Victor Stinner6c785c02018-08-01 17:56:14 +02001559static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001560config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001561{
Victor Stinner74f65682019-03-15 15:08:05 +01001562 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001563}
1564
1565
Victor Stinner331a6a52019-05-27 16:39:22 +02001566static PyStatus
1567config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001568{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001569 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001570
1571 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001572 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001573 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001574 PyStatus status = PyConfig_SetString(config, &config->home, home);
1575 if (_PyStatus_EXCEPTION(status)) {
1576 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001577 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001578 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001579 }
1580
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001581 return CONFIG_GET_ENV_DUP(config, &config->home,
1582 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001583}
1584
Victor Stinner331a6a52019-05-27 16:39:22 +02001585static PyStatus
1586config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001587{
Victor Stinner331a6a52019-05-27 16:39:22 +02001588 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001589
1590 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1591 /* Convert a text seed to a numeric one */
1592 if (seed_text && strcmp(seed_text, "random") != 0) {
1593 const char *endptr = seed_text;
1594 unsigned long seed;
1595 errno = 0;
1596 seed = strtoul(seed_text, (char **)&endptr, 10);
1597 if (*endptr != '\0'
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001598 || seed > MAX_HASH_SEED
Victor Stinner6c785c02018-08-01 17:56:14 +02001599 || (errno == ERANGE && seed == ULONG_MAX))
1600 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001601 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001602 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001603 }
1604 /* Use a specific hash */
1605 config->use_hash_seed = 1;
1606 config->hash_seed = seed;
1607 }
1608 else {
1609 /* Use a random hash */
1610 config->use_hash_seed = 0;
1611 config->hash_seed = 0;
1612 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001613 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001614}
1615
1616
Victor Stinner6c785c02018-08-01 17:56:14 +02001617static int
1618config_wstr_to_int(const wchar_t *wstr, int *result)
1619{
1620 const wchar_t *endptr = wstr;
1621 errno = 0;
1622 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1623 if (*endptr != '\0' || errno == ERANGE) {
1624 return -1;
1625 }
1626 if (value < INT_MIN || value > INT_MAX) {
1627 return -1;
1628 }
1629
1630 *result = (int)value;
1631 return 0;
1632}
1633
1634
Victor Stinner331a6a52019-05-27 16:39:22 +02001635static PyStatus
1636config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001637{
Victor Stinner331a6a52019-05-27 16:39:22 +02001638 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001639 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001640
Victor Stinner6c785c02018-08-01 17:56:14 +02001641 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001642 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1643 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1644 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1645 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001646
1647 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001648 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001649 if (dont_write_bytecode) {
1650 config->write_bytecode = 0;
1651 }
1652
1653 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001654 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001655 if (no_user_site_directory) {
1656 config->user_site_directory = 0;
1657 }
1658
1659 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001660 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001661 if (unbuffered_stdio) {
1662 config->buffered_stdio = 0;
1663 }
1664
1665#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001666 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001667 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001668#endif
1669
Victor Stinner331a6a52019-05-27 16:39:22 +02001670 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001671 config->dump_refs = 1;
1672 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001673 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001674 config->malloc_stats = 1;
1675 }
1676
Victor Stinner331a6a52019-05-27 16:39:22 +02001677 if (config->pythonpath_env == NULL) {
1678 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1679 L"PYTHONPATH", "PYTHONPATH");
1680 if (_PyStatus_EXCEPTION(status)) {
1681 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001682 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001683 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001684
Sandro Mani8f023a22020-06-08 17:28:11 +02001685 if(config->platlibdir == NULL) {
1686 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1687 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1688 if (_PyStatus_EXCEPTION(status)) {
1689 return status;
1690 }
1691 }
1692
Victor Stinner6c785c02018-08-01 17:56:14 +02001693 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001694 status = config_init_hash_seed(config);
1695 if (_PyStatus_EXCEPTION(status)) {
1696 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001697 }
1698 }
1699
Victor Stinner331a6a52019-05-27 16:39:22 +02001700 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001701}
1702
1703
Victor Stinner331a6a52019-05-27 16:39:22 +02001704static PyStatus
1705config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001706{
1707 int nframe;
1708 int valid;
1709
Victor Stinner331a6a52019-05-27 16:39:22 +02001710 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001711 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001712 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001713 valid = (nframe >= 0);
1714 }
1715 else {
1716 valid = 0;
1717 }
1718 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001719 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001720 }
1721 config->tracemalloc = nframe;
1722 }
1723
1724 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1725 if (xoption) {
1726 const wchar_t *sep = wcschr(xoption, L'=');
1727 if (sep) {
1728 if (!config_wstr_to_int(sep + 1, &nframe)) {
1729 valid = (nframe >= 0);
1730 }
1731 else {
1732 valid = 0;
1733 }
1734 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001735 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1736 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001737 }
1738 }
1739 else {
1740 /* -X tracemalloc behaves as -X tracemalloc=1 */
1741 nframe = 1;
1742 }
1743 config->tracemalloc = nframe;
1744 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001745 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001746}
1747
1748
Victor Stinner331a6a52019-05-27 16:39:22 +02001749static PyStatus
1750config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001751{
1752 assert(config->pycache_prefix == NULL);
1753
1754 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1755 if (xoption) {
1756 const wchar_t *sep = wcschr(xoption, L'=');
1757 if (sep && wcslen(sep) > 1) {
1758 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1759 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001760 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001761 }
1762 }
1763 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001764 // PYTHONPYCACHEPREFIX env var ignored
1765 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001766 config->pycache_prefix = NULL;
1767 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001768 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001769 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001770
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001771 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1772 L"PYTHONPYCACHEPREFIX",
1773 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001774}
1775
1776
Victor Stinner331a6a52019-05-27 16:39:22 +02001777static PyStatus
1778config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001779{
1780 /* More complex options configured by env var and -X option */
1781 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001782 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001783 || config_get_xoption(config, L"faulthandler")) {
1784 config->faulthandler = 1;
1785 }
1786 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001787 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001788 || config_get_xoption(config, L"importtime")) {
1789 config->import_time = 1;
1790 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001791
Victor Stinner331a6a52019-05-27 16:39:22 +02001792 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001793 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001794 status = config_init_tracemalloc(config);
1795 if (_PyStatus_EXCEPTION(status)) {
1796 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001797 }
1798 }
1799
1800 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001801 status = config_init_pycache_prefix(config);
1802 if (_PyStatus_EXCEPTION(status)) {
1803 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001804 }
1805 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001806 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001807}
1808
1809
Victor Stinner709d23d2019-05-02 14:56:30 -04001810static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001811config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001812{
Victor Stinner710e8262020-10-31 01:02:09 +01001813 if (preconfig->utf8_mode) {
1814 /* UTF-8 Mode uses UTF-8/surrogateescape */
1815 return L"surrogateescape";
1816 }
1817
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001818#ifndef MS_WINDOWS
1819 const char *loc = setlocale(LC_CTYPE, NULL);
1820 if (loc != NULL) {
1821 /* surrogateescape is the default in the legacy C and POSIX locales */
1822 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001823 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001824 }
1825
1826#ifdef PY_COERCE_C_LOCALE
1827 /* surrogateescape is the default in locale coercion target locales */
1828 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001829 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001830 }
1831#endif
1832 }
1833
Victor Stinner709d23d2019-05-02 14:56:30 -04001834 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001835#else
1836 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001837 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001838#endif
1839}
1840
1841
Victor Stinner82458b62020-11-01 20:59:35 +01001842// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001843static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001844config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1845 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001846{
Victor Stinnere662c392020-11-01 23:07:23 +01001847 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001848 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001849 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001850 }
Victor Stinner82458b62020-11-01 20:59:35 +01001851 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1852 PyMem_RawFree(encoding);
1853 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001854}
1855
1856
Victor Stinner331a6a52019-05-27 16:39:22 +02001857static PyStatus
1858config_init_stdio_encoding(PyConfig *config,
1859 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001860{
Victor Stinner331a6a52019-05-27 16:39:22 +02001861 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001862
Victor Stinner35297182020-11-04 11:20:10 +01001863 /* If Py_SetStandardStreamEncoding() has been called, use its
1864 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001865 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001866 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1867 _Py_StandardStreamEncoding,
1868 "_Py_StandardStreamEncoding");
1869 if (_PyStatus_EXCEPTION(status)) {
1870 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001871 }
1872 }
1873
1874 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001875 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1876 _Py_StandardStreamErrors,
1877 "_Py_StandardStreamErrors");
1878 if (_PyStatus_EXCEPTION(status)) {
1879 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001880 }
1881 }
1882
Victor Stinner35297182020-11-04 11:20:10 +01001883 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001884 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001885 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001886 }
1887
1888 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001889 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001890 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001891 char *pythonioencoding = _PyMem_RawStrdup(opt);
1892 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001893 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001894 }
1895
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001896 char *errors = strchr(pythonioencoding, ':');
1897 if (errors) {
1898 *errors = '\0';
1899 errors++;
1900 if (!errors[0]) {
1901 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001902 }
1903 }
1904
1905 /* Does PYTHONIOENCODING contain an encoding? */
1906 if (pythonioencoding[0]) {
1907 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001908 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1909 pythonioencoding,
1910 "PYTHONIOENCODING environment variable");
1911 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001912 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001913 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001914 }
1915 }
1916
1917 /* If the encoding is set but not the error handler,
1918 use "strict" error handler by default.
1919 PYTHONIOENCODING=latin1 behaves as
1920 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001921 if (!errors) {
1922 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001923 }
1924 }
1925
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001926 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001927 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1928 errors,
1929 "PYTHONIOENCODING environment variable");
1930 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001931 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001932 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001933 }
1934 }
1935
1936 PyMem_RawFree(pythonioencoding);
1937 }
1938
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001939 /* Choose the default error handler based on the current locale. */
1940 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001941 status = config_get_locale_encoding(config, preconfig,
1942 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001943 if (_PyStatus_EXCEPTION(status)) {
1944 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001945 }
1946 }
1947 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001948 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001949 assert(errors != NULL);
1950
Victor Stinner331a6a52019-05-27 16:39:22 +02001951 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1952 if (_PyStatus_EXCEPTION(status)) {
1953 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001954 }
1955 }
1956
Victor Stinner331a6a52019-05-27 16:39:22 +02001957 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001958}
1959
1960
Victor Stinner710e8262020-10-31 01:02:09 +01001961// See also config_get_locale_encoding()
1962static PyStatus
1963config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1964 wchar_t **fs_encoding)
1965{
1966#ifdef _Py_FORCE_UTF8_FS_ENCODING
1967 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1968#elif defined(MS_WINDOWS)
1969 const wchar_t *encoding;
1970 if (preconfig->legacy_windows_fs_encoding) {
1971 // Legacy Windows filesystem encoding: mbcs/replace
1972 encoding = L"mbcs";
1973 }
1974 else {
1975 // Windows defaults to utf-8/surrogatepass (PEP 529)
1976 encoding = L"utf-8";
1977 }
1978 return PyConfig_SetString(config, fs_encoding, encoding);
1979#else // !MS_WINDOWS
1980 if (preconfig->utf8_mode) {
1981 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1982 }
Victor Stinner35297182020-11-04 11:20:10 +01001983
1984 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01001985 return PyConfig_SetString(config, fs_encoding, L"ascii");
1986 }
Victor Stinner35297182020-11-04 11:20:10 +01001987
1988 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01001989#endif // !MS_WINDOWS
1990}
1991
1992
Victor Stinner331a6a52019-05-27 16:39:22 +02001993static PyStatus
1994config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001995{
Victor Stinner331a6a52019-05-27 16:39:22 +02001996 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001997
Victor Stinnerb2457ef2018-08-29 13:25:36 +02001998 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001999 status = config_get_fs_encoding(config, preconfig,
2000 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02002001 if (_PyStatus_EXCEPTION(status)) {
2002 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002003 }
2004 }
2005
2006 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002007 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04002008#ifdef MS_WINDOWS
2009 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002010 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04002011 }
2012 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04002013 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04002014 }
2015#else
Victor Stinner709d23d2019-05-02 14:56:30 -04002016 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04002017#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02002018 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2019 if (_PyStatus_EXCEPTION(status)) {
2020 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002021 }
2022 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002024}
2025
2026
Victor Stinner331a6a52019-05-27 16:39:22 +02002027static PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002028config_read(PyConfig *config, int compute_path_config)
Victor Stinner6c785c02018-08-01 17:56:14 +02002029{
Victor Stinner331a6a52019-05-27 16:39:22 +02002030 PyStatus status;
2031 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01002032
Victor Stinner20004952019-03-26 02:31:11 +01002033 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002034 status = config_read_env_vars(config);
2035 if (_PyStatus_EXCEPTION(status)) {
2036 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002037 }
2038 }
2039
2040 /* -X options */
2041 if (config_get_xoption(config, L"showrefcount")) {
2042 config->show_ref_count = 1;
2043 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002044
Victor Stinner331a6a52019-05-27 16:39:22 +02002045 status = config_read_complex_options(config);
2046 if (_PyStatus_EXCEPTION(status)) {
2047 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002048 }
2049
Victor Stinner6c785c02018-08-01 17:56:14 +02002050 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002051 status = config_init_home(config);
2052 if (_PyStatus_EXCEPTION(status)) {
2053 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002054 }
2055 }
2056
Steve Dower177a41a2018-11-17 20:41:48 -08002057 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 status = config_init_executable(config);
2059 if (_PyStatus_EXCEPTION(status)) {
2060 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08002061 }
2062 }
2063
Sandro Mani8f023a22020-06-08 17:28:11 +02002064 if(config->platlibdir == NULL) {
2065 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
2066 "PLATLIBDIR macro");
2067 if (_PyStatus_EXCEPTION(status)) {
2068 return status;
2069 }
2070 }
2071
Victor Stinnerace3f9a2020-11-10 21:10:22 +01002072 if (config->_install_importlib) {
2073 status = _PyConfig_InitPathConfig(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002074 if (_PyStatus_EXCEPTION(status)) {
2075 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002076 }
2077 }
2078
2079 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01002080 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02002081 if (config->faulthandler < 0) {
2082 config->faulthandler = 1;
2083 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002084 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002085 if (config->faulthandler < 0) {
2086 config->faulthandler = 0;
2087 }
2088 if (config->tracemalloc < 0) {
2089 config->tracemalloc = 0;
2090 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002091 if (config->use_hash_seed < 0) {
2092 config->use_hash_seed = 0;
2093 config->hash_seed = 0;
2094 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002095
Victor Stinner70fead22018-08-29 13:45:34 +02002096 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002097 status = config_init_fs_encoding(config, preconfig);
2098 if (_PyStatus_EXCEPTION(status)) {
2099 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002100 }
2101 }
2102
Victor Stinner331a6a52019-05-27 16:39:22 +02002103 status = config_init_stdio_encoding(config, preconfig);
2104 if (_PyStatus_EXCEPTION(status)) {
2105 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02002106 }
2107
Victor Stinner62599762019-03-15 16:03:23 +01002108 if (config->argv.length < 1) {
2109 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002110 status = PyWideStringList_Append(&config->argv, L"");
2111 if (_PyStatus_EXCEPTION(status)) {
2112 return status;
Victor Stinner62599762019-03-15 16:03:23 +01002113 }
2114 }
Victor Stinner870b0352019-05-17 03:15:12 +02002115
2116 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002117 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2118 L"default");
2119 if (_PyStatus_EXCEPTION(status)) {
2120 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002121 }
2122 }
2123
2124 if (config->configure_c_stdio < 0) {
2125 config->configure_c_stdio = 1;
2126 }
2127
Victor Stinnerdc42af82020-11-05 18:58:07 +01002128 // Only parse arguments once.
2129 if (config->parse_argv == 1) {
2130 config->parse_argv = 2;
2131 }
2132
Victor Stinner331a6a52019-05-27 16:39:22 +02002133 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02002134}
Victor Stinner5ed69952018-11-06 15:59:52 +01002135
2136
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002137static void
Victor Stinner331a6a52019-05-27 16:39:22 +02002138config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002139{
2140#if defined(MS_WINDOWS) || defined(__CYGWIN__)
2141 /* don't translate newlines (\r\n <=> \n) */
2142 _setmode(fileno(stdin), O_BINARY);
2143 _setmode(fileno(stdout), O_BINARY);
2144 _setmode(fileno(stderr), O_BINARY);
2145#endif
2146
2147 if (!config->buffered_stdio) {
2148#ifdef HAVE_SETVBUF
2149 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2150 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2151 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2152#else /* !HAVE_SETVBUF */
2153 setbuf(stdin, (char *)NULL);
2154 setbuf(stdout, (char *)NULL);
2155 setbuf(stderr, (char *)NULL);
2156#endif /* !HAVE_SETVBUF */
2157 }
2158 else if (config->interactive) {
2159#ifdef MS_WINDOWS
2160 /* Doesn't have to have line-buffered -- use unbuffered */
2161 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2162 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2163#else /* !MS_WINDOWS */
2164#ifdef HAVE_SETVBUF
2165 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2166 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2167#endif /* HAVE_SETVBUF */
2168#endif /* !MS_WINDOWS */
2169 /* Leave stderr alone - it should be unbuffered anyway. */
2170 }
2171}
2172
2173
2174/* Write the configuration:
2175
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002176 - set Py_xxx global configuration variables
2177 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02002178PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02002179_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002180{
Victor Stinner331a6a52019-05-27 16:39:22 +02002181 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002182
2183 if (config->configure_c_stdio) {
2184 config_init_stdio(config);
2185 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002186
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002187 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02002188 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002189 preconfig->isolated = config->isolated;
2190 preconfig->use_environment = config->use_environment;
2191 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02002192
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002193 if (_Py_SetArgcArgv(config->orig_argv.length,
2194 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02002195 {
2196 return _PyStatus_NO_MEMORY();
2197 }
2198 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01002199}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002200
2201
Victor Stinner331a6a52019-05-27 16:39:22 +02002202/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002203
2204static void
Victor Stinner2f549082019-03-29 15:13:46 +01002205config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002206{
Victor Stinner2f549082019-03-29 15:13:46 +01002207 FILE *f = error ? stderr : stdout;
2208
2209 fprintf(f, usage_line, program);
2210 if (error)
2211 fprintf(f, "Try `python -h' for more information.\n");
2212 else {
2213 fputs(usage_1, f);
2214 fputs(usage_2, f);
2215 fputs(usage_3, f);
2216 fprintf(f, usage_4, (wint_t)DELIM);
2217 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
2218 fputs(usage_6, f);
2219 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002220}
2221
2222
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002223/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02002224static PyStatus
2225config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02002226 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002227{
Victor Stinner331a6a52019-05-27 16:39:22 +02002228 PyStatus status;
2229 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01002230 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02002231 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01002232
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002233 _PyOS_ResetGetOpt();
2234 do {
2235 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01002236 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002237 if (c == EOF) {
2238 break;
2239 }
2240
2241 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002242 if (config->run_command == NULL) {
2243 /* -c is the last option; following arguments
2244 that look like options are left for the
2245 command to interpret. */
2246 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2247 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2248 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002249 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002250 }
2251 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2252 command[len - 2] = '\n';
2253 command[len - 1] = 0;
2254 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002255 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002256 break;
2257 }
2258
2259 if (c == 'm') {
2260 /* -m is the last option; following arguments
2261 that look like options are left for the
2262 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002263 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002264 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2265 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002266 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002267 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002268 }
2269 break;
2270 }
2271
2272 switch (c) {
2273 case 0:
2274 // Handle long option.
2275 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002276 if (wcscmp(_PyOS_optarg, L"always") == 0
2277 || wcscmp(_PyOS_optarg, L"never") == 0
2278 || wcscmp(_PyOS_optarg, L"default") == 0)
2279 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002280 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2281 _PyOS_optarg);
2282 if (_PyStatus_EXCEPTION(status)) {
2283 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002284 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002285 } else {
2286 fprintf(stderr, "--check-hash-based-pycs must be one of "
2287 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02002288 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002289 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002290 }
2291 break;
2292
2293 case 'b':
2294 config->bytes_warning++;
2295 break;
2296
2297 case 'd':
2298 config->parser_debug++;
2299 break;
2300
2301 case 'i':
2302 config->inspect++;
2303 config->interactive++;
2304 break;
2305
Victor Stinner6dcb5422019-03-05 02:44:12 +01002306 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002307 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01002308 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002309 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002310 break;
2311
2312 /* case 'J': reserved for Jython */
2313
2314 case 'O':
2315 config->optimization_level++;
2316 break;
2317
2318 case 'B':
2319 config->write_bytecode = 0;
2320 break;
2321
2322 case 's':
2323 config->user_site_directory = 0;
2324 break;
2325
2326 case 'S':
2327 config->site_import = 0;
2328 break;
2329
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002330 case 't':
2331 /* ignored for backwards compatibility */
2332 break;
2333
2334 case 'u':
2335 config->buffered_stdio = 0;
2336 break;
2337
2338 case 'v':
2339 config->verbose++;
2340 break;
2341
2342 case 'x':
2343 config->skip_source_first_line = 1;
2344 break;
2345
2346 case 'h':
2347 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002348 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002349 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002350
2351 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002352 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002353 break;
2354
2355 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002356 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2357 if (_PyStatus_EXCEPTION(status)) {
2358 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002359 }
2360 break;
2361
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002362 case 'q':
2363 config->quiet++;
2364 break;
2365
2366 case 'R':
2367 config->use_hash_seed = 0;
2368 break;
2369
2370 /* This space reserved for other options */
2371
2372 default:
2373 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002374 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002375 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002376 }
2377 } while (1);
2378
Victor Stinner2f549082019-03-29 15:13:46 +01002379 if (print_version) {
2380 printf("Python %s\n",
2381 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002382 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002383 }
2384
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002385 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002386 && _PyOS_optind < argv->length
2387 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002388 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002389 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002390 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002391 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002392 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002393 }
2394 }
2395
2396 if (config->run_command != NULL || config->run_module != NULL) {
2397 /* Backup _PyOS_optind */
2398 _PyOS_optind--;
2399 }
2400
Victor Stinnerae239f62019-05-16 17:02:56 +02002401 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002402
Victor Stinner331a6a52019-05-27 16:39:22 +02002403 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002404}
2405
2406
2407#ifdef MS_WINDOWS
2408# define WCSTOK wcstok_s
2409#else
2410# define WCSTOK wcstok
2411#endif
2412
2413/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002414static PyStatus
2415config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002416{
Victor Stinner331a6a52019-05-27 16:39:22 +02002417 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002418 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2419 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002420 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002421 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002422 if (_PyStatus_EXCEPTION(status)) {
2423 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002424 }
2425
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002426 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002427 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002428 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002429 }
2430
2431
2432 wchar_t *warning, *context = NULL;
2433 for (warning = WCSTOK(env, L",", &context);
2434 warning != NULL;
2435 warning = WCSTOK(NULL, L",", &context))
2436 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002437 status = PyWideStringList_Append(warnoptions, warning);
2438 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002439 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002441 }
2442 }
2443 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002444 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002445}
2446
2447
Victor Stinner331a6a52019-05-27 16:39:22 +02002448static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002449warnoptions_append(PyConfig *config, PyWideStringList *options,
2450 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002451{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002452 /* config_init_warnoptions() add existing config warnoptions at the end:
2453 ensure that the new option is not already present in this list to
2454 prevent change the options order whne config_init_warnoptions() is
2455 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002456 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002457 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002458 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002459 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002460 if (_PyWideStringList_Find(options, option)) {
2461 /* Already present: do nothing */
2462 return _PyStatus_OK();
2463 }
2464 return PyWideStringList_Append(options, option);
2465}
2466
2467
2468static PyStatus
2469warnoptions_extend(PyConfig *config, PyWideStringList *options,
2470 const PyWideStringList *options2)
2471{
2472 const Py_ssize_t len = options2->length;
2473 wchar_t *const *items = options2->items;
2474
2475 for (Py_ssize_t i = 0; i < len; i++) {
2476 PyStatus status = warnoptions_append(config, options, items[i]);
2477 if (_PyStatus_EXCEPTION(status)) {
2478 return status;
2479 }
2480 }
2481 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002482}
2483
2484
Victor Stinner331a6a52019-05-27 16:39:22 +02002485static PyStatus
2486config_init_warnoptions(PyConfig *config,
2487 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002488 const PyWideStringList *env_warnoptions,
2489 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002490{
Victor Stinner331a6a52019-05-27 16:39:22 +02002491 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002492 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002493
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002494 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002495 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002496 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002497 * - PyConfig.dev_mode: "default" filter
2498 * - PYTHONWARNINGS environment variable
2499 * - '-W' command line options
2500 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2501 * "default::BytesWarning" or "error::BytesWarning" filter
2502 * - early PySys_AddWarnOption() calls
2503 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002504 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002505 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2506 * module works on the basis of "the most recently added filter will be
2507 * checked first", we add the lowest precedence entries first so that later
2508 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002509 */
2510
Victor Stinner20004952019-03-26 02:31:11 +01002511 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002512 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002513 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002514 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002515 }
2516 }
2517
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002518 status = warnoptions_extend(config, &options, env_warnoptions);
2519 if (_PyStatus_EXCEPTION(status)) {
2520 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002521 }
2522
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002523 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2524 if (_PyStatus_EXCEPTION(status)) {
2525 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002526 }
2527
2528 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2529 * don't even try to emit a warning, so we skip setting the filter in that
2530 * case.
2531 */
2532 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002533 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002534 if (config->bytes_warning> 1) {
2535 filter = L"error::BytesWarning";
2536 }
2537 else {
2538 filter = L"default::BytesWarning";
2539 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002540 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002541 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002542 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002543 }
2544 }
Victor Stinner120b7072019-08-23 18:03:08 +01002545
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002546 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002547 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002548 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002549 }
2550
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002551 /* Always add all PyConfig.warnoptions options */
2552 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2553 if (_PyStatus_EXCEPTION(status)) {
2554 goto error;
2555 }
2556
2557 _PyWideStringList_Clear(&config->warnoptions);
2558 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002559 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002560
2561error:
2562 _PyWideStringList_Clear(&options);
2563 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002564}
2565
2566
Victor Stinner331a6a52019-05-27 16:39:22 +02002567static PyStatus
2568config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002569{
Victor Stinner331a6a52019-05-27 16:39:22 +02002570 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002571 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002572
Victor Stinner74f65682019-03-15 15:08:05 +01002573 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002574 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002575 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002576 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2577 if (_PyStatus_EXCEPTION(status)) {
2578 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002579 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002580 }
2581 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002582 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002583 slice.length = cmdline_argv->length - opt_index;
2584 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002585 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2586 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002587 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002588 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002589 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002590
2591 wchar_t *arg0 = NULL;
2592 if (config->run_command != NULL) {
2593 /* Force sys.argv[0] = '-c' */
2594 arg0 = L"-c";
2595 }
2596 else if (config->run_module != NULL) {
2597 /* Force sys.argv[0] = '-m'*/
2598 arg0 = L"-m";
2599 }
Victor Stinner3939c322019-06-25 15:02:43 +02002600
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002601 if (arg0 != NULL) {
2602 arg0 = _PyMem_RawWcsdup(arg0);
2603 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002604 _PyWideStringList_Clear(&config_argv);
2605 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002606 }
2607
Victor Stinnerfa153762019-03-20 04:25:38 +01002608 PyMem_RawFree(config_argv.items[0]);
2609 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002610 }
2611
Victor Stinner331a6a52019-05-27 16:39:22 +02002612 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002613 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002614 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002615}
2616
2617
Victor Stinner331a6a52019-05-27 16:39:22 +02002618static PyStatus
2619core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002620{
Victor Stinner331a6a52019-05-27 16:39:22 +02002621 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002622
Victor Stinnerdc42af82020-11-05 18:58:07 +01002623 if (config->parse_argv == 1) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002624 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2625 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002626 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002627 }
2628
Victor Stinner331a6a52019-05-27 16:39:22 +02002629 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002630
2631 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2632 if (_PyStatus_EXCEPTION(status)) {
2633 return status;
2634 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002635
Victor Stinner331a6a52019-05-27 16:39:22 +02002636 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002637
Victor Stinner331a6a52019-05-27 16:39:22 +02002638 status = _PyPreCmdline_Read(precmdline, &preconfig);
2639 if (_PyStatus_EXCEPTION(status)) {
2640 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002641 }
2642
Victor Stinner331a6a52019-05-27 16:39:22 +02002643 status = _PyPreCmdline_SetConfig(precmdline, config);
2644 if (_PyStatus_EXCEPTION(status)) {
2645 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002646 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002647 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002648}
2649
2650
Victor Stinner3939c322019-06-25 15:02:43 +02002651/* Get run_filename absolute path */
2652static PyStatus
2653config_run_filename_abspath(PyConfig *config)
2654{
2655 if (!config->run_filename) {
2656 return _PyStatus_OK();
2657 }
2658
2659#ifndef MS_WINDOWS
2660 if (_Py_isabs(config->run_filename)) {
2661 /* path is already absolute */
2662 return _PyStatus_OK();
2663 }
2664#endif
2665
2666 wchar_t *abs_filename;
2667 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2668 /* failed to get the absolute path of the command line filename:
2669 ignore the error, keep the relative path */
2670 return _PyStatus_OK();
2671 }
2672 if (abs_filename == NULL) {
2673 return _PyStatus_NO_MEMORY();
2674 }
2675
2676 PyMem_RawFree(config->run_filename);
2677 config->run_filename = abs_filename;
2678 return _PyStatus_OK();
2679}
2680
2681
Victor Stinner331a6a52019-05-27 16:39:22 +02002682static PyStatus
2683config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002684{
Victor Stinner331a6a52019-05-27 16:39:22 +02002685 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002686 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2687 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2688 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002689
Victor Stinnerae239f62019-05-16 17:02:56 +02002690 if (config->parse_argv < 0) {
2691 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002692 }
Victor Stinner870b0352019-05-17 03:15:12 +02002693
Victor Stinnerfed02e12019-05-17 11:12:09 +02002694 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002695 status = config_init_program_name(config);
2696 if (_PyStatus_EXCEPTION(status)) {
2697 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002698 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002699 }
Victor Stinner2f549082019-03-29 15:13:46 +01002700
Victor Stinnerdc42af82020-11-05 18:58:07 +01002701 if (config->parse_argv == 1) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002702 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002703 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2704 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002705 goto done;
2706 }
2707
Victor Stinner3939c322019-06-25 15:02:43 +02002708 status = config_run_filename_abspath(config);
2709 if (_PyStatus_EXCEPTION(status)) {
2710 goto done;
2711 }
2712
Victor Stinner331a6a52019-05-27 16:39:22 +02002713 status = config_update_argv(config, opt_index);
2714 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002715 goto done;
2716 }
Victor Stinner2f549082019-03-29 15:13:46 +01002717 }
Victor Stinner3939c322019-06-25 15:02:43 +02002718 else {
2719 status = config_run_filename_abspath(config);
2720 if (_PyStatus_EXCEPTION(status)) {
2721 goto done;
2722 }
2723 }
Victor Stinner2f549082019-03-29 15:13:46 +01002724
Victor Stinner2f549082019-03-29 15:13:46 +01002725 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002726 status = config_init_env_warnoptions(config, &env_warnoptions);
2727 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002728 goto done;
2729 }
2730 }
2731
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002732 /* Handle early PySys_AddWarnOption() calls */
2733 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2734 if (_PyStatus_EXCEPTION(status)) {
2735 goto done;
2736 }
2737
Victor Stinner331a6a52019-05-27 16:39:22 +02002738 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002739 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002740 &env_warnoptions,
2741 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002742 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002743 goto done;
2744 }
2745
Victor Stinner331a6a52019-05-27 16:39:22 +02002746 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002747
2748done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002749 _PyWideStringList_Clear(&cmdline_warnoptions);
2750 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002751 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002752 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002753}
2754
2755
Victor Stinner331a6a52019-05-27 16:39:22 +02002756PyStatus
2757_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002758{
Victor Stinner331a6a52019-05-27 16:39:22 +02002759 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2760 if (_PyStatus_EXCEPTION(status)) {
2761 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002762 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002763
Victor Stinner5f38b842019-05-01 02:30:12 +02002764 return _PyArgv_AsWstrList(args, &config->argv);
2765}
2766
2767
Victor Stinner70005ac2019-05-02 15:25:34 -04002768/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2769 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002770PyStatus
2771PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002772{
2773 _PyArgv args = {
2774 .argc = argc,
2775 .use_bytes_argv = 1,
2776 .bytes_argv = argv,
2777 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002778 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002779}
2780
2781
Victor Stinner331a6a52019-05-27 16:39:22 +02002782PyStatus
2783PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002784{
2785 _PyArgv args = {
2786 .argc = argc,
2787 .use_bytes_argv = 0,
2788 .bytes_argv = NULL,
2789 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002790 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002791}
2792
2793
Victor Stinner36242fd2019-07-01 19:13:50 +02002794PyStatus
2795PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2796 Py_ssize_t length, wchar_t **items)
2797{
2798 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2799 if (_PyStatus_EXCEPTION(status)) {
2800 return status;
2801 }
2802
2803 PyWideStringList list2 = {.length = length, .items = items};
2804 if (_PyWideStringList_Copy(list, &list2) < 0) {
2805 return _PyStatus_NO_MEMORY();
2806 }
2807 return _PyStatus_OK();
2808}
2809
2810
Victor Stinner331a6a52019-05-27 16:39:22 +02002811/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002812
2813 * Command line arguments
2814 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002815 * Py_xxx global configuration variables
2816
2817 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002818PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002819_PyConfig_Read(PyConfig *config, int compute_path_config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002820{
Victor Stinner331a6a52019-05-27 16:39:22 +02002821 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002822
Victor Stinner331a6a52019-05-27 16:39:22 +02002823 status = _Py_PreInitializeFromConfig(config, NULL);
2824 if (_PyStatus_EXCEPTION(status)) {
2825 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002826 }
2827
Victor Stinner331a6a52019-05-27 16:39:22 +02002828 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002829
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002830 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002831 && !(config->argv.length == 1
2832 && wcscmp(config->argv.items[0], L"") == 0))
2833 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002834 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002835 return _PyStatus_NO_MEMORY();
2836 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002837 }
2838
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002839 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002840 status = core_read_precmdline(config, &precmdline);
2841 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002842 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002843 }
2844
Victor Stinner870b0352019-05-17 03:15:12 +02002845 assert(config->isolated >= 0);
2846 if (config->isolated) {
2847 config->use_environment = 0;
2848 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002849 }
2850
Victor Stinner331a6a52019-05-27 16:39:22 +02002851 status = config_read_cmdline(config);
2852 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002853 goto done;
2854 }
2855
Victor Stinner120b7072019-08-23 18:03:08 +01002856 /* Handle early PySys_AddXOption() calls */
2857 status = _PySys_ReadPreinitXOptions(config);
2858 if (_PyStatus_EXCEPTION(status)) {
2859 goto done;
2860 }
2861
Victor Stinner9e1b8282020-11-10 13:21:52 +01002862 status = config_read(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002863 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002864 goto done;
2865 }
2866
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002867 assert(config_check_consistency(config));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002868
Victor Stinner331a6a52019-05-27 16:39:22 +02002869 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002870
2871done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002872 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002873 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002874}
Victor Stinner1075d162019-03-25 23:19:57 +01002875
2876
Victor Stinner9e1b8282020-11-10 13:21:52 +01002877PyStatus
2878PyConfig_Read(PyConfig *config)
2879{
2880 return _PyConfig_Read(config, 1);
2881}
2882
2883
Victor Stinner1075d162019-03-25 23:19:57 +01002884PyObject*
2885_Py_GetConfigsAsDict(void)
2886{
Victor Stinner331a6a52019-05-27 16:39:22 +02002887 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002888 PyObject *dict = NULL;
2889
Victor Stinner331a6a52019-05-27 16:39:22 +02002890 result = PyDict_New();
2891 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002892 goto error;
2893 }
2894
Victor Stinner331a6a52019-05-27 16:39:22 +02002895 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002896 dict = _Py_GetGlobalVariablesAsDict();
2897 if (dict == NULL) {
2898 goto error;
2899 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002900 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002901 goto error;
2902 }
2903 Py_CLEAR(dict);
2904
2905 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002906 PyThreadState *tstate = _PyThreadState_GET();
2907 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002908 dict = _PyPreConfig_AsDict(pre_config);
2909 if (dict == NULL) {
2910 goto error;
2911 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002912 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002913 goto error;
2914 }
2915 Py_CLEAR(dict);
2916
2917 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002918 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002919 dict = _PyConfig_AsDict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002920 if (dict == NULL) {
2921 goto error;
2922 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002923 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002924 goto error;
2925 }
2926 Py_CLEAR(dict);
2927
Victor Stinner8f427482020-07-08 00:20:37 +02002928 /* path config */
2929 dict = _PyPathConfig_AsDict();
2930 if (dict == NULL) {
2931 goto error;
2932 }
2933 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2934 goto error;
2935 }
2936 Py_CLEAR(dict);
2937
Victor Stinner331a6a52019-05-27 16:39:22 +02002938 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002939
2940error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002941 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002942 Py_XDECREF(dict);
2943 return NULL;
2944}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002945
2946
2947static void
2948init_dump_ascii_wstr(const wchar_t *str)
2949{
2950 if (str == NULL) {
2951 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002952 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002953 }
2954
2955 PySys_WriteStderr("'");
2956 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002957 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002958 if (ch == L'\'') {
2959 PySys_WriteStderr("\\'");
2960 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002961 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002962 }
2963 else if (ch <= 0xff) {
2964 PySys_WriteStderr("\\x%02x", ch);
2965 }
2966#if SIZEOF_WCHAR_T > 2
2967 else if (ch > 0xffff) {
2968 PySys_WriteStderr("\\U%08x", ch);
2969 }
2970#endif
2971 else {
2972 PySys_WriteStderr("\\u%04x", ch);
2973 }
2974 }
2975 PySys_WriteStderr("'");
2976}
2977
2978
2979/* Dump the Python path configuration into sys.stderr */
2980void
2981_Py_DumpPathConfig(PyThreadState *tstate)
2982{
2983 PyObject *exc_type, *exc_value, *exc_tb;
2984 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2985
2986 PySys_WriteStderr("Python path configuration:\n");
2987
2988#define DUMP_CONFIG(NAME, FIELD) \
2989 do { \
2990 PySys_WriteStderr(" " NAME " = "); \
2991 init_dump_ascii_wstr(config->FIELD); \
2992 PySys_WriteStderr("\n"); \
2993 } while (0)
2994
Victor Stinnerda7933e2020-04-13 03:04:28 +02002995 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002996 DUMP_CONFIG("PYTHONHOME", home);
2997 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
2998 DUMP_CONFIG("program name", program_name);
2999 PySys_WriteStderr(" isolated = %i\n", config->isolated);
3000 PySys_WriteStderr(" environment = %i\n", config->use_environment);
3001 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3002 PySys_WriteStderr(" import site = %i\n", config->site_import);
3003#undef DUMP_CONFIG
3004
3005#define DUMP_SYS(NAME) \
3006 do { \
3007 obj = PySys_GetObject(#NAME); \
3008 PySys_FormatStderr(" sys.%s = ", #NAME); \
3009 if (obj != NULL) { \
3010 PySys_FormatStderr("%A", obj); \
3011 } \
3012 else { \
3013 PySys_WriteStderr("(not set)"); \
3014 } \
3015 PySys_FormatStderr("\n"); \
3016 } while (0)
3017
3018 PyObject *obj;
3019 DUMP_SYS(_base_executable);
3020 DUMP_SYS(base_prefix);
3021 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02003022 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003023 DUMP_SYS(executable);
3024 DUMP_SYS(prefix);
3025 DUMP_SYS(exec_prefix);
3026#undef DUMP_SYS
3027
3028 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3029 if (sys_path != NULL && PyList_Check(sys_path)) {
3030 PySys_WriteStderr(" sys.path = [\n");
3031 Py_ssize_t len = PyList_GET_SIZE(sys_path);
3032 for (Py_ssize_t i=0; i < len; i++) {
3033 PyObject *path = PyList_GET_ITEM(sys_path, i);
3034 PySys_FormatStderr(" %A,\n", path);
3035 }
3036 PySys_WriteStderr(" ]\n");
3037 }
3038
3039 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3040}