blob: 4d95ac5d8859b1b6a20934db31bd18181118faeb [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner4f98f462020-04-15 04:01:58 +02002#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
3#include "pycore_getopt.h" // _PyOS_GetOpt()
4#include "pycore_initconfig.h" // _PyStatus_OK()
Victor Stinnere5014be2020-04-14 17:52:15 +02005#include "pycore_interp.h" // _PyInterpreterState.runtime
Victor Stinner4f98f462020-04-15 04:01:58 +02006#include "pycore_pathconfig.h" // _Py_path_config
7#include "pycore_pyerrors.h" // _PyErr_Fetch()
8#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
Victor Stinnerd9ea5ca2020-04-15 02:57:50 +02009#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
Victor Stinnere5014be2020-04-14 17:52:15 +020010#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinner4f98f462020-04-15 04:01:58 +020011
12#include "osdefs.h" // DELIM
Victor Stinnere5014be2020-04-14 17:52:15 +020013#include <locale.h> // setlocale()
Victor Stinner95e2cbf2019-03-01 16:25:19 +010014#if defined(MS_WINDOWS) || defined(__CYGWIN__)
Victor Stinner95e2cbf2019-03-01 16:25:19 +010015# ifdef HAVE_IO_H
16# include <io.h>
17# endif
18# ifdef HAVE_FCNTL_H
Victor Stinnere5014be2020-04-14 17:52:15 +020019# include <fcntl.h> // O_BINARY
Victor Stinner95e2cbf2019-03-01 16:25:19 +010020# endif
Victor Stinnerb2457ef2018-08-29 13:25:36 +020021#endif
22
Sandro Mani8f023a22020-06-08 17:28:11 +020023#ifndef PLATLIBDIR
24# error "PLATLIBDIR macro must be defined"
25#endif
26
Victor Stinner6c785c02018-08-01 17:56:14 +020027
Victor Stinner95e2cbf2019-03-01 16:25:19 +010028/* --- Command line options --------------------------------------- */
29
Victor Stinner95e2cbf2019-03-01 16:25:19 +010030/* Short usage message (with %s for argv0) */
31static const char usage_line[] =
32"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
33
34/* Long usage message, split into parts < 512 bytes */
35static const char usage_1[] = "\
36Options and arguments (and corresponding environment variables):\n\
37-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
38 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
39-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
40-c cmd : program passed in as string (terminates option list)\n\
41-d : debug output from parser; also PYTHONDEBUG=x\n\
42-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
43-h : print this help message and exit (also --help)\n\
44";
45static const char usage_2[] = "\
46-i : inspect interactively after running script; forces a prompt even\n\
47 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
48-I : isolate Python from the user's environment (implies -E and -s)\n\
49-m mod : run library module as a script (terminates option list)\n\
50-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
51 .pyc extension; also PYTHONOPTIMIZE=x\n\
52-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
53 .pyc extension\n\
54-q : don't print version and copyright messages on interactive startup\n\
55-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
56-S : don't imply 'import site' on initialization\n\
57";
58static const char usage_3[] = "\
59-u : force the stdout and stderr streams to be unbuffered;\n\
60 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
61-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
62 can be supplied multiple times to increase verbosity\n\
63-V : print the Python version number and exit (also --version)\n\
64 when given twice, print more information about the build\n\
65-W arg : warning control; arg is action:message:category:module:lineno\n\
66 also PYTHONWARNINGS=arg\n\
67-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000068-X opt : set implementation-specific option. The following options are available:\n\
69\n\
70 -X faulthandler: enable faulthandler\n\
71 -X showrefcount: output the total reference count and number of used\n\
72 memory blocks when the program finishes or after each statement in the\n\
73 interactive interpreter. This only works on debug builds\n\
74 -X tracemalloc: start tracing Python memory allocations using the\n\
75 tracemalloc module. By default, only the most recent frame is stored in a\n\
76 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
77 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000078 -X importtime: show how long each import takes. It shows module name,\n\
79 cumulative time (including nested imports) and self time (excluding\n\
80 nested imports). Note that its output may be broken in multi-threaded\n\
81 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
Serhiy Storchaka58de1dd2020-09-09 03:28:02 +030082 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000083 checks which are too expensive to be enabled by default. Effect of the\n\
84 developer mode:\n\
85 * Add default warning filter, as -W default\n\
86 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
87 * Enable the faulthandler module to dump the Python traceback on a crash\n\
88 * Enable asyncio debug mode\n\
89 * Set the dev_mode attribute of sys.flags to True\n\
90 * io.IOBase destructor logs close() exceptions\n\
91 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
92 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
93 otherwise activate automatically)\n\
94 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
95 given directory instead of to the code tree\n\
96\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010097--check-hash-based-pycs always|default|never:\n\
98 control how Python invalidates hash-based .pyc files\n\
99";
100static const char usage_4[] = "\
101file : program read from script file\n\
102- : program read from stdin (default; interactive mode if a tty)\n\
103arg ...: arguments passed to program in sys.argv[1:]\n\n\
104Other environment variables:\n\
105PYTHONSTARTUP: file executed on interactive startup (no default)\n\
106PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
107 default module search path. The result is sys.path.\n\
108";
109static const char usage_5[] =
110"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
111" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200112"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100113"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900114"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
116"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
117static const char usage_6[] =
118"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300119" to seed the hashes of str and bytes objects. It can also be set to an\n"
120" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100121" predictable seed.\n"
122"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
123" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
124" hooks.\n"
125"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
126" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
127" locale coercion and locale compatibility warnings on stderr.\n"
128"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
129" debugger. It can be set to the callable of your debugger of choice.\n"
130"PYTHONDEVMODE: enable the development mode.\n"
131"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
132
133#if defined(MS_WINDOWS)
134# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
135#else
136# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
137#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200138
139
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100140/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200141
Victor Stinner6c785c02018-08-01 17:56:14 +0200142/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200143 stdin and stdout error handler to "surrogateescape". */
144int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200145int Py_DebugFlag = 0; /* Needed by parser.c */
146int Py_VerboseFlag = 0; /* Needed by import.c */
147int Py_QuietFlag = 0; /* Needed by sysmodule.c */
148int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
149int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
150int Py_OptimizeFlag = 0; /* Needed by compile.c */
151int Py_NoSiteFlag = 0; /* Suppress 'import site' */
152int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
153int Py_FrozenFlag = 0; /* Needed by getpath.c */
154int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
155int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
156int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
157int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
158int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
159int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
160#ifdef MS_WINDOWS
161int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
162int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
163#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200164
165
Victor Stinner1075d162019-03-25 23:19:57 +0100166static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100167_Py_GetGlobalVariablesAsDict(void)
168{
169 PyObject *dict, *obj;
170
171 dict = PyDict_New();
172 if (dict == NULL) {
173 return NULL;
174 }
175
176#define SET_ITEM(KEY, EXPR) \
177 do { \
178 obj = (EXPR); \
179 if (obj == NULL) { \
180 return NULL; \
181 } \
182 int res = PyDict_SetItemString(dict, (KEY), obj); \
183 Py_DECREF(obj); \
184 if (res < 0) { \
185 goto fail; \
186 } \
187 } while (0)
188#define SET_ITEM_INT(VAR) \
189 SET_ITEM(#VAR, PyLong_FromLong(VAR))
190#define FROM_STRING(STR) \
191 ((STR != NULL) ? \
192 PyUnicode_FromString(STR) \
193 : (Py_INCREF(Py_None), Py_None))
194#define SET_ITEM_STR(VAR) \
195 SET_ITEM(#VAR, FROM_STRING(VAR))
196
197 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
198 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
199 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
200 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
201
202 SET_ITEM_INT(Py_UTF8Mode);
203 SET_ITEM_INT(Py_DebugFlag);
204 SET_ITEM_INT(Py_VerboseFlag);
205 SET_ITEM_INT(Py_QuietFlag);
206 SET_ITEM_INT(Py_InteractiveFlag);
207 SET_ITEM_INT(Py_InspectFlag);
208
209 SET_ITEM_INT(Py_OptimizeFlag);
210 SET_ITEM_INT(Py_NoSiteFlag);
211 SET_ITEM_INT(Py_BytesWarningFlag);
212 SET_ITEM_INT(Py_FrozenFlag);
213 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
214 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
215 SET_ITEM_INT(Py_NoUserSiteDirectory);
216 SET_ITEM_INT(Py_UnbufferedStdioFlag);
217 SET_ITEM_INT(Py_HashRandomizationFlag);
218 SET_ITEM_INT(Py_IsolatedFlag);
219
220#ifdef MS_WINDOWS
221 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
222 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
223#endif
224
225 return dict;
226
227fail:
228 Py_DECREF(dict);
229 return NULL;
230
231#undef FROM_STRING
232#undef SET_ITEM
233#undef SET_ITEM_INT
234#undef SET_ITEM_STR
235}
236
237
Victor Stinner331a6a52019-05-27 16:39:22 +0200238/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200239
Victor Stinner331a6a52019-05-27 16:39:22 +0200240PyStatus PyStatus_Ok(void)
241{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200244{
Victor Stinner048a3562020-11-05 00:45:56 +0100245 assert(err_msg != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +0200246 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner048a3562020-11-05 00:45:56 +0100247 .err_msg = err_msg};
Victor Stinner871ff772019-05-17 23:54:00 +0200248}
249
Victor Stinner331a6a52019-05-27 16:39:22 +0200250PyStatus PyStatus_NoMemory(void)
251{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200252
Victor Stinner331a6a52019-05-27 16:39:22 +0200253PyStatus PyStatus_Exit(int exitcode)
254{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200255
256
Victor Stinner331a6a52019-05-27 16:39:22 +0200257int PyStatus_IsError(PyStatus status)
258{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200259
Victor Stinner331a6a52019-05-27 16:39:22 +0200260int PyStatus_IsExit(PyStatus status)
261{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200262
Victor Stinner331a6a52019-05-27 16:39:22 +0200263int PyStatus_Exception(PyStatus status)
264{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200265
Victor Stinner048a3562020-11-05 00:45:56 +0100266PyObject*
267_PyErr_SetFromPyStatus(PyStatus status)
268{
269 if (!_PyStatus_IS_ERROR(status)) {
270 PyErr_Format(PyExc_SystemError,
271 "%s() expects an error PyStatus",
272 _PyStatus_GET_FUNC());
273 }
274 else if (status.func) {
275 PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
276 }
277 else {
278 PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
279 }
280 return NULL;
281}
282
Victor Stinner871ff772019-05-17 23:54:00 +0200283
Victor Stinner331a6a52019-05-27 16:39:22 +0200284/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100285
286#ifndef NDEBUG
287int
Victor Stinner331a6a52019-05-27 16:39:22 +0200288_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100289{
290 assert(list->length >= 0);
291 if (list->length != 0) {
292 assert(list->items != NULL);
293 }
294 for (Py_ssize_t i = 0; i < list->length; i++) {
295 assert(list->items[i] != NULL);
296 }
297 return 1;
298}
299#endif /* Py_DEBUG */
300
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100301
Victor Stinner6c785c02018-08-01 17:56:14 +0200302void
Victor Stinner331a6a52019-05-27 16:39:22 +0200303_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200304{
Victor Stinner331a6a52019-05-27 16:39:22 +0200305 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100306 for (Py_ssize_t i=0; i < list->length; i++) {
307 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200308 }
Victor Stinner74f65682019-03-15 15:08:05 +0100309 PyMem_RawFree(list->items);
310 list->length = 0;
311 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200312}
313
314
Victor Stinner74f65682019-03-15 15:08:05 +0100315int
Victor Stinner331a6a52019-05-27 16:39:22 +0200316_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200317{
Victor Stinner331a6a52019-05-27 16:39:22 +0200318 assert(_PyWideStringList_CheckConsistency(list));
319 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100320
321 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200322 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100323 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300324 }
Victor Stinner74f65682019-03-15 15:08:05 +0100325
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200326 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100327
328 size_t size = list2->length * sizeof(list2->items[0]);
329 copy.items = PyMem_RawMalloc(size);
330 if (copy.items == NULL) {
331 return -1;
332 }
333
334 for (Py_ssize_t i=0; i < list2->length; i++) {
335 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
336 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200337 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100338 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200339 }
Victor Stinner74f65682019-03-15 15:08:05 +0100340 copy.items[i] = item;
341 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200342 }
Victor Stinner74f65682019-03-15 15:08:05 +0100343
Victor Stinner331a6a52019-05-27 16:39:22 +0200344 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100345 *list = copy;
346 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200347}
348
349
Victor Stinner331a6a52019-05-27 16:39:22 +0200350PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100351PyWideStringList_Insert(PyWideStringList *list,
352 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100353{
Victor Stinner3842f292019-08-23 16:57:54 +0100354 Py_ssize_t len = list->length;
355 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000356 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200357 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100358 }
Victor Stinner3842f292019-08-23 16:57:54 +0100359 if (index < 0) {
360 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
361 }
362 if (index > len) {
363 index = len;
364 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100365
Victor Stinner74f65682019-03-15 15:08:05 +0100366 wchar_t *item2 = _PyMem_RawWcsdup(item);
367 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200368 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100369 }
Victor Stinner74f65682019-03-15 15:08:05 +0100370
Victor Stinner3842f292019-08-23 16:57:54 +0100371 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100372 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
373 if (items2 == NULL) {
374 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200375 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100376 }
377
Victor Stinner3842f292019-08-23 16:57:54 +0100378 if (index < len) {
379 memmove(&items2[index + 1],
380 &items2[index],
381 (len - index) * sizeof(items2[0]));
382 }
383
384 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100385 list->items = items2;
386 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200387 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100388}
389
390
Victor Stinner331a6a52019-05-27 16:39:22 +0200391PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100392PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
393{
394 return PyWideStringList_Insert(list, list->length, item);
395}
396
397
398PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200399_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100400{
401 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200402 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
403 if (_PyStatus_EXCEPTION(status)) {
404 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100405 }
406 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200407 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100408}
409
410
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100411static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200412_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100413{
414 for (Py_ssize_t i = 0; i < list->length; i++) {
415 if (wcscmp(list->items[i], item) == 0) {
416 return 1;
417 }
418 }
419 return 0;
420}
421
422
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100423PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200424_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100425{
Victor Stinner331a6a52019-05-27 16:39:22 +0200426 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100427
Victor Stinner74f65682019-03-15 15:08:05 +0100428 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100429 if (pylist == NULL) {
430 return NULL;
431 }
432
Victor Stinner74f65682019-03-15 15:08:05 +0100433 for (Py_ssize_t i = 0; i < list->length; i++) {
434 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
435 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100436 Py_DECREF(pylist);
437 return NULL;
438 }
Victor Stinner74f65682019-03-15 15:08:05 +0100439 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100440 }
441 return pylist;
442}
443
444
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100445/* --- Py_SetStandardStreamEncoding() ----------------------------- */
446
Victor Stinner124b9eb2018-08-29 01:29:06 +0200447/* Helper to allow an embedding application to override the normal
448 * mechanism that attempts to figure out an appropriate IO encoding
449 */
450
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200451static char *_Py_StandardStreamEncoding = NULL;
452static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200453
454int
455Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
456{
457 if (Py_IsInitialized()) {
458 /* This is too late to have any effect */
459 return -1;
460 }
461
462 int res = 0;
463
464 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
465 but Py_Initialize() can change the allocator. Use a known allocator
466 to be able to release the memory later. */
467 PyMemAllocatorEx old_alloc;
468 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
469
470 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
471 * initialised yet.
472 *
473 * However, the raw memory allocators are initialised appropriately
474 * as C static variables, so _PyMem_RawStrdup is OK even though
475 * Py_Initialize hasn't been called yet.
476 */
477 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200478 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200479 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
480 if (!_Py_StandardStreamEncoding) {
481 res = -2;
482 goto done;
483 }
484 }
485 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200486 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200487 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
488 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200489 PyMem_RawFree(_Py_StandardStreamEncoding);
490 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200491 res = -3;
492 goto done;
493 }
494 }
495#ifdef MS_WINDOWS
496 if (_Py_StandardStreamEncoding) {
497 /* Overriding the stream encoding implies legacy streams */
498 Py_LegacyWindowsStdioFlag = 1;
499 }
500#endif
501
502done:
503 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
504
505 return res;
506}
507
508
509void
510_Py_ClearStandardStreamEncoding(void)
511{
512 /* Use the same allocator than Py_SetStandardStreamEncoding() */
513 PyMemAllocatorEx old_alloc;
514 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
515
516 /* We won't need them anymore. */
517 if (_Py_StandardStreamEncoding) {
518 PyMem_RawFree(_Py_StandardStreamEncoding);
519 _Py_StandardStreamEncoding = NULL;
520 }
521 if (_Py_StandardStreamErrors) {
522 PyMem_RawFree(_Py_StandardStreamErrors);
523 _Py_StandardStreamErrors = NULL;
524 }
525
526 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
527}
528
529
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100530/* --- Py_GetArgcArgv() ------------------------------------------- */
531
532/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200533static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100534
535
536void
537_Py_ClearArgcArgv(void)
538{
539 PyMemAllocatorEx old_alloc;
540 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
541
Victor Stinner331a6a52019-05-27 16:39:22 +0200542 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100543
544 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
545}
546
547
Victor Stinner4fffd382019-03-06 01:44:31 +0100548static int
Victor Stinner74f65682019-03-15 15:08:05 +0100549_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100550{
Victor Stinner331a6a52019-05-27 16:39:22 +0200551 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100552 int res;
553
554 PyMemAllocatorEx old_alloc;
555 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
556
Victor Stinner331a6a52019-05-27 16:39:22 +0200557 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100558
559 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
560 return res;
561}
562
563
Victor Stinner4b9aad42020-11-02 16:49:54 +0100564// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100565void
566Py_GetArgcArgv(int *argc, wchar_t ***argv)
567{
Victor Stinner74f65682019-03-15 15:08:05 +0100568 *argc = (int)orig_argv.length;
569 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100570}
571
572
Victor Stinner331a6a52019-05-27 16:39:22 +0200573/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100574
575#define DECODE_LOCALE_ERR(NAME, LEN) \
576 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 ? _PyStatus_ERR("cannot decode " NAME) \
578 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100579
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100580#define MAX_HASH_SEED 4294967295UL
581
582
583#ifndef NDEBUG
584static int
585config_check_consistency(const PyConfig *config)
586{
587 /* Check config consistency */
588 assert(config->isolated >= 0);
589 assert(config->use_environment >= 0);
590 assert(config->dev_mode >= 0);
591 assert(config->install_signal_handlers >= 0);
592 assert(config->use_hash_seed >= 0);
593 assert(config->hash_seed <= MAX_HASH_SEED);
594 assert(config->faulthandler >= 0);
595 assert(config->tracemalloc >= 0);
596 assert(config->import_time >= 0);
597 assert(config->show_ref_count >= 0);
598 assert(config->dump_refs >= 0);
599 assert(config->malloc_stats >= 0);
600 assert(config->site_import >= 0);
601 assert(config->bytes_warning >= 0);
602 assert(config->inspect >= 0);
603 assert(config->interactive >= 0);
604 assert(config->optimization_level >= 0);
605 assert(config->parser_debug >= 0);
606 assert(config->write_bytecode >= 0);
607 assert(config->verbose >= 0);
608 assert(config->quiet >= 0);
609 assert(config->user_site_directory >= 0);
610 assert(config->parse_argv >= 0);
611 assert(config->configure_c_stdio >= 0);
612 assert(config->buffered_stdio >= 0);
613 assert(config->program_name != NULL);
614 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
615 assert(_PyWideStringList_CheckConsistency(&config->argv));
616 /* sys.argv must be non-empty: empty argv is replaced with [''] */
617 assert(config->argv.length >= 1);
618 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
619 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
620 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
621 assert(config->module_search_paths_set >= 0);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100622 assert(config->platlibdir != NULL);
623 assert(config->filesystem_encoding != NULL);
624 assert(config->filesystem_errors != NULL);
625 assert(config->stdio_encoding != NULL);
626 assert(config->stdio_errors != NULL);
627#ifdef MS_WINDOWS
628 assert(config->legacy_windows_stdio >= 0);
629#endif
630 /* -c and -m options are exclusive */
631 assert(!(config->run_command != NULL && config->run_module != NULL));
632 assert(config->check_hash_pycs_mode != NULL);
633 assert(config->_install_importlib >= 0);
634 assert(config->pathconfig_warnings >= 0);
635 return 1;
636}
637#endif
638
Victor Stinner441b10c2019-09-28 04:28:35 +0200639
Victor Stinner6c785c02018-08-01 17:56:14 +0200640/* Free memory allocated in config, but don't clear all attributes */
641void
Victor Stinner331a6a52019-05-27 16:39:22 +0200642PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200643{
644#define CLEAR(ATTR) \
645 do { \
646 PyMem_RawFree(ATTR); \
647 ATTR = NULL; \
648 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200649
650 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200651 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200652 CLEAR(config->home);
653 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200654
Victor Stinner331a6a52019-05-27 16:39:22 +0200655 _PyWideStringList_Clear(&config->argv);
656 _PyWideStringList_Clear(&config->warnoptions);
657 _PyWideStringList_Clear(&config->xoptions);
658 _PyWideStringList_Clear(&config->module_search_paths);
659 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200660
661 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700662 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200663 CLEAR(config->prefix);
664 CLEAR(config->base_prefix);
665 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200666 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200667 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200668
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200669 CLEAR(config->filesystem_encoding);
670 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200671 CLEAR(config->stdio_encoding);
672 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100673 CLEAR(config->run_command);
674 CLEAR(config->run_module);
675 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400676 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200677
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200678 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200679#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200680}
681
682
Victor Stinner8462a492019-10-01 12:06:16 +0200683void
Victor Stinner331a6a52019-05-27 16:39:22 +0200684_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200685{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200686 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200687
Victor Stinner022be022019-05-22 23:58:50 +0200688 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200689 config->isolated = -1;
690 config->use_environment = -1;
691 config->dev_mode = -1;
692 config->install_signal_handlers = 1;
693 config->use_hash_seed = -1;
694 config->faulthandler = -1;
695 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200696 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200697 config->parse_argv = 0;
698 config->site_import = -1;
699 config->bytes_warning = -1;
700 config->inspect = -1;
701 config->interactive = -1;
702 config->optimization_level = -1;
703 config->parser_debug= -1;
704 config->write_bytecode = -1;
705 config->verbose = -1;
706 config->quiet = -1;
707 config->user_site_directory = -1;
708 config->configure_c_stdio = 0;
709 config->buffered_stdio = -1;
710 config->_install_importlib = 1;
711 config->check_hash_pycs_mode = NULL;
712 config->pathconfig_warnings = -1;
713 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200714 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200715#ifdef MS_WINDOWS
716 config->legacy_windows_stdio = -1;
717#endif
718}
719
720
Victor Stinner8462a492019-10-01 12:06:16 +0200721static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200722config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200723{
Victor Stinner8462a492019-10-01 12:06:16 +0200724 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200725
726 config->isolated = 0;
727 config->use_environment = 1;
728 config->site_import = 1;
729 config->bytes_warning = 0;
730 config->inspect = 0;
731 config->interactive = 0;
732 config->optimization_level = 0;
733 config->parser_debug= 0;
734 config->write_bytecode = 1;
735 config->verbose = 0;
736 config->quiet = 0;
737 config->user_site_directory = 1;
738 config->buffered_stdio = 1;
739 config->pathconfig_warnings = 1;
740#ifdef MS_WINDOWS
741 config->legacy_windows_stdio = 0;
742#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200743}
744
745
Victor Stinner8462a492019-10-01 12:06:16 +0200746void
Victor Stinner331a6a52019-05-27 16:39:22 +0200747PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200748{
Victor Stinner8462a492019-10-01 12:06:16 +0200749 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200750
Victor Stinner022be022019-05-22 23:58:50 +0200751 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200752 config->configure_c_stdio = 1;
753 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200754}
755
756
Victor Stinner8462a492019-10-01 12:06:16 +0200757void
Victor Stinner331a6a52019-05-27 16:39:22 +0200758PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200759{
Victor Stinner8462a492019-10-01 12:06:16 +0200760 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200761
Victor Stinner022be022019-05-22 23:58:50 +0200762 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200763 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200764 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200765 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200766 config->dev_mode = 0;
767 config->install_signal_handlers = 0;
768 config->use_hash_seed = 0;
769 config->faulthandler = 0;
770 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200771 config->pathconfig_warnings = 0;
772#ifdef MS_WINDOWS
773 config->legacy_windows_stdio = 0;
774#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200775}
776
777
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200778/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200779PyStatus
780PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200781{
Victor Stinner331a6a52019-05-27 16:39:22 +0200782 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
783 if (_PyStatus_EXCEPTION(status)) {
784 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200785 }
786
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200787 wchar_t *str2;
788 if (str != NULL) {
789 str2 = _PyMem_RawWcsdup(str);
790 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200791 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200792 }
793 }
794 else {
795 str2 = NULL;
796 }
797 PyMem_RawFree(*config_str);
798 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200799 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200800}
801
802
Victor Stinner331a6a52019-05-27 16:39:22 +0200803static PyStatus
804config_set_bytes_string(PyConfig *config, wchar_t **config_str,
805 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200806{
Victor Stinner331a6a52019-05-27 16:39:22 +0200807 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
808 if (_PyStatus_EXCEPTION(status)) {
809 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400810 }
811
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200812 wchar_t *str2;
813 if (str != NULL) {
814 size_t len;
815 str2 = Py_DecodeLocale(str, &len);
816 if (str2 == NULL) {
817 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200818 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200819 }
820 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200821 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200822 }
823 }
824 }
825 else {
826 str2 = NULL;
827 }
828 PyMem_RawFree(*config_str);
829 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200830 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200831}
832
833
Victor Stinner331a6a52019-05-27 16:39:22 +0200834#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
835 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400836
837
Victor Stinner70005ac2019-05-02 15:25:34 -0400838/* Decode str using Py_DecodeLocale() and set the result into *config_str.
839 Pre-initialize Python if needed to ensure that encodings are properly
840 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200841PyStatus
842PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100843 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400844{
Victor Stinner331a6a52019-05-27 16:39:22 +0200845 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400846}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200847
848
Victor Stinner331a6a52019-05-27 16:39:22 +0200849PyStatus
850_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200851{
Victor Stinner331a6a52019-05-27 16:39:22 +0200852 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200853
Victor Stinner331a6a52019-05-27 16:39:22 +0200854 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200855
856#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200857#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200858 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200859 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
860 if (_PyStatus_EXCEPTION(status)) { \
861 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200862 } \
863 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100864#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200865 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200866 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200867 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200868 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200869 } while (0)
870
Victor Stinner6d1c4672019-05-20 11:02:00 +0200871 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100872 COPY_ATTR(isolated);
873 COPY_ATTR(use_environment);
874 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200875 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200876 COPY_ATTR(use_hash_seed);
877 COPY_ATTR(hash_seed);
878 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200879 COPY_ATTR(faulthandler);
880 COPY_ATTR(tracemalloc);
881 COPY_ATTR(import_time);
882 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200883 COPY_ATTR(dump_refs);
884 COPY_ATTR(malloc_stats);
885
Victor Stinner124b9eb2018-08-29 01:29:06 +0200886 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200887 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200888 COPY_WSTR_ATTR(home);
889 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200890
Victor Stinnerae239f62019-05-16 17:02:56 +0200891 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100892 COPY_WSTRLIST(argv);
893 COPY_WSTRLIST(warnoptions);
894 COPY_WSTRLIST(xoptions);
895 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200897
Victor Stinner124b9eb2018-08-29 01:29:06 +0200898 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700899 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200900 COPY_WSTR_ATTR(prefix);
901 COPY_WSTR_ATTR(base_prefix);
902 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200903 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200904 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200905
Victor Stinner6c785c02018-08-01 17:56:14 +0200906 COPY_ATTR(site_import);
907 COPY_ATTR(bytes_warning);
908 COPY_ATTR(inspect);
909 COPY_ATTR(interactive);
910 COPY_ATTR(optimization_level);
911 COPY_ATTR(parser_debug);
912 COPY_ATTR(write_bytecode);
913 COPY_ATTR(verbose);
914 COPY_ATTR(quiet);
915 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200916 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200917 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400918 COPY_WSTR_ATTR(filesystem_encoding);
919 COPY_WSTR_ATTR(filesystem_errors);
920 COPY_WSTR_ATTR(stdio_encoding);
921 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200922#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200923 COPY_ATTR(legacy_windows_stdio);
924#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100925 COPY_ATTR(skip_source_first_line);
926 COPY_WSTR_ATTR(run_command);
927 COPY_WSTR_ATTR(run_module);
928 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400929 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200930 COPY_ATTR(pathconfig_warnings);
931 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200932 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200933 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200934
935#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200936#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200937#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200938 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200939}
940
941
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100942PyObject *
943_PyConfig_AsDict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100944{
Victor Stinner8f427482020-07-08 00:20:37 +0200945 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100946 if (dict == NULL) {
947 return NULL;
948 }
949
950#define SET_ITEM(KEY, EXPR) \
951 do { \
952 PyObject *obj = (EXPR); \
953 if (obj == NULL) { \
954 goto fail; \
955 } \
956 int res = PyDict_SetItemString(dict, (KEY), obj); \
957 Py_DECREF(obj); \
958 if (res < 0) { \
959 goto fail; \
960 } \
961 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100962#define SET_ITEM_INT(ATTR) \
963 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
964#define SET_ITEM_UINT(ATTR) \
965 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100966#define FROM_WSTRING(STR) \
967 ((STR != NULL) ? \
968 PyUnicode_FromWideChar(STR, -1) \
969 : (Py_INCREF(Py_None), Py_None))
970#define SET_ITEM_WSTR(ATTR) \
971 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
972#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200973 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100974
Victor Stinner6d1c4672019-05-20 11:02:00 +0200975 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100976 SET_ITEM_INT(isolated);
977 SET_ITEM_INT(use_environment);
978 SET_ITEM_INT(dev_mode);
979 SET_ITEM_INT(install_signal_handlers);
980 SET_ITEM_INT(use_hash_seed);
981 SET_ITEM_UINT(hash_seed);
982 SET_ITEM_INT(faulthandler);
983 SET_ITEM_INT(tracemalloc);
984 SET_ITEM_INT(import_time);
985 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100986 SET_ITEM_INT(dump_refs);
987 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400988 SET_ITEM_WSTR(filesystem_encoding);
989 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100990 SET_ITEM_WSTR(pycache_prefix);
991 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200992 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100993 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100994 SET_ITEM_WSTRLIST(xoptions);
995 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +0200996 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100997 SET_ITEM_WSTR(home);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100998 SET_ITEM_INT(module_search_paths_set);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100999 SET_ITEM_WSTRLIST(module_search_paths);
1000 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -07001001 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001002 SET_ITEM_WSTR(prefix);
1003 SET_ITEM_WSTR(base_prefix);
1004 SET_ITEM_WSTR(exec_prefix);
1005 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02001006 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001007 SET_ITEM_INT(site_import);
1008 SET_ITEM_INT(bytes_warning);
1009 SET_ITEM_INT(inspect);
1010 SET_ITEM_INT(interactive);
1011 SET_ITEM_INT(optimization_level);
1012 SET_ITEM_INT(parser_debug);
1013 SET_ITEM_INT(write_bytecode);
1014 SET_ITEM_INT(verbose);
1015 SET_ITEM_INT(quiet);
1016 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001017 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001018 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -04001019 SET_ITEM_WSTR(stdio_encoding);
1020 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001021#ifdef MS_WINDOWS
1022 SET_ITEM_INT(legacy_windows_stdio);
1023#endif
1024 SET_ITEM_INT(skip_source_first_line);
1025 SET_ITEM_WSTR(run_command);
1026 SET_ITEM_WSTR(run_module);
1027 SET_ITEM_WSTR(run_filename);
1028 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001029 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001030 SET_ITEM_INT(pathconfig_warnings);
1031 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +02001032 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001033 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001034
1035 return dict;
1036
1037fail:
1038 Py_DECREF(dict);
1039 return NULL;
1040
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001041#undef FROM_WSTRING
1042#undef SET_ITEM
1043#undef SET_ITEM_INT
1044#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001045#undef SET_ITEM_WSTR
1046#undef SET_ITEM_WSTRLIST
1047}
1048
1049
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001050static PyObject*
1051config_dict_get(PyObject *dict, const char *name)
1052{
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001053 PyObject *item = _PyDict_GetItemStringWithError(dict, name);
1054 if (item == NULL && !PyErr_Occurred()) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001055 PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1056 return NULL;
1057 }
1058 return item;
1059}
1060
1061
1062static void
1063config_dict_invalid_value(const char *name)
1064{
1065 PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1066}
1067
1068
1069static void
1070config_dict_invalid_type(const char *name)
1071{
1072 PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1073}
1074
1075
1076static int
1077config_dict_get_int(PyObject *dict, const char *name, int *result)
1078{
1079 PyObject *item = config_dict_get(dict, name);
1080 if (item == NULL) {
1081 return -1;
1082 }
1083 int value = _PyLong_AsInt(item);
1084 if (value == -1 && PyErr_Occurred()) {
1085 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1086 config_dict_invalid_type(name);
1087 }
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001088 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001089 config_dict_invalid_value(name);
1090 }
1091 return -1;
1092 }
1093 *result = value;
1094 return 0;
1095}
1096
1097
1098static int
1099config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1100{
1101 PyObject *item = config_dict_get(dict, name);
1102 if (item == NULL) {
1103 return -1;
1104 }
1105 unsigned long value = PyLong_AsUnsignedLong(item);
1106 if (value == (unsigned long)-1 && PyErr_Occurred()) {
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001107 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1108 config_dict_invalid_type(name);
1109 }
1110 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1111 config_dict_invalid_value(name);
1112 }
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001113 return -1;
1114 }
1115 *result = value;
1116 return 0;
1117}
1118
1119
1120static int
1121config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1122 wchar_t **result)
1123{
1124 PyObject *item = config_dict_get(dict, name);
1125 if (item == NULL) {
1126 return -1;
1127 }
1128 PyStatus status;
1129 if (item == Py_None) {
1130 status = PyConfig_SetString(config, result, NULL);
1131 }
1132 else if (!PyUnicode_Check(item)) {
1133 config_dict_invalid_type(name);
1134 return -1;
1135 }
1136 else {
1137 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1138 if (wstr == NULL) {
1139 return -1;
1140 }
1141 status = PyConfig_SetString(config, result, wstr);
1142 PyMem_Free(wstr);
1143 }
1144 if (_PyStatus_EXCEPTION(status)) {
1145 PyErr_NoMemory();
1146 return -1;
1147 }
1148 return 0;
1149}
1150
1151
1152static int
1153config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1154 PyWideStringList *result)
1155{
1156 PyObject *list = config_dict_get(dict, name);
1157 if (list == NULL) {
1158 return -1;
1159 }
1160
1161 if (!PyList_CheckExact(list)) {
1162 config_dict_invalid_type(name);
1163 return -1;
1164 }
1165
1166 PyWideStringList wstrlist = _PyWideStringList_INIT;
1167 for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1168 PyObject *item = PyList_GET_ITEM(list, i);
1169
1170 if (item == Py_None) {
1171 config_dict_invalid_value(name);
1172 goto error;
1173 }
1174 else if (!PyUnicode_Check(item)) {
1175 config_dict_invalid_type(name);
1176 goto error;
1177 }
1178 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1179 if (wstr == NULL) {
1180 goto error;
1181 }
1182 PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1183 PyMem_Free(wstr);
1184 if (_PyStatus_EXCEPTION(status)) {
1185 PyErr_NoMemory();
1186 goto error;
1187 }
1188 }
1189
1190 if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1191 PyErr_NoMemory();
1192 goto error;
1193 }
1194 _PyWideStringList_Clear(&wstrlist);
1195 return 0;
1196
1197error:
1198 _PyWideStringList_Clear(&wstrlist);
1199 return -1;
1200}
1201
1202
1203int
1204_PyConfig_FromDict(PyConfig *config, PyObject *dict)
1205{
1206 if (!PyDict_Check(dict)) {
1207 PyErr_SetString(PyExc_TypeError, "dict expected");
1208 return -1;
1209 }
1210
1211#define CHECK_VALUE(NAME, TEST) \
1212 if (!(TEST)) { \
1213 config_dict_invalid_value(NAME); \
1214 return -1; \
1215 }
1216#define GET_UINT(KEY) \
1217 do { \
1218 if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1219 return -1; \
1220 } \
1221 CHECK_VALUE(#KEY, config->KEY >= 0); \
1222 } while (0)
1223#define GET_WSTR(KEY) \
1224 do { \
1225 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1226 return -1; \
1227 } \
1228 CHECK_VALUE(#KEY, config->KEY != NULL); \
1229 } while (0)
1230#define GET_WSTR_OPT(KEY) \
1231 do { \
1232 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1233 return -1; \
1234 } \
1235 } while (0)
1236#define GET_WSTRLIST(KEY) \
1237 do { \
1238 if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1239 return -1; \
1240 } \
1241 } while (0)
1242
1243 GET_UINT(_config_init);
1244 CHECK_VALUE("_config_init",
1245 config->_config_init == _PyConfig_INIT_COMPAT
1246 || config->_config_init == _PyConfig_INIT_PYTHON
1247 || config->_config_init == _PyConfig_INIT_ISOLATED);
1248 GET_UINT(isolated);
1249 GET_UINT(use_environment);
1250 GET_UINT(dev_mode);
1251 GET_UINT(install_signal_handlers);
1252 GET_UINT(use_hash_seed);
1253 if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1254 return -1;
1255 }
1256 CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1257 GET_UINT(faulthandler);
1258 GET_UINT(tracemalloc);
1259 GET_UINT(import_time);
1260 GET_UINT(show_ref_count);
1261 GET_UINT(dump_refs);
1262 GET_UINT(malloc_stats);
1263 GET_WSTR(filesystem_encoding);
1264 GET_WSTR(filesystem_errors);
1265 GET_WSTR_OPT(pycache_prefix);
1266 GET_UINT(parse_argv);
1267 GET_WSTRLIST(orig_argv);
1268 GET_WSTRLIST(argv);
1269 GET_WSTRLIST(xoptions);
1270 GET_WSTRLIST(warnoptions);
1271 GET_UINT(site_import);
1272 GET_UINT(bytes_warning);
1273 GET_UINT(inspect);
1274 GET_UINT(interactive);
1275 GET_UINT(optimization_level);
1276 GET_UINT(parser_debug);
1277 GET_UINT(write_bytecode);
1278 GET_UINT(verbose);
1279 GET_UINT(quiet);
1280 GET_UINT(user_site_directory);
1281 GET_UINT(configure_c_stdio);
1282 GET_UINT(buffered_stdio);
1283 GET_WSTR(stdio_encoding);
1284 GET_WSTR(stdio_errors);
1285#ifdef MS_WINDOWS
1286 GET_UINT(legacy_windows_stdio);
1287#endif
1288 GET_WSTR(check_hash_pycs_mode);
1289
1290 GET_UINT(pathconfig_warnings);
1291 GET_WSTR(program_name);
1292 GET_WSTR_OPT(pythonpath_env);
1293 GET_WSTR_OPT(home);
1294 GET_WSTR(platlibdir);
1295
Victor Stinner9e1b8282020-11-10 13:21:52 +01001296 // Path configuration output
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001297 GET_UINT(module_search_paths_set);
1298 GET_WSTRLIST(module_search_paths);
Victor Stinner9e1b8282020-11-10 13:21:52 +01001299 GET_WSTR_OPT(executable);
1300 GET_WSTR_OPT(base_executable);
1301 GET_WSTR_OPT(prefix);
1302 GET_WSTR_OPT(base_prefix);
1303 GET_WSTR_OPT(exec_prefix);
1304 GET_WSTR_OPT(base_exec_prefix);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001305
1306 GET_UINT(skip_source_first_line);
1307 GET_WSTR_OPT(run_command);
1308 GET_WSTR_OPT(run_module);
1309 GET_WSTR_OPT(run_filename);
1310
1311 GET_UINT(_install_importlib);
1312 GET_UINT(_init_main);
1313 GET_UINT(_isolated_interpreter);
1314
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001315#undef CHECK_VALUE
1316#undef GET_UINT
1317#undef GET_WSTR
1318#undef GET_WSTR_OPT
1319 return 0;
1320}
1321
1322
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001323static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +02001324config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001325{
Victor Stinner20004952019-03-26 02:31:11 +01001326 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001327}
1328
1329
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001330/* Get a copy of the environment variable as wchar_t*.
1331 Return 0 on success, but *dest can be NULL.
1332 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001333static PyStatus
1334config_get_env_dup(PyConfig *config,
1335 wchar_t **dest,
1336 wchar_t *wname, char *name,
1337 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +02001338{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001339 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001340 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001341
Victor Stinner20004952019-03-26 02:31:11 +01001342 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001343 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001344 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001345 }
1346
1347#ifdef MS_WINDOWS
1348 const wchar_t *var = _wgetenv(wname);
1349 if (!var || var[0] == '\0') {
1350 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001351 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001352 }
1353
Victor Stinner331a6a52019-05-27 16:39:22 +02001354 return PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001355#else
1356 const char *var = getenv(name);
1357 if (!var || var[0] == '\0') {
1358 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001359 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001360 }
1361
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001363#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001364}
1365
1366
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001367#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001368 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001369
1370
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001371static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001372config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001373{
Victor Stinner022be022019-05-22 23:58:50 +02001374 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1375 /* Python and Isolated configuration ignore global variables */
1376 return;
1377 }
1378
Victor Stinner6c785c02018-08-01 17:56:14 +02001379#define COPY_FLAG(ATTR, VALUE) \
1380 if (config->ATTR == -1) { \
1381 config->ATTR = VALUE; \
1382 }
1383#define COPY_NOT_FLAG(ATTR, VALUE) \
1384 if (config->ATTR == -1) { \
1385 config->ATTR = !(VALUE); \
1386 }
1387
Victor Stinner20004952019-03-26 02:31:11 +01001388 COPY_FLAG(isolated, Py_IsolatedFlag);
1389 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001390 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1391 COPY_FLAG(inspect, Py_InspectFlag);
1392 COPY_FLAG(interactive, Py_InteractiveFlag);
1393 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1394 COPY_FLAG(parser_debug, Py_DebugFlag);
1395 COPY_FLAG(verbose, Py_VerboseFlag);
1396 COPY_FLAG(quiet, Py_QuietFlag);
1397#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001398 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1399#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001400 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001401
Victor Stinner6c785c02018-08-01 17:56:14 +02001402 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1403 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1404 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1405 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1406
Victor Stinner6c785c02018-08-01 17:56:14 +02001407#undef COPY_FLAG
1408#undef COPY_NOT_FLAG
1409}
1410
1411
1412/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001413static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001414config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001415{
1416#define COPY_FLAG(ATTR, VAR) \
1417 if (config->ATTR != -1) { \
1418 VAR = config->ATTR; \
1419 }
1420#define COPY_NOT_FLAG(ATTR, VAR) \
1421 if (config->ATTR != -1) { \
1422 VAR = !config->ATTR; \
1423 }
1424
Victor Stinner20004952019-03-26 02:31:11 +01001425 COPY_FLAG(isolated, Py_IsolatedFlag);
1426 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001427 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1428 COPY_FLAG(inspect, Py_InspectFlag);
1429 COPY_FLAG(interactive, Py_InteractiveFlag);
1430 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1431 COPY_FLAG(parser_debug, Py_DebugFlag);
1432 COPY_FLAG(verbose, Py_VerboseFlag);
1433 COPY_FLAG(quiet, Py_QuietFlag);
1434#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1436#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001437 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001438
Victor Stinner6c785c02018-08-01 17:56:14 +02001439 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1440 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1441 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1442 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1443
Victor Stinner6c785c02018-08-01 17:56:14 +02001444 /* Random or non-zero hash seed */
1445 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1446 config->hash_seed != 0);
1447
1448#undef COPY_FLAG
1449#undef COPY_NOT_FLAG
1450}
1451
1452
1453/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1454 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001455static PyStatus
1456config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001457{
Victor Stinner331a6a52019-05-27 16:39:22 +02001458 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001459
Victor Stinner6c785c02018-08-01 17:56:14 +02001460 /* If Py_SetProgramName() was called, use its value */
1461 const wchar_t *program_name = _Py_path_config.program_name;
1462 if (program_name != NULL) {
1463 config->program_name = _PyMem_RawWcsdup(program_name);
1464 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001465 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001466 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001467 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001468 }
1469
1470#ifdef __APPLE__
1471 /* On MacOS X, when the Python interpreter is embedded in an
1472 application bundle, it gets executed by a bootstrapping script
1473 that does os.execve() with an argv[0] that's different from the
1474 actual Python executable. This is needed to keep the Finder happy,
1475 or rather, to work around Apple's overly strict requirements of
1476 the process name. However, we still need a usable sys.executable,
1477 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001478 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001479 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001480 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001481 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001482 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1483 "PYTHONEXECUTABLE environment variable");
1484 if (_PyStatus_EXCEPTION(status)) {
1485 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001486 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001487 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001488 }
1489#ifdef WITH_NEXT_FRAMEWORK
1490 else {
1491 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1492 if (pyvenv_launcher && *pyvenv_launcher) {
1493 /* Used by Mac/Tools/pythonw.c to forward
1494 * the argv0 of the stub executable
1495 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001496 status = CONFIG_SET_BYTES_STR(config,
1497 &config->program_name,
1498 pyvenv_launcher,
1499 "__PYVENV_LAUNCHER__ environment variable");
1500 if (_PyStatus_EXCEPTION(status)) {
1501 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001502 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001503
1504 /*
1505 * This environment variable is used to communicate between
1506 * the stub launcher and the real interpreter and isn't needed
1507 * beyond this point.
1508 *
1509 * Clean up to avoid problems when launching other programs
1510 * later on.
1511 */
1512 (void)unsetenv("__PYVENV_LAUNCHER__");
1513
Victor Stinner331a6a52019-05-27 16:39:22 +02001514 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001515 }
1516 }
1517#endif /* WITH_NEXT_FRAMEWORK */
1518#endif /* __APPLE__ */
1519
Victor Stinnerfed02e12019-05-17 11:12:09 +02001520 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001521 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001522 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1523 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1524 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001525 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001526 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001527 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001528 }
1529
Victor Stinnerfed02e12019-05-17 11:12:09 +02001530 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001531#ifdef MS_WINDOWS
1532 const wchar_t *default_program_name = L"python";
1533#else
1534 const wchar_t *default_program_name = L"python3";
1535#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001536 status = PyConfig_SetString(config, &config->program_name,
1537 default_program_name);
1538 if (_PyStatus_EXCEPTION(status)) {
1539 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001540 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001541 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001542}
1543
Victor Stinner331a6a52019-05-27 16:39:22 +02001544static PyStatus
1545config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001546{
1547 assert(config->executable == NULL);
1548
1549 /* If Py_SetProgramFullPath() was called, use its value */
1550 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1551 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001552 PyStatus status = PyConfig_SetString(config,
1553 &config->executable,
1554 program_full_path);
1555 if (_PyStatus_EXCEPTION(status)) {
1556 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001557 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001558 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001559 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001561}
Victor Stinner6c785c02018-08-01 17:56:14 +02001562
Victor Stinner4fffd382019-03-06 01:44:31 +01001563
Victor Stinner6c785c02018-08-01 17:56:14 +02001564static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001565config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001566{
Victor Stinner74f65682019-03-15 15:08:05 +01001567 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001568}
1569
1570
Victor Stinner331a6a52019-05-27 16:39:22 +02001571static PyStatus
1572config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001573{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001574 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001575
1576 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001577 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001578 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001579 PyStatus status = PyConfig_SetString(config, &config->home, home);
1580 if (_PyStatus_EXCEPTION(status)) {
1581 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001582 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001583 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001584 }
1585
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001586 return CONFIG_GET_ENV_DUP(config, &config->home,
1587 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001588}
1589
Victor Stinner331a6a52019-05-27 16:39:22 +02001590static PyStatus
1591config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001592{
Victor Stinner331a6a52019-05-27 16:39:22 +02001593 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001594
1595 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1596 /* Convert a text seed to a numeric one */
1597 if (seed_text && strcmp(seed_text, "random") != 0) {
1598 const char *endptr = seed_text;
1599 unsigned long seed;
1600 errno = 0;
1601 seed = strtoul(seed_text, (char **)&endptr, 10);
1602 if (*endptr != '\0'
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001603 || seed > MAX_HASH_SEED
Victor Stinner6c785c02018-08-01 17:56:14 +02001604 || (errno == ERANGE && seed == ULONG_MAX))
1605 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001606 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001607 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001608 }
1609 /* Use a specific hash */
1610 config->use_hash_seed = 1;
1611 config->hash_seed = seed;
1612 }
1613 else {
1614 /* Use a random hash */
1615 config->use_hash_seed = 0;
1616 config->hash_seed = 0;
1617 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001618 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001619}
1620
1621
Victor Stinner6c785c02018-08-01 17:56:14 +02001622static int
1623config_wstr_to_int(const wchar_t *wstr, int *result)
1624{
1625 const wchar_t *endptr = wstr;
1626 errno = 0;
1627 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1628 if (*endptr != '\0' || errno == ERANGE) {
1629 return -1;
1630 }
1631 if (value < INT_MIN || value > INT_MAX) {
1632 return -1;
1633 }
1634
1635 *result = (int)value;
1636 return 0;
1637}
1638
1639
Victor Stinner331a6a52019-05-27 16:39:22 +02001640static PyStatus
1641config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001642{
Victor Stinner331a6a52019-05-27 16:39:22 +02001643 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001644 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001645
Victor Stinner6c785c02018-08-01 17:56:14 +02001646 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001647 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1648 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1649 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1650 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001651
1652 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001653 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001654 if (dont_write_bytecode) {
1655 config->write_bytecode = 0;
1656 }
1657
1658 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001659 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001660 if (no_user_site_directory) {
1661 config->user_site_directory = 0;
1662 }
1663
1664 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001665 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001666 if (unbuffered_stdio) {
1667 config->buffered_stdio = 0;
1668 }
1669
1670#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001671 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001672 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001673#endif
1674
Victor Stinner331a6a52019-05-27 16:39:22 +02001675 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001676 config->dump_refs = 1;
1677 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001678 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001679 config->malloc_stats = 1;
1680 }
1681
Victor Stinner331a6a52019-05-27 16:39:22 +02001682 if (config->pythonpath_env == NULL) {
1683 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1684 L"PYTHONPATH", "PYTHONPATH");
1685 if (_PyStatus_EXCEPTION(status)) {
1686 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001687 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001688 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001689
Sandro Mani8f023a22020-06-08 17:28:11 +02001690 if(config->platlibdir == NULL) {
1691 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1692 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1693 if (_PyStatus_EXCEPTION(status)) {
1694 return status;
1695 }
1696 }
1697
Victor Stinner6c785c02018-08-01 17:56:14 +02001698 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001699 status = config_init_hash_seed(config);
1700 if (_PyStatus_EXCEPTION(status)) {
1701 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001702 }
1703 }
1704
Victor Stinner331a6a52019-05-27 16:39:22 +02001705 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001706}
1707
1708
Victor Stinner331a6a52019-05-27 16:39:22 +02001709static PyStatus
1710config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001711{
1712 int nframe;
1713 int valid;
1714
Victor Stinner331a6a52019-05-27 16:39:22 +02001715 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001716 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001717 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001718 valid = (nframe >= 0);
1719 }
1720 else {
1721 valid = 0;
1722 }
1723 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001724 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001725 }
1726 config->tracemalloc = nframe;
1727 }
1728
1729 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1730 if (xoption) {
1731 const wchar_t *sep = wcschr(xoption, L'=');
1732 if (sep) {
1733 if (!config_wstr_to_int(sep + 1, &nframe)) {
1734 valid = (nframe >= 0);
1735 }
1736 else {
1737 valid = 0;
1738 }
1739 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001740 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1741 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001742 }
1743 }
1744 else {
1745 /* -X tracemalloc behaves as -X tracemalloc=1 */
1746 nframe = 1;
1747 }
1748 config->tracemalloc = nframe;
1749 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001750 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001751}
1752
1753
Victor Stinner331a6a52019-05-27 16:39:22 +02001754static PyStatus
1755config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001756{
1757 assert(config->pycache_prefix == NULL);
1758
1759 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1760 if (xoption) {
1761 const wchar_t *sep = wcschr(xoption, L'=');
1762 if (sep && wcslen(sep) > 1) {
1763 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1764 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001765 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001766 }
1767 }
1768 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001769 // PYTHONPYCACHEPREFIX env var ignored
1770 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001771 config->pycache_prefix = NULL;
1772 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001773 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001774 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001775
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001776 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1777 L"PYTHONPYCACHEPREFIX",
1778 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001779}
1780
1781
Victor Stinner331a6a52019-05-27 16:39:22 +02001782static PyStatus
1783config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001784{
1785 /* More complex options configured by env var and -X option */
1786 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001787 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001788 || config_get_xoption(config, L"faulthandler")) {
1789 config->faulthandler = 1;
1790 }
1791 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001792 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001793 || config_get_xoption(config, L"importtime")) {
1794 config->import_time = 1;
1795 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001796
Victor Stinner331a6a52019-05-27 16:39:22 +02001797 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001798 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001799 status = config_init_tracemalloc(config);
1800 if (_PyStatus_EXCEPTION(status)) {
1801 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001802 }
1803 }
1804
1805 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001806 status = config_init_pycache_prefix(config);
1807 if (_PyStatus_EXCEPTION(status)) {
1808 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001809 }
1810 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001811 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001812}
1813
1814
Victor Stinner709d23d2019-05-02 14:56:30 -04001815static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001816config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001817{
Victor Stinner710e8262020-10-31 01:02:09 +01001818 if (preconfig->utf8_mode) {
1819 /* UTF-8 Mode uses UTF-8/surrogateescape */
1820 return L"surrogateescape";
1821 }
1822
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001823#ifndef MS_WINDOWS
1824 const char *loc = setlocale(LC_CTYPE, NULL);
1825 if (loc != NULL) {
1826 /* surrogateescape is the default in the legacy C and POSIX locales */
1827 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001828 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001829 }
1830
1831#ifdef PY_COERCE_C_LOCALE
1832 /* surrogateescape is the default in locale coercion target locales */
1833 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001834 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001835 }
1836#endif
1837 }
1838
Victor Stinner709d23d2019-05-02 14:56:30 -04001839 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001840#else
1841 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001842 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001843#endif
1844}
1845
1846
Victor Stinner82458b62020-11-01 20:59:35 +01001847// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001848static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001849config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1850 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001851{
Victor Stinnere662c392020-11-01 23:07:23 +01001852 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001853 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001854 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001855 }
Victor Stinner82458b62020-11-01 20:59:35 +01001856 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1857 PyMem_RawFree(encoding);
1858 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001859}
1860
1861
Victor Stinner331a6a52019-05-27 16:39:22 +02001862static PyStatus
1863config_init_stdio_encoding(PyConfig *config,
1864 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001865{
Victor Stinner331a6a52019-05-27 16:39:22 +02001866 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001867
Victor Stinner35297182020-11-04 11:20:10 +01001868 /* If Py_SetStandardStreamEncoding() has been called, use its
1869 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001870 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001871 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1872 _Py_StandardStreamEncoding,
1873 "_Py_StandardStreamEncoding");
1874 if (_PyStatus_EXCEPTION(status)) {
1875 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001876 }
1877 }
1878
1879 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001880 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1881 _Py_StandardStreamErrors,
1882 "_Py_StandardStreamErrors");
1883 if (_PyStatus_EXCEPTION(status)) {
1884 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001885 }
1886 }
1887
Victor Stinner35297182020-11-04 11:20:10 +01001888 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001889 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001890 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001891 }
1892
1893 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001894 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001895 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001896 char *pythonioencoding = _PyMem_RawStrdup(opt);
1897 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001898 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001899 }
1900
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001901 char *errors = strchr(pythonioencoding, ':');
1902 if (errors) {
1903 *errors = '\0';
1904 errors++;
1905 if (!errors[0]) {
1906 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001907 }
1908 }
1909
1910 /* Does PYTHONIOENCODING contain an encoding? */
1911 if (pythonioencoding[0]) {
1912 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001913 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1914 pythonioencoding,
1915 "PYTHONIOENCODING environment variable");
1916 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001917 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001918 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001919 }
1920 }
1921
1922 /* If the encoding is set but not the error handler,
1923 use "strict" error handler by default.
1924 PYTHONIOENCODING=latin1 behaves as
1925 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001926 if (!errors) {
1927 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001928 }
1929 }
1930
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001931 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001932 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1933 errors,
1934 "PYTHONIOENCODING environment variable");
1935 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001936 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001937 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001938 }
1939 }
1940
1941 PyMem_RawFree(pythonioencoding);
1942 }
1943
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001944 /* Choose the default error handler based on the current locale. */
1945 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001946 status = config_get_locale_encoding(config, preconfig,
1947 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001948 if (_PyStatus_EXCEPTION(status)) {
1949 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001950 }
1951 }
1952 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001953 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001954 assert(errors != NULL);
1955
Victor Stinner331a6a52019-05-27 16:39:22 +02001956 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1957 if (_PyStatus_EXCEPTION(status)) {
1958 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001959 }
1960 }
1961
Victor Stinner331a6a52019-05-27 16:39:22 +02001962 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001963}
1964
1965
Victor Stinner710e8262020-10-31 01:02:09 +01001966// See also config_get_locale_encoding()
1967static PyStatus
1968config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1969 wchar_t **fs_encoding)
1970{
1971#ifdef _Py_FORCE_UTF8_FS_ENCODING
1972 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1973#elif defined(MS_WINDOWS)
1974 const wchar_t *encoding;
1975 if (preconfig->legacy_windows_fs_encoding) {
1976 // Legacy Windows filesystem encoding: mbcs/replace
1977 encoding = L"mbcs";
1978 }
1979 else {
1980 // Windows defaults to utf-8/surrogatepass (PEP 529)
1981 encoding = L"utf-8";
1982 }
1983 return PyConfig_SetString(config, fs_encoding, encoding);
1984#else // !MS_WINDOWS
1985 if (preconfig->utf8_mode) {
1986 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1987 }
Victor Stinner35297182020-11-04 11:20:10 +01001988
1989 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01001990 return PyConfig_SetString(config, fs_encoding, L"ascii");
1991 }
Victor Stinner35297182020-11-04 11:20:10 +01001992
1993 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01001994#endif // !MS_WINDOWS
1995}
1996
1997
Victor Stinner331a6a52019-05-27 16:39:22 +02001998static PyStatus
1999config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002000{
Victor Stinner331a6a52019-05-27 16:39:22 +02002001 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002002
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002003 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01002004 status = config_get_fs_encoding(config, preconfig,
2005 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02002006 if (_PyStatus_EXCEPTION(status)) {
2007 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002008 }
2009 }
2010
2011 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002012 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04002013#ifdef MS_WINDOWS
2014 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002015 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04002016 }
2017 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04002018 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04002019 }
2020#else
Victor Stinner709d23d2019-05-02 14:56:30 -04002021 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04002022#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02002023 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2024 if (_PyStatus_EXCEPTION(status)) {
2025 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002026 }
2027 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002028 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002029}
2030
2031
Victor Stinner331a6a52019-05-27 16:39:22 +02002032static PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002033config_read(PyConfig *config, int compute_path_config)
Victor Stinner6c785c02018-08-01 17:56:14 +02002034{
Victor Stinner331a6a52019-05-27 16:39:22 +02002035 PyStatus status;
2036 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01002037
Victor Stinner20004952019-03-26 02:31:11 +01002038 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002039 status = config_read_env_vars(config);
2040 if (_PyStatus_EXCEPTION(status)) {
2041 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002042 }
2043 }
2044
2045 /* -X options */
2046 if (config_get_xoption(config, L"showrefcount")) {
2047 config->show_ref_count = 1;
2048 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002049
Victor Stinner331a6a52019-05-27 16:39:22 +02002050 status = config_read_complex_options(config);
2051 if (_PyStatus_EXCEPTION(status)) {
2052 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002053 }
2054
Victor Stinner6c785c02018-08-01 17:56:14 +02002055 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002056 status = config_init_home(config);
2057 if (_PyStatus_EXCEPTION(status)) {
2058 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002059 }
2060 }
2061
Steve Dower177a41a2018-11-17 20:41:48 -08002062 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002063 status = config_init_executable(config);
2064 if (_PyStatus_EXCEPTION(status)) {
2065 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08002066 }
2067 }
2068
Sandro Mani8f023a22020-06-08 17:28:11 +02002069 if(config->platlibdir == NULL) {
2070 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
2071 "PLATLIBDIR macro");
2072 if (_PyStatus_EXCEPTION(status)) {
2073 return status;
2074 }
2075 }
2076
Victor Stinnerace3f9a2020-11-10 21:10:22 +01002077 if (config->_install_importlib) {
2078 status = _PyConfig_InitPathConfig(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002079 if (_PyStatus_EXCEPTION(status)) {
2080 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002081 }
2082 }
2083
2084 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01002085 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02002086 if (config->faulthandler < 0) {
2087 config->faulthandler = 1;
2088 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002089 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002090 if (config->faulthandler < 0) {
2091 config->faulthandler = 0;
2092 }
2093 if (config->tracemalloc < 0) {
2094 config->tracemalloc = 0;
2095 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002096 if (config->use_hash_seed < 0) {
2097 config->use_hash_seed = 0;
2098 config->hash_seed = 0;
2099 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002100
Victor Stinner70fead22018-08-29 13:45:34 +02002101 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002102 status = config_init_fs_encoding(config, preconfig);
2103 if (_PyStatus_EXCEPTION(status)) {
2104 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002105 }
2106 }
2107
Victor Stinner331a6a52019-05-27 16:39:22 +02002108 status = config_init_stdio_encoding(config, preconfig);
2109 if (_PyStatus_EXCEPTION(status)) {
2110 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02002111 }
2112
Victor Stinner62599762019-03-15 16:03:23 +01002113 if (config->argv.length < 1) {
2114 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002115 status = PyWideStringList_Append(&config->argv, L"");
2116 if (_PyStatus_EXCEPTION(status)) {
2117 return status;
Victor Stinner62599762019-03-15 16:03:23 +01002118 }
2119 }
Victor Stinner870b0352019-05-17 03:15:12 +02002120
2121 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002122 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2123 L"default");
2124 if (_PyStatus_EXCEPTION(status)) {
2125 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002126 }
2127 }
2128
2129 if (config->configure_c_stdio < 0) {
2130 config->configure_c_stdio = 1;
2131 }
2132
Victor Stinnerdc42af82020-11-05 18:58:07 +01002133 // Only parse arguments once.
2134 if (config->parse_argv == 1) {
2135 config->parse_argv = 2;
2136 }
2137
Victor Stinner331a6a52019-05-27 16:39:22 +02002138 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02002139}
Victor Stinner5ed69952018-11-06 15:59:52 +01002140
2141
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002142static void
Victor Stinner331a6a52019-05-27 16:39:22 +02002143config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002144{
2145#if defined(MS_WINDOWS) || defined(__CYGWIN__)
2146 /* don't translate newlines (\r\n <=> \n) */
2147 _setmode(fileno(stdin), O_BINARY);
2148 _setmode(fileno(stdout), O_BINARY);
2149 _setmode(fileno(stderr), O_BINARY);
2150#endif
2151
2152 if (!config->buffered_stdio) {
2153#ifdef HAVE_SETVBUF
2154 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2155 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2156 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2157#else /* !HAVE_SETVBUF */
2158 setbuf(stdin, (char *)NULL);
2159 setbuf(stdout, (char *)NULL);
2160 setbuf(stderr, (char *)NULL);
2161#endif /* !HAVE_SETVBUF */
2162 }
2163 else if (config->interactive) {
2164#ifdef MS_WINDOWS
2165 /* Doesn't have to have line-buffered -- use unbuffered */
2166 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2167 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2168#else /* !MS_WINDOWS */
2169#ifdef HAVE_SETVBUF
2170 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2171 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2172#endif /* HAVE_SETVBUF */
2173#endif /* !MS_WINDOWS */
2174 /* Leave stderr alone - it should be unbuffered anyway. */
2175 }
2176}
2177
2178
2179/* Write the configuration:
2180
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002181 - set Py_xxx global configuration variables
2182 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02002183PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02002184_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002185{
Victor Stinner331a6a52019-05-27 16:39:22 +02002186 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002187
2188 if (config->configure_c_stdio) {
2189 config_init_stdio(config);
2190 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002191
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002192 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02002193 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002194 preconfig->isolated = config->isolated;
2195 preconfig->use_environment = config->use_environment;
2196 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02002197
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002198 if (_Py_SetArgcArgv(config->orig_argv.length,
2199 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02002200 {
2201 return _PyStatus_NO_MEMORY();
2202 }
2203 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01002204}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002205
2206
Victor Stinner331a6a52019-05-27 16:39:22 +02002207/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002208
2209static void
Victor Stinner2f549082019-03-29 15:13:46 +01002210config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002211{
Victor Stinner2f549082019-03-29 15:13:46 +01002212 FILE *f = error ? stderr : stdout;
2213
2214 fprintf(f, usage_line, program);
2215 if (error)
2216 fprintf(f, "Try `python -h' for more information.\n");
2217 else {
2218 fputs(usage_1, f);
2219 fputs(usage_2, f);
2220 fputs(usage_3, f);
2221 fprintf(f, usage_4, (wint_t)DELIM);
2222 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
2223 fputs(usage_6, f);
2224 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002225}
2226
2227
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002228/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02002229static PyStatus
2230config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02002231 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002232{
Victor Stinner331a6a52019-05-27 16:39:22 +02002233 PyStatus status;
2234 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01002235 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02002236 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01002237
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002238 _PyOS_ResetGetOpt();
2239 do {
2240 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01002241 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002242 if (c == EOF) {
2243 break;
2244 }
2245
2246 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002247 if (config->run_command == NULL) {
2248 /* -c is the last option; following arguments
2249 that look like options are left for the
2250 command to interpret. */
2251 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2252 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2253 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002254 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002255 }
2256 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2257 command[len - 2] = '\n';
2258 command[len - 1] = 0;
2259 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002260 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002261 break;
2262 }
2263
2264 if (c == 'm') {
2265 /* -m is the last option; following arguments
2266 that look like options are left for the
2267 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002268 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002269 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2270 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002271 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002272 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002273 }
2274 break;
2275 }
2276
2277 switch (c) {
2278 case 0:
2279 // Handle long option.
2280 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002281 if (wcscmp(_PyOS_optarg, L"always") == 0
2282 || wcscmp(_PyOS_optarg, L"never") == 0
2283 || wcscmp(_PyOS_optarg, L"default") == 0)
2284 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002285 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2286 _PyOS_optarg);
2287 if (_PyStatus_EXCEPTION(status)) {
2288 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002289 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002290 } else {
2291 fprintf(stderr, "--check-hash-based-pycs must be one of "
2292 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02002293 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002294 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002295 }
2296 break;
2297
2298 case 'b':
2299 config->bytes_warning++;
2300 break;
2301
2302 case 'd':
2303 config->parser_debug++;
2304 break;
2305
2306 case 'i':
2307 config->inspect++;
2308 config->interactive++;
2309 break;
2310
Victor Stinner6dcb5422019-03-05 02:44:12 +01002311 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002312 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01002313 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002314 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002315 break;
2316
2317 /* case 'J': reserved for Jython */
2318
2319 case 'O':
2320 config->optimization_level++;
2321 break;
2322
2323 case 'B':
2324 config->write_bytecode = 0;
2325 break;
2326
2327 case 's':
2328 config->user_site_directory = 0;
2329 break;
2330
2331 case 'S':
2332 config->site_import = 0;
2333 break;
2334
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002335 case 't':
2336 /* ignored for backwards compatibility */
2337 break;
2338
2339 case 'u':
2340 config->buffered_stdio = 0;
2341 break;
2342
2343 case 'v':
2344 config->verbose++;
2345 break;
2346
2347 case 'x':
2348 config->skip_source_first_line = 1;
2349 break;
2350
2351 case 'h':
2352 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002353 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002354 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002355
2356 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002357 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002358 break;
2359
2360 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002361 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2362 if (_PyStatus_EXCEPTION(status)) {
2363 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002364 }
2365 break;
2366
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002367 case 'q':
2368 config->quiet++;
2369 break;
2370
2371 case 'R':
2372 config->use_hash_seed = 0;
2373 break;
2374
2375 /* This space reserved for other options */
2376
2377 default:
2378 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002379 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002380 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002381 }
2382 } while (1);
2383
Victor Stinner2f549082019-03-29 15:13:46 +01002384 if (print_version) {
2385 printf("Python %s\n",
2386 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002387 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002388 }
2389
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002390 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002391 && _PyOS_optind < argv->length
2392 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002393 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002394 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002395 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002396 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002397 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002398 }
2399 }
2400
2401 if (config->run_command != NULL || config->run_module != NULL) {
2402 /* Backup _PyOS_optind */
2403 _PyOS_optind--;
2404 }
2405
Victor Stinnerae239f62019-05-16 17:02:56 +02002406 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002407
Victor Stinner331a6a52019-05-27 16:39:22 +02002408 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002409}
2410
2411
2412#ifdef MS_WINDOWS
2413# define WCSTOK wcstok_s
2414#else
2415# define WCSTOK wcstok
2416#endif
2417
2418/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002419static PyStatus
2420config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002421{
Victor Stinner331a6a52019-05-27 16:39:22 +02002422 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002423 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2424 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002425 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002426 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002427 if (_PyStatus_EXCEPTION(status)) {
2428 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002429 }
2430
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002431 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002432 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002434 }
2435
2436
2437 wchar_t *warning, *context = NULL;
2438 for (warning = WCSTOK(env, L",", &context);
2439 warning != NULL;
2440 warning = WCSTOK(NULL, L",", &context))
2441 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002442 status = PyWideStringList_Append(warnoptions, warning);
2443 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002444 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002445 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002446 }
2447 }
2448 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002449 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002450}
2451
2452
Victor Stinner331a6a52019-05-27 16:39:22 +02002453static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002454warnoptions_append(PyConfig *config, PyWideStringList *options,
2455 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002456{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002457 /* config_init_warnoptions() add existing config warnoptions at the end:
2458 ensure that the new option is not already present in this list to
2459 prevent change the options order whne config_init_warnoptions() is
2460 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002461 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002462 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002463 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002464 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002465 if (_PyWideStringList_Find(options, option)) {
2466 /* Already present: do nothing */
2467 return _PyStatus_OK();
2468 }
2469 return PyWideStringList_Append(options, option);
2470}
2471
2472
2473static PyStatus
2474warnoptions_extend(PyConfig *config, PyWideStringList *options,
2475 const PyWideStringList *options2)
2476{
2477 const Py_ssize_t len = options2->length;
2478 wchar_t *const *items = options2->items;
2479
2480 for (Py_ssize_t i = 0; i < len; i++) {
2481 PyStatus status = warnoptions_append(config, options, items[i]);
2482 if (_PyStatus_EXCEPTION(status)) {
2483 return status;
2484 }
2485 }
2486 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002487}
2488
2489
Victor Stinner331a6a52019-05-27 16:39:22 +02002490static PyStatus
2491config_init_warnoptions(PyConfig *config,
2492 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002493 const PyWideStringList *env_warnoptions,
2494 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002495{
Victor Stinner331a6a52019-05-27 16:39:22 +02002496 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002497 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002498
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002499 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002500 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002501 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002502 * - PyConfig.dev_mode: "default" filter
2503 * - PYTHONWARNINGS environment variable
2504 * - '-W' command line options
2505 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2506 * "default::BytesWarning" or "error::BytesWarning" filter
2507 * - early PySys_AddWarnOption() calls
2508 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002509 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002510 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2511 * module works on the basis of "the most recently added filter will be
2512 * checked first", we add the lowest precedence entries first so that later
2513 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002514 */
2515
Victor Stinner20004952019-03-26 02:31:11 +01002516 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002517 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002518 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002519 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002520 }
2521 }
2522
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002523 status = warnoptions_extend(config, &options, env_warnoptions);
2524 if (_PyStatus_EXCEPTION(status)) {
2525 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002526 }
2527
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002528 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2529 if (_PyStatus_EXCEPTION(status)) {
2530 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002531 }
2532
2533 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2534 * don't even try to emit a warning, so we skip setting the filter in that
2535 * case.
2536 */
2537 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002538 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002539 if (config->bytes_warning> 1) {
2540 filter = L"error::BytesWarning";
2541 }
2542 else {
2543 filter = L"default::BytesWarning";
2544 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002545 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002546 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002547 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002548 }
2549 }
Victor Stinner120b7072019-08-23 18:03:08 +01002550
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002551 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002552 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002553 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002554 }
2555
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002556 /* Always add all PyConfig.warnoptions options */
2557 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2558 if (_PyStatus_EXCEPTION(status)) {
2559 goto error;
2560 }
2561
2562 _PyWideStringList_Clear(&config->warnoptions);
2563 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002564 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002565
2566error:
2567 _PyWideStringList_Clear(&options);
2568 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002569}
2570
2571
Victor Stinner331a6a52019-05-27 16:39:22 +02002572static PyStatus
2573config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002574{
Victor Stinner331a6a52019-05-27 16:39:22 +02002575 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002576 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002577
Victor Stinner74f65682019-03-15 15:08:05 +01002578 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002579 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002580 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002581 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2582 if (_PyStatus_EXCEPTION(status)) {
2583 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002584 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002585 }
2586 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002587 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002588 slice.length = cmdline_argv->length - opt_index;
2589 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002590 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2591 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002592 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002593 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002594 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002595
2596 wchar_t *arg0 = NULL;
2597 if (config->run_command != NULL) {
2598 /* Force sys.argv[0] = '-c' */
2599 arg0 = L"-c";
2600 }
2601 else if (config->run_module != NULL) {
2602 /* Force sys.argv[0] = '-m'*/
2603 arg0 = L"-m";
2604 }
Victor Stinner3939c322019-06-25 15:02:43 +02002605
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002606 if (arg0 != NULL) {
2607 arg0 = _PyMem_RawWcsdup(arg0);
2608 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002609 _PyWideStringList_Clear(&config_argv);
2610 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002611 }
2612
Victor Stinnerfa153762019-03-20 04:25:38 +01002613 PyMem_RawFree(config_argv.items[0]);
2614 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002615 }
2616
Victor Stinner331a6a52019-05-27 16:39:22 +02002617 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002618 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002619 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002620}
2621
2622
Victor Stinner331a6a52019-05-27 16:39:22 +02002623static PyStatus
2624core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002625{
Victor Stinner331a6a52019-05-27 16:39:22 +02002626 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002627
Victor Stinnerdc42af82020-11-05 18:58:07 +01002628 if (config->parse_argv == 1) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002629 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2630 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002631 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002632 }
2633
Victor Stinner331a6a52019-05-27 16:39:22 +02002634 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002635
2636 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2637 if (_PyStatus_EXCEPTION(status)) {
2638 return status;
2639 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002640
Victor Stinner331a6a52019-05-27 16:39:22 +02002641 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002642
Victor Stinner331a6a52019-05-27 16:39:22 +02002643 status = _PyPreCmdline_Read(precmdline, &preconfig);
2644 if (_PyStatus_EXCEPTION(status)) {
2645 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002646 }
2647
Victor Stinner331a6a52019-05-27 16:39:22 +02002648 status = _PyPreCmdline_SetConfig(precmdline, config);
2649 if (_PyStatus_EXCEPTION(status)) {
2650 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002651 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002652 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002653}
2654
2655
Victor Stinner3939c322019-06-25 15:02:43 +02002656/* Get run_filename absolute path */
2657static PyStatus
2658config_run_filename_abspath(PyConfig *config)
2659{
2660 if (!config->run_filename) {
2661 return _PyStatus_OK();
2662 }
2663
2664#ifndef MS_WINDOWS
2665 if (_Py_isabs(config->run_filename)) {
2666 /* path is already absolute */
2667 return _PyStatus_OK();
2668 }
2669#endif
2670
2671 wchar_t *abs_filename;
2672 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2673 /* failed to get the absolute path of the command line filename:
2674 ignore the error, keep the relative path */
2675 return _PyStatus_OK();
2676 }
2677 if (abs_filename == NULL) {
2678 return _PyStatus_NO_MEMORY();
2679 }
2680
2681 PyMem_RawFree(config->run_filename);
2682 config->run_filename = abs_filename;
2683 return _PyStatus_OK();
2684}
2685
2686
Victor Stinner331a6a52019-05-27 16:39:22 +02002687static PyStatus
2688config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002689{
Victor Stinner331a6a52019-05-27 16:39:22 +02002690 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002691 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2692 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2693 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002694
Victor Stinnerae239f62019-05-16 17:02:56 +02002695 if (config->parse_argv < 0) {
2696 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002697 }
Victor Stinner870b0352019-05-17 03:15:12 +02002698
Victor Stinnerfed02e12019-05-17 11:12:09 +02002699 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002700 status = config_init_program_name(config);
2701 if (_PyStatus_EXCEPTION(status)) {
2702 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002703 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002704 }
Victor Stinner2f549082019-03-29 15:13:46 +01002705
Victor Stinnerdc42af82020-11-05 18:58:07 +01002706 if (config->parse_argv == 1) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002707 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002708 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2709 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002710 goto done;
2711 }
2712
Victor Stinner3939c322019-06-25 15:02:43 +02002713 status = config_run_filename_abspath(config);
2714 if (_PyStatus_EXCEPTION(status)) {
2715 goto done;
2716 }
2717
Victor Stinner331a6a52019-05-27 16:39:22 +02002718 status = config_update_argv(config, opt_index);
2719 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002720 goto done;
2721 }
Victor Stinner2f549082019-03-29 15:13:46 +01002722 }
Victor Stinner3939c322019-06-25 15:02:43 +02002723 else {
2724 status = config_run_filename_abspath(config);
2725 if (_PyStatus_EXCEPTION(status)) {
2726 goto done;
2727 }
2728 }
Victor Stinner2f549082019-03-29 15:13:46 +01002729
Victor Stinner2f549082019-03-29 15:13:46 +01002730 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002731 status = config_init_env_warnoptions(config, &env_warnoptions);
2732 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002733 goto done;
2734 }
2735 }
2736
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002737 /* Handle early PySys_AddWarnOption() calls */
2738 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2739 if (_PyStatus_EXCEPTION(status)) {
2740 goto done;
2741 }
2742
Victor Stinner331a6a52019-05-27 16:39:22 +02002743 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002744 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002745 &env_warnoptions,
2746 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002747 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002748 goto done;
2749 }
2750
Victor Stinner331a6a52019-05-27 16:39:22 +02002751 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002752
2753done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002754 _PyWideStringList_Clear(&cmdline_warnoptions);
2755 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002756 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002757 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002758}
2759
2760
Victor Stinner331a6a52019-05-27 16:39:22 +02002761PyStatus
2762_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002763{
Victor Stinner331a6a52019-05-27 16:39:22 +02002764 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2765 if (_PyStatus_EXCEPTION(status)) {
2766 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002767 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002768
Victor Stinner5f38b842019-05-01 02:30:12 +02002769 return _PyArgv_AsWstrList(args, &config->argv);
2770}
2771
2772
Victor Stinner70005ac2019-05-02 15:25:34 -04002773/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2774 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002775PyStatus
2776PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002777{
2778 _PyArgv args = {
2779 .argc = argc,
2780 .use_bytes_argv = 1,
2781 .bytes_argv = argv,
2782 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002783 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002784}
2785
2786
Victor Stinner331a6a52019-05-27 16:39:22 +02002787PyStatus
2788PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002789{
2790 _PyArgv args = {
2791 .argc = argc,
2792 .use_bytes_argv = 0,
2793 .bytes_argv = NULL,
2794 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002795 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002796}
2797
2798
Victor Stinner36242fd2019-07-01 19:13:50 +02002799PyStatus
2800PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2801 Py_ssize_t length, wchar_t **items)
2802{
2803 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2804 if (_PyStatus_EXCEPTION(status)) {
2805 return status;
2806 }
2807
2808 PyWideStringList list2 = {.length = length, .items = items};
2809 if (_PyWideStringList_Copy(list, &list2) < 0) {
2810 return _PyStatus_NO_MEMORY();
2811 }
2812 return _PyStatus_OK();
2813}
2814
2815
Victor Stinner331a6a52019-05-27 16:39:22 +02002816/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002817
2818 * Command line arguments
2819 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002820 * Py_xxx global configuration variables
2821
2822 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002823PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002824_PyConfig_Read(PyConfig *config, int compute_path_config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002825{
Victor Stinner331a6a52019-05-27 16:39:22 +02002826 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002827
Victor Stinner331a6a52019-05-27 16:39:22 +02002828 status = _Py_PreInitializeFromConfig(config, NULL);
2829 if (_PyStatus_EXCEPTION(status)) {
2830 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002831 }
2832
Victor Stinner331a6a52019-05-27 16:39:22 +02002833 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002834
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002835 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002836 && !(config->argv.length == 1
2837 && wcscmp(config->argv.items[0], L"") == 0))
2838 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002839 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002840 return _PyStatus_NO_MEMORY();
2841 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002842 }
2843
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002844 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002845 status = core_read_precmdline(config, &precmdline);
2846 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002847 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002848 }
2849
Victor Stinner870b0352019-05-17 03:15:12 +02002850 assert(config->isolated >= 0);
2851 if (config->isolated) {
2852 config->use_environment = 0;
2853 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002854 }
2855
Victor Stinner331a6a52019-05-27 16:39:22 +02002856 status = config_read_cmdline(config);
2857 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002858 goto done;
2859 }
2860
Victor Stinner120b7072019-08-23 18:03:08 +01002861 /* Handle early PySys_AddXOption() calls */
2862 status = _PySys_ReadPreinitXOptions(config);
2863 if (_PyStatus_EXCEPTION(status)) {
2864 goto done;
2865 }
2866
Victor Stinner9e1b8282020-11-10 13:21:52 +01002867 status = config_read(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002868 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002869 goto done;
2870 }
2871
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002872 assert(config_check_consistency(config));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002873
Victor Stinner331a6a52019-05-27 16:39:22 +02002874 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002875
2876done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002877 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002878 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002879}
Victor Stinner1075d162019-03-25 23:19:57 +01002880
2881
Victor Stinner9e1b8282020-11-10 13:21:52 +01002882PyStatus
2883PyConfig_Read(PyConfig *config)
2884{
2885 return _PyConfig_Read(config, 1);
2886}
2887
2888
Victor Stinner1075d162019-03-25 23:19:57 +01002889PyObject*
2890_Py_GetConfigsAsDict(void)
2891{
Victor Stinner331a6a52019-05-27 16:39:22 +02002892 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002893 PyObject *dict = NULL;
2894
Victor Stinner331a6a52019-05-27 16:39:22 +02002895 result = PyDict_New();
2896 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002897 goto error;
2898 }
2899
Victor Stinner331a6a52019-05-27 16:39:22 +02002900 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002901 dict = _Py_GetGlobalVariablesAsDict();
2902 if (dict == NULL) {
2903 goto error;
2904 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002905 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002906 goto error;
2907 }
2908 Py_CLEAR(dict);
2909
2910 /* pre config */
Victor Stinnerff4584c2020-03-13 18:03:56 +01002911 PyThreadState *tstate = _PyThreadState_GET();
2912 const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002913 dict = _PyPreConfig_AsDict(pre_config);
2914 if (dict == NULL) {
2915 goto error;
2916 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002917 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002918 goto error;
2919 }
2920 Py_CLEAR(dict);
2921
2922 /* core config */
Victor Stinnerda7933e2020-04-13 03:04:28 +02002923 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002924 dict = _PyConfig_AsDict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002925 if (dict == NULL) {
2926 goto error;
2927 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002928 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002929 goto error;
2930 }
2931 Py_CLEAR(dict);
2932
Victor Stinner8f427482020-07-08 00:20:37 +02002933 /* path config */
2934 dict = _PyPathConfig_AsDict();
2935 if (dict == NULL) {
2936 goto error;
2937 }
2938 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2939 goto error;
2940 }
2941 Py_CLEAR(dict);
2942
Victor Stinner331a6a52019-05-27 16:39:22 +02002943 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002944
2945error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002946 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002947 Py_XDECREF(dict);
2948 return NULL;
2949}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002950
2951
2952static void
2953init_dump_ascii_wstr(const wchar_t *str)
2954{
2955 if (str == NULL) {
2956 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002957 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002958 }
2959
2960 PySys_WriteStderr("'");
2961 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002962 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002963 if (ch == L'\'') {
2964 PySys_WriteStderr("\\'");
2965 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002966 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002967 }
2968 else if (ch <= 0xff) {
2969 PySys_WriteStderr("\\x%02x", ch);
2970 }
2971#if SIZEOF_WCHAR_T > 2
2972 else if (ch > 0xffff) {
2973 PySys_WriteStderr("\\U%08x", ch);
2974 }
2975#endif
2976 else {
2977 PySys_WriteStderr("\\u%04x", ch);
2978 }
2979 }
2980 PySys_WriteStderr("'");
2981}
2982
2983
2984/* Dump the Python path configuration into sys.stderr */
2985void
2986_Py_DumpPathConfig(PyThreadState *tstate)
2987{
2988 PyObject *exc_type, *exc_value, *exc_tb;
2989 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2990
2991 PySys_WriteStderr("Python path configuration:\n");
2992
2993#define DUMP_CONFIG(NAME, FIELD) \
2994 do { \
2995 PySys_WriteStderr(" " NAME " = "); \
2996 init_dump_ascii_wstr(config->FIELD); \
2997 PySys_WriteStderr("\n"); \
2998 } while (0)
2999
Victor Stinnerda7933e2020-04-13 03:04:28 +02003000 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003001 DUMP_CONFIG("PYTHONHOME", home);
3002 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
3003 DUMP_CONFIG("program name", program_name);
3004 PySys_WriteStderr(" isolated = %i\n", config->isolated);
3005 PySys_WriteStderr(" environment = %i\n", config->use_environment);
3006 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3007 PySys_WriteStderr(" import site = %i\n", config->site_import);
3008#undef DUMP_CONFIG
3009
3010#define DUMP_SYS(NAME) \
3011 do { \
3012 obj = PySys_GetObject(#NAME); \
3013 PySys_FormatStderr(" sys.%s = ", #NAME); \
3014 if (obj != NULL) { \
3015 PySys_FormatStderr("%A", obj); \
3016 } \
3017 else { \
3018 PySys_WriteStderr("(not set)"); \
3019 } \
3020 PySys_FormatStderr("\n"); \
3021 } while (0)
3022
3023 PyObject *obj;
3024 DUMP_SYS(_base_executable);
3025 DUMP_SYS(base_prefix);
3026 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02003027 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003028 DUMP_SYS(executable);
3029 DUMP_SYS(prefix);
3030 DUMP_SYS(exec_prefix);
3031#undef DUMP_SYS
3032
3033 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3034 if (sys_path != NULL && PyList_Check(sys_path)) {
3035 PySys_WriteStderr(" sys.path = [\n");
3036 Py_ssize_t len = PyList_GET_SIZE(sys_path);
3037 for (Py_ssize_t i=0; i < len; i++) {
3038 PyObject *path = PyList_GET_ITEM(sys_path, i);
3039 PySys_FormatStderr(" %A,\n", path);
3040 }
3041 PySys_WriteStderr(" ]\n");
3042 }
3043
3044 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3045}