blob: b2986116fdc350a1eb43f95335860872659e9984 [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\
Pablo Galindo99b59442020-12-02 17:56:17 +000041-d : turn on parser debugging output (for experts only, only works on\n\
42 debug builds); also PYTHONDEBUG=x\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010043-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
44-h : print this help message and exit (also --help)\n\
45";
46static const char usage_2[] = "\
47-i : inspect interactively after running script; forces a prompt even\n\
48 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
49-I : isolate Python from the user's environment (implies -E and -s)\n\
50-m mod : run library module as a script (terminates option list)\n\
51-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
52 .pyc extension; also PYTHONOPTIMIZE=x\n\
53-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
54 .pyc extension\n\
55-q : don't print version and copyright messages on interactive startup\n\
56-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
57-S : don't imply 'import site' on initialization\n\
58";
59static const char usage_3[] = "\
60-u : force the stdout and stderr streams to be unbuffered;\n\
61 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
62-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
63 can be supplied multiple times to increase verbosity\n\
64-V : print the Python version number and exit (also --version)\n\
65 when given twice, print more information about the build\n\
66-W arg : warning control; arg is action:message:category:module:lineno\n\
67 also PYTHONWARNINGS=arg\n\
68-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000069-X opt : set implementation-specific option. The following options are available:\n\
70\n\
71 -X faulthandler: enable faulthandler\n\
72 -X showrefcount: output the total reference count and number of used\n\
73 memory blocks when the program finishes or after each statement in the\n\
74 interactive interpreter. This only works on debug builds\n\
75 -X tracemalloc: start tracing Python memory allocations using the\n\
76 tracemalloc module. By default, only the most recent frame is stored in a\n\
77 traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
78 traceback limit of NFRAME frames\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000079 -X importtime: show how long each import takes. It shows module name,\n\
80 cumulative time (including nested imports) and self time (excluding\n\
81 nested imports). Note that its output may be broken in multi-threaded\n\
82 application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
Serhiy Storchaka58de1dd2020-09-09 03:28:02 +030083 -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000084 checks which are too expensive to be enabled by default. Effect of the\n\
85 developer mode:\n\
86 * Add default warning filter, as -W default\n\
87 * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
88 * Enable the faulthandler module to dump the Python traceback on a crash\n\
89 * Enable asyncio debug mode\n\
90 * Set the dev_mode attribute of sys.flags to True\n\
91 * io.IOBase destructor logs close() exceptions\n\
92 -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
93 locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
94 otherwise activate automatically)\n\
95 -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
96 given directory instead of to the code tree\n\
Inada Naoki48274832021-03-29 12:28:14 +090097 -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\
Pablo Galindo41f0ef62020-01-23 01:03:04 +000098\n\
Victor Stinner95e2cbf2019-03-01 16:25:19 +010099--check-hash-based-pycs always|default|never:\n\
100 control how Python invalidates hash-based .pyc files\n\
101";
102static const char usage_4[] = "\
103file : program read from script file\n\
104- : program read from stdin (default; interactive mode if a tty)\n\
105arg ...: arguments passed to program in sys.argv[1:]\n\n\
106Other environment variables:\n\
107PYTHONSTARTUP: file executed on interactive startup (no default)\n\
108PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
109 default module search path. The result is sys.path.\n\
110";
111static const char usage_5[] =
112"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
113" The default module search path uses %s.\n"
Sandro Mani8f023a22020-06-08 17:28:11 +0200114"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100115"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
Inada Naoki95826c72019-12-14 14:27:32 +0900116"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100117"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
118"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
119static const char usage_6[] =
120"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
Serhiy Storchakae9c90aa2019-08-24 12:49:27 +0300121" to seed the hashes of str and bytes objects. It can also be set to an\n"
122" integer in the range [0,4294967295] to get hash values with a\n"
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100123" predictable seed.\n"
124"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
125" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
126" hooks.\n"
127"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
128" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
129" locale coercion and locale compatibility warnings on stderr.\n"
130"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
131" debugger. It can be set to the callable of your debugger of choice.\n"
132"PYTHONDEVMODE: enable the development mode.\n"
Inada Naoki48274832021-03-29 12:28:14 +0900133"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"
134"PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n";
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100135
136#if defined(MS_WINDOWS)
137# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
138#else
139# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
140#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200141
142
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100143/* --- Global configuration variables ----------------------------- */
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200144
Victor Stinner6c785c02018-08-01 17:56:14 +0200145/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
Victor Stinner20e1e252019-05-23 04:12:27 +0200146 stdin and stdout error handler to "surrogateescape". */
147int Py_UTF8Mode = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200148int Py_DebugFlag = 0; /* Needed by parser.c */
149int Py_VerboseFlag = 0; /* Needed by import.c */
150int Py_QuietFlag = 0; /* Needed by sysmodule.c */
151int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
152int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
153int Py_OptimizeFlag = 0; /* Needed by compile.c */
154int Py_NoSiteFlag = 0; /* Suppress 'import site' */
155int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
156int Py_FrozenFlag = 0; /* Needed by getpath.c */
157int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
158int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
159int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
160int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
161int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
162int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
163#ifdef MS_WINDOWS
164int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
165int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
166#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200167
168
Victor Stinner1075d162019-03-25 23:19:57 +0100169static PyObject *
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100170_Py_GetGlobalVariablesAsDict(void)
171{
172 PyObject *dict, *obj;
173
174 dict = PyDict_New();
175 if (dict == NULL) {
176 return NULL;
177 }
178
179#define SET_ITEM(KEY, EXPR) \
180 do { \
181 obj = (EXPR); \
182 if (obj == NULL) { \
183 return NULL; \
184 } \
185 int res = PyDict_SetItemString(dict, (KEY), obj); \
186 Py_DECREF(obj); \
187 if (res < 0) { \
188 goto fail; \
189 } \
190 } while (0)
191#define SET_ITEM_INT(VAR) \
192 SET_ITEM(#VAR, PyLong_FromLong(VAR))
193#define FROM_STRING(STR) \
194 ((STR != NULL) ? \
195 PyUnicode_FromString(STR) \
196 : (Py_INCREF(Py_None), Py_None))
197#define SET_ITEM_STR(VAR) \
198 SET_ITEM(#VAR, FROM_STRING(VAR))
199
200 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
201 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
202 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
203 SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
204
205 SET_ITEM_INT(Py_UTF8Mode);
206 SET_ITEM_INT(Py_DebugFlag);
207 SET_ITEM_INT(Py_VerboseFlag);
208 SET_ITEM_INT(Py_QuietFlag);
209 SET_ITEM_INT(Py_InteractiveFlag);
210 SET_ITEM_INT(Py_InspectFlag);
211
212 SET_ITEM_INT(Py_OptimizeFlag);
213 SET_ITEM_INT(Py_NoSiteFlag);
214 SET_ITEM_INT(Py_BytesWarningFlag);
215 SET_ITEM_INT(Py_FrozenFlag);
216 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
217 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
218 SET_ITEM_INT(Py_NoUserSiteDirectory);
219 SET_ITEM_INT(Py_UnbufferedStdioFlag);
220 SET_ITEM_INT(Py_HashRandomizationFlag);
221 SET_ITEM_INT(Py_IsolatedFlag);
222
223#ifdef MS_WINDOWS
224 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
225 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
226#endif
227
228 return dict;
229
230fail:
231 Py_DECREF(dict);
232 return NULL;
233
234#undef FROM_STRING
235#undef SET_ITEM
236#undef SET_ITEM_INT
237#undef SET_ITEM_STR
238}
239
240
Victor Stinner331a6a52019-05-27 16:39:22 +0200241/* --- PyStatus ----------------------------------------------- */
Victor Stinner871ff772019-05-17 23:54:00 +0200242
Victor Stinner331a6a52019-05-27 16:39:22 +0200243PyStatus PyStatus_Ok(void)
244{ return _PyStatus_OK(); }
Victor Stinner871ff772019-05-17 23:54:00 +0200245
Victor Stinner331a6a52019-05-27 16:39:22 +0200246PyStatus PyStatus_Error(const char *err_msg)
Victor Stinner871ff772019-05-17 23:54:00 +0200247{
Victor Stinner048a3562020-11-05 00:45:56 +0100248 assert(err_msg != NULL);
Victor Stinner331a6a52019-05-27 16:39:22 +0200249 return (PyStatus){._type = _PyStatus_TYPE_ERROR,
Victor Stinner048a3562020-11-05 00:45:56 +0100250 .err_msg = err_msg};
Victor Stinner871ff772019-05-17 23:54:00 +0200251}
252
Victor Stinner331a6a52019-05-27 16:39:22 +0200253PyStatus PyStatus_NoMemory(void)
254{ return PyStatus_Error("memory allocation failed"); }
Victor Stinner871ff772019-05-17 23:54:00 +0200255
Victor Stinner331a6a52019-05-27 16:39:22 +0200256PyStatus PyStatus_Exit(int exitcode)
257{ return _PyStatus_EXIT(exitcode); }
Victor Stinner871ff772019-05-17 23:54:00 +0200258
259
Victor Stinner331a6a52019-05-27 16:39:22 +0200260int PyStatus_IsError(PyStatus status)
261{ return _PyStatus_IS_ERROR(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200262
Victor Stinner331a6a52019-05-27 16:39:22 +0200263int PyStatus_IsExit(PyStatus status)
264{ return _PyStatus_IS_EXIT(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200265
Victor Stinner331a6a52019-05-27 16:39:22 +0200266int PyStatus_Exception(PyStatus status)
267{ return _PyStatus_EXCEPTION(status); }
Victor Stinner871ff772019-05-17 23:54:00 +0200268
Victor Stinner048a3562020-11-05 00:45:56 +0100269PyObject*
270_PyErr_SetFromPyStatus(PyStatus status)
271{
272 if (!_PyStatus_IS_ERROR(status)) {
273 PyErr_Format(PyExc_SystemError,
274 "%s() expects an error PyStatus",
275 _PyStatus_GET_FUNC());
276 }
277 else if (status.func) {
278 PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
279 }
280 else {
281 PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
282 }
283 return NULL;
284}
285
Victor Stinner871ff772019-05-17 23:54:00 +0200286
Victor Stinner331a6a52019-05-27 16:39:22 +0200287/* --- PyWideStringList ------------------------------------------------ */
Victor Stinner74f65682019-03-15 15:08:05 +0100288
289#ifndef NDEBUG
290int
Victor Stinner331a6a52019-05-27 16:39:22 +0200291_PyWideStringList_CheckConsistency(const PyWideStringList *list)
Victor Stinner74f65682019-03-15 15:08:05 +0100292{
293 assert(list->length >= 0);
294 if (list->length != 0) {
295 assert(list->items != NULL);
296 }
297 for (Py_ssize_t i = 0; i < list->length; i++) {
298 assert(list->items[i] != NULL);
299 }
300 return 1;
301}
302#endif /* Py_DEBUG */
303
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100304
Victor Stinner6c785c02018-08-01 17:56:14 +0200305void
Victor Stinner331a6a52019-05-27 16:39:22 +0200306_PyWideStringList_Clear(PyWideStringList *list)
Victor Stinner6c785c02018-08-01 17:56:14 +0200307{
Victor Stinner331a6a52019-05-27 16:39:22 +0200308 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner74f65682019-03-15 15:08:05 +0100309 for (Py_ssize_t i=0; i < list->length; i++) {
310 PyMem_RawFree(list->items[i]);
Victor Stinner6c785c02018-08-01 17:56:14 +0200311 }
Victor Stinner74f65682019-03-15 15:08:05 +0100312 PyMem_RawFree(list->items);
313 list->length = 0;
314 list->items = NULL;
Victor Stinner6c785c02018-08-01 17:56:14 +0200315}
316
317
Victor Stinner74f65682019-03-15 15:08:05 +0100318int
Victor Stinner331a6a52019-05-27 16:39:22 +0200319_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200320{
Victor Stinner331a6a52019-05-27 16:39:22 +0200321 assert(_PyWideStringList_CheckConsistency(list));
322 assert(_PyWideStringList_CheckConsistency(list2));
Victor Stinner74f65682019-03-15 15:08:05 +0100323
324 if (list2->length == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200325 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100326 return 0;
Alexey Izbysheveb746db2018-08-25 02:34:56 +0300327 }
Victor Stinner74f65682019-03-15 15:08:05 +0100328
Victor Stinnerfb4ae152019-09-30 01:40:17 +0200329 PyWideStringList copy = _PyWideStringList_INIT;
Victor Stinner74f65682019-03-15 15:08:05 +0100330
331 size_t size = list2->length * sizeof(list2->items[0]);
332 copy.items = PyMem_RawMalloc(size);
333 if (copy.items == NULL) {
334 return -1;
335 }
336
337 for (Py_ssize_t i=0; i < list2->length; i++) {
338 wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
339 if (item == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200340 _PyWideStringList_Clear(&copy);
Victor Stinner74f65682019-03-15 15:08:05 +0100341 return -1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200342 }
Victor Stinner74f65682019-03-15 15:08:05 +0100343 copy.items[i] = item;
344 copy.length = i + 1;
Victor Stinner6c785c02018-08-01 17:56:14 +0200345 }
Victor Stinner74f65682019-03-15 15:08:05 +0100346
Victor Stinner331a6a52019-05-27 16:39:22 +0200347 _PyWideStringList_Clear(list);
Victor Stinner74f65682019-03-15 15:08:05 +0100348 *list = copy;
349 return 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200350}
351
352
Victor Stinner331a6a52019-05-27 16:39:22 +0200353PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100354PyWideStringList_Insert(PyWideStringList *list,
355 Py_ssize_t index, const wchar_t *item)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100356{
Victor Stinner3842f292019-08-23 16:57:54 +0100357 Py_ssize_t len = list->length;
358 if (len == PY_SSIZE_T_MAX) {
Min ho Kim96e12d52019-07-22 06:12:33 +1000359 /* length+1 would overflow */
Victor Stinner331a6a52019-05-27 16:39:22 +0200360 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100361 }
Victor Stinner3842f292019-08-23 16:57:54 +0100362 if (index < 0) {
363 return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
364 }
365 if (index > len) {
366 index = len;
367 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100368
Victor Stinner74f65682019-03-15 15:08:05 +0100369 wchar_t *item2 = _PyMem_RawWcsdup(item);
370 if (item2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200371 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100372 }
Victor Stinner74f65682019-03-15 15:08:05 +0100373
Victor Stinner3842f292019-08-23 16:57:54 +0100374 size_t size = (len + 1) * sizeof(list->items[0]);
Victor Stinner74f65682019-03-15 15:08:05 +0100375 wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
376 if (items2 == NULL) {
377 PyMem_RawFree(item2);
Victor Stinner331a6a52019-05-27 16:39:22 +0200378 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +0100379 }
380
Victor Stinner3842f292019-08-23 16:57:54 +0100381 if (index < len) {
382 memmove(&items2[index + 1],
383 &items2[index],
384 (len - index) * sizeof(items2[0]));
385 }
386
387 items2[index] = item2;
Victor Stinner74f65682019-03-15 15:08:05 +0100388 list->items = items2;
389 list->length++;
Victor Stinner331a6a52019-05-27 16:39:22 +0200390 return _PyStatus_OK();
Victor Stinner74f65682019-03-15 15:08:05 +0100391}
392
393
Victor Stinner331a6a52019-05-27 16:39:22 +0200394PyStatus
Victor Stinner3842f292019-08-23 16:57:54 +0100395PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
396{
397 return PyWideStringList_Insert(list, list->length, item);
398}
399
400
401PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +0200402_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
Victor Stinner74f65682019-03-15 15:08:05 +0100403{
404 for (Py_ssize_t i = 0; i < list2->length; i++) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200405 PyStatus status = PyWideStringList_Append(list, list2->items[i]);
406 if (_PyStatus_EXCEPTION(status)) {
407 return status;
Victor Stinner74f65682019-03-15 15:08:05 +0100408 }
409 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200410 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100411}
412
413
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100414static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200415_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100416{
417 for (Py_ssize_t i = 0; i < list->length; i++) {
418 if (wcscmp(list->items[i], item) == 0) {
419 return 1;
420 }
421 }
422 return 0;
423}
424
425
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100426PyObject*
Victor Stinner331a6a52019-05-27 16:39:22 +0200427_PyWideStringList_AsList(const PyWideStringList *list)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100428{
Victor Stinner331a6a52019-05-27 16:39:22 +0200429 assert(_PyWideStringList_CheckConsistency(list));
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100430
Victor Stinner74f65682019-03-15 15:08:05 +0100431 PyObject *pylist = PyList_New(list->length);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100432 if (pylist == NULL) {
433 return NULL;
434 }
435
Victor Stinner74f65682019-03-15 15:08:05 +0100436 for (Py_ssize_t i = 0; i < list->length; i++) {
437 PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
438 if (item == NULL) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100439 Py_DECREF(pylist);
440 return NULL;
441 }
Victor Stinner74f65682019-03-15 15:08:05 +0100442 PyList_SET_ITEM(pylist, i, item);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100443 }
444 return pylist;
445}
446
447
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100448/* --- Py_SetStandardStreamEncoding() ----------------------------- */
449
Victor Stinner124b9eb2018-08-29 01:29:06 +0200450/* Helper to allow an embedding application to override the normal
451 * mechanism that attempts to figure out an appropriate IO encoding
452 */
453
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200454static char *_Py_StandardStreamEncoding = NULL;
455static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200456
457int
458Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
459{
460 if (Py_IsInitialized()) {
461 /* This is too late to have any effect */
462 return -1;
463 }
464
465 int res = 0;
466
467 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
468 but Py_Initialize() can change the allocator. Use a known allocator
469 to be able to release the memory later. */
470 PyMemAllocatorEx old_alloc;
471 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
472
473 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
474 * initialised yet.
475 *
476 * However, the raw memory allocators are initialised appropriately
477 * as C static variables, so _PyMem_RawStrdup is OK even though
478 * Py_Initialize hasn't been called yet.
479 */
480 if (encoding) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200481 PyMem_RawFree(_Py_StandardStreamEncoding);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200482 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
483 if (!_Py_StandardStreamEncoding) {
484 res = -2;
485 goto done;
486 }
487 }
488 if (errors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200489 PyMem_RawFree(_Py_StandardStreamErrors);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200490 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
491 if (!_Py_StandardStreamErrors) {
Victor Stinner463b82a2019-05-01 01:36:13 +0200492 PyMem_RawFree(_Py_StandardStreamEncoding);
493 _Py_StandardStreamEncoding = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +0200494 res = -3;
495 goto done;
496 }
497 }
498#ifdef MS_WINDOWS
499 if (_Py_StandardStreamEncoding) {
500 /* Overriding the stream encoding implies legacy streams */
501 Py_LegacyWindowsStdioFlag = 1;
502 }
503#endif
504
505done:
506 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
507
508 return res;
509}
510
511
512void
513_Py_ClearStandardStreamEncoding(void)
514{
515 /* Use the same allocator than Py_SetStandardStreamEncoding() */
516 PyMemAllocatorEx old_alloc;
517 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
518
519 /* We won't need them anymore. */
520 if (_Py_StandardStreamEncoding) {
521 PyMem_RawFree(_Py_StandardStreamEncoding);
522 _Py_StandardStreamEncoding = NULL;
523 }
524 if (_Py_StandardStreamErrors) {
525 PyMem_RawFree(_Py_StandardStreamErrors);
526 _Py_StandardStreamErrors = NULL;
527 }
528
529 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
530}
531
532
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100533/* --- Py_GetArgcArgv() ------------------------------------------- */
534
535/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
Victor Stinner331a6a52019-05-27 16:39:22 +0200536static PyWideStringList orig_argv = {.length = 0, .items = NULL};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100537
538
539void
540_Py_ClearArgcArgv(void)
541{
542 PyMemAllocatorEx old_alloc;
543 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
544
Victor Stinner331a6a52019-05-27 16:39:22 +0200545 _PyWideStringList_Clear(&orig_argv);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100546
547 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
548}
549
550
Victor Stinner4fffd382019-03-06 01:44:31 +0100551static int
Victor Stinner74f65682019-03-15 15:08:05 +0100552_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100553{
Victor Stinner331a6a52019-05-27 16:39:22 +0200554 const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100555 int res;
556
557 PyMemAllocatorEx old_alloc;
558 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
559
Victor Stinner331a6a52019-05-27 16:39:22 +0200560 res = _PyWideStringList_Copy(&orig_argv, &argv_list);
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100561
562 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
563 return res;
564}
565
566
Victor Stinner4b9aad42020-11-02 16:49:54 +0100567// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100568void
569Py_GetArgcArgv(int *argc, wchar_t ***argv)
570{
Victor Stinner74f65682019-03-15 15:08:05 +0100571 *argc = (int)orig_argv.length;
572 *argv = orig_argv.items;
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100573}
574
575
Victor Stinner331a6a52019-05-27 16:39:22 +0200576/* --- PyConfig ---------------------------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100577
578#define DECODE_LOCALE_ERR(NAME, LEN) \
579 (((LEN) == -2) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200580 ? _PyStatus_ERR("cannot decode " NAME) \
581 : _PyStatus_NO_MEMORY())
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100582
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100583#define MAX_HASH_SEED 4294967295UL
584
585
586#ifndef NDEBUG
587static int
588config_check_consistency(const PyConfig *config)
589{
590 /* Check config consistency */
591 assert(config->isolated >= 0);
592 assert(config->use_environment >= 0);
593 assert(config->dev_mode >= 0);
594 assert(config->install_signal_handlers >= 0);
595 assert(config->use_hash_seed >= 0);
596 assert(config->hash_seed <= MAX_HASH_SEED);
597 assert(config->faulthandler >= 0);
598 assert(config->tracemalloc >= 0);
599 assert(config->import_time >= 0);
600 assert(config->show_ref_count >= 0);
601 assert(config->dump_refs >= 0);
602 assert(config->malloc_stats >= 0);
603 assert(config->site_import >= 0);
604 assert(config->bytes_warning >= 0);
Inada Naoki48274832021-03-29 12:28:14 +0900605 assert(config->warn_default_encoding >= 0);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100606 assert(config->inspect >= 0);
607 assert(config->interactive >= 0);
608 assert(config->optimization_level >= 0);
609 assert(config->parser_debug >= 0);
610 assert(config->write_bytecode >= 0);
611 assert(config->verbose >= 0);
612 assert(config->quiet >= 0);
613 assert(config->user_site_directory >= 0);
614 assert(config->parse_argv >= 0);
615 assert(config->configure_c_stdio >= 0);
616 assert(config->buffered_stdio >= 0);
617 assert(config->program_name != NULL);
618 assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
619 assert(_PyWideStringList_CheckConsistency(&config->argv));
620 /* sys.argv must be non-empty: empty argv is replaced with [''] */
621 assert(config->argv.length >= 1);
622 assert(_PyWideStringList_CheckConsistency(&config->xoptions));
623 assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
624 assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
625 assert(config->module_search_paths_set >= 0);
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100626 assert(config->platlibdir != NULL);
627 assert(config->filesystem_encoding != NULL);
628 assert(config->filesystem_errors != NULL);
629 assert(config->stdio_encoding != NULL);
630 assert(config->stdio_errors != NULL);
631#ifdef MS_WINDOWS
632 assert(config->legacy_windows_stdio >= 0);
633#endif
634 /* -c and -m options are exclusive */
635 assert(!(config->run_command != NULL && config->run_module != NULL));
636 assert(config->check_hash_pycs_mode != NULL);
637 assert(config->_install_importlib >= 0);
638 assert(config->pathconfig_warnings >= 0);
639 return 1;
640}
641#endif
642
Victor Stinner441b10c2019-09-28 04:28:35 +0200643
Victor Stinner6c785c02018-08-01 17:56:14 +0200644/* Free memory allocated in config, but don't clear all attributes */
645void
Victor Stinner331a6a52019-05-27 16:39:22 +0200646PyConfig_Clear(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +0200647{
648#define CLEAR(ATTR) \
649 do { \
650 PyMem_RawFree(ATTR); \
651 ATTR = NULL; \
652 } while (0)
Victor Stinner6c785c02018-08-01 17:56:14 +0200653
654 CLEAR(config->pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200655 CLEAR(config->pythonpath_env);
Victor Stinner6c785c02018-08-01 17:56:14 +0200656 CLEAR(config->home);
657 CLEAR(config->program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200658
Victor Stinner331a6a52019-05-27 16:39:22 +0200659 _PyWideStringList_Clear(&config->argv);
660 _PyWideStringList_Clear(&config->warnoptions);
661 _PyWideStringList_Clear(&config->xoptions);
662 _PyWideStringList_Clear(&config->module_search_paths);
663 config->module_search_paths_set = 0;
Victor Stinner6c785c02018-08-01 17:56:14 +0200664
665 CLEAR(config->executable);
Steve Dower9048c492019-06-29 10:34:11 -0700666 CLEAR(config->base_executable);
Victor Stinner6c785c02018-08-01 17:56:14 +0200667 CLEAR(config->prefix);
668 CLEAR(config->base_prefix);
669 CLEAR(config->exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200670 CLEAR(config->base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200671 CLEAR(config->platlibdir);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200672
Victor Stinnerb2457ef2018-08-29 13:25:36 +0200673 CLEAR(config->filesystem_encoding);
674 CLEAR(config->filesystem_errors);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200675 CLEAR(config->stdio_encoding);
676 CLEAR(config->stdio_errors);
Victor Stinner4fffd382019-03-06 01:44:31 +0100677 CLEAR(config->run_command);
678 CLEAR(config->run_module);
679 CLEAR(config->run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400680 CLEAR(config->check_hash_pycs_mode);
Victor Stinnere2d47a02020-06-15 16:27:47 +0200681
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200682 _PyWideStringList_Clear(&config->orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200683#undef CLEAR
Victor Stinner6c785c02018-08-01 17:56:14 +0200684}
685
686
Victor Stinner8462a492019-10-01 12:06:16 +0200687void
Victor Stinner331a6a52019-05-27 16:39:22 +0200688_PyConfig_InitCompatConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200689{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200690 memset(config, 0, sizeof(*config));
Victor Stinner441b10c2019-09-28 04:28:35 +0200691
Victor Stinner022be022019-05-22 23:58:50 +0200692 config->_config_init = (int)_PyConfig_INIT_COMPAT;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200693 config->isolated = -1;
694 config->use_environment = -1;
695 config->dev_mode = -1;
696 config->install_signal_handlers = 1;
697 config->use_hash_seed = -1;
698 config->faulthandler = -1;
699 config->tracemalloc = -1;
Victor Stinner331a6a52019-05-27 16:39:22 +0200700 config->module_search_paths_set = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200701 config->parse_argv = 0;
702 config->site_import = -1;
703 config->bytes_warning = -1;
Inada Naoki48274832021-03-29 12:28:14 +0900704 config->warn_default_encoding = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200705 config->inspect = -1;
706 config->interactive = -1;
707 config->optimization_level = -1;
708 config->parser_debug= -1;
709 config->write_bytecode = -1;
710 config->verbose = -1;
711 config->quiet = -1;
712 config->user_site_directory = -1;
713 config->configure_c_stdio = 0;
714 config->buffered_stdio = -1;
715 config->_install_importlib = 1;
716 config->check_hash_pycs_mode = NULL;
717 config->pathconfig_warnings = -1;
718 config->_init_main = 1;
Victor Stinner252346a2020-05-01 11:33:44 +0200719 config->_isolated_interpreter = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200720#ifdef MS_WINDOWS
721 config->legacy_windows_stdio = -1;
722#endif
723}
724
725
Victor Stinner8462a492019-10-01 12:06:16 +0200726static void
Victor Stinner331a6a52019-05-27 16:39:22 +0200727config_init_defaults(PyConfig *config)
Victor Stinnerbab0db62019-05-18 03:21:27 +0200728{
Victor Stinner8462a492019-10-01 12:06:16 +0200729 _PyConfig_InitCompatConfig(config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200730
731 config->isolated = 0;
732 config->use_environment = 1;
733 config->site_import = 1;
734 config->bytes_warning = 0;
735 config->inspect = 0;
736 config->interactive = 0;
737 config->optimization_level = 0;
738 config->parser_debug= 0;
739 config->write_bytecode = 1;
740 config->verbose = 0;
741 config->quiet = 0;
742 config->user_site_directory = 1;
743 config->buffered_stdio = 1;
744 config->pathconfig_warnings = 1;
745#ifdef MS_WINDOWS
746 config->legacy_windows_stdio = 0;
747#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200748}
749
750
Victor Stinner8462a492019-10-01 12:06:16 +0200751void
Victor Stinner331a6a52019-05-27 16:39:22 +0200752PyConfig_InitPythonConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200753{
Victor Stinner8462a492019-10-01 12:06:16 +0200754 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200755
Victor Stinner022be022019-05-22 23:58:50 +0200756 config->_config_init = (int)_PyConfig_INIT_PYTHON;
Victor Stinnercab5d072019-05-17 19:01:14 +0200757 config->configure_c_stdio = 1;
758 config->parse_argv = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200759}
760
761
Victor Stinner8462a492019-10-01 12:06:16 +0200762void
Victor Stinner331a6a52019-05-27 16:39:22 +0200763PyConfig_InitIsolatedConfig(PyConfig *config)
Victor Stinnercab5d072019-05-17 19:01:14 +0200764{
Victor Stinner8462a492019-10-01 12:06:16 +0200765 config_init_defaults(config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200766
Victor Stinner022be022019-05-22 23:58:50 +0200767 config->_config_init = (int)_PyConfig_INIT_ISOLATED;
Victor Stinnercab5d072019-05-17 19:01:14 +0200768 config->isolated = 1;
Victor Stinnercab5d072019-05-17 19:01:14 +0200769 config->use_environment = 0;
Victor Stinnerbab0db62019-05-18 03:21:27 +0200770 config->user_site_directory = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200771 config->dev_mode = 0;
772 config->install_signal_handlers = 0;
773 config->use_hash_seed = 0;
774 config->faulthandler = 0;
775 config->tracemalloc = 0;
Victor Stinnercab5d072019-05-17 19:01:14 +0200776 config->pathconfig_warnings = 0;
777#ifdef MS_WINDOWS
778 config->legacy_windows_stdio = 0;
779#endif
Victor Stinnercab5d072019-05-17 19:01:14 +0200780}
781
782
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200783/* Copy str into *config_str (duplicate the string) */
Victor Stinner331a6a52019-05-27 16:39:22 +0200784PyStatus
785PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200786{
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
788 if (_PyStatus_EXCEPTION(status)) {
789 return status;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200790 }
791
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200792 wchar_t *str2;
793 if (str != NULL) {
794 str2 = _PyMem_RawWcsdup(str);
795 if (str2 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200796 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200797 }
798 }
799 else {
800 str2 = NULL;
801 }
802 PyMem_RawFree(*config_str);
803 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200804 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200805}
806
807
Victor Stinner331a6a52019-05-27 16:39:22 +0200808static PyStatus
809config_set_bytes_string(PyConfig *config, wchar_t **config_str,
810 const char *str, const char *decode_err_msg)
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200811{
Victor Stinner331a6a52019-05-27 16:39:22 +0200812 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
813 if (_PyStatus_EXCEPTION(status)) {
814 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -0400815 }
816
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200817 wchar_t *str2;
818 if (str != NULL) {
819 size_t len;
820 str2 = Py_DecodeLocale(str, &len);
821 if (str2 == NULL) {
822 if (len == (size_t)-2) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200823 return _PyStatus_ERR(decode_err_msg);
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200824 }
825 else {
Victor Stinner331a6a52019-05-27 16:39:22 +0200826 return _PyStatus_NO_MEMORY();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200827 }
828 }
829 }
830 else {
831 str2 = NULL;
832 }
833 PyMem_RawFree(*config_str);
834 *config_str = str2;
Victor Stinner331a6a52019-05-27 16:39:22 +0200835 return _PyStatus_OK();
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200836}
837
838
Victor Stinner331a6a52019-05-27 16:39:22 +0200839#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
840 config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
Victor Stinner709d23d2019-05-02 14:56:30 -0400841
842
Victor Stinner70005ac2019-05-02 15:25:34 -0400843/* Decode str using Py_DecodeLocale() and set the result into *config_str.
844 Pre-initialize Python if needed to ensure that encodings are properly
845 configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200846PyStatus
847PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
Victor Stinner710e8262020-10-31 01:02:09 +0100848 const char *str)
Victor Stinner709d23d2019-05-02 14:56:30 -0400849{
Victor Stinner331a6a52019-05-27 16:39:22 +0200850 return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
Victor Stinner709d23d2019-05-02 14:56:30 -0400851}
Victor Stinner1a9f0d82019-05-01 15:22:52 +0200852
853
Victor Stinner331a6a52019-05-27 16:39:22 +0200854PyStatus
855_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
Victor Stinner6c785c02018-08-01 17:56:14 +0200856{
Victor Stinner331a6a52019-05-27 16:39:22 +0200857 PyStatus status;
Victor Stinner441b10c2019-09-28 04:28:35 +0200858
Victor Stinner331a6a52019-05-27 16:39:22 +0200859 PyConfig_Clear(config);
Victor Stinner6c785c02018-08-01 17:56:14 +0200860
861#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200862#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200863 do { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200864 status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
865 if (_PyStatus_EXCEPTION(status)) { \
866 return status; \
Victor Stinner6c785c02018-08-01 17:56:14 +0200867 } \
868 } while (0)
Victor Stinner74f65682019-03-15 15:08:05 +0100869#define COPY_WSTRLIST(LIST) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200870 do { \
Victor Stinner36242fd2019-07-01 19:13:50 +0200871 if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +0200872 return _PyStatus_NO_MEMORY(); \
Victor Stinner6c785c02018-08-01 17:56:14 +0200873 } \
Victor Stinner6c785c02018-08-01 17:56:14 +0200874 } while (0)
875
Victor Stinner6d1c4672019-05-20 11:02:00 +0200876 COPY_ATTR(_config_init);
Victor Stinner20004952019-03-26 02:31:11 +0100877 COPY_ATTR(isolated);
878 COPY_ATTR(use_environment);
879 COPY_ATTR(dev_mode);
Victor Stinner6c785c02018-08-01 17:56:14 +0200880 COPY_ATTR(install_signal_handlers);
Victor Stinner6c785c02018-08-01 17:56:14 +0200881 COPY_ATTR(use_hash_seed);
882 COPY_ATTR(hash_seed);
883 COPY_ATTR(_install_importlib);
Victor Stinner6c785c02018-08-01 17:56:14 +0200884 COPY_ATTR(faulthandler);
885 COPY_ATTR(tracemalloc);
886 COPY_ATTR(import_time);
887 COPY_ATTR(show_ref_count);
Victor Stinner6c785c02018-08-01 17:56:14 +0200888 COPY_ATTR(dump_refs);
889 COPY_ATTR(malloc_stats);
890
Victor Stinner124b9eb2018-08-29 01:29:06 +0200891 COPY_WSTR_ATTR(pycache_prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200892 COPY_WSTR_ATTR(pythonpath_env);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200893 COPY_WSTR_ATTR(home);
894 COPY_WSTR_ATTR(program_name);
Victor Stinner6c785c02018-08-01 17:56:14 +0200895
Victor Stinnerae239f62019-05-16 17:02:56 +0200896 COPY_ATTR(parse_argv);
Victor Stinner74f65682019-03-15 15:08:05 +0100897 COPY_WSTRLIST(argv);
898 COPY_WSTRLIST(warnoptions);
899 COPY_WSTRLIST(xoptions);
900 COPY_WSTRLIST(module_search_paths);
Victor Stinner331a6a52019-05-27 16:39:22 +0200901 COPY_ATTR(module_search_paths_set);
Victor Stinner6c785c02018-08-01 17:56:14 +0200902
Victor Stinner124b9eb2018-08-29 01:29:06 +0200903 COPY_WSTR_ATTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -0700904 COPY_WSTR_ATTR(base_executable);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200905 COPY_WSTR_ATTR(prefix);
906 COPY_WSTR_ATTR(base_prefix);
907 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner124b9eb2018-08-29 01:29:06 +0200908 COPY_WSTR_ATTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +0200909 COPY_WSTR_ATTR(platlibdir);
Victor Stinner6c785c02018-08-01 17:56:14 +0200910
Victor Stinner6c785c02018-08-01 17:56:14 +0200911 COPY_ATTR(site_import);
912 COPY_ATTR(bytes_warning);
Inada Naoki48274832021-03-29 12:28:14 +0900913 COPY_ATTR(warn_default_encoding);
Victor Stinner6c785c02018-08-01 17:56:14 +0200914 COPY_ATTR(inspect);
915 COPY_ATTR(interactive);
916 COPY_ATTR(optimization_level);
917 COPY_ATTR(parser_debug);
918 COPY_ATTR(write_bytecode);
919 COPY_ATTR(verbose);
920 COPY_ATTR(quiet);
921 COPY_ATTR(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +0200922 COPY_ATTR(configure_c_stdio);
Victor Stinner6c785c02018-08-01 17:56:14 +0200923 COPY_ATTR(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -0400924 COPY_WSTR_ATTR(filesystem_encoding);
925 COPY_WSTR_ATTR(filesystem_errors);
926 COPY_WSTR_ATTR(stdio_encoding);
927 COPY_WSTR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200928#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +0200929 COPY_ATTR(legacy_windows_stdio);
930#endif
Victor Stinner62be7632019-03-01 13:10:14 +0100931 COPY_ATTR(skip_source_first_line);
932 COPY_WSTR_ATTR(run_command);
933 COPY_WSTR_ATTR(run_module);
934 COPY_WSTR_ATTR(run_filename);
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400935 COPY_WSTR_ATTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200936 COPY_ATTR(pathconfig_warnings);
937 COPY_ATTR(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +0200938 COPY_ATTR(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +0200939 COPY_WSTRLIST(orig_argv);
Victor Stinner6c785c02018-08-01 17:56:14 +0200940
941#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200942#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200943#undef COPY_WSTRLIST
Victor Stinner331a6a52019-05-27 16:39:22 +0200944 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +0200945}
946
947
Victor Stinnerf3cb8142020-11-05 18:12:33 +0100948PyObject *
949_PyConfig_AsDict(const PyConfig *config)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100950{
Victor Stinner8f427482020-07-08 00:20:37 +0200951 PyObject *dict = PyDict_New();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100952 if (dict == NULL) {
953 return NULL;
954 }
955
956#define SET_ITEM(KEY, EXPR) \
957 do { \
958 PyObject *obj = (EXPR); \
959 if (obj == NULL) { \
960 goto fail; \
961 } \
962 int res = PyDict_SetItemString(dict, (KEY), obj); \
963 Py_DECREF(obj); \
964 if (res < 0) { \
965 goto fail; \
966 } \
967 } while (0)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100968#define SET_ITEM_INT(ATTR) \
969 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
970#define SET_ITEM_UINT(ATTR) \
971 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100972#define FROM_WSTRING(STR) \
973 ((STR != NULL) ? \
974 PyUnicode_FromWideChar(STR, -1) \
975 : (Py_INCREF(Py_None), Py_None))
976#define SET_ITEM_WSTR(ATTR) \
977 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
978#define SET_ITEM_WSTRLIST(LIST) \
Victor Stinner331a6a52019-05-27 16:39:22 +0200979 SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100980
Victor Stinner6d1c4672019-05-20 11:02:00 +0200981 SET_ITEM_INT(_config_init);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100982 SET_ITEM_INT(isolated);
983 SET_ITEM_INT(use_environment);
984 SET_ITEM_INT(dev_mode);
985 SET_ITEM_INT(install_signal_handlers);
986 SET_ITEM_INT(use_hash_seed);
987 SET_ITEM_UINT(hash_seed);
988 SET_ITEM_INT(faulthandler);
989 SET_ITEM_INT(tracemalloc);
990 SET_ITEM_INT(import_time);
991 SET_ITEM_INT(show_ref_count);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100992 SET_ITEM_INT(dump_refs);
993 SET_ITEM_INT(malloc_stats);
Victor Stinner709d23d2019-05-02 14:56:30 -0400994 SET_ITEM_WSTR(filesystem_encoding);
995 SET_ITEM_WSTR(filesystem_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100996 SET_ITEM_WSTR(pycache_prefix);
997 SET_ITEM_WSTR(program_name);
Victor Stinnerae239f62019-05-16 17:02:56 +0200998 SET_ITEM_INT(parse_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100999 SET_ITEM_WSTRLIST(argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001000 SET_ITEM_WSTRLIST(xoptions);
1001 SET_ITEM_WSTRLIST(warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 SET_ITEM_WSTR(pythonpath_env);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001003 SET_ITEM_WSTR(home);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001004 SET_ITEM_INT(module_search_paths_set);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001005 SET_ITEM_WSTRLIST(module_search_paths);
1006 SET_ITEM_WSTR(executable);
Steve Dower9048c492019-06-29 10:34:11 -07001007 SET_ITEM_WSTR(base_executable);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001008 SET_ITEM_WSTR(prefix);
1009 SET_ITEM_WSTR(base_prefix);
1010 SET_ITEM_WSTR(exec_prefix);
1011 SET_ITEM_WSTR(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02001012 SET_ITEM_WSTR(platlibdir);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001013 SET_ITEM_INT(site_import);
1014 SET_ITEM_INT(bytes_warning);
Inada Naoki48274832021-03-29 12:28:14 +09001015 SET_ITEM_INT(warn_default_encoding);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001016 SET_ITEM_INT(inspect);
1017 SET_ITEM_INT(interactive);
1018 SET_ITEM_INT(optimization_level);
1019 SET_ITEM_INT(parser_debug);
1020 SET_ITEM_INT(write_bytecode);
1021 SET_ITEM_INT(verbose);
1022 SET_ITEM_INT(quiet);
1023 SET_ITEM_INT(user_site_directory);
Victor Stinner54b43bb2019-05-16 18:30:15 +02001024 SET_ITEM_INT(configure_c_stdio);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001025 SET_ITEM_INT(buffered_stdio);
Victor Stinner709d23d2019-05-02 14:56:30 -04001026 SET_ITEM_WSTR(stdio_encoding);
1027 SET_ITEM_WSTR(stdio_errors);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001028#ifdef MS_WINDOWS
1029 SET_ITEM_INT(legacy_windows_stdio);
1030#endif
1031 SET_ITEM_INT(skip_source_first_line);
1032 SET_ITEM_WSTR(run_command);
1033 SET_ITEM_WSTR(run_module);
1034 SET_ITEM_WSTR(run_filename);
1035 SET_ITEM_INT(_install_importlib);
Victor Stinnercb9fbd32019-05-01 23:51:56 -04001036 SET_ITEM_WSTR(check_hash_pycs_mode);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001037 SET_ITEM_INT(pathconfig_warnings);
1038 SET_ITEM_INT(_init_main);
Victor Stinner252346a2020-05-01 11:33:44 +02001039 SET_ITEM_INT(_isolated_interpreter);
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02001040 SET_ITEM_WSTRLIST(orig_argv);
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001041
1042 return dict;
1043
1044fail:
1045 Py_DECREF(dict);
1046 return NULL;
1047
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001048#undef FROM_WSTRING
1049#undef SET_ITEM
1050#undef SET_ITEM_INT
1051#undef SET_ITEM_UINT
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001052#undef SET_ITEM_WSTR
1053#undef SET_ITEM_WSTRLIST
1054}
1055
1056
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001057static PyObject*
1058config_dict_get(PyObject *dict, const char *name)
1059{
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001060 PyObject *item = _PyDict_GetItemStringWithError(dict, name);
1061 if (item == NULL && !PyErr_Occurred()) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001062 PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
1063 return NULL;
1064 }
1065 return item;
1066}
1067
1068
1069static void
1070config_dict_invalid_value(const char *name)
1071{
1072 PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
1073}
1074
1075
1076static void
1077config_dict_invalid_type(const char *name)
1078{
1079 PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
1080}
1081
1082
1083static int
1084config_dict_get_int(PyObject *dict, const char *name, int *result)
1085{
1086 PyObject *item = config_dict_get(dict, name);
1087 if (item == NULL) {
1088 return -1;
1089 }
1090 int value = _PyLong_AsInt(item);
1091 if (value == -1 && PyErr_Occurred()) {
1092 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1093 config_dict_invalid_type(name);
1094 }
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001095 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001096 config_dict_invalid_value(name);
1097 }
1098 return -1;
1099 }
1100 *result = value;
1101 return 0;
1102}
1103
1104
1105static int
1106config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
1107{
1108 PyObject *item = config_dict_get(dict, name);
1109 if (item == NULL) {
1110 return -1;
1111 }
1112 unsigned long value = PyLong_AsUnsignedLong(item);
1113 if (value == (unsigned long)-1 && PyErr_Occurred()) {
Serhiy Storchaka14d81dc2020-11-24 14:07:32 +02001114 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1115 config_dict_invalid_type(name);
1116 }
1117 else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1118 config_dict_invalid_value(name);
1119 }
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001120 return -1;
1121 }
1122 *result = value;
1123 return 0;
1124}
1125
1126
1127static int
1128config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
1129 wchar_t **result)
1130{
1131 PyObject *item = config_dict_get(dict, name);
1132 if (item == NULL) {
1133 return -1;
1134 }
1135 PyStatus status;
1136 if (item == Py_None) {
1137 status = PyConfig_SetString(config, result, NULL);
1138 }
1139 else if (!PyUnicode_Check(item)) {
1140 config_dict_invalid_type(name);
1141 return -1;
1142 }
1143 else {
1144 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1145 if (wstr == NULL) {
1146 return -1;
1147 }
1148 status = PyConfig_SetString(config, result, wstr);
1149 PyMem_Free(wstr);
1150 }
1151 if (_PyStatus_EXCEPTION(status)) {
1152 PyErr_NoMemory();
1153 return -1;
1154 }
1155 return 0;
1156}
1157
1158
1159static int
1160config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
1161 PyWideStringList *result)
1162{
1163 PyObject *list = config_dict_get(dict, name);
1164 if (list == NULL) {
1165 return -1;
1166 }
1167
1168 if (!PyList_CheckExact(list)) {
1169 config_dict_invalid_type(name);
1170 return -1;
1171 }
1172
1173 PyWideStringList wstrlist = _PyWideStringList_INIT;
1174 for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
1175 PyObject *item = PyList_GET_ITEM(list, i);
1176
1177 if (item == Py_None) {
1178 config_dict_invalid_value(name);
1179 goto error;
1180 }
1181 else if (!PyUnicode_Check(item)) {
1182 config_dict_invalid_type(name);
1183 goto error;
1184 }
1185 wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
1186 if (wstr == NULL) {
1187 goto error;
1188 }
1189 PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
1190 PyMem_Free(wstr);
1191 if (_PyStatus_EXCEPTION(status)) {
1192 PyErr_NoMemory();
1193 goto error;
1194 }
1195 }
1196
1197 if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
1198 PyErr_NoMemory();
1199 goto error;
1200 }
1201 _PyWideStringList_Clear(&wstrlist);
1202 return 0;
1203
1204error:
1205 _PyWideStringList_Clear(&wstrlist);
1206 return -1;
1207}
1208
1209
1210int
1211_PyConfig_FromDict(PyConfig *config, PyObject *dict)
1212{
1213 if (!PyDict_Check(dict)) {
1214 PyErr_SetString(PyExc_TypeError, "dict expected");
1215 return -1;
1216 }
1217
1218#define CHECK_VALUE(NAME, TEST) \
1219 if (!(TEST)) { \
1220 config_dict_invalid_value(NAME); \
1221 return -1; \
1222 }
1223#define GET_UINT(KEY) \
1224 do { \
1225 if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
1226 return -1; \
1227 } \
1228 CHECK_VALUE(#KEY, config->KEY >= 0); \
1229 } while (0)
1230#define GET_WSTR(KEY) \
1231 do { \
1232 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1233 return -1; \
1234 } \
1235 CHECK_VALUE(#KEY, config->KEY != NULL); \
1236 } while (0)
1237#define GET_WSTR_OPT(KEY) \
1238 do { \
1239 if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
1240 return -1; \
1241 } \
1242 } while (0)
1243#define GET_WSTRLIST(KEY) \
1244 do { \
1245 if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
1246 return -1; \
1247 } \
1248 } while (0)
1249
1250 GET_UINT(_config_init);
1251 CHECK_VALUE("_config_init",
1252 config->_config_init == _PyConfig_INIT_COMPAT
1253 || config->_config_init == _PyConfig_INIT_PYTHON
1254 || config->_config_init == _PyConfig_INIT_ISOLATED);
1255 GET_UINT(isolated);
1256 GET_UINT(use_environment);
1257 GET_UINT(dev_mode);
1258 GET_UINT(install_signal_handlers);
1259 GET_UINT(use_hash_seed);
1260 if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
1261 return -1;
1262 }
1263 CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
1264 GET_UINT(faulthandler);
1265 GET_UINT(tracemalloc);
1266 GET_UINT(import_time);
1267 GET_UINT(show_ref_count);
1268 GET_UINT(dump_refs);
1269 GET_UINT(malloc_stats);
1270 GET_WSTR(filesystem_encoding);
1271 GET_WSTR(filesystem_errors);
1272 GET_WSTR_OPT(pycache_prefix);
1273 GET_UINT(parse_argv);
1274 GET_WSTRLIST(orig_argv);
1275 GET_WSTRLIST(argv);
1276 GET_WSTRLIST(xoptions);
1277 GET_WSTRLIST(warnoptions);
1278 GET_UINT(site_import);
1279 GET_UINT(bytes_warning);
Inada Naoki48274832021-03-29 12:28:14 +09001280 GET_UINT(warn_default_encoding);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001281 GET_UINT(inspect);
1282 GET_UINT(interactive);
1283 GET_UINT(optimization_level);
1284 GET_UINT(parser_debug);
1285 GET_UINT(write_bytecode);
1286 GET_UINT(verbose);
1287 GET_UINT(quiet);
1288 GET_UINT(user_site_directory);
1289 GET_UINT(configure_c_stdio);
1290 GET_UINT(buffered_stdio);
1291 GET_WSTR(stdio_encoding);
1292 GET_WSTR(stdio_errors);
1293#ifdef MS_WINDOWS
1294 GET_UINT(legacy_windows_stdio);
1295#endif
1296 GET_WSTR(check_hash_pycs_mode);
1297
1298 GET_UINT(pathconfig_warnings);
1299 GET_WSTR(program_name);
1300 GET_WSTR_OPT(pythonpath_env);
1301 GET_WSTR_OPT(home);
1302 GET_WSTR(platlibdir);
1303
Victor Stinner9e1b8282020-11-10 13:21:52 +01001304 // Path configuration output
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001305 GET_UINT(module_search_paths_set);
1306 GET_WSTRLIST(module_search_paths);
Victor Stinner9e1b8282020-11-10 13:21:52 +01001307 GET_WSTR_OPT(executable);
1308 GET_WSTR_OPT(base_executable);
1309 GET_WSTR_OPT(prefix);
1310 GET_WSTR_OPT(base_prefix);
1311 GET_WSTR_OPT(exec_prefix);
1312 GET_WSTR_OPT(base_exec_prefix);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001313
1314 GET_UINT(skip_source_first_line);
1315 GET_WSTR_OPT(run_command);
1316 GET_WSTR_OPT(run_module);
1317 GET_WSTR_OPT(run_filename);
1318
1319 GET_UINT(_install_importlib);
1320 GET_UINT(_init_main);
1321 GET_UINT(_isolated_interpreter);
1322
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001323#undef CHECK_VALUE
1324#undef GET_UINT
1325#undef GET_WSTR
1326#undef GET_WSTR_OPT
1327 return 0;
1328}
1329
1330
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001331static const char*
Victor Stinner331a6a52019-05-27 16:39:22 +02001332config_get_env(const PyConfig *config, const char *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001333{
Victor Stinner20004952019-03-26 02:31:11 +01001334 return _Py_GetEnv(config->use_environment, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001335}
1336
1337
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001338/* Get a copy of the environment variable as wchar_t*.
1339 Return 0 on success, but *dest can be NULL.
1340 Return -1 on memory allocation failure. Return -2 on decoding error. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001341static PyStatus
1342config_get_env_dup(PyConfig *config,
1343 wchar_t **dest,
1344 wchar_t *wname, char *name,
1345 const char *decode_err_msg)
Victor Stinner6c785c02018-08-01 17:56:14 +02001346{
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001347 assert(*dest == NULL);
Victor Stinner20004952019-03-26 02:31:11 +01001348 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001349
Victor Stinner20004952019-03-26 02:31:11 +01001350 if (!config->use_environment) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001351 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001352 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001353 }
1354
1355#ifdef MS_WINDOWS
1356 const wchar_t *var = _wgetenv(wname);
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 PyConfig_SetString(config, dest, var);
Victor Stinner6c785c02018-08-01 17:56:14 +02001363#else
1364 const char *var = getenv(name);
1365 if (!var || var[0] == '\0') {
1366 *dest = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02001367 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001368 }
1369
Victor Stinner331a6a52019-05-27 16:39:22 +02001370 return config_set_bytes_string(config, dest, var, decode_err_msg);
Victor Stinner6c785c02018-08-01 17:56:14 +02001371#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02001372}
1373
1374
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001375#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
Victor Stinner331a6a52019-05-27 16:39:22 +02001376 config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001377
1378
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001379static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001380config_get_global_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001381{
Victor Stinner022be022019-05-22 23:58:50 +02001382 if (config->_config_init != _PyConfig_INIT_COMPAT) {
1383 /* Python and Isolated configuration ignore global variables */
1384 return;
1385 }
1386
Victor Stinner6c785c02018-08-01 17:56:14 +02001387#define COPY_FLAG(ATTR, VALUE) \
1388 if (config->ATTR == -1) { \
1389 config->ATTR = VALUE; \
1390 }
1391#define COPY_NOT_FLAG(ATTR, VALUE) \
1392 if (config->ATTR == -1) { \
1393 config->ATTR = !(VALUE); \
1394 }
1395
Victor Stinner20004952019-03-26 02:31:11 +01001396 COPY_FLAG(isolated, Py_IsolatedFlag);
1397 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001398 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1399 COPY_FLAG(inspect, Py_InspectFlag);
1400 COPY_FLAG(interactive, Py_InteractiveFlag);
1401 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1402 COPY_FLAG(parser_debug, Py_DebugFlag);
1403 COPY_FLAG(verbose, Py_VerboseFlag);
1404 COPY_FLAG(quiet, Py_QuietFlag);
1405#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001406 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1407#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001408 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001409
Victor Stinner6c785c02018-08-01 17:56:14 +02001410 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1411 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1412 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1413 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1414
Victor Stinner6c785c02018-08-01 17:56:14 +02001415#undef COPY_FLAG
1416#undef COPY_NOT_FLAG
1417}
1418
1419
1420/* Set Py_xxx global configuration variables from 'config' configuration. */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001421static void
Victor Stinner331a6a52019-05-27 16:39:22 +02001422config_set_global_vars(const PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001423{
1424#define COPY_FLAG(ATTR, VAR) \
1425 if (config->ATTR != -1) { \
1426 VAR = config->ATTR; \
1427 }
1428#define COPY_NOT_FLAG(ATTR, VAR) \
1429 if (config->ATTR != -1) { \
1430 VAR = !config->ATTR; \
1431 }
1432
Victor Stinner20004952019-03-26 02:31:11 +01001433 COPY_FLAG(isolated, Py_IsolatedFlag);
1434 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001435 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
1436 COPY_FLAG(inspect, Py_InspectFlag);
1437 COPY_FLAG(interactive, Py_InteractiveFlag);
1438 COPY_FLAG(optimization_level, Py_OptimizeFlag);
1439 COPY_FLAG(parser_debug, Py_DebugFlag);
1440 COPY_FLAG(verbose, Py_VerboseFlag);
1441 COPY_FLAG(quiet, Py_QuietFlag);
1442#ifdef MS_WINDOWS
Victor Stinner6c785c02018-08-01 17:56:14 +02001443 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
1444#endif
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001445 COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
Victor Stinner6c785c02018-08-01 17:56:14 +02001446
Victor Stinner6c785c02018-08-01 17:56:14 +02001447 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
1448 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
1449 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
1450 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
1451
Victor Stinner6c785c02018-08-01 17:56:14 +02001452 /* Random or non-zero hash seed */
1453 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1454 config->hash_seed != 0);
1455
1456#undef COPY_FLAG
1457#undef COPY_NOT_FLAG
1458}
1459
1460
1461/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1462 environment variables on macOS if available. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001463static PyStatus
1464config_init_program_name(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001465{
Victor Stinner331a6a52019-05-27 16:39:22 +02001466 PyStatus status;
Victor Stinner5a953fd2018-08-03 22:49:07 +02001467
Victor Stinner6c785c02018-08-01 17:56:14 +02001468 /* If Py_SetProgramName() was called, use its value */
1469 const wchar_t *program_name = _Py_path_config.program_name;
1470 if (program_name != NULL) {
1471 config->program_name = _PyMem_RawWcsdup(program_name);
1472 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001473 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001474 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001475 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001476 }
1477
1478#ifdef __APPLE__
1479 /* On MacOS X, when the Python interpreter is embedded in an
1480 application bundle, it gets executed by a bootstrapping script
1481 that does os.execve() with an argv[0] that's different from the
1482 actual Python executable. This is needed to keep the Finder happy,
1483 or rather, to work around Apple's overly strict requirements of
1484 the process name. However, we still need a usable sys.executable,
1485 so the actual executable path is passed in an environment variable.
Min ho Kimc4cacc82019-07-31 08:16:13 +10001486 See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
Victor Stinner6c785c02018-08-01 17:56:14 +02001487 script. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001488 const char *p = config_get_env(config, "PYTHONEXECUTABLE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001489 if (p != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001490 status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
1491 "PYTHONEXECUTABLE environment variable");
1492 if (_PyStatus_EXCEPTION(status)) {
1493 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001494 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001495 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001496 }
1497#ifdef WITH_NEXT_FRAMEWORK
1498 else {
1499 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1500 if (pyvenv_launcher && *pyvenv_launcher) {
1501 /* Used by Mac/Tools/pythonw.c to forward
1502 * the argv0 of the stub executable
1503 */
Victor Stinner331a6a52019-05-27 16:39:22 +02001504 status = CONFIG_SET_BYTES_STR(config,
1505 &config->program_name,
1506 pyvenv_launcher,
1507 "__PYVENV_LAUNCHER__ environment variable");
1508 if (_PyStatus_EXCEPTION(status)) {
1509 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001510 }
Ronald Oussoren044cf942020-03-22 19:31:46 +01001511
1512 /*
1513 * This environment variable is used to communicate between
1514 * the stub launcher and the real interpreter and isn't needed
1515 * beyond this point.
1516 *
1517 * Clean up to avoid problems when launching other programs
1518 * later on.
1519 */
1520 (void)unsetenv("__PYVENV_LAUNCHER__");
1521
Victor Stinner331a6a52019-05-27 16:39:22 +02001522 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001523 }
1524 }
1525#endif /* WITH_NEXT_FRAMEWORK */
1526#endif /* __APPLE__ */
1527
Victor Stinnerfed02e12019-05-17 11:12:09 +02001528 /* Use argv[0] if available and non-empty */
Victor Stinner331a6a52019-05-27 16:39:22 +02001529 const PyWideStringList *argv = &config->argv;
Victor Stinnerfed02e12019-05-17 11:12:09 +02001530 if (argv->length >= 1 && argv->items[0][0] != L'\0') {
1531 config->program_name = _PyMem_RawWcsdup(argv->items[0]);
1532 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001533 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001534 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001535 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001536 }
1537
Victor Stinnerfed02e12019-05-17 11:12:09 +02001538 /* Last fall back: hardcoded name */
Victor Stinner6c785c02018-08-01 17:56:14 +02001539#ifdef MS_WINDOWS
1540 const wchar_t *default_program_name = L"python";
1541#else
1542 const wchar_t *default_program_name = L"python3";
1543#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02001544 status = PyConfig_SetString(config, &config->program_name,
1545 default_program_name);
1546 if (_PyStatus_EXCEPTION(status)) {
1547 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001548 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001549 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001550}
1551
Victor Stinner331a6a52019-05-27 16:39:22 +02001552static PyStatus
1553config_init_executable(PyConfig *config)
Steve Dower177a41a2018-11-17 20:41:48 -08001554{
1555 assert(config->executable == NULL);
1556
1557 /* If Py_SetProgramFullPath() was called, use its value */
1558 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1559 if (program_full_path != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001560 PyStatus status = PyConfig_SetString(config,
1561 &config->executable,
1562 program_full_path);
1563 if (_PyStatus_EXCEPTION(status)) {
1564 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08001565 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001566 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001567 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001568 return _PyStatus_OK();
Steve Dower177a41a2018-11-17 20:41:48 -08001569}
Victor Stinner6c785c02018-08-01 17:56:14 +02001570
Victor Stinner4fffd382019-03-06 01:44:31 +01001571
Victor Stinner6c785c02018-08-01 17:56:14 +02001572static const wchar_t*
Victor Stinner331a6a52019-05-27 16:39:22 +02001573config_get_xoption(const PyConfig *config, wchar_t *name)
Victor Stinner6c785c02018-08-01 17:56:14 +02001574{
Victor Stinner74f65682019-03-15 15:08:05 +01001575 return _Py_get_xoption(&config->xoptions, name);
Victor Stinner6c785c02018-08-01 17:56:14 +02001576}
1577
1578
Victor Stinner331a6a52019-05-27 16:39:22 +02001579static PyStatus
1580config_init_home(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001581{
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001582 assert(config->home == NULL);
Victor Stinner6c785c02018-08-01 17:56:14 +02001583
1584 /* If Py_SetPythonHome() was called, use its value */
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01001585 wchar_t *home = _Py_path_config.home;
Victor Stinner6c785c02018-08-01 17:56:14 +02001586 if (home) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001587 PyStatus status = PyConfig_SetString(config, &config->home, home);
1588 if (_PyStatus_EXCEPTION(status)) {
1589 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001590 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001591 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001592 }
1593
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001594 return CONFIG_GET_ENV_DUP(config, &config->home,
1595 L"PYTHONHOME", "PYTHONHOME");
Victor Stinner6c785c02018-08-01 17:56:14 +02001596}
1597
Victor Stinner331a6a52019-05-27 16:39:22 +02001598static PyStatus
1599config_init_hash_seed(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001600{
Victor Stinner331a6a52019-05-27 16:39:22 +02001601 const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001602
1603 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
1604 /* Convert a text seed to a numeric one */
1605 if (seed_text && strcmp(seed_text, "random") != 0) {
1606 const char *endptr = seed_text;
1607 unsigned long seed;
1608 errno = 0;
1609 seed = strtoul(seed_text, (char **)&endptr, 10);
1610 if (*endptr != '\0'
Victor Stinnerf3cb8142020-11-05 18:12:33 +01001611 || seed > MAX_HASH_SEED
Victor Stinner6c785c02018-08-01 17:56:14 +02001612 || (errno == ERANGE && seed == ULONG_MAX))
1613 {
Victor Stinner331a6a52019-05-27 16:39:22 +02001614 return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
Victor Stinnerdb719752019-05-01 05:35:33 +02001615 "or an integer in range [0; 4294967295]");
Victor Stinner6c785c02018-08-01 17:56:14 +02001616 }
1617 /* Use a specific hash */
1618 config->use_hash_seed = 1;
1619 config->hash_seed = seed;
1620 }
1621 else {
1622 /* Use a random hash */
1623 config->use_hash_seed = 0;
1624 config->hash_seed = 0;
1625 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001626 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001627}
1628
1629
Victor Stinner6c785c02018-08-01 17:56:14 +02001630static int
1631config_wstr_to_int(const wchar_t *wstr, int *result)
1632{
1633 const wchar_t *endptr = wstr;
1634 errno = 0;
1635 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1636 if (*endptr != '\0' || errno == ERANGE) {
1637 return -1;
1638 }
1639 if (value < INT_MIN || value > INT_MAX) {
1640 return -1;
1641 }
1642
1643 *result = (int)value;
1644 return 0;
1645}
1646
1647
Victor Stinner331a6a52019-05-27 16:39:22 +02001648static PyStatus
1649config_read_env_vars(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001650{
Victor Stinner331a6a52019-05-27 16:39:22 +02001651 PyStatus status;
Victor Stinner20004952019-03-26 02:31:11 +01001652 int use_env = config->use_environment;
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001653
Victor Stinner6c785c02018-08-01 17:56:14 +02001654 /* Get environment variables */
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001655 _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
1656 _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
1657 _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
1658 _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
Victor Stinner6c785c02018-08-01 17:56:14 +02001659
1660 int dont_write_bytecode = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001661 _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001662 if (dont_write_bytecode) {
1663 config->write_bytecode = 0;
1664 }
1665
1666 int no_user_site_directory = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001667 _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
Victor Stinner6c785c02018-08-01 17:56:14 +02001668 if (no_user_site_directory) {
1669 config->user_site_directory = 0;
1670 }
1671
1672 int unbuffered_stdio = 0;
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001673 _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
Victor Stinner6c785c02018-08-01 17:56:14 +02001674 if (unbuffered_stdio) {
1675 config->buffered_stdio = 0;
1676 }
1677
1678#ifdef MS_WINDOWS
Victor Stinnerf78a5e92019-03-26 00:03:15 +01001679 _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
Victor Stinnere662c392020-11-01 23:07:23 +01001680 "PYTHONLEGACYWINDOWSSTDIO");
Victor Stinner6c785c02018-08-01 17:56:14 +02001681#endif
1682
Victor Stinner331a6a52019-05-27 16:39:22 +02001683 if (config_get_env(config, "PYTHONDUMPREFS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001684 config->dump_refs = 1;
1685 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001686 if (config_get_env(config, "PYTHONMALLOCSTATS")) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001687 config->malloc_stats = 1;
1688 }
1689
Victor Stinner331a6a52019-05-27 16:39:22 +02001690 if (config->pythonpath_env == NULL) {
1691 status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
1692 L"PYTHONPATH", "PYTHONPATH");
1693 if (_PyStatus_EXCEPTION(status)) {
1694 return status;
Victor Stinner4a1468e2019-03-20 03:11:38 +01001695 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001696 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001697
Sandro Mani8f023a22020-06-08 17:28:11 +02001698 if(config->platlibdir == NULL) {
1699 status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
1700 L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
1701 if (_PyStatus_EXCEPTION(status)) {
1702 return status;
1703 }
1704 }
1705
Victor Stinner6c785c02018-08-01 17:56:14 +02001706 if (config->use_hash_seed < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001707 status = config_init_hash_seed(config);
1708 if (_PyStatus_EXCEPTION(status)) {
1709 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001710 }
1711 }
1712
Victor Stinner331a6a52019-05-27 16:39:22 +02001713 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001714}
1715
1716
Victor Stinner331a6a52019-05-27 16:39:22 +02001717static PyStatus
1718config_init_tracemalloc(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001719{
1720 int nframe;
1721 int valid;
1722
Victor Stinner331a6a52019-05-27 16:39:22 +02001723 const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
Victor Stinner6c785c02018-08-01 17:56:14 +02001724 if (env) {
Victor Stinner5a02e0d2019-03-05 12:32:09 +01001725 if (!_Py_str_to_int(env, &nframe)) {
Victor Stinner6c785c02018-08-01 17:56:14 +02001726 valid = (nframe >= 0);
1727 }
1728 else {
1729 valid = 0;
1730 }
1731 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001732 return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001733 }
1734 config->tracemalloc = nframe;
1735 }
1736
1737 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1738 if (xoption) {
1739 const wchar_t *sep = wcschr(xoption, L'=');
1740 if (sep) {
1741 if (!config_wstr_to_int(sep + 1, &nframe)) {
1742 valid = (nframe >= 0);
1743 }
1744 else {
1745 valid = 0;
1746 }
1747 if (!valid) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001748 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
1749 "invalid number of frames");
Victor Stinner6c785c02018-08-01 17:56:14 +02001750 }
1751 }
1752 else {
1753 /* -X tracemalloc behaves as -X tracemalloc=1 */
1754 nframe = 1;
1755 }
1756 config->tracemalloc = nframe;
1757 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001758 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001759}
1760
1761
Victor Stinner331a6a52019-05-27 16:39:22 +02001762static PyStatus
1763config_init_pycache_prefix(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001764{
1765 assert(config->pycache_prefix == NULL);
1766
1767 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
1768 if (xoption) {
1769 const wchar_t *sep = wcschr(xoption, L'=');
1770 if (sep && wcslen(sep) > 1) {
1771 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
1772 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001773 return _PyStatus_NO_MEMORY();
Victor Stinner6c785c02018-08-01 17:56:14 +02001774 }
1775 }
1776 else {
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001777 // PYTHONPYCACHEPREFIX env var ignored
1778 // if "-X pycache_prefix=" option is used
Victor Stinner6c785c02018-08-01 17:56:14 +02001779 config->pycache_prefix = NULL;
1780 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001781 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001782 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001783
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001784 return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
1785 L"PYTHONPYCACHEPREFIX",
1786 "PYTHONPYCACHEPREFIX");
Victor Stinner6c785c02018-08-01 17:56:14 +02001787}
1788
1789
Victor Stinner331a6a52019-05-27 16:39:22 +02001790static PyStatus
1791config_read_complex_options(PyConfig *config)
Victor Stinner6c785c02018-08-01 17:56:14 +02001792{
1793 /* More complex options configured by env var and -X option */
1794 if (config->faulthandler < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001795 if (config_get_env(config, "PYTHONFAULTHANDLER")
Victor Stinner6c785c02018-08-01 17:56:14 +02001796 || config_get_xoption(config, L"faulthandler")) {
1797 config->faulthandler = 1;
1798 }
1799 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001800 if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
Victor Stinner6c785c02018-08-01 17:56:14 +02001801 || config_get_xoption(config, L"importtime")) {
1802 config->import_time = 1;
1803 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001804
Victor Stinner331a6a52019-05-27 16:39:22 +02001805 PyStatus status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001806 if (config->tracemalloc < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001807 status = config_init_tracemalloc(config);
1808 if (_PyStatus_EXCEPTION(status)) {
1809 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001810 }
1811 }
1812
1813 if (config->pycache_prefix == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001814 status = config_init_pycache_prefix(config);
1815 if (_PyStatus_EXCEPTION(status)) {
1816 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02001817 }
1818 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001819 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02001820}
1821
1822
Victor Stinner709d23d2019-05-02 14:56:30 -04001823static const wchar_t *
Victor Stinner710e8262020-10-31 01:02:09 +01001824config_get_stdio_errors(const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001825{
Victor Stinner710e8262020-10-31 01:02:09 +01001826 if (preconfig->utf8_mode) {
1827 /* UTF-8 Mode uses UTF-8/surrogateescape */
1828 return L"surrogateescape";
1829 }
1830
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001831#ifndef MS_WINDOWS
1832 const char *loc = setlocale(LC_CTYPE, NULL);
1833 if (loc != NULL) {
1834 /* surrogateescape is the default in the legacy C and POSIX locales */
1835 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001836 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001837 }
1838
1839#ifdef PY_COERCE_C_LOCALE
1840 /* surrogateescape is the default in locale coercion target locales */
1841 if (_Py_IsLocaleCoercionTarget(loc)) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001842 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001843 }
1844#endif
1845 }
1846
Victor Stinner709d23d2019-05-02 14:56:30 -04001847 return L"strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001848#else
1849 /* On Windows, always use surrogateescape by default */
Victor Stinner709d23d2019-05-02 14:56:30 -04001850 return L"surrogateescape";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001851#endif
1852}
1853
1854
Victor Stinner82458b62020-11-01 20:59:35 +01001855// See also config_get_fs_encoding()
Victor Stinner331a6a52019-05-27 16:39:22 +02001856static PyStatus
Victor Stinner710e8262020-10-31 01:02:09 +01001857config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
1858 wchar_t **locale_encoding)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001859{
Victor Stinnere662c392020-11-01 23:07:23 +01001860 wchar_t *encoding = _Py_GetLocaleEncoding();
Victor Stinner82458b62020-11-01 20:59:35 +01001861 if (encoding == NULL) {
Victor Stinnere662c392020-11-01 23:07:23 +01001862 return _PyStatus_NO_MEMORY();
Victor Stinner710e8262020-10-31 01:02:09 +01001863 }
Victor Stinner82458b62020-11-01 20:59:35 +01001864 PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
1865 PyMem_RawFree(encoding);
1866 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001867}
1868
1869
Victor Stinner331a6a52019-05-27 16:39:22 +02001870static PyStatus
1871config_init_stdio_encoding(PyConfig *config,
1872 const PyPreConfig *preconfig)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001873{
Victor Stinner331a6a52019-05-27 16:39:22 +02001874 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001875
Victor Stinner35297182020-11-04 11:20:10 +01001876 /* If Py_SetStandardStreamEncoding() has been called, use its
1877 arguments if they are not NULL. */
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001878 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001879 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1880 _Py_StandardStreamEncoding,
1881 "_Py_StandardStreamEncoding");
1882 if (_PyStatus_EXCEPTION(status)) {
1883 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001884 }
1885 }
1886
1887 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001888 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1889 _Py_StandardStreamErrors,
1890 "_Py_StandardStreamErrors");
1891 if (_PyStatus_EXCEPTION(status)) {
1892 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001893 }
1894 }
1895
Victor Stinner35297182020-11-04 11:20:10 +01001896 // Exit if encoding and errors are defined
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001897 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001898 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001899 }
1900
1901 /* PYTHONIOENCODING environment variable */
Victor Stinner331a6a52019-05-27 16:39:22 +02001902 const char *opt = config_get_env(config, "PYTHONIOENCODING");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001903 if (opt) {
Victor Stinner709d23d2019-05-02 14:56:30 -04001904 char *pythonioencoding = _PyMem_RawStrdup(opt);
1905 if (pythonioencoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001906 return _PyStatus_NO_MEMORY();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001907 }
1908
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001909 char *errors = strchr(pythonioencoding, ':');
1910 if (errors) {
1911 *errors = '\0';
1912 errors++;
1913 if (!errors[0]) {
1914 errors = NULL;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001915 }
1916 }
1917
1918 /* Does PYTHONIOENCODING contain an encoding? */
1919 if (pythonioencoding[0]) {
1920 if (config->stdio_encoding == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001921 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
1922 pythonioencoding,
1923 "PYTHONIOENCODING environment variable");
1924 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001925 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001926 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001927 }
1928 }
1929
1930 /* If the encoding is set but not the error handler,
1931 use "strict" error handler by default.
1932 PYTHONIOENCODING=latin1 behaves as
1933 PYTHONIOENCODING=latin1:strict. */
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001934 if (!errors) {
1935 errors = "strict";
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001936 }
1937 }
1938
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001939 if (config->stdio_errors == NULL && errors != NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001940 status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
1941 errors,
1942 "PYTHONIOENCODING environment variable");
1943 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001944 PyMem_RawFree(pythonioencoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001945 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001946 }
1947 }
1948
1949 PyMem_RawFree(pythonioencoding);
1950 }
1951
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001952 /* Choose the default error handler based on the current locale. */
1953 if (config->stdio_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001954 status = config_get_locale_encoding(config, preconfig,
1955 &config->stdio_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02001956 if (_PyStatus_EXCEPTION(status)) {
1957 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001958 }
1959 }
1960 if (config->stdio_errors == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01001961 const wchar_t *errors = config_get_stdio_errors(preconfig);
Victor Stinner1a9f0d82019-05-01 15:22:52 +02001962 assert(errors != NULL);
1963
Victor Stinner331a6a52019-05-27 16:39:22 +02001964 status = PyConfig_SetString(config, &config->stdio_errors, errors);
1965 if (_PyStatus_EXCEPTION(status)) {
1966 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001967 }
1968 }
1969
Victor Stinner331a6a52019-05-27 16:39:22 +02001970 return _PyStatus_OK();
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001971}
1972
1973
Victor Stinner710e8262020-10-31 01:02:09 +01001974// See also config_get_locale_encoding()
1975static PyStatus
1976config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
1977 wchar_t **fs_encoding)
1978{
1979#ifdef _Py_FORCE_UTF8_FS_ENCODING
1980 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1981#elif defined(MS_WINDOWS)
1982 const wchar_t *encoding;
1983 if (preconfig->legacy_windows_fs_encoding) {
1984 // Legacy Windows filesystem encoding: mbcs/replace
1985 encoding = L"mbcs";
1986 }
1987 else {
1988 // Windows defaults to utf-8/surrogatepass (PEP 529)
1989 encoding = L"utf-8";
1990 }
1991 return PyConfig_SetString(config, fs_encoding, encoding);
1992#else // !MS_WINDOWS
1993 if (preconfig->utf8_mode) {
1994 return PyConfig_SetString(config, fs_encoding, L"utf-8");
1995 }
Victor Stinner35297182020-11-04 11:20:10 +01001996
1997 if (_Py_GetForceASCII()) {
Victor Stinner710e8262020-10-31 01:02:09 +01001998 return PyConfig_SetString(config, fs_encoding, L"ascii");
1999 }
Victor Stinner35297182020-11-04 11:20:10 +01002000
2001 return config_get_locale_encoding(config, preconfig, fs_encoding);
Victor Stinner710e8262020-10-31 01:02:09 +01002002#endif // !MS_WINDOWS
2003}
2004
2005
Victor Stinner331a6a52019-05-27 16:39:22 +02002006static PyStatus
2007config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002008{
Victor Stinner331a6a52019-05-27 16:39:22 +02002009 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002010
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002011 if (config->filesystem_encoding == NULL) {
Victor Stinner710e8262020-10-31 01:02:09 +01002012 status = config_get_fs_encoding(config, preconfig,
2013 &config->filesystem_encoding);
Victor Stinner331a6a52019-05-27 16:39:22 +02002014 if (_PyStatus_EXCEPTION(status)) {
2015 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002016 }
2017 }
2018
2019 if (config->filesystem_errors == NULL) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002020 const wchar_t *errors;
Victor Stinnere2510952019-05-02 11:28:57 -04002021#ifdef MS_WINDOWS
2022 if (preconfig->legacy_windows_fs_encoding) {
Victor Stinner709d23d2019-05-02 14:56:30 -04002023 errors = L"replace";
Victor Stinnere2510952019-05-02 11:28:57 -04002024 }
2025 else {
Victor Stinner709d23d2019-05-02 14:56:30 -04002026 errors = L"surrogatepass";
Victor Stinnere2510952019-05-02 11:28:57 -04002027 }
2028#else
Victor Stinner709d23d2019-05-02 14:56:30 -04002029 errors = L"surrogateescape";
Victor Stinnere2510952019-05-02 11:28:57 -04002030#endif
Victor Stinner331a6a52019-05-27 16:39:22 +02002031 status = PyConfig_SetString(config, &config->filesystem_errors, errors);
2032 if (_PyStatus_EXCEPTION(status)) {
2033 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002034 }
2035 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002036 return _PyStatus_OK();
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002037}
2038
2039
Victor Stinner331a6a52019-05-27 16:39:22 +02002040static PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002041config_read(PyConfig *config, int compute_path_config)
Victor Stinner6c785c02018-08-01 17:56:14 +02002042{
Victor Stinner331a6a52019-05-27 16:39:22 +02002043 PyStatus status;
2044 const PyPreConfig *preconfig = &_PyRuntime.preconfig;
Victor Stinnera6fbc4e2019-03-25 18:37:10 +01002045
Victor Stinner20004952019-03-26 02:31:11 +01002046 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002047 status = config_read_env_vars(config);
2048 if (_PyStatus_EXCEPTION(status)) {
2049 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002050 }
2051 }
2052
2053 /* -X options */
2054 if (config_get_xoption(config, L"showrefcount")) {
2055 config->show_ref_count = 1;
2056 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002057
Victor Stinner331a6a52019-05-27 16:39:22 +02002058 status = config_read_complex_options(config);
2059 if (_PyStatus_EXCEPTION(status)) {
2060 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002061 }
2062
Victor Stinner6c785c02018-08-01 17:56:14 +02002063 if (config->home == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002064 status = config_init_home(config);
2065 if (_PyStatus_EXCEPTION(status)) {
2066 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002067 }
2068 }
2069
Steve Dower177a41a2018-11-17 20:41:48 -08002070 if (config->executable == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002071 status = config_init_executable(config);
2072 if (_PyStatus_EXCEPTION(status)) {
2073 return status;
Steve Dower177a41a2018-11-17 20:41:48 -08002074 }
2075 }
2076
Sandro Mani8f023a22020-06-08 17:28:11 +02002077 if(config->platlibdir == NULL) {
2078 status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
2079 "PLATLIBDIR macro");
2080 if (_PyStatus_EXCEPTION(status)) {
2081 return status;
2082 }
2083 }
2084
Victor Stinnerace3f9a2020-11-10 21:10:22 +01002085 if (config->_install_importlib) {
2086 status = _PyConfig_InitPathConfig(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002087 if (_PyStatus_EXCEPTION(status)) {
2088 return status;
Victor Stinner6c785c02018-08-01 17:56:14 +02002089 }
2090 }
2091
2092 /* default values */
Victor Stinner20004952019-03-26 02:31:11 +01002093 if (config->dev_mode) {
Victor Stinner6c785c02018-08-01 17:56:14 +02002094 if (config->faulthandler < 0) {
2095 config->faulthandler = 1;
2096 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002097 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002098 if (config->faulthandler < 0) {
2099 config->faulthandler = 0;
2100 }
2101 if (config->tracemalloc < 0) {
2102 config->tracemalloc = 0;
2103 }
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002104 if (config->use_hash_seed < 0) {
2105 config->use_hash_seed = 0;
2106 config->hash_seed = 0;
2107 }
Victor Stinner6c785c02018-08-01 17:56:14 +02002108
Victor Stinner70fead22018-08-29 13:45:34 +02002109 if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002110 status = config_init_fs_encoding(config, preconfig);
2111 if (_PyStatus_EXCEPTION(status)) {
2112 return status;
Victor Stinnerb2457ef2018-08-29 13:25:36 +02002113 }
2114 }
2115
Victor Stinner331a6a52019-05-27 16:39:22 +02002116 status = config_init_stdio_encoding(config, preconfig);
2117 if (_PyStatus_EXCEPTION(status)) {
2118 return status;
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02002119 }
2120
Victor Stinner62599762019-03-15 16:03:23 +01002121 if (config->argv.length < 1) {
2122 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002123 status = PyWideStringList_Append(&config->argv, L"");
2124 if (_PyStatus_EXCEPTION(status)) {
2125 return status;
Victor Stinner62599762019-03-15 16:03:23 +01002126 }
2127 }
Victor Stinner870b0352019-05-17 03:15:12 +02002128
2129 if (config->check_hash_pycs_mode == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002130 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2131 L"default");
2132 if (_PyStatus_EXCEPTION(status)) {
2133 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002134 }
2135 }
2136
2137 if (config->configure_c_stdio < 0) {
2138 config->configure_c_stdio = 1;
2139 }
2140
Victor Stinnerdc42af82020-11-05 18:58:07 +01002141 // Only parse arguments once.
2142 if (config->parse_argv == 1) {
2143 config->parse_argv = 2;
2144 }
2145
Victor Stinner331a6a52019-05-27 16:39:22 +02002146 return _PyStatus_OK();
Victor Stinner6c785c02018-08-01 17:56:14 +02002147}
Victor Stinner5ed69952018-11-06 15:59:52 +01002148
2149
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002150static void
Victor Stinner331a6a52019-05-27 16:39:22 +02002151config_init_stdio(const PyConfig *config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002152{
2153#if defined(MS_WINDOWS) || defined(__CYGWIN__)
2154 /* don't translate newlines (\r\n <=> \n) */
2155 _setmode(fileno(stdin), O_BINARY);
2156 _setmode(fileno(stdout), O_BINARY);
2157 _setmode(fileno(stderr), O_BINARY);
2158#endif
2159
2160 if (!config->buffered_stdio) {
2161#ifdef HAVE_SETVBUF
2162 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
2163 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2164 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
2165#else /* !HAVE_SETVBUF */
2166 setbuf(stdin, (char *)NULL);
2167 setbuf(stdout, (char *)NULL);
2168 setbuf(stderr, (char *)NULL);
2169#endif /* !HAVE_SETVBUF */
2170 }
2171 else if (config->interactive) {
2172#ifdef MS_WINDOWS
2173 /* Doesn't have to have line-buffered -- use unbuffered */
2174 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
2175 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
2176#else /* !MS_WINDOWS */
2177#ifdef HAVE_SETVBUF
2178 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
2179 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
2180#endif /* HAVE_SETVBUF */
2181#endif /* !MS_WINDOWS */
2182 /* Leave stderr alone - it should be unbuffered anyway. */
2183 }
2184}
2185
2186
2187/* Write the configuration:
2188
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002189 - set Py_xxx global configuration variables
2190 - initialize C standard streams (stdin, stdout, stderr) */
Victor Stinnere81f6e62020-06-08 18:12:59 +02002191PyStatus
Victor Stinner331a6a52019-05-27 16:39:22 +02002192_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002193{
Victor Stinner331a6a52019-05-27 16:39:22 +02002194 config_set_global_vars(config);
Victor Stinner54b43bb2019-05-16 18:30:15 +02002195
2196 if (config->configure_c_stdio) {
2197 config_init_stdio(config);
2198 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002199
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002200 /* Write the new pre-configuration into _PyRuntime */
Victor Stinner331a6a52019-05-27 16:39:22 +02002201 PyPreConfig *preconfig = &runtime->preconfig;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002202 preconfig->isolated = config->isolated;
2203 preconfig->use_environment = config->use_environment;
2204 preconfig->dev_mode = config->dev_mode;
Victor Stinnere81f6e62020-06-08 18:12:59 +02002205
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002206 if (_Py_SetArgcArgv(config->orig_argv.length,
2207 config->orig_argv.items) < 0)
Victor Stinnere81f6e62020-06-08 18:12:59 +02002208 {
2209 return _PyStatus_NO_MEMORY();
2210 }
2211 return _PyStatus_OK();
Victor Stinner5ed69952018-11-06 15:59:52 +01002212}
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002213
2214
Victor Stinner331a6a52019-05-27 16:39:22 +02002215/* --- PyConfig command line parser -------------------------- */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002216
2217static void
Victor Stinner2f549082019-03-29 15:13:46 +01002218config_usage(int error, const wchar_t* program)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002219{
Victor Stinner2f549082019-03-29 15:13:46 +01002220 FILE *f = error ? stderr : stdout;
2221
2222 fprintf(f, usage_line, program);
2223 if (error)
2224 fprintf(f, "Try `python -h' for more information.\n");
2225 else {
2226 fputs(usage_1, f);
2227 fputs(usage_2, f);
2228 fputs(usage_3, f);
2229 fprintf(f, usage_4, (wint_t)DELIM);
2230 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
2231 fputs(usage_6, f);
2232 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002233}
2234
2235
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002236/* Parse the command line arguments */
Victor Stinner331a6a52019-05-27 16:39:22 +02002237static PyStatus
2238config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
Victor Stinnerb5947842019-05-18 00:38:16 +02002239 Py_ssize_t *opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002240{
Victor Stinner331a6a52019-05-27 16:39:22 +02002241 PyStatus status;
2242 const PyWideStringList *argv = &config->argv;
Victor Stinner2f549082019-03-29 15:13:46 +01002243 int print_version = 0;
Victor Stinnerfed02e12019-05-17 11:12:09 +02002244 const wchar_t* program = config->program_name;
Victor Stinnerfa153762019-03-20 04:25:38 +01002245
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002246 _PyOS_ResetGetOpt();
2247 do {
2248 int longindex = -1;
Victor Stinnerfa153762019-03-20 04:25:38 +01002249 int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002250 if (c == EOF) {
2251 break;
2252 }
2253
2254 if (c == 'c') {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002255 if (config->run_command == NULL) {
2256 /* -c is the last option; following arguments
2257 that look like options are left for the
2258 command to interpret. */
2259 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
2260 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
2261 if (command == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002262 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002263 }
2264 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
2265 command[len - 2] = '\n';
2266 command[len - 1] = 0;
2267 config->run_command = command;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002268 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002269 break;
2270 }
2271
2272 if (c == 'm') {
2273 /* -m is the last option; following arguments
2274 that look like options are left for the
2275 module to interpret. */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002276 if (config->run_module == NULL) {
Victor Stinner4a1468e2019-03-20 03:11:38 +01002277 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
2278 if (config->run_module == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002279 return _PyStatus_NO_MEMORY();
Victor Stinner4a1468e2019-03-20 03:11:38 +01002280 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002281 }
2282 break;
2283 }
2284
2285 switch (c) {
2286 case 0:
2287 // Handle long option.
2288 assert(longindex == 0); // Only one long option now.
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002289 if (wcscmp(_PyOS_optarg, L"always") == 0
2290 || wcscmp(_PyOS_optarg, L"never") == 0
2291 || wcscmp(_PyOS_optarg, L"default") == 0)
2292 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002293 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
2294 _PyOS_optarg);
2295 if (_PyStatus_EXCEPTION(status)) {
2296 return status;
Victor Stinnercb9fbd32019-05-01 23:51:56 -04002297 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002298 } else {
2299 fprintf(stderr, "--check-hash-based-pycs must be one of "
2300 "'default', 'always', or 'never'\n");
Victor Stinnerfed02e12019-05-17 11:12:09 +02002301 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002302 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002303 }
2304 break;
2305
2306 case 'b':
2307 config->bytes_warning++;
2308 break;
2309
2310 case 'd':
2311 config->parser_debug++;
2312 break;
2313
2314 case 'i':
2315 config->inspect++;
2316 config->interactive++;
2317 break;
2318
Victor Stinner6dcb5422019-03-05 02:44:12 +01002319 case 'E':
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002320 case 'I':
Victor Stinnerfa153762019-03-20 04:25:38 +01002321 case 'X':
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002322 /* option handled by _PyPreCmdline_Read() */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002323 break;
2324
2325 /* case 'J': reserved for Jython */
2326
2327 case 'O':
2328 config->optimization_level++;
2329 break;
2330
2331 case 'B':
2332 config->write_bytecode = 0;
2333 break;
2334
2335 case 's':
2336 config->user_site_directory = 0;
2337 break;
2338
2339 case 'S':
2340 config->site_import = 0;
2341 break;
2342
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002343 case 't':
2344 /* ignored for backwards compatibility */
2345 break;
2346
2347 case 'u':
2348 config->buffered_stdio = 0;
2349 break;
2350
2351 case 'v':
2352 config->verbose++;
2353 break;
2354
2355 case 'x':
2356 config->skip_source_first_line = 1;
2357 break;
2358
2359 case 'h':
2360 case '?':
Victor Stinnerfed02e12019-05-17 11:12:09 +02002361 config_usage(0, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002362 return _PyStatus_EXIT(0);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002363
2364 case 'V':
Victor Stinner2f549082019-03-29 15:13:46 +01002365 print_version++;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002366 break;
2367
2368 case 'W':
Victor Stinner331a6a52019-05-27 16:39:22 +02002369 status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
2370 if (_PyStatus_EXCEPTION(status)) {
2371 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002372 }
2373 break;
2374
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002375 case 'q':
2376 config->quiet++;
2377 break;
2378
2379 case 'R':
2380 config->use_hash_seed = 0;
2381 break;
2382
2383 /* This space reserved for other options */
2384
2385 default:
2386 /* unknown argument: parsing failed */
Victor Stinnerfed02e12019-05-17 11:12:09 +02002387 config_usage(1, program);
Victor Stinner331a6a52019-05-27 16:39:22 +02002388 return _PyStatus_EXIT(2);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002389 }
2390 } while (1);
2391
Victor Stinner2f549082019-03-29 15:13:46 +01002392 if (print_version) {
2393 printf("Python %s\n",
2394 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
Victor Stinner331a6a52019-05-27 16:39:22 +02002395 return _PyStatus_EXIT(0);
Victor Stinner2f549082019-03-29 15:13:46 +01002396 }
2397
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002398 if (config->run_command == NULL && config->run_module == NULL
Victor Stinnerfa153762019-03-20 04:25:38 +01002399 && _PyOS_optind < argv->length
2400 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
Victor Stinner4a1468e2019-03-20 03:11:38 +01002401 && config->run_filename == NULL)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002402 {
Victor Stinnerfa153762019-03-20 04:25:38 +01002403 config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002404 if (config->run_filename == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002405 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002406 }
2407 }
2408
2409 if (config->run_command != NULL || config->run_module != NULL) {
2410 /* Backup _PyOS_optind */
2411 _PyOS_optind--;
2412 }
2413
Victor Stinnerae239f62019-05-16 17:02:56 +02002414 *opt_index = _PyOS_optind;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002415
Victor Stinner331a6a52019-05-27 16:39:22 +02002416 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002417}
2418
2419
2420#ifdef MS_WINDOWS
2421# define WCSTOK wcstok_s
2422#else
2423# define WCSTOK wcstok
2424#endif
2425
2426/* Get warning options from PYTHONWARNINGS environment variable. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002427static PyStatus
2428config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002429{
Victor Stinner331a6a52019-05-27 16:39:22 +02002430 PyStatus status;
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002431 /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
2432 wchar_t *env = NULL;
Victor Stinner331a6a52019-05-27 16:39:22 +02002433 status = CONFIG_GET_ENV_DUP(config, &env,
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002434 L"PYTHONWARNINGS", "PYTHONWARNINGS");
Victor Stinner331a6a52019-05-27 16:39:22 +02002435 if (_PyStatus_EXCEPTION(status)) {
2436 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002437 }
2438
Victor Stinner1a9f0d82019-05-01 15:22:52 +02002439 /* env var is not set or is empty */
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002440 if (env == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002441 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002442 }
2443
2444
2445 wchar_t *warning, *context = NULL;
2446 for (warning = WCSTOK(env, L",", &context);
2447 warning != NULL;
2448 warning = WCSTOK(NULL, L",", &context))
2449 {
Victor Stinner331a6a52019-05-27 16:39:22 +02002450 status = PyWideStringList_Append(warnoptions, warning);
2451 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002452 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002453 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002454 }
2455 }
2456 PyMem_RawFree(env);
Victor Stinner331a6a52019-05-27 16:39:22 +02002457 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002458}
2459
2460
Victor Stinner331a6a52019-05-27 16:39:22 +02002461static PyStatus
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002462warnoptions_append(PyConfig *config, PyWideStringList *options,
2463 const wchar_t *option)
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002464{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002465 /* config_init_warnoptions() add existing config warnoptions at the end:
2466 ensure that the new option is not already present in this list to
Christian Claussccd82a02021-10-07 17:30:08 +02002467 prevent change the options order when config_init_warnoptions() is
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002468 called twice. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002469 if (_PyWideStringList_Find(&config->warnoptions, option)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002470 /* Already present: do nothing */
Victor Stinner331a6a52019-05-27 16:39:22 +02002471 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002472 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002473 if (_PyWideStringList_Find(options, option)) {
2474 /* Already present: do nothing */
2475 return _PyStatus_OK();
2476 }
2477 return PyWideStringList_Append(options, option);
2478}
2479
2480
2481static PyStatus
2482warnoptions_extend(PyConfig *config, PyWideStringList *options,
2483 const PyWideStringList *options2)
2484{
2485 const Py_ssize_t len = options2->length;
2486 wchar_t *const *items = options2->items;
2487
2488 for (Py_ssize_t i = 0; i < len; i++) {
2489 PyStatus status = warnoptions_append(config, options, items[i]);
2490 if (_PyStatus_EXCEPTION(status)) {
2491 return status;
2492 }
2493 }
2494 return _PyStatus_OK();
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002495}
2496
2497
Victor Stinner331a6a52019-05-27 16:39:22 +02002498static PyStatus
2499config_init_warnoptions(PyConfig *config,
2500 const PyWideStringList *cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002501 const PyWideStringList *env_warnoptions,
2502 const PyWideStringList *sys_warnoptions)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002503{
Victor Stinner331a6a52019-05-27 16:39:22 +02002504 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002505 PyWideStringList options = _PyWideStringList_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002506
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002507 /* Priority of warnings options, lowest to highest:
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002508 *
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002509 * - any implicit filters added by _warnings.c/warnings.py
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002510 * - PyConfig.dev_mode: "default" filter
2511 * - PYTHONWARNINGS environment variable
2512 * - '-W' command line options
2513 * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
2514 * "default::BytesWarning" or "error::BytesWarning" filter
2515 * - early PySys_AddWarnOption() calls
2516 * - PyConfig.warnoptions
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002517 *
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002518 * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
2519 * module works on the basis of "the most recently added filter will be
2520 * checked first", we add the lowest precedence entries first so that later
2521 * entries override them.
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002522 */
2523
Victor Stinner20004952019-03-26 02:31:11 +01002524 if (config->dev_mode) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002525 status = warnoptions_append(config, &options, L"default");
Victor Stinner331a6a52019-05-27 16:39:22 +02002526 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002527 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002528 }
2529 }
2530
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002531 status = warnoptions_extend(config, &options, env_warnoptions);
2532 if (_PyStatus_EXCEPTION(status)) {
2533 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002534 }
2535
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002536 status = warnoptions_extend(config, &options, cmdline_warnoptions);
2537 if (_PyStatus_EXCEPTION(status)) {
2538 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002539 }
2540
2541 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
2542 * don't even try to emit a warning, so we skip setting the filter in that
2543 * case.
2544 */
2545 if (config->bytes_warning) {
Victor Stinner74f65682019-03-15 15:08:05 +01002546 const wchar_t *filter;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002547 if (config->bytes_warning> 1) {
2548 filter = L"error::BytesWarning";
2549 }
2550 else {
2551 filter = L"default::BytesWarning";
2552 }
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002553 status = warnoptions_append(config, &options, filter);
Victor Stinner331a6a52019-05-27 16:39:22 +02002554 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002555 goto error;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002556 }
2557 }
Victor Stinner120b7072019-08-23 18:03:08 +01002558
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002559 status = warnoptions_extend(config, &options, sys_warnoptions);
Victor Stinner120b7072019-08-23 18:03:08 +01002560 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002561 goto error;
Victor Stinner120b7072019-08-23 18:03:08 +01002562 }
2563
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002564 /* Always add all PyConfig.warnoptions options */
2565 status = _PyWideStringList_Extend(&options, &config->warnoptions);
2566 if (_PyStatus_EXCEPTION(status)) {
2567 goto error;
2568 }
2569
2570 _PyWideStringList_Clear(&config->warnoptions);
2571 config->warnoptions = options;
Victor Stinner331a6a52019-05-27 16:39:22 +02002572 return _PyStatus_OK();
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002573
2574error:
2575 _PyWideStringList_Clear(&options);
2576 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002577}
2578
2579
Victor Stinner331a6a52019-05-27 16:39:22 +02002580static PyStatus
2581config_update_argv(PyConfig *config, Py_ssize_t opt_index)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002582{
Victor Stinner331a6a52019-05-27 16:39:22 +02002583 const PyWideStringList *cmdline_argv = &config->argv;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002584 PyWideStringList config_argv = _PyWideStringList_INIT;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002585
Victor Stinner74f65682019-03-15 15:08:05 +01002586 /* Copy argv to be able to modify it (to force -c/-m) */
Victor Stinnerae239f62019-05-16 17:02:56 +02002587 if (cmdline_argv->length <= opt_index) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002588 /* Ensure at least one (empty) argument is seen */
Victor Stinner331a6a52019-05-27 16:39:22 +02002589 PyStatus status = PyWideStringList_Append(&config_argv, L"");
2590 if (_PyStatus_EXCEPTION(status)) {
2591 return status;
Victor Stinner74f65682019-03-15 15:08:05 +01002592 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002593 }
2594 else {
Victor Stinner331a6a52019-05-27 16:39:22 +02002595 PyWideStringList slice;
Victor Stinnerae239f62019-05-16 17:02:56 +02002596 slice.length = cmdline_argv->length - opt_index;
2597 slice.items = &cmdline_argv->items[opt_index];
Victor Stinner331a6a52019-05-27 16:39:22 +02002598 if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
2599 return _PyStatus_NO_MEMORY();
Victor Stinner74f65682019-03-15 15:08:05 +01002600 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002601 }
Victor Stinnerfa153762019-03-20 04:25:38 +01002602 assert(config_argv.length >= 1);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002603
2604 wchar_t *arg0 = NULL;
2605 if (config->run_command != NULL) {
2606 /* Force sys.argv[0] = '-c' */
2607 arg0 = L"-c";
2608 }
2609 else if (config->run_module != NULL) {
2610 /* Force sys.argv[0] = '-m'*/
2611 arg0 = L"-m";
2612 }
Victor Stinner3939c322019-06-25 15:02:43 +02002613
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002614 if (arg0 != NULL) {
2615 arg0 = _PyMem_RawWcsdup(arg0);
2616 if (arg0 == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002617 _PyWideStringList_Clear(&config_argv);
2618 return _PyStatus_NO_MEMORY();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002619 }
2620
Victor Stinnerfa153762019-03-20 04:25:38 +01002621 PyMem_RawFree(config_argv.items[0]);
2622 config_argv.items[0] = arg0;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002623 }
2624
Victor Stinner331a6a52019-05-27 16:39:22 +02002625 _PyWideStringList_Clear(&config->argv);
Victor Stinnerfa153762019-03-20 04:25:38 +01002626 config->argv = config_argv;
Victor Stinner331a6a52019-05-27 16:39:22 +02002627 return _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002628}
2629
2630
Victor Stinner331a6a52019-05-27 16:39:22 +02002631static PyStatus
2632core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
Victor Stinner5ac27a52019-03-27 13:40:14 +01002633{
Victor Stinner331a6a52019-05-27 16:39:22 +02002634 PyStatus status;
Victor Stinner5ac27a52019-03-27 13:40:14 +01002635
Victor Stinnerdc42af82020-11-05 18:58:07 +01002636 if (config->parse_argv == 1) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002637 if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
2638 return _PyStatus_NO_MEMORY();
Victor Stinnercab5d072019-05-17 19:01:14 +02002639 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002640 }
2641
Victor Stinner331a6a52019-05-27 16:39:22 +02002642 PyPreConfig preconfig;
Victor Stinner441b10c2019-09-28 04:28:35 +02002643
2644 status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
2645 if (_PyStatus_EXCEPTION(status)) {
2646 return status;
2647 }
Victor Stinner5ac27a52019-03-27 13:40:14 +01002648
Victor Stinner331a6a52019-05-27 16:39:22 +02002649 _PyPreConfig_GetConfig(&preconfig, config);
Victor Stinner5ac27a52019-03-27 13:40:14 +01002650
Victor Stinner331a6a52019-05-27 16:39:22 +02002651 status = _PyPreCmdline_Read(precmdline, &preconfig);
2652 if (_PyStatus_EXCEPTION(status)) {
2653 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002654 }
2655
Victor Stinner331a6a52019-05-27 16:39:22 +02002656 status = _PyPreCmdline_SetConfig(precmdline, config);
2657 if (_PyStatus_EXCEPTION(status)) {
2658 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002659 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002660 return _PyStatus_OK();
Victor Stinner5ac27a52019-03-27 13:40:14 +01002661}
2662
2663
Victor Stinner3939c322019-06-25 15:02:43 +02002664/* Get run_filename absolute path */
2665static PyStatus
2666config_run_filename_abspath(PyConfig *config)
2667{
2668 if (!config->run_filename) {
2669 return _PyStatus_OK();
2670 }
2671
2672#ifndef MS_WINDOWS
2673 if (_Py_isabs(config->run_filename)) {
2674 /* path is already absolute */
2675 return _PyStatus_OK();
2676 }
2677#endif
2678
2679 wchar_t *abs_filename;
2680 if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
2681 /* failed to get the absolute path of the command line filename:
2682 ignore the error, keep the relative path */
2683 return _PyStatus_OK();
2684 }
2685 if (abs_filename == NULL) {
2686 return _PyStatus_NO_MEMORY();
2687 }
2688
2689 PyMem_RawFree(config->run_filename);
2690 config->run_filename = abs_filename;
2691 return _PyStatus_OK();
2692}
2693
2694
Victor Stinner331a6a52019-05-27 16:39:22 +02002695static PyStatus
2696config_read_cmdline(PyConfig *config)
Victor Stinner2f549082019-03-29 15:13:46 +01002697{
Victor Stinner331a6a52019-05-27 16:39:22 +02002698 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002699 PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
2700 PyWideStringList env_warnoptions = _PyWideStringList_INIT;
2701 PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
Victor Stinner2f549082019-03-29 15:13:46 +01002702
Victor Stinnerae239f62019-05-16 17:02:56 +02002703 if (config->parse_argv < 0) {
2704 config->parse_argv = 1;
Victor Stinner2f549082019-03-29 15:13:46 +01002705 }
Victor Stinner870b0352019-05-17 03:15:12 +02002706
Victor Stinnerfed02e12019-05-17 11:12:09 +02002707 if (config->program_name == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002708 status = config_init_program_name(config);
2709 if (_PyStatus_EXCEPTION(status)) {
2710 return status;
Victor Stinner870b0352019-05-17 03:15:12 +02002711 }
Victor Stinner54b43bb2019-05-16 18:30:15 +02002712 }
Victor Stinner2f549082019-03-29 15:13:46 +01002713
Victor Stinnerdc42af82020-11-05 18:58:07 +01002714 if (config->parse_argv == 1) {
Victor Stinnerb5947842019-05-18 00:38:16 +02002715 Py_ssize_t opt_index;
Victor Stinner331a6a52019-05-27 16:39:22 +02002716 status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
2717 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002718 goto done;
2719 }
2720
Victor Stinner3939c322019-06-25 15:02:43 +02002721 status = config_run_filename_abspath(config);
2722 if (_PyStatus_EXCEPTION(status)) {
2723 goto done;
2724 }
2725
Victor Stinner331a6a52019-05-27 16:39:22 +02002726 status = config_update_argv(config, opt_index);
2727 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerae239f62019-05-16 17:02:56 +02002728 goto done;
2729 }
Victor Stinner2f549082019-03-29 15:13:46 +01002730 }
Victor Stinner3939c322019-06-25 15:02:43 +02002731 else {
2732 status = config_run_filename_abspath(config);
2733 if (_PyStatus_EXCEPTION(status)) {
2734 goto done;
2735 }
2736 }
Victor Stinner2f549082019-03-29 15:13:46 +01002737
Victor Stinner2f549082019-03-29 15:13:46 +01002738 if (config->use_environment) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002739 status = config_init_env_warnoptions(config, &env_warnoptions);
2740 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002741 goto done;
2742 }
2743 }
2744
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002745 /* Handle early PySys_AddWarnOption() calls */
2746 status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
2747 if (_PyStatus_EXCEPTION(status)) {
2748 goto done;
2749 }
2750
Victor Stinner331a6a52019-05-27 16:39:22 +02002751 status = config_init_warnoptions(config,
Victor Stinner120b7072019-08-23 18:03:08 +01002752 &cmdline_warnoptions,
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002753 &env_warnoptions,
2754 &sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002755 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner2f549082019-03-29 15:13:46 +01002756 goto done;
2757 }
2758
Victor Stinner331a6a52019-05-27 16:39:22 +02002759 status = _PyStatus_OK();
Victor Stinner2f549082019-03-29 15:13:46 +01002760
2761done:
Victor Stinner331a6a52019-05-27 16:39:22 +02002762 _PyWideStringList_Clear(&cmdline_warnoptions);
2763 _PyWideStringList_Clear(&env_warnoptions);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02002764 _PyWideStringList_Clear(&sys_warnoptions);
Victor Stinner331a6a52019-05-27 16:39:22 +02002765 return status;
Victor Stinner2f549082019-03-29 15:13:46 +01002766}
2767
2768
Victor Stinner331a6a52019-05-27 16:39:22 +02002769PyStatus
2770_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
Victor Stinner5f38b842019-05-01 02:30:12 +02002771{
Victor Stinner331a6a52019-05-27 16:39:22 +02002772 PyStatus status = _Py_PreInitializeFromConfig(config, args);
2773 if (_PyStatus_EXCEPTION(status)) {
2774 return status;
Victor Stinner70005ac2019-05-02 15:25:34 -04002775 }
Victor Stinner6d1c4672019-05-20 11:02:00 +02002776
Victor Stinner5f38b842019-05-01 02:30:12 +02002777 return _PyArgv_AsWstrList(args, &config->argv);
2778}
2779
2780
Victor Stinner70005ac2019-05-02 15:25:34 -04002781/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
2782 if needed to ensure that encodings are properly configured. */
Victor Stinner331a6a52019-05-27 16:39:22 +02002783PyStatus
2784PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002785{
2786 _PyArgv args = {
2787 .argc = argc,
2788 .use_bytes_argv = 1,
2789 .bytes_argv = argv,
2790 .wchar_argv = NULL};
Victor Stinner331a6a52019-05-27 16:39:22 +02002791 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002792}
2793
2794
Victor Stinner331a6a52019-05-27 16:39:22 +02002795PyStatus
2796PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
Victor Stinner5f38b842019-05-01 02:30:12 +02002797{
2798 _PyArgv args = {
2799 .argc = argc,
2800 .use_bytes_argv = 0,
2801 .bytes_argv = NULL,
2802 .wchar_argv = argv};
Victor Stinner331a6a52019-05-27 16:39:22 +02002803 return _PyConfig_SetPyArgv(config, &args);
Victor Stinner5f38b842019-05-01 02:30:12 +02002804}
2805
2806
Victor Stinner36242fd2019-07-01 19:13:50 +02002807PyStatus
2808PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
2809 Py_ssize_t length, wchar_t **items)
2810{
2811 PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
2812 if (_PyStatus_EXCEPTION(status)) {
2813 return status;
2814 }
2815
2816 PyWideStringList list2 = {.length = length, .items = items};
2817 if (_PyWideStringList_Copy(list, &list2) < 0) {
2818 return _PyStatus_NO_MEMORY();
2819 }
2820 return _PyStatus_OK();
2821}
2822
2823
Victor Stinner331a6a52019-05-27 16:39:22 +02002824/* Read the configuration into PyConfig from:
Victor Stinner5a02e0d2019-03-05 12:32:09 +01002825
2826 * Command line arguments
2827 * Environment variables
Victor Stinner54b43bb2019-05-16 18:30:15 +02002828 * Py_xxx global configuration variables
2829
2830 The only side effects are to modify config and to call _Py_SetArgcArgv(). */
Victor Stinner331a6a52019-05-27 16:39:22 +02002831PyStatus
Victor Stinner9e1b8282020-11-10 13:21:52 +01002832_PyConfig_Read(PyConfig *config, int compute_path_config)
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002833{
Victor Stinner331a6a52019-05-27 16:39:22 +02002834 PyStatus status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002835
Victor Stinner331a6a52019-05-27 16:39:22 +02002836 status = _Py_PreInitializeFromConfig(config, NULL);
2837 if (_PyStatus_EXCEPTION(status)) {
2838 return status;
Victor Stinner6d5ee972019-03-23 12:05:43 +01002839 }
2840
Victor Stinner331a6a52019-05-27 16:39:22 +02002841 config_get_global_vars(config);
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002842
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002843 if (config->orig_argv.length == 0
Victor Stinnere81f6e62020-06-08 18:12:59 +02002844 && !(config->argv.length == 1
2845 && wcscmp(config->argv.items[0], L"") == 0))
2846 {
Victor Stinnerdd8a93e2020-06-30 00:49:03 +02002847 if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
Victor Stinnere81f6e62020-06-08 18:12:59 +02002848 return _PyStatus_NO_MEMORY();
2849 }
Victor Stinnercab5d072019-05-17 19:01:14 +02002850 }
2851
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002852 _PyPreCmdline precmdline = _PyPreCmdline_INIT;
Victor Stinner331a6a52019-05-27 16:39:22 +02002853 status = core_read_precmdline(config, &precmdline);
2854 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner5ac27a52019-03-27 13:40:14 +01002855 goto done;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002856 }
2857
Victor Stinner870b0352019-05-17 03:15:12 +02002858 assert(config->isolated >= 0);
2859 if (config->isolated) {
2860 config->use_environment = 0;
2861 config->user_site_directory = 0;
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002862 }
2863
Victor Stinner331a6a52019-05-27 16:39:22 +02002864 status = config_read_cmdline(config);
2865 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner870b0352019-05-17 03:15:12 +02002866 goto done;
2867 }
2868
Victor Stinner120b7072019-08-23 18:03:08 +01002869 /* Handle early PySys_AddXOption() calls */
2870 status = _PySys_ReadPreinitXOptions(config);
2871 if (_PyStatus_EXCEPTION(status)) {
2872 goto done;
2873 }
2874
Victor Stinner9e1b8282020-11-10 13:21:52 +01002875 status = config_read(config, compute_path_config);
Victor Stinner331a6a52019-05-27 16:39:22 +02002876 if (_PyStatus_EXCEPTION(status)) {
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002877 goto done;
2878 }
2879
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002880 assert(config_check_consistency(config));
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002881
Victor Stinner331a6a52019-05-27 16:39:22 +02002882 status = _PyStatus_OK();
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002883
2884done:
Victor Stinnerf8ba6f52019-03-26 16:58:50 +01002885 _PyPreCmdline_Clear(&precmdline);
Victor Stinner331a6a52019-05-27 16:39:22 +02002886 return status;
Victor Stinner95e2cbf2019-03-01 16:25:19 +01002887}
Victor Stinner1075d162019-03-25 23:19:57 +01002888
2889
Victor Stinner9e1b8282020-11-10 13:21:52 +01002890PyStatus
2891PyConfig_Read(PyConfig *config)
2892{
2893 return _PyConfig_Read(config, 1);
2894}
2895
2896
Victor Stinner1075d162019-03-25 23:19:57 +01002897PyObject*
2898_Py_GetConfigsAsDict(void)
2899{
Victor Stinner331a6a52019-05-27 16:39:22 +02002900 PyObject *result = NULL;
Victor Stinner1075d162019-03-25 23:19:57 +01002901 PyObject *dict = NULL;
2902
Victor Stinner331a6a52019-05-27 16:39:22 +02002903 result = PyDict_New();
2904 if (result == NULL) {
Victor Stinner1075d162019-03-25 23:19:57 +01002905 goto error;
2906 }
2907
Victor Stinner331a6a52019-05-27 16:39:22 +02002908 /* global result */
Victor Stinner1075d162019-03-25 23:19:57 +01002909 dict = _Py_GetGlobalVariablesAsDict();
2910 if (dict == NULL) {
2911 goto error;
2912 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002913 if (PyDict_SetItemString(result, "global_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002914 goto error;
2915 }
2916 Py_CLEAR(dict);
2917
2918 /* pre config */
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002919 PyInterpreterState *interp = _PyInterpreterState_GET();
2920 const PyPreConfig *pre_config = &interp->runtime->preconfig;
Victor Stinner1075d162019-03-25 23:19:57 +01002921 dict = _PyPreConfig_AsDict(pre_config);
2922 if (dict == NULL) {
2923 goto error;
2924 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002925 if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002926 goto error;
2927 }
2928 Py_CLEAR(dict);
2929
2930 /* core config */
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002931 const PyConfig *config = _PyInterpreterState_GetConfig(interp);
Victor Stinnerf3cb8142020-11-05 18:12:33 +01002932 dict = _PyConfig_AsDict(config);
Victor Stinner1075d162019-03-25 23:19:57 +01002933 if (dict == NULL) {
2934 goto error;
2935 }
Victor Stinner331a6a52019-05-27 16:39:22 +02002936 if (PyDict_SetItemString(result, "config", dict) < 0) {
Victor Stinner1075d162019-03-25 23:19:57 +01002937 goto error;
2938 }
2939 Py_CLEAR(dict);
2940
Victor Stinner8f427482020-07-08 00:20:37 +02002941 /* path config */
2942 dict = _PyPathConfig_AsDict();
2943 if (dict == NULL) {
2944 goto error;
2945 }
2946 if (PyDict_SetItemString(result, "path_config", dict) < 0) {
2947 goto error;
2948 }
2949 Py_CLEAR(dict);
2950
Victor Stinner331a6a52019-05-27 16:39:22 +02002951 return result;
Victor Stinner1075d162019-03-25 23:19:57 +01002952
2953error:
Victor Stinner331a6a52019-05-27 16:39:22 +02002954 Py_XDECREF(result);
Victor Stinner1075d162019-03-25 23:19:57 +01002955 Py_XDECREF(dict);
2956 return NULL;
2957}
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002958
2959
2960static void
2961init_dump_ascii_wstr(const wchar_t *str)
2962{
2963 if (str == NULL) {
2964 PySys_WriteStderr("(not set)");
Victor Stinner88e64472019-09-23 15:35:46 +02002965 return;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002966 }
2967
2968 PySys_WriteStderr("'");
2969 for (; *str != L'\0'; str++) {
Victor Stinner640e8e12020-09-09 12:07:17 +02002970 unsigned int ch = (unsigned int)*str;
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002971 if (ch == L'\'') {
2972 PySys_WriteStderr("\\'");
2973 } else if (0x20 <= ch && ch < 0x7f) {
Samuel Marksc3229482020-09-21 18:35:17 +10002974 PySys_WriteStderr("%c", ch);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02002975 }
2976 else if (ch <= 0xff) {
2977 PySys_WriteStderr("\\x%02x", ch);
2978 }
2979#if SIZEOF_WCHAR_T > 2
2980 else if (ch > 0xffff) {
2981 PySys_WriteStderr("\\U%08x", ch);
2982 }
2983#endif
2984 else {
2985 PySys_WriteStderr("\\u%04x", ch);
2986 }
2987 }
2988 PySys_WriteStderr("'");
2989}
2990
2991
2992/* Dump the Python path configuration into sys.stderr */
2993void
2994_Py_DumpPathConfig(PyThreadState *tstate)
2995{
2996 PyObject *exc_type, *exc_value, *exc_tb;
2997 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
2998
2999 PySys_WriteStderr("Python path configuration:\n");
3000
3001#define DUMP_CONFIG(NAME, FIELD) \
3002 do { \
3003 PySys_WriteStderr(" " NAME " = "); \
3004 init_dump_ascii_wstr(config->FIELD); \
3005 PySys_WriteStderr("\n"); \
3006 } while (0)
3007
Victor Stinnerda7933e2020-04-13 03:04:28 +02003008 const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003009 DUMP_CONFIG("PYTHONHOME", home);
3010 DUMP_CONFIG("PYTHONPATH", pythonpath_env);
3011 DUMP_CONFIG("program name", program_name);
3012 PySys_WriteStderr(" isolated = %i\n", config->isolated);
3013 PySys_WriteStderr(" environment = %i\n", config->use_environment);
3014 PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
3015 PySys_WriteStderr(" import site = %i\n", config->site_import);
3016#undef DUMP_CONFIG
3017
3018#define DUMP_SYS(NAME) \
3019 do { \
3020 obj = PySys_GetObject(#NAME); \
3021 PySys_FormatStderr(" sys.%s = ", #NAME); \
3022 if (obj != NULL) { \
3023 PySys_FormatStderr("%A", obj); \
3024 } \
3025 else { \
3026 PySys_WriteStderr("(not set)"); \
3027 } \
3028 PySys_FormatStderr("\n"); \
3029 } while (0)
3030
3031 PyObject *obj;
3032 DUMP_SYS(_base_executable);
3033 DUMP_SYS(base_prefix);
3034 DUMP_SYS(base_exec_prefix);
Sandro Mani8f023a22020-06-08 17:28:11 +02003035 DUMP_SYS(platlibdir);
Victor Stinnerfcdb0272019-09-23 14:45:47 +02003036 DUMP_SYS(executable);
3037 DUMP_SYS(prefix);
3038 DUMP_SYS(exec_prefix);
3039#undef DUMP_SYS
3040
3041 PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
3042 if (sys_path != NULL && PyList_Check(sys_path)) {
3043 PySys_WriteStderr(" sys.path = [\n");
3044 Py_ssize_t len = PyList_GET_SIZE(sys_path);
3045 for (Py_ssize_t i=0; i < len; i++) {
3046 PyObject *path = PyList_GET_ITEM(sys_path, i);
3047 PySys_FormatStderr(" %A,\n", path);
3048 }
3049 PySys_WriteStderr(" ]\n");
3050 }
3051
3052 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
3053}