blob: e0811b56cb374e83542b7aabbe7864742400632f [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);
622 if (config->_install_importlib) {
623 /* don't check config->module_search_paths */
624 assert(config->executable != NULL);
625 assert(config->base_executable != NULL);
626 assert(config->prefix != NULL);
627 assert(config->base_prefix != NULL);
628 assert(config->exec_prefix != NULL);
629 assert(config->base_exec_prefix != NULL);
630 }
631 assert(config->platlibdir != NULL);
632 assert(config->filesystem_encoding != NULL);
633 assert(config->filesystem_errors != NULL);
634 assert(config->stdio_encoding != NULL);
635 assert(config->stdio_errors != NULL);
636#ifdef MS_WINDOWS
637 assert(config->legacy_windows_stdio >= 0);
638#endif
639 /* -c and -m options are exclusive */
640 assert(!(config->run_command != NULL && config->run_module != NULL));
641 assert(config->check_hash_pycs_mode != NULL);
642 assert(config->_install_importlib >= 0);
643 assert(config->pathconfig_warnings >= 0);
644 return 1;
645}
646#endif
647
Victor Stinner441b10c2019-09-28 04:28:35 +0200648
Victor Stinner6c785c02018-08-01 17:56:14 +0200649/* Free memory allocated in config, but don't clear all attributes */
650void
Victor Stinner331a6a52019-05-27 16:39:22 +0200651PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200652{
653#define CLEAR(ATTR) \
654 do { \
655 PyMem_RawFree(ATTR); \
656 ATTR = NULL; \
657 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200658
659 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200660 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200661 CLEAR(config->home);
662 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200663
Victor Stinner331a6a52019-05-27 16:39:22 +0200664 _PyWideStringList_Clear(&config->argv);
665 _PyWideStringList_Clear(&config->warnoptions);
666 _PyWideStringList_Clear(&config->xoptions);
667 _PyWideStringList_Clear(&config->module_search_paths);
668 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200669
670 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700671 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200672 CLEAR(config->prefix);
673 CLEAR(config->base_prefix);
674 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200675 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200676 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200677
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200678 CLEAR(config->filesystem_encoding);
679 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200680 CLEAR(config->stdio_encoding);
681 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100682 CLEAR(config->run_command);
683 CLEAR(config->run_module);
684 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400685 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200686
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200687 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200688#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200689}
690
691
Victor Stinner8462a492019-10-01 12:06:16 +0200692void
Victor Stinner331a6a52019-05-27 16:39:22 +0200693_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200694{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200695 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200696
Victor Stinner022be022019-05-22 23:58:50 +0200697 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200698 config->isolated = -1;
699 config->use_environment = -1;
700 config->dev_mode = -1;
701 config->install_signal_handlers = 1;
702 config->use_hash_seed = -1;
703 config->faulthandler = -1;
704 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200705 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200706 config->parse_argv = 0;
707 config->site_import = -1;
708 config->bytes_warning = -1;
709 config->inspect = -1;
710 config->interactive = -1;
711 config->optimization_level = -1;
712 config->parser_debug= -1;
713 config->write_bytecode = -1;
714 config->verbose = -1;
715 config->quiet = -1;
716 config->user_site_directory = -1;
717 config->configure_c_stdio = 0;
718 config->buffered_stdio = -1;
719 config->_install_importlib = 1;
720 config->check_hash_pycs_mode = NULL;
721 config->pathconfig_warnings = -1;
722 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200723 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200724#ifdef MS_WINDOWS
725 config->legacy_windows_stdio = -1;
726#endif
727}
728
729
Victor Stinner8462a492019-10-01 12:06:16 +0200730static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200731config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200732{
Victor Stinner8462a492019-10-01 12:06:16 +0200733 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200734
735 config->isolated = 0;
736 config->use_environment = 1;
737 config->site_import = 1;
738 config->bytes_warning = 0;
739 config->inspect = 0;
740 config->interactive = 0;
741 config->optimization_level = 0;
742 config->parser_debug= 0;
743 config->write_bytecode = 1;
744 config->verbose = 0;
745 config->quiet = 0;
746 config->user_site_directory = 1;
747 config->buffered_stdio = 1;
748 config->pathconfig_warnings = 1;
749#ifdef MS_WINDOWS
750 config->legacy_windows_stdio = 0;
751#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200752}
753
754
Victor Stinner8462a492019-10-01 12:06:16 +0200755void
Victor Stinner331a6a52019-05-27 16:39:22 +0200756PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200757{
Victor Stinner8462a492019-10-01 12:06:16 +0200758 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200759
Victor Stinner022be022019-05-22 23:58:50 +0200760 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200761 config->configure_c_stdio = 1;
762 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200763}
764
765
Victor Stinner8462a492019-10-01 12:06:16 +0200766void
Victor Stinner331a6a52019-05-27 16:39:22 +0200767PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200768{
Victor Stinner8462a492019-10-01 12:06:16 +0200769 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200770
Victor Stinner022be022019-05-22 23:58:50 +0200771 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200772 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200773 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200774 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200775 config->dev_mode = 0;
776 config->install_signal_handlers = 0;
777 config->use_hash_seed = 0;
778 config->faulthandler = 0;
779 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200780 config->pathconfig_warnings = 0;
781#ifdef MS_WINDOWS
782 config->legacy_windows_stdio = 0;
783#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200784}
785
786
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200787/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200788PyStatus
789PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200790{
Victor Stinner331a6a52019-05-27 16:39:22 +0200791 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
792 if (_PyStatus_EXCEPTION(status)) {
793 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200794 }
795
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200796 wchar_t *str2;
797 if (str != NULL) {
798 str2 = _PyMem_RawWcsdup(str);
799 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200800 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200801 }
802 }
803 else {
804 str2 = NULL;
805 }
806 PyMem_RawFree(*config_str);
807 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200808 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200809}
810
811
Victor Stinner331a6a52019-05-27 16:39:22 +0200812static PyStatus
813config_set_bytes_string(PyConfig *config, wchar_t **config_str,
814 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200815{
Victor Stinner331a6a52019-05-27 16:39:22 +0200816 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
817 if (_PyStatus_EXCEPTION(status)) {
818 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400819 }
820
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200821 wchar_t *str2;
822 if (str != NULL) {
823 size_t len;
824 str2 = Py_DecodeLocale(str, &len);
825 if (str2 == NULL) {
826 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200827 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200828 }
829 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200830 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200831 }
832 }
833 }
834 else {
835 str2 = NULL;
836 }
837 PyMem_RawFree(*config_str);
838 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200839 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200840}
841
842
Victor Stinner331a6a52019-05-27 16:39:22 +0200843#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
844 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400845
846
Victor Stinner70005ac2019-05-02 15:25:34 -0400847/* Decode str using Py_DecodeLocale() and set the result into *config_str.
848 Pre-initialize Python if needed to ensure that encodings are properly
849 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200850PyStatus
851PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100852 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400853{
Victor Stinner331a6a52019-05-27 16:39:22 +0200854 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400855}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200856
857
Victor Stinner331a6a52019-05-27 16:39:22 +0200858PyStatus
859_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200860{
Victor Stinner331a6a52019-05-27 16:39:22 +0200861 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200862
Victor Stinner331a6a52019-05-27 16:39:22 +0200863 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200864
865#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200866#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200867 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200868 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
869 if (_PyStatus_EXCEPTION(status)) { \
870 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200871 } \
872 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100873#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200874 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200875 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200876 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200877 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200878 } while (0)
879
Victor Stinner6d1c4672019-05-20 11:02:00 +0200880 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100881 COPY_ATTR(isolated);
882 COPY_ATTR(use_environment);
883 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200884 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200885 COPY_ATTR(use_hash_seed);
886 COPY_ATTR(hash_seed);
887 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200888 COPY_ATTR(faulthandler);
889 COPY_ATTR(tracemalloc);
890 COPY_ATTR(import_time);
891 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200892 COPY_ATTR(dump_refs);
893 COPY_ATTR(malloc_stats);
894
Victor Stinner124b9eb2018-08-29 01:29:06 +0200895 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200897 COPY_WSTR_ATTR(home);
898 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200899
Victor Stinnerae239f62019-05-16 17:02:56 +0200900 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100901 COPY_WSTRLIST(argv);
902 COPY_WSTRLIST(warnoptions);
903 COPY_WSTRLIST(xoptions);
904 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200905 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200906
Victor Stinner124b9eb2018-08-29 01:29:06 +0200907 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700908 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200909 COPY_WSTR_ATTR(prefix);
910 COPY_WSTR_ATTR(base_prefix);
911 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200912 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200913 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200914
Victor Stinner6c785c02018-08-01 17:56:14 +0200915 COPY_ATTR(site_import);
916 COPY_ATTR(bytes_warning);
917 COPY_ATTR(inspect);
918 COPY_ATTR(interactive);
919 COPY_ATTR(optimization_level);
920 COPY_ATTR(parser_debug);
921 COPY_ATTR(write_bytecode);
922 COPY_ATTR(verbose);
923 COPY_ATTR(quiet);
924 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200925 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200926 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400927 COPY_WSTR_ATTR(filesystem_encoding);
928 COPY_WSTR_ATTR(filesystem_errors);
929 COPY_WSTR_ATTR(stdio_encoding);
930 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200931#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200932 COPY_ATTR(legacy_windows_stdio);
933#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100934 COPY_ATTR(skip_source_first_line);
935 COPY_WSTR_ATTR(run_command);
936 COPY_WSTR_ATTR(run_module);
937 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400938 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200939 COPY_ATTR(pathconfig_warnings);
940 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200941 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200942 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200943
944#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200945#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200946#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200947 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200948}
949
950
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100951PyObject *
952_PyConfig_AsDict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100953{
Victor Stinner8f427482020-07-08 00:20:37 +0200954 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100955 if (dict == NULL) {
956 return NULL;
957 }
958
959#define SET_ITEM(KEY, EXPR) \
960 do { \
961 PyObject *obj = (EXPR); \
962 if (obj == NULL) { \
963 goto fail; \
964 } \
965 int res = PyDict_SetItemString(dict, (KEY), obj); \
966 Py_DECREF(obj); \
967 if (res < 0) { \
968 goto fail; \
969 } \
970 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100971#define SET_ITEM_INT(ATTR) \
972 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
973#define SET_ITEM_UINT(ATTR) \
974 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100975#define FROM_WSTRING(STR) \
976 ((STR != NULL) ? \
977 PyUnicode_FromWideChar(STR, -1) \
978 : (Py_INCREF(Py_None), Py_None))
979#define SET_ITEM_WSTR(ATTR) \
980 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
981#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200982 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100983
Victor Stinner6d1c4672019-05-20 11:02:00 +0200984 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100985 SET_ITEM_INT(isolated);
986 SET_ITEM_INT(use_environment);
987 SET_ITEM_INT(dev_mode);
988 SET_ITEM_INT(install_signal_handlers);
989 SET_ITEM_INT(use_hash_seed);
990 SET_ITEM_UINT(hash_seed);
991 SET_ITEM_INT(faulthandler);
992 SET_ITEM_INT(tracemalloc);
993 SET_ITEM_INT(import_time);
994 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100995 SET_ITEM_INT(dump_refs);
996 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400997 SET_ITEM_WSTR(filesystem_encoding);
998 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100999 SET_ITEM_WSTR(pycache_prefix);
1000 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +02001001 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001002 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001003 SET_ITEM_WSTRLIST(xoptions);
1004 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02001005 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001006 SET_ITEM_WSTR(home);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001007 SET_ITEM_INT(module_search_paths_set);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001008 SET_ITEM_WSTRLIST(module_search_paths);
1009 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -07001010 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001011 SET_ITEM_WSTR(prefix);
1012 SET_ITEM_WSTR(base_prefix);
1013 SET_ITEM_WSTR(exec_prefix);
1014 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02001015 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001016 SET_ITEM_INT(site_import);
1017 SET_ITEM_INT(bytes_warning);
1018 SET_ITEM_INT(inspect);
1019 SET_ITEM_INT(interactive);
1020 SET_ITEM_INT(optimization_level);
1021 SET_ITEM_INT(parser_debug);
1022 SET_ITEM_INT(write_bytecode);
1023 SET_ITEM_INT(verbose);
1024 SET_ITEM_INT(quiet);
1025 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001026 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001027 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -04001028 SET_ITEM_WSTR(stdio_encoding);
1029 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001030#ifdef MS_WINDOWS
1031 SET_ITEM_INT(legacy_windows_stdio);
1032#endif
1033 SET_ITEM_INT(skip_source_first_line);
1034 SET_ITEM_WSTR(run_command);
1035 SET_ITEM_WSTR(run_module);
1036 SET_ITEM_WSTR(run_filename);
1037 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001038 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001039 SET_ITEM_INT(pathconfig_warnings);
1040 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +02001041 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001042 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001043
1044 return dict;
1045
1046fail:
1047 Py_DECREF(dict);
1048 return NULL;
1049
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001050#undef FROM_WSTRING
1051#undef SET_ITEM
1052#undef SET_ITEM_INT
1053#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001054#undef SET_ITEM_WSTR
1055#undef SET_ITEM_WSTRLIST
1056}
1057
1058
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001059static PyObject*
1060config_dict_get(PyObject *dict, const char *name)
1061{
1062 PyObject *item = PyDict_GetItemString(dict, name);
1063 if (item == NULL) {
1064 PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1065 return NULL;
1066 }
1067 return item;
1068}
1069
1070
1071static void
1072config_dict_invalid_value(const char *name)
1073{
1074 PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1075}
1076
1077
1078static void
1079config_dict_invalid_type(const char *name)
1080{
1081 PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1082}
1083
1084
1085static int
1086config_dict_get_int(PyObject *dict, const char *name, int *result)
1087{
1088 PyObject *item = config_dict_get(dict, name);
1089 if (item == NULL) {
1090 return -1;
1091 }
1092 int value = _PyLong_AsInt(item);
1093 if (value == -1 && PyErr_Occurred()) {
1094 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1095 config_dict_invalid_type(name);
1096 }
1097 else {
1098 config_dict_invalid_value(name);
1099 }
1100 return -1;
1101 }
1102 *result = value;
1103 return 0;
1104}
1105
1106
1107static int
1108config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1109{
1110 PyObject *item = config_dict_get(dict, name);
1111 if (item == NULL) {
1112 return -1;
1113 }
1114 unsigned long value = PyLong_AsUnsignedLong(item);
1115 if (value == (unsigned long)-1 && PyErr_Occurred()) {
1116 config_dict_invalid_value(name);
1117 return -1;
1118 }
1119 *result = value;
1120 return 0;
1121}
1122
1123
1124static int
1125config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1126 wchar_t **result)
1127{
1128 PyObject *item = config_dict_get(dict, name);
1129 if (item == NULL) {
1130 return -1;
1131 }
1132 PyStatus status;
1133 if (item == Py_None) {
1134 status = PyConfig_SetString(config, result, NULL);
1135 }
1136 else if (!PyUnicode_Check(item)) {
1137 config_dict_invalid_type(name);
1138 return -1;
1139 }
1140 else {
1141 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1142 if (wstr == NULL) {
1143 return -1;
1144 }
1145 status = PyConfig_SetString(config, result, wstr);
1146 PyMem_Free(wstr);
1147 }
1148 if (_PyStatus_EXCEPTION(status)) {
1149 PyErr_NoMemory();
1150 return -1;
1151 }
1152 return 0;
1153}
1154
1155
1156static int
1157config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1158 PyWideStringList *result)
1159{
1160 PyObject *list = config_dict_get(dict, name);
1161 if (list == NULL) {
1162 return -1;
1163 }
1164
1165 if (!PyList_CheckExact(list)) {
1166 config_dict_invalid_type(name);
1167 return -1;
1168 }
1169
1170 PyWideStringList wstrlist = _PyWideStringList_INIT;
1171 for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1172 PyObject *item = PyList_GET_ITEM(list, i);
1173
1174 if (item == Py_None) {
1175 config_dict_invalid_value(name);
1176 goto error;
1177 }
1178 else if (!PyUnicode_Check(item)) {
1179 config_dict_invalid_type(name);
1180 goto error;
1181 }
1182 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1183 if (wstr == NULL) {
1184 goto error;
1185 }
1186 PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1187 PyMem_Free(wstr);
1188 if (_PyStatus_EXCEPTION(status)) {
1189 PyErr_NoMemory();
1190 goto error;
1191 }
1192 }
1193
1194 if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1195 PyErr_NoMemory();
1196 goto error;
1197 }
1198 _PyWideStringList_Clear(&wstrlist);
1199 return 0;
1200
1201error:
1202 _PyWideStringList_Clear(&wstrlist);
1203 return -1;
1204}
1205
1206
1207int
1208_PyConfig_FromDict(PyConfig *config, PyObject *dict)
1209{
1210 if (!PyDict_Check(dict)) {
1211 PyErr_SetString(PyExc_TypeError, "dict expected");
1212 return -1;
1213 }
1214
1215#define CHECK_VALUE(NAME, TEST) \
1216 if (!(TEST)) { \
1217 config_dict_invalid_value(NAME); \
1218 return -1; \
1219 }
1220#define GET_UINT(KEY) \
1221 do { \
1222 if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1223 return -1; \
1224 } \
1225 CHECK_VALUE(#KEY, config->KEY >= 0); \
1226 } while (0)
1227#define GET_WSTR(KEY) \
1228 do { \
1229 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1230 return -1; \
1231 } \
1232 CHECK_VALUE(#KEY, config->KEY != NULL); \
1233 } while (0)
1234#define GET_WSTR_OPT(KEY) \
1235 do { \
1236 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1237 return -1; \
1238 } \
1239 } while (0)
1240#define GET_WSTRLIST(KEY) \
1241 do { \
1242 if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1243 return -1; \
1244 } \
1245 } while (0)
1246
1247 GET_UINT(_config_init);
1248 CHECK_VALUE("_config_init",
1249 config->_config_init == _PyConfig_INIT_COMPAT
1250 || config->_config_init == _PyConfig_INIT_PYTHON
1251 || config->_config_init == _PyConfig_INIT_ISOLATED);
1252 GET_UINT(isolated);
1253 GET_UINT(use_environment);
1254 GET_UINT(dev_mode);
1255 GET_UINT(install_signal_handlers);
1256 GET_UINT(use_hash_seed);
1257 if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1258 return -1;
1259 }
1260 CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1261 GET_UINT(faulthandler);
1262 GET_UINT(tracemalloc);
1263 GET_UINT(import_time);
1264 GET_UINT(show_ref_count);
1265 GET_UINT(dump_refs);
1266 GET_UINT(malloc_stats);
1267 GET_WSTR(filesystem_encoding);
1268 GET_WSTR(filesystem_errors);
1269 GET_WSTR_OPT(pycache_prefix);
1270 GET_UINT(parse_argv);
1271 GET_WSTRLIST(orig_argv);
1272 GET_WSTRLIST(argv);
1273 GET_WSTRLIST(xoptions);
1274 GET_WSTRLIST(warnoptions);
1275 GET_UINT(site_import);
1276 GET_UINT(bytes_warning);
1277 GET_UINT(inspect);
1278 GET_UINT(interactive);
1279 GET_UINT(optimization_level);
1280 GET_UINT(parser_debug);
1281 GET_UINT(write_bytecode);
1282 GET_UINT(verbose);
1283 GET_UINT(quiet);
1284 GET_UINT(user_site_directory);
1285 GET_UINT(configure_c_stdio);
1286 GET_UINT(buffered_stdio);
1287 GET_WSTR(stdio_encoding);
1288 GET_WSTR(stdio_errors);
1289#ifdef MS_WINDOWS
1290 GET_UINT(legacy_windows_stdio);
1291#endif
1292 GET_WSTR(check_hash_pycs_mode);
1293
1294 GET_UINT(pathconfig_warnings);
1295 GET_WSTR(program_name);
1296 GET_WSTR_OPT(pythonpath_env);
1297 GET_WSTR_OPT(home);
1298 GET_WSTR(platlibdir);
1299
1300 GET_UINT(module_search_paths_set);
1301 GET_WSTRLIST(module_search_paths);
1302 if (config->_install_importlib) {
1303 GET_WSTR(executable);
1304 GET_WSTR(base_executable);
1305 GET_WSTR(prefix);
1306 GET_WSTR(base_prefix);
1307 GET_WSTR(exec_prefix);
1308 GET_WSTR(base_exec_prefix);
1309 }
1310 else {
1311 GET_WSTR_OPT(executable);
1312 GET_WSTR_OPT(base_executable);
1313 GET_WSTR_OPT(prefix);
1314 GET_WSTR_OPT(base_prefix);
1315 GET_WSTR_OPT(exec_prefix);
1316 GET_WSTR_OPT(base_exec_prefix);
1317 }
1318
1319 GET_UINT(skip_source_first_line);
1320 GET_WSTR_OPT(run_command);
1321 GET_WSTR_OPT(run_module);
1322 GET_WSTR_OPT(run_filename);
1323
1324 GET_UINT(_install_importlib);
1325 GET_UINT(_init_main);
1326 GET_UINT(_isolated_interpreter);
1327
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001328#undef CHECK_VALUE
1329#undef GET_UINT
1330#undef GET_WSTR
1331#undef GET_WSTR_OPT
1332 return 0;
1333}
1334
1335
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001336static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +02001337config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001338{
Victor Stinner20004952019-03-26 02:31:11 +01001339 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001340}
1341
1342
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001343/* Get a copy of the environment variable as wchar_t*.
1344 Return 0 on success, but *dest can be NULL.
1345 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001346static PyStatus
1347config_get_env_dup(PyConfig *config,
1348 wchar_t **dest,
1349 wchar_t *wname, char *name,
1350 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +02001351{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001352 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001353 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001354
Victor Stinner20004952019-03-26 02:31:11 +01001355 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001356 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001357 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001358 }
1359
1360#ifdef MS_WINDOWS
1361 const wchar_t *var = _wgetenv(wname);
1362 if (!var || var[0] == '\0') {
1363 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001364 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001365 }
1366
Victor Stinner331a6a52019-05-27 16:39:22 +02001367 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001368#else
1369 const char *var = getenv(name);
1370 if (!var || var[0] == '\0') {
1371 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001372 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001373 }
1374
Victor Stinner331a6a52019-05-27 16:39:22 +02001375 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001376#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001377}
1378
1379
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001380#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001381 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001382
1383
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001384static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001385config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001386{
Victor Stinner022be022019-05-22 23:58:50 +02001387 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1388 /* Python and Isolated configuration ignore global variables */
1389 return;
1390 }
1391
Victor Stinner6c785c02018-08-01 17:56:14 +02001392#define COPY_FLAG(ATTR, VALUE) \
1393 if (config->ATTR == -1) { \
1394 config->ATTR = VALUE; \
1395 }
1396#define COPY_NOT_FLAG(ATTR, VALUE) \
1397 if (config->ATTR == -1) { \
1398 config->ATTR = !(VALUE); \
1399 }
1400
Victor Stinner20004952019-03-26 02:31:11 +01001401 COPY_FLAG(isolated, Py_IsolatedFlag);
1402 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001403 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1404 COPY_FLAG(inspect, Py_InspectFlag);
1405 COPY_FLAG(interactive, Py_InteractiveFlag);
1406 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1407 COPY_FLAG(parser_debug, Py_DebugFlag);
1408 COPY_FLAG(verbose, Py_VerboseFlag);
1409 COPY_FLAG(quiet, Py_QuietFlag);
1410#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001411 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1412#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001413 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001414
Victor Stinner6c785c02018-08-01 17:56:14 +02001415 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1416 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1417 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1418 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1419
Victor Stinner6c785c02018-08-01 17:56:14 +02001420#undef COPY_FLAG
1421#undef COPY_NOT_FLAG
1422}
1423
1424
1425/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001426static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001427config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001428{
1429#define COPY_FLAG(ATTR, VAR) \
1430 if (config->ATTR != -1) { \
1431 VAR = config->ATTR; \
1432 }
1433#define COPY_NOT_FLAG(ATTR, VAR) \
1434 if (config->ATTR != -1) { \
1435 VAR = !config->ATTR; \
1436 }
1437
Victor Stinner20004952019-03-26 02:31:11 +01001438 COPY_FLAG(isolated, Py_IsolatedFlag);
1439 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001440 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1441 COPY_FLAG(inspect, Py_InspectFlag);
1442 COPY_FLAG(interactive, Py_InteractiveFlag);
1443 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1444 COPY_FLAG(parser_debug, Py_DebugFlag);
1445 COPY_FLAG(verbose, Py_VerboseFlag);
1446 COPY_FLAG(quiet, Py_QuietFlag);
1447#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001448 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1449#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001450 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001451
Victor Stinner6c785c02018-08-01 17:56:14 +02001452 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1453 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1454 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1455 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1456
Victor Stinner6c785c02018-08-01 17:56:14 +02001457 /* Random or non-zero hash seed */
1458 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1459 config->hash_seed != 0);
1460
1461#undef COPY_FLAG
1462#undef COPY_NOT_FLAG
1463}
1464
1465
1466/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1467 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001468static PyStatus
1469config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001470{
Victor Stinner331a6a52019-05-27 16:39:22 +02001471 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001472
Victor Stinner6c785c02018-08-01 17:56:14 +02001473 /* If Py_SetProgramName() was called, use its value */
1474 const wchar_t *program_name = _Py_path_config.program_name;
1475 if (program_name != NULL) {
1476 config->program_name = _PyMem_RawWcsdup(program_name);
1477 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001478 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001479 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001481 }
1482
1483#ifdef __APPLE__
1484 /* On MacOS X, when the Python interpreter is embedded in an
1485 application bundle, it gets executed by a bootstrapping script
1486 that does os.execve() with an argv[0] that's different from the
1487 actual Python executable. This is needed to keep the Finder happy,
1488 or rather, to work around Apple's overly strict requirements of
1489 the process name. However, we still need a usable sys.executable,
1490 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001491 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001492 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001493 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001494 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1496 "PYTHONEXECUTABLE environment variable");
1497 if (_PyStatus_EXCEPTION(status)) {
1498 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001499 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001500 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001501 }
1502#ifdef WITH_NEXT_FRAMEWORK
1503 else {
1504 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1505 if (pyvenv_launcher && *pyvenv_launcher) {
1506 /* Used by Mac/Tools/pythonw.c to forward
1507 * the argv0 of the stub executable
1508 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001509 status = CONFIG_SET_BYTES_STR(config,
1510 &config->program_name,
1511 pyvenv_launcher,
1512 "__PYVENV_LAUNCHER__ environment variable");
1513 if (_PyStatus_EXCEPTION(status)) {
1514 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001515 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001516
1517 /*
1518 * This environment variable is used to communicate between
1519 * the stub launcher and the real interpreter and isn't needed
1520 * beyond this point.
1521 *
1522 * Clean up to avoid problems when launching other programs
1523 * later on.
1524 */
1525 (void)unsetenv("__PYVENV_LAUNCHER__");
1526
Victor Stinner331a6a52019-05-27 16:39:22 +02001527 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001528 }
1529 }
1530#endif /* WITH_NEXT_FRAMEWORK */
1531#endif /* __APPLE__ */
1532
Victor Stinnerfed02e12019-05-17 11:12:09 +02001533 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001535 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1536 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1537 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001538 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001539 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001540 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001541 }
1542
Victor Stinnerfed02e12019-05-17 11:12:09 +02001543 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001544#ifdef MS_WINDOWS
1545 const wchar_t *default_program_name = L"python";
1546#else
1547 const wchar_t *default_program_name = L"python3";
1548#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001549 status = PyConfig_SetString(config, &config->program_name,
1550 default_program_name);
1551 if (_PyStatus_EXCEPTION(status)) {
1552 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001553 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001554 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001555}
1556
Victor Stinner331a6a52019-05-27 16:39:22 +02001557static PyStatus
1558config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001559{
1560 assert(config->executable == NULL);
1561
1562 /* If Py_SetProgramFullPath() was called, use its value */
1563 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1564 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001565 PyStatus status = PyConfig_SetString(config,
1566 &config->executable,
1567 program_full_path);
1568 if (_PyStatus_EXCEPTION(status)) {
1569 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001570 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001571 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001572 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001573 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001574}
Victor Stinner6c785c02018-08-01 17:56:14 +02001575
Victor Stinner4fffd382019-03-06 01:44:31 +01001576
Victor Stinner6c785c02018-08-01 17:56:14 +02001577static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001578config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001579{
Victor Stinner74f65682019-03-15 15:08:05 +01001580 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001581}
1582
1583
Victor Stinner331a6a52019-05-27 16:39:22 +02001584static PyStatus
1585config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001586{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001587 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001588
1589 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001590 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001591 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001592 PyStatus status = PyConfig_SetString(config, &config->home, home);
1593 if (_PyStatus_EXCEPTION(status)) {
1594 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001595 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001596 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001597 }
1598
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001599 return CONFIG_GET_ENV_DUP(config, &config->home,
1600 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001601}
1602
Victor Stinner331a6a52019-05-27 16:39:22 +02001603static PyStatus
1604config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001605{
Victor Stinner331a6a52019-05-27 16:39:22 +02001606 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001607
1608 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1609 /* Convert a text seed to a numeric one */
1610 if (seed_text && strcmp(seed_text, "random") != 0) {
1611 const char *endptr = seed_text;
1612 unsigned long seed;
1613 errno = 0;
1614 seed = strtoul(seed_text, (char **)&endptr, 10);
1615 if (*endptr != '\0'
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001616 || seed > MAX_HASH_SEED
Victor Stinner6c785c02018-08-01 17:56:14 +02001617 || (errno == ERANGE && seed == ULONG_MAX))
1618 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001619 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001620 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001621 }
1622 /* Use a specific hash */
1623 config->use_hash_seed = 1;
1624 config->hash_seed = seed;
1625 }
1626 else {
1627 /* Use a random hash */
1628 config->use_hash_seed = 0;
1629 config->hash_seed = 0;
1630 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001631 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001632}
1633
1634
Victor Stinner6c785c02018-08-01 17:56:14 +02001635static int
1636config_wstr_to_int(const wchar_t *wstr, int *result)
1637{
1638 const wchar_t *endptr = wstr;
1639 errno = 0;
1640 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1641 if (*endptr != '\0' || errno == ERANGE) {
1642 return -1;
1643 }
1644 if (value < INT_MIN || value > INT_MAX) {
1645 return -1;
1646 }
1647
1648 *result = (int)value;
1649 return 0;
1650}
1651
1652
Victor Stinner331a6a52019-05-27 16:39:22 +02001653static PyStatus
1654config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001655{
Victor Stinner331a6a52019-05-27 16:39:22 +02001656 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001657 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001658
Victor Stinner6c785c02018-08-01 17:56:14 +02001659 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001660 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1661 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1662 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1663 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001664
1665 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001666 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001667 if (dont_write_bytecode) {
1668 config->write_bytecode = 0;
1669 }
1670
1671 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001672 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001673 if (no_user_site_directory) {
1674 config->user_site_directory = 0;
1675 }
1676
1677 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001678 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001679 if (unbuffered_stdio) {
1680 config->buffered_stdio = 0;
1681 }
1682
1683#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001684 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001685 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001686#endif
1687
Victor Stinner331a6a52019-05-27 16:39:22 +02001688 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001689 config->dump_refs = 1;
1690 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001691 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001692 config->malloc_stats = 1;
1693 }
1694
Victor Stinner331a6a52019-05-27 16:39:22 +02001695 if (config->pythonpath_env == NULL) {
1696 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1697 L"PYTHONPATH", "PYTHONPATH");
1698 if (_PyStatus_EXCEPTION(status)) {
1699 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001700 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001701 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001702
Sandro Mani8f023a22020-06-08 17:28:11 +02001703 if(config->platlibdir == NULL) {
1704 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1705 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1706 if (_PyStatus_EXCEPTION(status)) {
1707 return status;
1708 }
1709 }
1710
Victor Stinner6c785c02018-08-01 17:56:14 +02001711 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001712 status = config_init_hash_seed(config);
1713 if (_PyStatus_EXCEPTION(status)) {
1714 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001715 }
1716 }
1717
Victor Stinner331a6a52019-05-27 16:39:22 +02001718 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001719}
1720
1721
Victor Stinner331a6a52019-05-27 16:39:22 +02001722static PyStatus
1723config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001724{
1725 int nframe;
1726 int valid;
1727
Victor Stinner331a6a52019-05-27 16:39:22 +02001728 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001729 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001730 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001731 valid = (nframe >= 0);
1732 }
1733 else {
1734 valid = 0;
1735 }
1736 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001737 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001738 }
1739 config->tracemalloc = nframe;
1740 }
1741
1742 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1743 if (xoption) {
1744 const wchar_t *sep = wcschr(xoption, L'=');
1745 if (sep) {
1746 if (!config_wstr_to_int(sep + 1, &nframe)) {
1747 valid = (nframe >= 0);
1748 }
1749 else {
1750 valid = 0;
1751 }
1752 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001753 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1754 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001755 }
1756 }
1757 else {
1758 /* -X tracemalloc behaves as -X tracemalloc=1 */
1759 nframe = 1;
1760 }
1761 config->tracemalloc = nframe;
1762 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001763 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001764}
1765
1766
Victor Stinner331a6a52019-05-27 16:39:22 +02001767static PyStatus
1768config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001769{
1770 assert(config->pycache_prefix == NULL);
1771
1772 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1773 if (xoption) {
1774 const wchar_t *sep = wcschr(xoption, L'=');
1775 if (sep && wcslen(sep) > 1) {
1776 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1777 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001778 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001779 }
1780 }
1781 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001782 // PYTHONPYCACHEPREFIX env var ignored
1783 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001784 config->pycache_prefix = NULL;
1785 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001786 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001787 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001788
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001789 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1790 L"PYTHONPYCACHEPREFIX",
1791 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001792}
1793
1794
Victor Stinner331a6a52019-05-27 16:39:22 +02001795static PyStatus
1796config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001797{
1798 /* More complex options configured by env var and -X option */
1799 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001800 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001801 || config_get_xoption(config, L"faulthandler")) {
1802 config->faulthandler = 1;
1803 }
1804 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001805 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001806 || config_get_xoption(config, L"importtime")) {
1807 config->import_time = 1;
1808 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001809
Victor Stinner331a6a52019-05-27 16:39:22 +02001810 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001811 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001812 status = config_init_tracemalloc(config);
1813 if (_PyStatus_EXCEPTION(status)) {
1814 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001815 }
1816 }
1817
1818 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001819 status = config_init_pycache_prefix(config);
1820 if (_PyStatus_EXCEPTION(status)) {
1821 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001822 }
1823 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001824 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001825}
1826
1827
Victor Stinner709d23d2019-05-02 14:56:30 -04001828static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001829config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001830{
Victor Stinner710e8262020-10-31 01:02:09 +01001831 if (preconfig->utf8_mode) {
1832 /* UTF-8 Mode uses UTF-8/surrogateescape */
1833 return L"surrogateescape";
1834 }
1835
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001836#ifndef MS_WINDOWS
1837 const char *loc = setlocale(LC_CTYPE, NULL);
1838 if (loc != NULL) {
1839 /* surrogateescape is the default in the legacy C and POSIX locales */
1840 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001841 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001842 }
1843
1844#ifdef PY_COERCE_C_LOCALE
1845 /* surrogateescape is the default in locale coercion target locales */
1846 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001847 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001848 }
1849#endif
1850 }
1851
Victor Stinner709d23d2019-05-02 14:56:30 -04001852 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001853#else
1854 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001855 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001856#endif
1857}
1858
1859
Victor Stinner82458b62020-11-01 20:59:35 +01001860// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001861static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001862config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1863 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001864{
Victor Stinnere662c392020-11-01 23:07:23 +01001865 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001866 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001867 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001868 }
Victor Stinner82458b62020-11-01 20:59:35 +01001869 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1870 PyMem_RawFree(encoding);
1871 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001872}
1873
1874
Victor Stinner331a6a52019-05-27 16:39:22 +02001875static PyStatus
1876config_init_stdio_encoding(PyConfig *config,
1877 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001878{
Victor Stinner331a6a52019-05-27 16:39:22 +02001879 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001880
Victor Stinner35297182020-11-04 11:20:10 +01001881 /* If Py_SetStandardStreamEncoding() has been called, use its
1882 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001883 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001884 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1885 _Py_StandardStreamEncoding,
1886 "_Py_StandardStreamEncoding");
1887 if (_PyStatus_EXCEPTION(status)) {
1888 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001889 }
1890 }
1891
1892 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001893 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1894 _Py_StandardStreamErrors,
1895 "_Py_StandardStreamErrors");
1896 if (_PyStatus_EXCEPTION(status)) {
1897 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001898 }
1899 }
1900
Victor Stinner35297182020-11-04 11:20:10 +01001901 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001902 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001903 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001904 }
1905
1906 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001907 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001908 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001909 char *pythonioencoding = _PyMem_RawStrdup(opt);
1910 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001911 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001912 }
1913
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001914 char *errors = strchr(pythonioencoding, ':');
1915 if (errors) {
1916 *errors = '\0';
1917 errors++;
1918 if (!errors[0]) {
1919 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001920 }
1921 }
1922
1923 /* Does PYTHONIOENCODING contain an encoding? */
1924 if (pythonioencoding[0]) {
1925 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001926 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1927 pythonioencoding,
1928 "PYTHONIOENCODING environment variable");
1929 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001930 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001931 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001932 }
1933 }
1934
1935 /* If the encoding is set but not the error handler,
1936 use "strict" error handler by default.
1937 PYTHONIOENCODING=latin1 behaves as
1938 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001939 if (!errors) {
1940 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001941 }
1942 }
1943
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001944 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001945 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1946 errors,
1947 "PYTHONIOENCODING environment variable");
1948 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001949 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001950 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001951 }
1952 }
1953
1954 PyMem_RawFree(pythonioencoding);
1955 }
1956
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001957 /* Choose the default error handler based on the current locale. */
1958 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001959 status = config_get_locale_encoding(config, preconfig,
1960 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001961 if (_PyStatus_EXCEPTION(status)) {
1962 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001963 }
1964 }
1965 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001966 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001967 assert(errors != NULL);
1968
Victor Stinner331a6a52019-05-27 16:39:22 +02001969 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1970 if (_PyStatus_EXCEPTION(status)) {
1971 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001972 }
1973 }
1974
Victor Stinner331a6a52019-05-27 16:39:22 +02001975 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001976}
1977
1978
Victor Stinner710e8262020-10-31 01:02:09 +01001979// See also config_get_locale_encoding()
1980static PyStatus
1981config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1982 wchar_t **fs_encoding)
1983{
1984#ifdef _Py_FORCE_UTF8_FS_ENCODING
1985 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1986#elif defined(MS_WINDOWS)
1987 const wchar_t *encoding;
1988 if (preconfig->legacy_windows_fs_encoding) {
1989 // Legacy Windows filesystem encoding: mbcs/replace
1990 encoding = L"mbcs";
1991 }
1992 else {
1993 // Windows defaults to utf-8/surrogatepass (PEP 529)
1994 encoding = L"utf-8";
1995 }
1996 return PyConfig_SetString(config, fs_encoding, encoding);
1997#else // !MS_WINDOWS
1998 if (preconfig->utf8_mode) {
1999 return PyConfig_SetString(config, fs_encoding, L"utf-8");
2000 }
Victor Stinner35297182020-11-04 11:20:10 +01002001
2002 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01002003 return PyConfig_SetString(config, fs_encoding, L"ascii");
2004 }
Victor Stinner35297182020-11-04 11:20:10 +01002005
2006 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01002007#endif // !MS_WINDOWS
2008}
2009
2010
Victor Stinner331a6a52019-05-27 16:39:22 +02002011static PyStatus
2012config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002013{
Victor Stinner331a6a52019-05-27 16:39:22 +02002014 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002015
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002016 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01002017 status = config_get_fs_encoding(config, preconfig,
2018 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02002019 if (_PyStatus_EXCEPTION(status)) {
2020 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002021 }
2022 }
2023
2024 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002025 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04002026#ifdef MS_WINDOWS
2027 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002028 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04002029 }
2030 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04002031 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04002032 }
2033#else
Victor Stinner709d23d2019-05-02 14:56:30 -04002034 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04002035#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02002036 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2037 if (_PyStatus_EXCEPTION(status)) {
2038 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002039 }
2040 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002041 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002042}
2043
2044
Victor Stinner331a6a52019-05-27 16:39:22 +02002045static PyStatus
2046config_read(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02002047{
Victor Stinner331a6a52019-05-27 16:39:22 +02002048 PyStatus status;
2049 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01002050
Victor Stinner20004952019-03-26 02:31:11 +01002051 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002052 status = config_read_env_vars(config);
2053 if (_PyStatus_EXCEPTION(status)) {
2054 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002055 }
2056 }
2057
2058 /* -X options */
2059 if (config_get_xoption(config, L"showrefcount")) {
2060 config->show_ref_count = 1;
2061 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002062
Victor Stinner331a6a52019-05-27 16:39:22 +02002063 status = config_read_complex_options(config);
2064 if (_PyStatus_EXCEPTION(status)) {
2065 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002066 }
2067
Victor Stinner6c785c02018-08-01 17:56:14 +02002068 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002069 status = config_init_home(config);
2070 if (_PyStatus_EXCEPTION(status)) {
2071 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002072 }
2073 }
2074
Steve Dower177a41a2018-11-17 20:41:48 -08002075 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002076 status = config_init_executable(config);
2077 if (_PyStatus_EXCEPTION(status)) {
2078 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08002079 }
2080 }
2081
Sandro Mani8f023a22020-06-08 17:28:11 +02002082 if(config->platlibdir == NULL) {
2083 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
2084 "PLATLIBDIR macro");
2085 if (_PyStatus_EXCEPTION(status)) {
2086 return status;
2087 }
2088 }
2089
Victor Stinner6c785c02018-08-01 17:56:14 +02002090 if (config->_install_importlib) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002091 status = _PyConfig_InitPathConfig(config);
2092 if (_PyStatus_EXCEPTION(status)) {
2093 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002094 }
2095 }
2096
2097 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01002098 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02002099 if (config->faulthandler < 0) {
2100 config->faulthandler = 1;
2101 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002102 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002103 if (config->faulthandler < 0) {
2104 config->faulthandler = 0;
2105 }
2106 if (config->tracemalloc < 0) {
2107 config->tracemalloc = 0;
2108 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002109 if (config->use_hash_seed < 0) {
2110 config->use_hash_seed = 0;
2111 config->hash_seed = 0;
2112 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002113
Victor Stinner70fead22018-08-29 13:45:34 +02002114 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002115 status = config_init_fs_encoding(config, preconfig);
2116 if (_PyStatus_EXCEPTION(status)) {
2117 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002118 }
2119 }
2120
Victor Stinner331a6a52019-05-27 16:39:22 +02002121 status = config_init_stdio_encoding(config, preconfig);
2122 if (_PyStatus_EXCEPTION(status)) {
2123 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02002124 }
2125
Victor Stinner62599762019-03-15 16:03:23 +01002126 if (config->argv.length < 1) {
2127 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002128 status = PyWideStringList_Append(&config->argv, L"");
2129 if (_PyStatus_EXCEPTION(status)) {
2130 return status;
Victor Stinner62599762019-03-15 16:03:23 +01002131 }
2132 }
Victor Stinner870b0352019-05-17 03:15:12 +02002133
2134 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002135 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2136 L"default");
2137 if (_PyStatus_EXCEPTION(status)) {
2138 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002139 }
2140 }
2141
2142 if (config->configure_c_stdio < 0) {
2143 config->configure_c_stdio = 1;
2144 }
2145
Victor Stinnerdc42af82020-11-05 18:58:07 +01002146 // Only parse arguments once.
2147 if (config->parse_argv == 1) {
2148 config->parse_argv = 2;
2149 }
2150
Victor Stinner331a6a52019-05-27 16:39:22 +02002151 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02002152}
Victor Stinner5ed69952018-11-06 15:59:52 +01002153
2154
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002155static void
Victor Stinner331a6a52019-05-27 16:39:22 +02002156config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002157{
2158#if defined(MS_WINDOWS) || defined(__CYGWIN__)
2159 /* don't translate newlines (\r\n <=> \n) */
2160 _setmode(fileno(stdin), O_BINARY);
2161 _setmode(fileno(stdout), O_BINARY);
2162 _setmode(fileno(stderr), O_BINARY);
2163#endif
2164
2165 if (!config->buffered_stdio) {
2166#ifdef HAVE_SETVBUF
2167 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2168 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2169 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2170#else /* !HAVE_SETVBUF */
2171 setbuf(stdin, (char *)NULL);
2172 setbuf(stdout, (char *)NULL);
2173 setbuf(stderr, (char *)NULL);
2174#endif /* !HAVE_SETVBUF */
2175 }
2176 else if (config->interactive) {
2177#ifdef MS_WINDOWS
2178 /* Doesn't have to have line-buffered -- use unbuffered */
2179 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2180 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2181#else /* !MS_WINDOWS */
2182#ifdef HAVE_SETVBUF
2183 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2184 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2185#endif /* HAVE_SETVBUF */
2186#endif /* !MS_WINDOWS */
2187 /* Leave stderr alone - it should be unbuffered anyway. */
2188 }
2189}
2190
2191
2192/* Write the configuration:
2193
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002194 - set Py_xxx global configuration variables
2195 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02002196PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02002197_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002198{
Victor Stinner331a6a52019-05-27 16:39:22 +02002199 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002200
2201 if (config->configure_c_stdio) {
2202 config_init_stdio(config);
2203 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002204
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002205 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02002206 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002207 preconfig->isolated = config->isolated;
2208 preconfig->use_environment = config->use_environment;
2209 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02002210
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002211 if (_Py_SetArgcArgv(config->orig_argv.length,
2212 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02002213 {
2214 return _PyStatus_NO_MEMORY();
2215 }
2216 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01002217}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002218
2219
Victor Stinner331a6a52019-05-27 16:39:22 +02002220/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002221
2222static void
Victor Stinner2f549082019-03-29 15:13:46 +01002223config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002224{
Victor Stinner2f549082019-03-29 15:13:46 +01002225 FILE *f = error ? stderr : stdout;
2226
2227 fprintf(f, usage_line, program);
2228 if (error)
2229 fprintf(f, "Try `python -h' for more information.\n");
2230 else {
2231 fputs(usage_1, f);
2232 fputs(usage_2, f);
2233 fputs(usage_3, f);
2234 fprintf(f, usage_4, (wint_t)DELIM);
2235 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
2236 fputs(usage_6, f);
2237 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238}
2239
2240
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002241/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02002242static PyStatus
2243config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02002244 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002245{
Victor Stinner331a6a52019-05-27 16:39:22 +02002246 PyStatus status;
2247 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01002248 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02002249 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01002250
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002251 _PyOS_ResetGetOpt();
2252 do {
2253 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01002254 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002255 if (c == EOF) {
2256 break;
2257 }
2258
2259 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002260 if (config->run_command == NULL) {
2261 /* -c is the last option; following arguments
2262 that look like options are left for the
2263 command to interpret. */
2264 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2265 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2266 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002267 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002268 }
2269 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2270 command[len - 2] = '\n';
2271 command[len - 1] = 0;
2272 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002273 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002274 break;
2275 }
2276
2277 if (c == 'm') {
2278 /* -m is the last option; following arguments
2279 that look like options are left for the
2280 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002281 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002282 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2283 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002284 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002285 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002286 }
2287 break;
2288 }
2289
2290 switch (c) {
2291 case 0:
2292 // Handle long option.
2293 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002294 if (wcscmp(_PyOS_optarg, L"always") == 0
2295 || wcscmp(_PyOS_optarg, L"never") == 0
2296 || wcscmp(_PyOS_optarg, L"default") == 0)
2297 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002298 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2299 _PyOS_optarg);
2300 if (_PyStatus_EXCEPTION(status)) {
2301 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002302 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002303 } else {
2304 fprintf(stderr, "--check-hash-based-pycs must be one of "
2305 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02002306 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002307 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002308 }
2309 break;
2310
2311 case 'b':
2312 config->bytes_warning++;
2313 break;
2314
2315 case 'd':
2316 config->parser_debug++;
2317 break;
2318
2319 case 'i':
2320 config->inspect++;
2321 config->interactive++;
2322 break;
2323
Victor Stinner6dcb5422019-03-05 02:44:12 +01002324 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002325 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01002326 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002327 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002328 break;
2329
2330 /* case 'J': reserved for Jython */
2331
2332 case 'O':
2333 config->optimization_level++;
2334 break;
2335
2336 case 'B':
2337 config->write_bytecode = 0;
2338 break;
2339
2340 case 's':
2341 config->user_site_directory = 0;
2342 break;
2343
2344 case 'S':
2345 config->site_import = 0;
2346 break;
2347
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002348 case 't':
2349 /* ignored for backwards compatibility */
2350 break;
2351
2352 case 'u':
2353 config->buffered_stdio = 0;
2354 break;
2355
2356 case 'v':
2357 config->verbose++;
2358 break;
2359
2360 case 'x':
2361 config->skip_source_first_line = 1;
2362 break;
2363
2364 case 'h':
2365 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002366 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002367 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002368
2369 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002370 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002371 break;
2372
2373 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002374 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2375 if (_PyStatus_EXCEPTION(status)) {
2376 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002377 }
2378 break;
2379
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002380 case 'q':
2381 config->quiet++;
2382 break;
2383
2384 case 'R':
2385 config->use_hash_seed = 0;
2386 break;
2387
2388 /* This space reserved for other options */
2389
2390 default:
2391 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002392 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002393 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002394 }
2395 } while (1);
2396
Victor Stinner2f549082019-03-29 15:13:46 +01002397 if (print_version) {
2398 printf("Python %s\n",
2399 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002400 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002401 }
2402
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002403 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002404 && _PyOS_optind < argv->length
2405 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002406 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002407 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002408 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002409 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002410 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002411 }
2412 }
2413
2414 if (config->run_command != NULL || config->run_module != NULL) {
2415 /* Backup _PyOS_optind */
2416 _PyOS_optind--;
2417 }
2418
Victor Stinnerae239f62019-05-16 17:02:56 +02002419 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002420
Victor Stinner331a6a52019-05-27 16:39:22 +02002421 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002422}
2423
2424
2425#ifdef MS_WINDOWS
2426# define WCSTOK wcstok_s
2427#else
2428# define WCSTOK wcstok
2429#endif
2430
2431/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002432static PyStatus
2433config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002434{
Victor Stinner331a6a52019-05-27 16:39:22 +02002435 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002436 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2437 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002438 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002439 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002440 if (_PyStatus_EXCEPTION(status)) {
2441 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002442 }
2443
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002444 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002445 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002446 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002447 }
2448
2449
2450 wchar_t *warning, *context = NULL;
2451 for (warning = WCSTOK(env, L",", &context);
2452 warning != NULL;
2453 warning = WCSTOK(NULL, L",", &context))
2454 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002455 status = PyWideStringList_Append(warnoptions, warning);
2456 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002457 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002458 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002459 }
2460 }
2461 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002462 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002463}
2464
2465
Victor Stinner331a6a52019-05-27 16:39:22 +02002466static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002467warnoptions_append(PyConfig *config, PyWideStringList *options,
2468 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002469{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002470 /* config_init_warnoptions() add existing config warnoptions at the end:
2471 ensure that the new option is not already present in this list to
2472 prevent change the options order whne config_init_warnoptions() is
2473 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002474 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002475 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002476 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002477 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002478 if (_PyWideStringList_Find(options, option)) {
2479 /* Already present: do nothing */
2480 return _PyStatus_OK();
2481 }
2482 return PyWideStringList_Append(options, option);
2483}
2484
2485
2486static PyStatus
2487warnoptions_extend(PyConfig *config, PyWideStringList *options,
2488 const PyWideStringList *options2)
2489{
2490 const Py_ssize_t len = options2->length;
2491 wchar_t *const *items = options2->items;
2492
2493 for (Py_ssize_t i = 0; i < len; i++) {
2494 PyStatus status = warnoptions_append(config, options, items[i]);
2495 if (_PyStatus_EXCEPTION(status)) {
2496 return status;
2497 }
2498 }
2499 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002500}
2501
2502
Victor Stinner331a6a52019-05-27 16:39:22 +02002503static PyStatus
2504config_init_warnoptions(PyConfig *config,
2505 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002506 const PyWideStringList *env_warnoptions,
2507 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002508{
Victor Stinner331a6a52019-05-27 16:39:22 +02002509 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002510 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002511
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002512 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002513 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002514 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002515 * - PyConfig.dev_mode: "default" filter
2516 * - PYTHONWARNINGS environment variable
2517 * - '-W' command line options
2518 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2519 * "default::BytesWarning" or "error::BytesWarning" filter
2520 * - early PySys_AddWarnOption() calls
2521 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002522 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002523 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2524 * module works on the basis of "the most recently added filter will be
2525 * checked first", we add the lowest precedence entries first so that later
2526 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002527 */
2528
Victor Stinner20004952019-03-26 02:31:11 +01002529 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002530 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002531 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002532 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002533 }
2534 }
2535
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002536 status = warnoptions_extend(config, &options, env_warnoptions);
2537 if (_PyStatus_EXCEPTION(status)) {
2538 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002539 }
2540
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002541 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2542 if (_PyStatus_EXCEPTION(status)) {
2543 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002544 }
2545
2546 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2547 * don't even try to emit a warning, so we skip setting the filter in that
2548 * case.
2549 */
2550 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002551 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002552 if (config->bytes_warning> 1) {
2553 filter = L"error::BytesWarning";
2554 }
2555 else {
2556 filter = L"default::BytesWarning";
2557 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002558 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002559 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002560 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002561 }
2562 }
Victor Stinner120b7072019-08-23 18:03:08 +01002563
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002564 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002565 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002566 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002567 }
2568
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002569 /* Always add all PyConfig.warnoptions options */
2570 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2571 if (_PyStatus_EXCEPTION(status)) {
2572 goto error;
2573 }
2574
2575 _PyWideStringList_Clear(&config->warnoptions);
2576 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002577 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002578
2579error:
2580 _PyWideStringList_Clear(&options);
2581 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002582}
2583
2584
Victor Stinner331a6a52019-05-27 16:39:22 +02002585static PyStatus
2586config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002587{
Victor Stinner331a6a52019-05-27 16:39:22 +02002588 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002589 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002590
Victor Stinner74f65682019-03-15 15:08:05 +01002591 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002592 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002593 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002594 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2595 if (_PyStatus_EXCEPTION(status)) {
2596 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002597 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002598 }
2599 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002600 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002601 slice.length = cmdline_argv->length - opt_index;
2602 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002603 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2604 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002605 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002606 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002607 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002608
2609 wchar_t *arg0 = NULL;
2610 if (config->run_command != NULL) {
2611 /* Force sys.argv[0] = '-c' */
2612 arg0 = L"-c";
2613 }
2614 else if (config->run_module != NULL) {
2615 /* Force sys.argv[0] = '-m'*/
2616 arg0 = L"-m";
2617 }
Victor Stinner3939c322019-06-25 15:02:43 +02002618
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002619 if (arg0 != NULL) {
2620 arg0 = _PyMem_RawWcsdup(arg0);
2621 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002622 _PyWideStringList_Clear(&config_argv);
2623 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002624 }
2625
Victor Stinnerfa153762019-03-20 04:25:38 +01002626 PyMem_RawFree(config_argv.items[0]);
2627 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002628 }
2629
Victor Stinner331a6a52019-05-27 16:39:22 +02002630 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002631 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002632 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002633}
2634
2635
Victor Stinner331a6a52019-05-27 16:39:22 +02002636static PyStatus
2637core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002638{
Victor Stinner331a6a52019-05-27 16:39:22 +02002639 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002640
Victor Stinnerdc42af82020-11-05 18:58:07 +01002641 if (config->parse_argv == 1) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002642 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2643 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002644 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002645 }
2646
Victor Stinner331a6a52019-05-27 16:39:22 +02002647 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002648
2649 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2650 if (_PyStatus_EXCEPTION(status)) {
2651 return status;
2652 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002653
Victor Stinner331a6a52019-05-27 16:39:22 +02002654 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002655
Victor Stinner331a6a52019-05-27 16:39:22 +02002656 status = _PyPreCmdline_Read(precmdline, &preconfig);
2657 if (_PyStatus_EXCEPTION(status)) {
2658 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002659 }
2660
Victor Stinner331a6a52019-05-27 16:39:22 +02002661 status = _PyPreCmdline_SetConfig(precmdline, config);
2662 if (_PyStatus_EXCEPTION(status)) {
2663 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002664 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002665 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002666}
2667
2668
Victor Stinner3939c322019-06-25 15:02:43 +02002669/* Get run_filename absolute path */
2670static PyStatus
2671config_run_filename_abspath(PyConfig *config)
2672{
2673 if (!config->run_filename) {
2674 return _PyStatus_OK();
2675 }
2676
2677#ifndef MS_WINDOWS
2678 if (_Py_isabs(config->run_filename)) {
2679 /* path is already absolute */
2680 return _PyStatus_OK();
2681 }
2682#endif
2683
2684 wchar_t *abs_filename;
2685 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2686 /* failed to get the absolute path of the command line filename:
2687 ignore the error, keep the relative path */
2688 return _PyStatus_OK();
2689 }
2690 if (abs_filename == NULL) {
2691 return _PyStatus_NO_MEMORY();
2692 }
2693
2694 PyMem_RawFree(config->run_filename);
2695 config->run_filename = abs_filename;
2696 return _PyStatus_OK();
2697}
2698
2699
Victor Stinner331a6a52019-05-27 16:39:22 +02002700static PyStatus
2701config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002702{
Victor Stinner331a6a52019-05-27 16:39:22 +02002703 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002704 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2705 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2706 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002707
Victor Stinnerae239f62019-05-16 17:02:56 +02002708 if (config->parse_argv < 0) {
2709 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002710 }
Victor Stinner870b0352019-05-17 03:15:12 +02002711
Victor Stinnerfed02e12019-05-17 11:12:09 +02002712 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002713 status = config_init_program_name(config);
2714 if (_PyStatus_EXCEPTION(status)) {
2715 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002716 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002717 }
Victor Stinner2f549082019-03-29 15:13:46 +01002718
Victor Stinnerdc42af82020-11-05 18:58:07 +01002719 if (config->parse_argv == 1) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002720 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002721 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2722 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002723 goto done;
2724 }
2725
Victor Stinner3939c322019-06-25 15:02:43 +02002726 status = config_run_filename_abspath(config);
2727 if (_PyStatus_EXCEPTION(status)) {
2728 goto done;
2729 }
2730
Victor Stinner331a6a52019-05-27 16:39:22 +02002731 status = config_update_argv(config, opt_index);
2732 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002733 goto done;
2734 }
Victor Stinner2f549082019-03-29 15:13:46 +01002735 }
Victor Stinner3939c322019-06-25 15:02:43 +02002736 else {
2737 status = config_run_filename_abspath(config);
2738 if (_PyStatus_EXCEPTION(status)) {
2739 goto done;
2740 }
2741 }
Victor Stinner2f549082019-03-29 15:13:46 +01002742
Victor Stinner2f549082019-03-29 15:13:46 +01002743 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002744 status = config_init_env_warnoptions(config, &env_warnoptions);
2745 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002746 goto done;
2747 }
2748 }
2749
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002750 /* Handle early PySys_AddWarnOption() calls */
2751 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2752 if (_PyStatus_EXCEPTION(status)) {
2753 goto done;
2754 }
2755
Victor Stinner331a6a52019-05-27 16:39:22 +02002756 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002757 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002758 &env_warnoptions,
2759 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002760 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002761 goto done;
2762 }
2763
Victor Stinner331a6a52019-05-27 16:39:22 +02002764 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002765
2766done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002767 _PyWideStringList_Clear(&cmdline_warnoptions);
2768 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002769 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002770 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002771}
2772
2773
Victor Stinner331a6a52019-05-27 16:39:22 +02002774PyStatus
2775_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002776{
Victor Stinner331a6a52019-05-27 16:39:22 +02002777 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2778 if (_PyStatus_EXCEPTION(status)) {
2779 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002780 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002781
Victor Stinner5f38b842019-05-01 02:30:12 +02002782 return _PyArgv_AsWstrList(args, &config->argv);
2783}
2784
2785
Victor Stinner70005ac2019-05-02 15:25:34 -04002786/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2787 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002788PyStatus
2789PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002790{
2791 _PyArgv args = {
2792 .argc = argc,
2793 .use_bytes_argv = 1,
2794 .bytes_argv = argv,
2795 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002796 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002797}
2798
2799
Victor Stinner331a6a52019-05-27 16:39:22 +02002800PyStatus
2801PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002802{
2803 _PyArgv args = {
2804 .argc = argc,
2805 .use_bytes_argv = 0,
2806 .bytes_argv = NULL,
2807 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002808 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002809}
2810
2811
Victor Stinner36242fd2019-07-01 19:13:50 +02002812PyStatus
2813PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2814 Py_ssize_t length, wchar_t **items)
2815{
2816 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2817 if (_PyStatus_EXCEPTION(status)) {
2818 return status;
2819 }
2820
2821 PyWideStringList list2 = {.length = length, .items = items};
2822 if (_PyWideStringList_Copy(list, &list2) < 0) {
2823 return _PyStatus_NO_MEMORY();
2824 }
2825 return _PyStatus_OK();
2826}
2827
2828
Victor Stinner331a6a52019-05-27 16:39:22 +02002829/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002830
2831 * Command line arguments
2832 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002833 * Py_xxx global configuration variables
2834
2835 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002836PyStatus
2837PyConfig_Read(PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002838{
Victor Stinner331a6a52019-05-27 16:39:22 +02002839 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002840
Victor Stinner331a6a52019-05-27 16:39:22 +02002841 status = _Py_PreInitializeFromConfig(config, NULL);
2842 if (_PyStatus_EXCEPTION(status)) {
2843 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002844 }
2845
Victor Stinner331a6a52019-05-27 16:39:22 +02002846 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002847
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002848 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002849 && !(config->argv.length == 1
2850 && wcscmp(config->argv.items[0], L"") == 0))
2851 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002852 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002853 return _PyStatus_NO_MEMORY();
2854 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002855 }
2856
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002857 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002858 status = core_read_precmdline(config, &precmdline);
2859 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002860 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002861 }
2862
Victor Stinner870b0352019-05-17 03:15:12 +02002863 assert(config->isolated >= 0);
2864 if (config->isolated) {
2865 config->use_environment = 0;
2866 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002867 }
2868
Victor Stinner331a6a52019-05-27 16:39:22 +02002869 status = config_read_cmdline(config);
2870 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002871 goto done;
2872 }
2873
Victor Stinner120b7072019-08-23 18:03:08 +01002874 /* Handle early PySys_AddXOption() calls */
2875 status = _PySys_ReadPreinitXOptions(config);
2876 if (_PyStatus_EXCEPTION(status)) {
2877 goto done;
2878 }
2879
Victor Stinner331a6a52019-05-27 16:39:22 +02002880 status = config_read(config);
2881 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002882 goto done;
2883 }
2884
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002885 assert(config_check_consistency(config));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002886
Victor Stinner331a6a52019-05-27 16:39:22 +02002887 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002888
2889done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002890 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002891 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002892}
Victor Stinner1075d162019-03-25 23:19:57 +01002893
2894
2895PyObject*
2896_Py_GetConfigsAsDict(void)
2897{
Victor Stinner331a6a52019-05-27 16:39:22 +02002898 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002899 PyObject *dict = NULL;
2900
Victor Stinner331a6a52019-05-27 16:39:22 +02002901 result = PyDict_New();
2902 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002903 goto error;
2904 }
2905
Victor Stinner331a6a52019-05-27 16:39:22 +02002906 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002907 dict = _Py_GetGlobalVariablesAsDict();
2908 if (dict == NULL) {
2909 goto error;
2910 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002911 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002912 goto error;
2913 }
2914 Py_CLEAR(dict);
2915
2916 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002917 PyThreadState *tstate = _PyThreadState_GET();
2918 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002919 dict = _PyPreConfig_AsDict(pre_config);
2920 if (dict == NULL) {
2921 goto error;
2922 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002923 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002924 goto error;
2925 }
2926 Py_CLEAR(dict);
2927
2928 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002929 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002930 dict = _PyConfig_AsDict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002931 if (dict == NULL) {
2932 goto error;
2933 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002934 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002935 goto error;
2936 }
2937 Py_CLEAR(dict);
2938
Victor Stinner8f427482020-07-08 00:20:37 +02002939 /* path config */
2940 dict = _PyPathConfig_AsDict();
2941 if (dict == NULL) {
2942 goto error;
2943 }
2944 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2945 goto error;
2946 }
2947 Py_CLEAR(dict);
2948
Victor Stinner331a6a52019-05-27 16:39:22 +02002949 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002950
2951error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002952 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002953 Py_XDECREF(dict);
2954 return NULL;
2955}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002956
2957
2958static void
2959init_dump_ascii_wstr(const wchar_t *str)
2960{
2961 if (str == NULL) {
2962 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002963 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002964 }
2965
2966 PySys_WriteStderr("'");
2967 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002968 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002969 if (ch == L'\'') {
2970 PySys_WriteStderr("\\'");
2971 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002972 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002973 }
2974 else if (ch <= 0xff) {
2975 PySys_WriteStderr("\\x%02x", ch);
2976 }
2977#if SIZEOF_WCHAR_T > 2
2978 else if (ch > 0xffff) {
2979 PySys_WriteStderr("\\U%08x", ch);
2980 }
2981#endif
2982 else {
2983 PySys_WriteStderr("\\u%04x", ch);
2984 }
2985 }
2986 PySys_WriteStderr("'");
2987}
2988
2989
2990/* Dump the Python path configuration into sys.stderr */
2991void
2992_Py_DumpPathConfig(PyThreadState *tstate)
2993{
2994 PyObject *exc_type, *exc_value, *exc_tb;
2995 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2996
2997 PySys_WriteStderr("Python path configuration:\n");
2998
2999#define DUMP_CONFIG(NAME, FIELD) \
3000 do { \
3001 PySys_WriteStderr(" " NAME " = "); \
3002 init_dump_ascii_wstr(config->FIELD); \
3003 PySys_WriteStderr("\n"); \
3004 } while (0)
3005
Victor Stinnerda7933e2020-04-13 03:04:28 +02003006 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003007 DUMP_CONFIG("PYTHONHOME", home);
3008 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
3009 DUMP_CONFIG("program name", program_name);
3010 PySys_WriteStderr(" isolated = %i\n", config->isolated);
3011 PySys_WriteStderr(" environment = %i\n", config->use_environment);
3012 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3013 PySys_WriteStderr(" import site = %i\n", config->site_import);
3014#undef DUMP_CONFIG
3015
3016#define DUMP_SYS(NAME) \
3017 do { \
3018 obj = PySys_GetObject(#NAME); \
3019 PySys_FormatStderr(" sys.%s = ", #NAME); \
3020 if (obj != NULL) { \
3021 PySys_FormatStderr("%A", obj); \
3022 } \
3023 else { \
3024 PySys_WriteStderr("(not set)"); \
3025 } \
3026 PySys_FormatStderr("\n"); \
3027 } while (0)
3028
3029 PyObject *obj;
3030 DUMP_SYS(_base_executable);
3031 DUMP_SYS(base_prefix);
3032 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02003033 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003034 DUMP_SYS(executable);
3035 DUMP_SYS(prefix);
3036 DUMP_SYS(exec_prefix);
3037#undef DUMP_SYS
3038
3039 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3040 if (sys_path != NULL && PyList_Check(sys_path)) {
3041 PySys_WriteStderr(" sys.path = [\n");
3042 Py_ssize_t len = PyList_GET_SIZE(sys_path);
3043 for (Py_ssize_t i=0; i < len; i++) {
3044 PyObject *path = PyList_GET_ITEM(sys_path, i);
3045 PySys_FormatStderr(" %A,\n", path);
3046 }
3047 PySys_WriteStderr(" ]\n");
3048 }
3049
3050 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3051}